x402-trust-layer 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/DEPLOY.md +53 -0
- package/Dockerfile +30 -0
- package/LICENSE +21 -0
- package/README.md +294 -0
- package/dist/agents/a2a-payment.d.ts +37 -0
- package/dist/agents/a2a-payment.js +105 -0
- package/dist/agents/agent-escrow.d.ts +30 -0
- package/dist/agents/agent-escrow.js +23 -0
- package/dist/agents/agent-verify.d.ts +15 -0
- package/dist/agents/agent-verify.js +112 -0
- package/dist/agents/api-router.d.ts +32 -0
- package/dist/agents/api-router.js +228 -0
- package/dist/agents/attestation-registry.d.ts +35 -0
- package/dist/agents/attestation-registry.js +76 -0
- package/dist/agents/audition-coach.d.ts +45 -0
- package/dist/agents/audition-coach.js +257 -0
- package/dist/agents/bedrock-bridge.d.ts +3 -0
- package/dist/agents/bedrock-bridge.js +60 -0
- package/dist/agents/budget-allocator.d.ts +24 -0
- package/dist/agents/budget-allocator.js +31 -0
- package/dist/agents/compliance-ledger.d.ts +66 -0
- package/dist/agents/compliance-ledger.js +80 -0
- package/dist/agents/dispute-resolver.d.ts +62 -0
- package/dist/agents/dispute-resolver.js +124 -0
- package/dist/agents/evidence-locker.d.ts +30 -0
- package/dist/agents/evidence-locker.js +47 -0
- package/dist/agents/facilitator-failover.d.ts +15 -0
- package/dist/agents/facilitator-failover.js +18 -0
- package/dist/agents/identity-gate.d.ts +20 -0
- package/dist/agents/identity-gate.js +79 -0
- package/dist/agents/mandate-compiler.d.ts +51 -0
- package/dist/agents/mandate-compiler.js +73 -0
- package/dist/agents/mandate-diff.d.ts +41 -0
- package/dist/agents/mandate-diff.js +170 -0
- package/dist/agents/market-buy-advisor.d.ts +65 -0
- package/dist/agents/market-buy-advisor.js +234 -0
- package/dist/agents/merchant-trust.d.ts +38 -0
- package/dist/agents/merchant-trust.js +171 -0
- package/dist/agents/mpp-session-broker.d.ts +27 -0
- package/dist/agents/mpp-session-broker.js +29 -0
- package/dist/agents/mpp-session-v2.d.ts +76 -0
- package/dist/agents/mpp-session-v2.js +269 -0
- package/dist/agents/payment-intent-compiler.d.ts +21 -0
- package/dist/agents/payment-intent-compiler.js +45 -0
- package/dist/agents/pipeline-execute.d.ts +40 -0
- package/dist/agents/pipeline-execute.js +100 -0
- package/dist/agents/pipeline-trust-v2.d.ts +31 -0
- package/dist/agents/pipeline-trust-v2.js +111 -0
- package/dist/agents/pre-x402-guard.d.ts +35 -0
- package/dist/agents/pre-x402-guard.js +84 -0
- package/dist/agents/quality-escrow-semantic.d.ts +88 -0
- package/dist/agents/quality-escrow-semantic.js +137 -0
- package/dist/agents/quality-escrow.d.ts +65 -0
- package/dist/agents/quality-escrow.js +104 -0
- package/dist/agents/quality-monitor.d.ts +32 -0
- package/dist/agents/quality-monitor.js +77 -0
- package/dist/agents/rail-optimizer.d.ts +33 -0
- package/dist/agents/rail-optimizer.js +133 -0
- package/dist/agents/receipt-auditor.d.ts +14 -0
- package/dist/agents/receipt-auditor.js +145 -0
- package/dist/agents/refund-arbiter.d.ts +24 -0
- package/dist/agents/refund-arbiter.js +70 -0
- package/dist/agents/research-brief.d.ts +14 -0
- package/dist/agents/research-brief.js +66 -0
- package/dist/agents/risk-gate.d.ts +11 -0
- package/dist/agents/risk-gate.js +78 -0
- package/dist/agents/settlement-graph.d.ts +16 -0
- package/dist/agents/settlement-graph.js +38 -0
- package/dist/agents/spend-governor.d.ts +2 -0
- package/dist/agents/spend-governor.js +70 -0
- package/dist/agents/trust-network.d.ts +138 -0
- package/dist/agents/trust-network.js +244 -0
- package/dist/agents/x402-proxy.d.ts +32 -0
- package/dist/agents/x402-proxy.js +90 -0
- package/dist/client/demo-alchemy-live.d.ts +1 -0
- package/dist/client/demo-alchemy-live.js +226 -0
- package/dist/client/demo-tail.d.ts +1 -0
- package/dist/client/demo-tail.js +100 -0
- package/dist/client/demo.d.ts +1 -0
- package/dist/client/demo.js +293 -0
- package/dist/config.d.ts +94 -0
- package/dist/config.js +223 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +389 -0
- package/dist/lib/agent-response.d.ts +14 -0
- package/dist/lib/agent-response.js +13 -0
- package/dist/lib/agentic-gateways.d.ts +5 -0
- package/dist/lib/agentic-gateways.js +15 -0
- package/dist/lib/agentic-probes.d.ts +10 -0
- package/dist/lib/agentic-probes.js +49 -0
- package/dist/lib/alchemy-x402-fetch.d.ts +16 -0
- package/dist/lib/alchemy-x402-fetch.js +95 -0
- package/dist/lib/apply-verifier-body.d.ts +7 -0
- package/dist/lib/apply-verifier-body.js +179 -0
- package/dist/lib/attestation.d.ts +30 -0
- package/dist/lib/attestation.js +107 -0
- package/dist/lib/bazaar-extension.d.ts +15 -0
- package/dist/lib/bazaar-extension.js +265 -0
- package/dist/lib/bazaar.d.ts +100 -0
- package/dist/lib/bazaar.js +341 -0
- package/dist/lib/certified-sellers.d.ts +41 -0
- package/dist/lib/certified-sellers.js +129 -0
- package/dist/lib/chains.d.ts +20 -0
- package/dist/lib/chains.js +78 -0
- package/dist/lib/db-persistence.d.ts +7 -0
- package/dist/lib/db-persistence.js +65 -0
- package/dist/lib/db.d.ts +5 -0
- package/dist/lib/db.js +113 -0
- package/dist/lib/discovery-page.d.ts +2 -0
- package/dist/lib/discovery-page.js +71 -0
- package/dist/lib/ecosystem-telemetry.d.ts +20 -0
- package/dist/lib/ecosystem-telemetry.js +80 -0
- package/dist/lib/erc8004/agent-card.d.ts +34 -0
- package/dist/lib/erc8004/agent-card.js +151 -0
- package/dist/lib/erc8004/cache.d.ts +3 -0
- package/dist/lib/erc8004/cache.js +17 -0
- package/dist/lib/erc8004/constants.d.ts +22 -0
- package/dist/lib/erc8004/constants.js +35 -0
- package/dist/lib/erc8004/registry.d.ts +19 -0
- package/dist/lib/erc8004/registry.js +171 -0
- package/dist/lib/erc8004/resolve-agent.d.ts +7 -0
- package/dist/lib/erc8004/resolve-agent.js +70 -0
- package/dist/lib/erc8004/trust-score.d.ts +33 -0
- package/dist/lib/erc8004/trust-score.js +136 -0
- package/dist/lib/escrow-ledger.d.ts +14 -0
- package/dist/lib/escrow-ledger.js +54 -0
- package/dist/lib/escrow-unified.d.ts +15 -0
- package/dist/lib/escrow-unified.js +28 -0
- package/dist/lib/facilitator-extra.d.ts +13 -0
- package/dist/lib/facilitator-extra.js +52 -0
- package/dist/lib/facilitators.d.ts +20 -0
- package/dist/lib/facilitators.js +89 -0
- package/dist/lib/host-policy.d.ts +4 -0
- package/dist/lib/host-policy.js +20 -0
- package/dist/lib/idempotency.d.ts +4 -0
- package/dist/lib/idempotency.js +120 -0
- package/dist/lib/ledger.d.ts +2 -0
- package/dist/lib/ledger.js +17 -0
- package/dist/lib/logger.d.ts +6 -0
- package/dist/lib/logger.js +24 -0
- package/dist/lib/mandate-vc.d.ts +20 -0
- package/dist/lib/mandate-vc.js +25 -0
- package/dist/lib/mandate.d.ts +44 -0
- package/dist/lib/mandate.js +190 -0
- package/dist/lib/marketplace.d.ts +7 -0
- package/dist/lib/marketplace.js +127 -0
- package/dist/lib/migrations.d.ts +2 -0
- package/dist/lib/migrations.js +130 -0
- package/dist/lib/nonce-store.d.ts +6 -0
- package/dist/lib/nonce-store.js +109 -0
- package/dist/lib/openapi-agentcash.d.ts +5 -0
- package/dist/lib/openapi-agentcash.js +288 -0
- package/dist/lib/openapi-meta.d.ts +5 -0
- package/dist/lib/openapi-meta.js +235 -0
- package/dist/lib/otel.d.ts +2 -0
- package/dist/lib/otel.js +25 -0
- package/dist/lib/paid-resource-url.d.ts +6 -0
- package/dist/lib/paid-resource-url.js +47 -0
- package/dist/lib/parse-with-verifier-fallback.d.ts +3 -0
- package/dist/lib/parse-with-verifier-fallback.js +13 -0
- package/dist/lib/payment-request-context.d.ts +10 -0
- package/dist/lib/payment-request-context.js +5 -0
- package/dist/lib/payment-response.d.ts +13 -0
- package/dist/lib/payment-response.js +39 -0
- package/dist/lib/payto-guard.d.ts +10 -0
- package/dist/lib/payto-guard.js +20 -0
- package/dist/lib/probe.d.ts +29 -0
- package/dist/lib/probe.js +157 -0
- package/dist/lib/problem-detail.d.ts +10 -0
- package/dist/lib/problem-detail.js +14 -0
- package/dist/lib/rate-limit.d.ts +12 -0
- package/dist/lib/rate-limit.js +126 -0
- package/dist/lib/replay-middleware.d.ts +3 -0
- package/dist/lib/replay-middleware.js +27 -0
- package/dist/lib/response-guard.d.ts +5 -0
- package/dist/lib/response-guard.js +40 -0
- package/dist/lib/safe-fetch.d.ts +5 -0
- package/dist/lib/safe-fetch.js +19 -0
- package/dist/lib/security.d.ts +13 -0
- package/dist/lib/security.js +61 -0
- package/dist/lib/semantic-judge.d.ts +14 -0
- package/dist/lib/semantic-judge.js +107 -0
- package/dist/lib/semantic-judge.test.d.ts +1 -0
- package/dist/lib/semantic-judge.test.js +11 -0
- package/dist/lib/ssrf.d.ts +10 -0
- package/dist/lib/ssrf.js +130 -0
- package/dist/lib/ssrf.test.d.ts +1 -0
- package/dist/lib/ssrf.test.js +16 -0
- package/dist/lib/suite-catalog.d.ts +83 -0
- package/dist/lib/suite-catalog.js +131 -0
- package/dist/lib/telemetry.d.ts +5 -0
- package/dist/lib/telemetry.js +37 -0
- package/dist/lib/verifier-fast-path.d.ts +10 -0
- package/dist/lib/verifier-fast-path.js +44 -0
- package/dist/lib/verifier-probe-protocol.d.ts +7 -0
- package/dist/lib/verifier-probe-protocol.js +115 -0
- package/dist/lib/verify-examples.d.ts +2 -0
- package/dist/lib/verify-examples.js +438 -0
- package/dist/lib/version.d.ts +2 -0
- package/dist/lib/version.js +2 -0
- package/dist/lib/webhook-auth.d.ts +3 -0
- package/dist/lib/webhook-auth.js +34 -0
- package/dist/lib/webhook-routes.d.ts +2 -0
- package/dist/lib/webhook-routes.js +112 -0
- package/dist/lib/webhooks.d.ts +23 -0
- package/dist/lib/webhooks.js +123 -0
- package/dist/lib/webhooks.test.d.ts +1 -0
- package/dist/lib/webhooks.test.js +16 -0
- package/dist/lib/x402-client-options.d.ts +28 -0
- package/dist/lib/x402-client-options.js +138 -0
- package/dist/lib/x402-headers.d.ts +10 -0
- package/dist/lib/x402-headers.js +27 -0
- package/dist/lib/x402-paid.d.ts +5 -0
- package/dist/lib/x402-paid.js +252 -0
- package/dist/lib/x402-payment-replay.d.ts +22 -0
- package/dist/lib/x402-payment-replay.js +57 -0
- package/dist/lib/x402gle-host-verify.d.ts +3 -0
- package/dist/lib/x402gle-host-verify.js +27 -0
- package/dist/protocol/agent-passport.d.ts +34 -0
- package/dist/protocol/agent-passport.js +44 -0
- package/dist/protocol/compliance-v2.d.ts +21 -0
- package/dist/protocol/compliance-v2.js +19 -0
- package/dist/protocol/credit-bureau.d.ts +18 -0
- package/dist/protocol/credit-bureau.js +44 -0
- package/dist/protocol/crypto.d.ts +6 -0
- package/dist/protocol/crypto.js +41 -0
- package/dist/protocol/escrow-fsm.d.ts +33 -0
- package/dist/protocol/escrow-fsm.js +99 -0
- package/dist/protocol/fraud-engine.d.ts +28 -0
- package/dist/protocol/fraud-engine.js +77 -0
- package/dist/protocol/observability.d.ts +14 -0
- package/dist/protocol/observability.js +21 -0
- package/dist/protocol/pipeline-full-trust.d.ts +40 -0
- package/dist/protocol/pipeline-full-trust.js +96 -0
- package/dist/protocol/proof-of-execution.d.ts +36 -0
- package/dist/protocol/proof-of-execution.js +48 -0
- package/dist/protocol/reasoning-audit.d.ts +27 -0
- package/dist/protocol/reasoning-audit.js +51 -0
- package/dist/protocol/replay-guard.d.ts +28 -0
- package/dist/protocol/replay-guard.js +76 -0
- package/dist/protocol/replay-guard.test.d.ts +1 -0
- package/dist/protocol/replay-guard.test.js +10 -0
- package/dist/protocol/security-audit.d.ts +18 -0
- package/dist/protocol/security-audit.js +45 -0
- package/dist/protocol/store.d.ts +5 -0
- package/dist/protocol/store.js +59 -0
- package/dist/protocol/threat-catalog.d.ts +13 -0
- package/dist/protocol/threat-catalog.js +75 -0
- package/dist/protocol/trust-oracle.d.ts +23 -0
- package/dist/protocol/trust-oracle.js +30 -0
- package/dist/protocol/trust-score-v2.d.ts +33 -0
- package/dist/protocol/trust-score-v2.js +78 -0
- package/dist/protocol/zk-proofs.d.ts +24 -0
- package/dist/protocol/zk-proofs.js +32 -0
- package/dist/routes/a2a-agent-card.d.ts +3 -0
- package/dist/routes/a2a-agent-card.js +28 -0
- package/dist/routes/catalog.d.ts +5 -0
- package/dist/routes/catalog.js +47 -0
- package/dist/routes/register-all.d.ts +3 -0
- package/dist/routes/register-all.js +1240 -0
- package/dist/routes/schemas.d.ts +83 -0
- package/dist/routes/schemas.js +38 -0
- package/dist/routes/shared.d.ts +16 -0
- package/dist/routes/shared.js +27 -0
- package/dist/routes-protocol.d.ts +10 -0
- package/dist/routes-protocol.js +322 -0
- package/dist/routes.d.ts +2 -0
- package/dist/routes.js +2 -0
- package/dist/types.d.ts +66 -0
- package/dist/types.js +1 -0
- package/openapi.json +7940 -0
- package/package.json +124 -0
- package/public/.well-known/ai-plugin.json +12 -0
- package/public/assets/aegis-logo-blue.png +0 -0
- package/public/assets/aegis-logo-gold.png +0 -0
- package/public/assets/aegis-logo-green.png +0 -0
- package/public/assets/aegis-logo-purple.png +0 -0
- package/public/assets/aegis-logo-red.png +0 -0
- package/public/assets/aegis-logo-white.png +0 -0
- package/public/assets/aegis-logo.png +0 -0
- package/public/assets/x402-trustlayer-logo.png +0 -0
- package/public/assets/x402-trustlayer-logo.svg +5 -0
- package/public/data/agents.json +1528 -0
- package/public/index.html +198 -0
- package/public/landing.css +342 -0
- package/public/landing.js +405 -0
- package/public/llms-full.txt +582 -0
- package/public/llms.txt +132 -0
- package/public/skill.md +135 -0
- package/railway.toml +9 -0
- package/scripts/docker-entrypoint.sh +7 -0
- package/scripts/patch-facilitator-timeout.mjs +61 -0
package/dist/lib/db.d.ts
ADDED
package/dist/lib/db.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { mkdirSync } from "node:fs";
|
|
4
|
+
import { runMigrations } from "./migrations.js";
|
|
5
|
+
export function resolveDbPath() {
|
|
6
|
+
const explicit = process.env.DB_PATH?.trim();
|
|
7
|
+
if (explicit)
|
|
8
|
+
return explicit;
|
|
9
|
+
const dataDir = process.env.DATA_DIR?.trim() || path.join(process.cwd(), "data");
|
|
10
|
+
return path.join(dataDir, "trust-layer.db");
|
|
11
|
+
}
|
|
12
|
+
const DB_PATH = resolveDbPath();
|
|
13
|
+
function ensureDataDirWritable() {
|
|
14
|
+
const dir = path.dirname(DB_PATH);
|
|
15
|
+
try {
|
|
16
|
+
mkdirSync(dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
20
|
+
throw new Error(`Cannot create data directory ${dir} (${msg}). ` +
|
|
21
|
+
`On Railway, mount the volume at /app/data and set DATA_DIR=/app/data (or omit DATA_DIR). ` +
|
|
22
|
+
`SQLITE_CANTOPEN often means the volume is not writable by the app user.`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
ensureDataDirWritable();
|
|
26
|
+
let db;
|
|
27
|
+
try {
|
|
28
|
+
db = new Database(DB_PATH);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
|
|
32
|
+
if (code === "SQLITE_CANTOPEN") {
|
|
33
|
+
throw new Error(`Cannot open SQLite database at ${DB_PATH}. ` +
|
|
34
|
+
`Check DATA_DIR matches the volume mount (use /app/data). ` +
|
|
35
|
+
`Redeploy with the docker entrypoint that chowns the volume, or fix volume permissions.`, { cause: err });
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
export { db };
|
|
40
|
+
db.pragma("journal_mode = WAL");
|
|
41
|
+
db.pragma("foreign_keys = ON");
|
|
42
|
+
db.exec(`
|
|
43
|
+
CREATE TABLE IF NOT EXISTS attestations (
|
|
44
|
+
id TEXT PRIMARY KEY,
|
|
45
|
+
agent_id TEXT NOT NULL,
|
|
46
|
+
wallet_address TEXT NOT NULL,
|
|
47
|
+
payload JSON NOT NULL,
|
|
48
|
+
hmac_signature TEXT NOT NULL,
|
|
49
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
50
|
+
expires_at INTEGER,
|
|
51
|
+
revoked INTEGER NOT NULL DEFAULT 0
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
CREATE TABLE IF NOT EXISTS spend_ledger (
|
|
55
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
56
|
+
agent_id TEXT NOT NULL,
|
|
57
|
+
wallet_address TEXT,
|
|
58
|
+
endpoint TEXT,
|
|
59
|
+
amount_usdc REAL NOT NULL,
|
|
60
|
+
network TEXT,
|
|
61
|
+
tx_hash TEXT,
|
|
62
|
+
day_key TEXT NOT NULL,
|
|
63
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_spend_day ON spend_ledger(agent_id, day_key);
|
|
67
|
+
|
|
68
|
+
CREATE TABLE IF NOT EXISTS mpp_sessions (
|
|
69
|
+
session_id TEXT PRIMARY KEY,
|
|
70
|
+
agent_id TEXT NOT NULL,
|
|
71
|
+
budget_usdc REAL NOT NULL,
|
|
72
|
+
spent_usdc REAL NOT NULL DEFAULT 0,
|
|
73
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
74
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
75
|
+
closed_at INTEGER,
|
|
76
|
+
payload TEXT
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
CREATE TABLE IF NOT EXISTS escrow_records (
|
|
80
|
+
escrow_id TEXT PRIMARY KEY,
|
|
81
|
+
buyer_agent_id TEXT NOT NULL,
|
|
82
|
+
seller_agent_id TEXT NOT NULL,
|
|
83
|
+
amount_usdc REAL NOT NULL,
|
|
84
|
+
condition_hash TEXT,
|
|
85
|
+
status TEXT NOT NULL DEFAULT 'held',
|
|
86
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
87
|
+
released_at INTEGER,
|
|
88
|
+
payload TEXT
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
CREATE TABLE IF NOT EXISTS used_nonces (
|
|
92
|
+
nonce TEXT PRIMARY KEY,
|
|
93
|
+
network TEXT NOT NULL,
|
|
94
|
+
used_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE INDEX IF NOT EXISTS idx_nonces_time ON used_nonces(used_at);
|
|
98
|
+
`);
|
|
99
|
+
function ensurePayloadColumns() {
|
|
100
|
+
const mppCols = db.prepare("PRAGMA table_info(mpp_sessions)").all();
|
|
101
|
+
if (!mppCols.some((c) => c.name === "payload")) {
|
|
102
|
+
db.exec("ALTER TABLE mpp_sessions ADD COLUMN payload TEXT");
|
|
103
|
+
}
|
|
104
|
+
const escCols = db.prepare("PRAGMA table_info(escrow_records)").all();
|
|
105
|
+
if (!escCols.some((c) => c.name === "payload")) {
|
|
106
|
+
db.exec("ALTER TABLE escrow_records ADD COLUMN payload TEXT");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
ensurePayloadColumns();
|
|
110
|
+
runMigrations(db);
|
|
111
|
+
export function dbPath() {
|
|
112
|
+
return DB_PATH;
|
|
113
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Human-readable discovery page — avoids sending browsers to raw /.well-known/x402 JSON. */
|
|
2
|
+
export function renderDiscoveryPage(manifest, baseUrl) {
|
|
3
|
+
const json = JSON.stringify(manifest, null, 2)
|
|
4
|
+
.replace(/&/g, "&")
|
|
5
|
+
.replace(/</g, "<")
|
|
6
|
+
.replace(/>/g, ">");
|
|
7
|
+
return `<!doctype html>
|
|
8
|
+
<html lang="en">
|
|
9
|
+
<head>
|
|
10
|
+
<meta charset="utf-8"/>
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
12
|
+
<title>x402 Discovery Manifest — x402 Trust Layer</title>
|
|
13
|
+
<meta name="description" content="x402 Trust Layer discovery manifest — 31 verified payable resource URLs for agents and scanners."/>
|
|
14
|
+
<link rel="icon" type="image/svg+xml" href="/assets/x402-trustlayer-logo.svg"/>
|
|
15
|
+
<link rel="stylesheet" href="/landing.css?v=4"/>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
<div class="grid-bg"></div>
|
|
19
|
+
<header class="nav">
|
|
20
|
+
<div class="nav-shell">
|
|
21
|
+
<a class="brand" href="/"><img src="/assets/x402-trustlayer-logo.svg" alt=""/><span class="brand-text">x402<span class="dim">trustlayer</span></span></a>
|
|
22
|
+
<nav class="nav-menu">
|
|
23
|
+
<a href="/">Home</a>
|
|
24
|
+
<a href="/openapi.json">OpenAPI</a>
|
|
25
|
+
<a href="/health">Status</a>
|
|
26
|
+
</nav>
|
|
27
|
+
</div>
|
|
28
|
+
</header>
|
|
29
|
+
<section class="pad" style="padding-top:48px">
|
|
30
|
+
<div class="wrap" style="max-width:900px">
|
|
31
|
+
<p class="kicker">Discovery</p>
|
|
32
|
+
<h2 style="font-size:clamp(24px,4vw,36px);margin-bottom:12px">x402 manifest</h2>
|
|
33
|
+
<p class="section-desc" style="max-width:100%;margin-bottom:24px">
|
|
34
|
+
Machine-readable catalog for x402scan, Agentic Market, and OpenDexter.
|
|
35
|
+
Scanners use <code class="mono">GET /.well-known/x402</code>.
|
|
36
|
+
In the browser, open <code class="mono">/discovery.json</code> for the same JSON without Chrome warnings.
|
|
37
|
+
</p>
|
|
38
|
+
<div class="tag-row" style="margin-bottom:20px">
|
|
39
|
+
<span class="tag mono">31 resources</span>
|
|
40
|
+
<span class="tag mono">100% verified</span>
|
|
41
|
+
<span class="tag mono">Base · Solana</span>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="terminal-panel">
|
|
44
|
+
<div class="term-chrome">
|
|
45
|
+
<span class="dot r"></span><span class="dot y"></span><span class="dot g"></span>
|
|
46
|
+
<span class="term-title mono">x402 discovery manifest</span>
|
|
47
|
+
</div>
|
|
48
|
+
<pre class="code-block mono" style="margin:0;border:none;border-radius:0;max-height:60vh;overflow:auto">${json}</pre>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="hero-actions" style="justify-content:flex-start;margin-top:24px">
|
|
51
|
+
<button type="button" class="btn solid" id="copy-json">Copy JSON</button>
|
|
52
|
+
<a class="btn ghost" href="/discovery.json" target="_blank" rel="noopener">Open JSON</a>
|
|
53
|
+
<a class="btn ghost" href="/x402/api/discover">Full catalog</a>
|
|
54
|
+
</div>
|
|
55
|
+
<p class="section-desc" style="margin-top:20px;font-size:12px">
|
|
56
|
+
Register individual paid URLs from <code>resources[]</code> on x402scan — not this catalog URL.
|
|
57
|
+
</p>
|
|
58
|
+
</div>
|
|
59
|
+
</section>
|
|
60
|
+
<script>
|
|
61
|
+
document.getElementById("copy-json")?.addEventListener("click", function () {
|
|
62
|
+
var text = document.querySelector("pre.code-block")?.textContent || "";
|
|
63
|
+
navigator.clipboard.writeText(text).then(function () {
|
|
64
|
+
var b = document.getElementById("copy-json");
|
|
65
|
+
if (b) { b.textContent = "Copied ✓"; setTimeout(function () { b.textContent = "Copy JSON"; }, 2000); }
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
</script>
|
|
69
|
+
</body>
|
|
70
|
+
</html>`;
|
|
71
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type HostTelemetry = {
|
|
2
|
+
host: string;
|
|
3
|
+
source: string;
|
|
4
|
+
washTradePct?: number;
|
|
5
|
+
observedTxns?: number;
|
|
6
|
+
observedVolumeUsdc?: number;
|
|
7
|
+
verifiedResources?: number;
|
|
8
|
+
totalResources?: number;
|
|
9
|
+
realVolumePct?: number;
|
|
10
|
+
fetchedAt: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Best-effort telemetry from x402watch public API (free tier).
|
|
14
|
+
* Set X402WATCH_API_BASE to override. Falls back gracefully if unreachable.
|
|
15
|
+
*/
|
|
16
|
+
export declare function fetchHostTelemetry(hostInput: string, targetUrl?: string): Promise<HostTelemetry | null>;
|
|
17
|
+
export declare function mergeTelemetryIntoMerchantInput<T extends Record<string, unknown>>(input: T, telemetry: HostTelemetry | null): T & {
|
|
18
|
+
telemetrySource?: string;
|
|
19
|
+
telemetryFetchedAt?: string;
|
|
20
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { hostOf } from "./probe.js";
|
|
2
|
+
const WATCH_API = (process.env.X402WATCH_API_BASE ?? "https://api.x402.printmoneylab.com/api/v1").replace(/\/$/, "");
|
|
3
|
+
function hostMatches(service, host) {
|
|
4
|
+
const candidates = [service.domain, service.host, service.url, service.name].filter(Boolean);
|
|
5
|
+
return candidates.some((c) => {
|
|
6
|
+
try {
|
|
7
|
+
const h = (c.includes("://") ? hostOf(c) : c.toLowerCase()) || "";
|
|
8
|
+
return h.length > 0 && (h === host || h.endsWith(`.${host}`) || host.endsWith(`.${h}`));
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return c.toLowerCase().includes(host);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function pickService(services, host) {
|
|
16
|
+
const exact = services.find((s) => hostMatches(s, host));
|
|
17
|
+
if (exact)
|
|
18
|
+
return exact;
|
|
19
|
+
return services.find((s) => {
|
|
20
|
+
const d = (s.domain ?? s.host ?? "").toLowerCase();
|
|
21
|
+
return d && (host.includes(d) || d.includes(host));
|
|
22
|
+
}) ?? null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Best-effort telemetry from x402watch public API (free tier).
|
|
26
|
+
* Set X402WATCH_API_BASE to override. Falls back gracefully if unreachable.
|
|
27
|
+
*/
|
|
28
|
+
export async function fetchHostTelemetry(hostInput, targetUrl) {
|
|
29
|
+
const host = (hostInput || hostOf(targetUrl ?? "") || "").toLowerCase();
|
|
30
|
+
if (!host)
|
|
31
|
+
return null;
|
|
32
|
+
const fetchedAt = new Date().toISOString();
|
|
33
|
+
try {
|
|
34
|
+
const searchUrl = `${WATCH_API}/services?search=${encodeURIComponent(host)}&limit=20`;
|
|
35
|
+
const res = await fetch(searchUrl, {
|
|
36
|
+
signal: AbortSignal.timeout(Number(process.env.TELEMETRY_FETCH_MS ?? 8_000)),
|
|
37
|
+
headers: { accept: "application/json" },
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
return null;
|
|
41
|
+
const body = (await res.json());
|
|
42
|
+
const list = body.data ?? body.services ?? (Array.isArray(body) ? body : []);
|
|
43
|
+
const svc = pickService(list, host);
|
|
44
|
+
if (!svc)
|
|
45
|
+
return { host, source: "x402watch:miss", fetchedAt };
|
|
46
|
+
const realPct = svc.realVolumePct ?? svc.real_volume_pct;
|
|
47
|
+
const wash = svc.washPct ??
|
|
48
|
+
svc.wash_pct ??
|
|
49
|
+
(typeof realPct === "number" ? Math.max(0, Math.min(100, 100 - realPct)) : undefined);
|
|
50
|
+
return {
|
|
51
|
+
host,
|
|
52
|
+
source: "x402watch",
|
|
53
|
+
washTradePct: wash,
|
|
54
|
+
observedTxns: svc.txCount ?? svc.transactionCount,
|
|
55
|
+
observedVolumeUsdc: svc.volumeUsdc ?? svc.volume_usdc,
|
|
56
|
+
verifiedResources: svc.verifiedCount,
|
|
57
|
+
totalResources: svc.resourceCount ?? svc.resources,
|
|
58
|
+
realVolumePct: realPct,
|
|
59
|
+
fetchedAt,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return { host, source: "x402watch:unavailable", fetchedAt };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function mergeTelemetryIntoMerchantInput(input, telemetry) {
|
|
67
|
+
if (!telemetry || telemetry.source === "x402watch:miss" || telemetry.source === "x402watch:unavailable") {
|
|
68
|
+
return { ...input, telemetrySource: telemetry?.source ?? "none" };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
...input,
|
|
72
|
+
washTradePct: input.washTradePct ?? telemetry.washTradePct,
|
|
73
|
+
observedTxns: input.observedTxns ?? telemetry.observedTxns,
|
|
74
|
+
observedVolumeUsdc: input.observedVolumeUsdc ?? telemetry.observedVolumeUsdc,
|
|
75
|
+
verifiedResources: input.verifiedResources ?? telemetry.verifiedResources,
|
|
76
|
+
totalResources: input.totalResources ?? telemetry.totalResources,
|
|
77
|
+
telemetrySource: telemetry.source,
|
|
78
|
+
telemetryFetchedAt: telemetry.fetchedAt,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type AgentCardJson = {
|
|
2
|
+
name?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
active?: boolean;
|
|
5
|
+
status?: string;
|
|
6
|
+
x402Support?: boolean;
|
|
7
|
+
services?: unknown[];
|
|
8
|
+
endpoints?: unknown[];
|
|
9
|
+
registrations?: {
|
|
10
|
+
domain?: string;
|
|
11
|
+
url?: string;
|
|
12
|
+
}[];
|
|
13
|
+
domain?: string;
|
|
14
|
+
url?: string;
|
|
15
|
+
};
|
|
16
|
+
export type AgentCardScore = {
|
|
17
|
+
points: number;
|
|
18
|
+
maxPoints: number;
|
|
19
|
+
valid: boolean;
|
|
20
|
+
fields: string[];
|
|
21
|
+
missing: string[];
|
|
22
|
+
agentUri: string | null;
|
|
23
|
+
domain: string | null;
|
|
24
|
+
};
|
|
25
|
+
export type WellKnownScore = {
|
|
26
|
+
points: number;
|
|
27
|
+
maxPoints: number;
|
|
28
|
+
verified: boolean;
|
|
29
|
+
url: string | null;
|
|
30
|
+
error: string | null;
|
|
31
|
+
};
|
|
32
|
+
export declare function fetchAgentCard(agentUri: string): Promise<AgentCardJson | null>;
|
|
33
|
+
export declare function scoreAgentCard(card: AgentCardJson | null, agentUri: string | null): AgentCardScore;
|
|
34
|
+
export declare function verifyWellKnown(domain: string | null): Promise<WellKnownScore>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { assertSafeOutboundUrl } from "../ssrf.js";
|
|
2
|
+
import { safeFetch } from "../safe-fetch.js";
|
|
3
|
+
function parseDataUri(uri) {
|
|
4
|
+
const comma = uri.indexOf(",");
|
|
5
|
+
if (comma < 0)
|
|
6
|
+
return null;
|
|
7
|
+
const payload = uri.slice(comma + 1);
|
|
8
|
+
try {
|
|
9
|
+
const text = uri.includes(";base64")
|
|
10
|
+
? Buffer.from(payload, "base64").toString("utf8")
|
|
11
|
+
: decodeURIComponent(payload);
|
|
12
|
+
return JSON.parse(text);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function ipfsToHttps(uri) {
|
|
19
|
+
if (uri.startsWith("ipfs://")) {
|
|
20
|
+
return `https://ipfs.io/ipfs/${uri.slice(7)}`;
|
|
21
|
+
}
|
|
22
|
+
return uri;
|
|
23
|
+
}
|
|
24
|
+
export async function fetchAgentCard(agentUri) {
|
|
25
|
+
if (agentUri.startsWith("data:")) {
|
|
26
|
+
return parseDataUri(agentUri);
|
|
27
|
+
}
|
|
28
|
+
const url = ipfsToHttps(agentUri);
|
|
29
|
+
if (!url.startsWith("http"))
|
|
30
|
+
return null;
|
|
31
|
+
try {
|
|
32
|
+
assertSafeOutboundUrl(url);
|
|
33
|
+
const res = await safeFetch(url, {
|
|
34
|
+
headers: { accept: "application/json" },
|
|
35
|
+
timeoutMs: 8000,
|
|
36
|
+
});
|
|
37
|
+
if (res.status >= 300 && res.status < 400)
|
|
38
|
+
return null;
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
return null;
|
|
41
|
+
return (await res.json());
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function extractDomain(card, agentUri) {
|
|
48
|
+
if (card.domain && typeof card.domain === "string") {
|
|
49
|
+
return card.domain.replace(/^https?:\/\//, "").split("/")[0] ?? null;
|
|
50
|
+
}
|
|
51
|
+
const reg = card.registrations?.find((r) => r.domain);
|
|
52
|
+
if (reg?.domain)
|
|
53
|
+
return reg.domain.replace(/^https?:\/\//, "").split("/")[0] ?? null;
|
|
54
|
+
try {
|
|
55
|
+
if (agentUri.startsWith("http")) {
|
|
56
|
+
return new URL(agentUri).hostname;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* ignore */
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
export function scoreAgentCard(card, agentUri) {
|
|
65
|
+
const maxPoints = 15;
|
|
66
|
+
if (!card) {
|
|
67
|
+
return {
|
|
68
|
+
points: 0,
|
|
69
|
+
maxPoints,
|
|
70
|
+
valid: false,
|
|
71
|
+
fields: [],
|
|
72
|
+
missing: ["name", "services", "x402Support", "active"],
|
|
73
|
+
agentUri,
|
|
74
|
+
domain: null,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const fields = [];
|
|
78
|
+
const missing = [];
|
|
79
|
+
if (card.name && card.name.trim().length > 0)
|
|
80
|
+
fields.push("name");
|
|
81
|
+
else
|
|
82
|
+
missing.push("name");
|
|
83
|
+
const hasServices = (Array.isArray(card.services) && card.services.length > 0) ||
|
|
84
|
+
(Array.isArray(card.endpoints) && card.endpoints.length > 0);
|
|
85
|
+
if (hasServices)
|
|
86
|
+
fields.push("services");
|
|
87
|
+
else
|
|
88
|
+
missing.push("services");
|
|
89
|
+
const x402 = card.x402Support === true ||
|
|
90
|
+
(Array.isArray(card.services) &&
|
|
91
|
+
card.services.some((s) => typeof s === "object" &&
|
|
92
|
+
s !== null &&
|
|
93
|
+
("x402" in s || "payment" in s || "protocol" in s)));
|
|
94
|
+
if (x402)
|
|
95
|
+
fields.push("x402Support");
|
|
96
|
+
else
|
|
97
|
+
missing.push("x402Support");
|
|
98
|
+
const active = card.active === true ||
|
|
99
|
+
card.status === "active" ||
|
|
100
|
+
card.status === "online";
|
|
101
|
+
if (active)
|
|
102
|
+
fields.push("active");
|
|
103
|
+
else
|
|
104
|
+
missing.push("active");
|
|
105
|
+
const completeness = fields.length / 4;
|
|
106
|
+
const points = Math.round(maxPoints * completeness);
|
|
107
|
+
const domain = extractDomain(card, agentUri ?? "");
|
|
108
|
+
return {
|
|
109
|
+
points,
|
|
110
|
+
maxPoints,
|
|
111
|
+
valid: fields.length >= 3,
|
|
112
|
+
fields,
|
|
113
|
+
missing,
|
|
114
|
+
agentUri,
|
|
115
|
+
domain,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export async function verifyWellKnown(domain) {
|
|
119
|
+
const maxPoints = 10;
|
|
120
|
+
if (!domain) {
|
|
121
|
+
return { points: 0, maxPoints, verified: false, url: null, error: "no_domain_in_agent_card" };
|
|
122
|
+
}
|
|
123
|
+
const url = `https://${domain}/.well-known/agent-registration.json`;
|
|
124
|
+
try {
|
|
125
|
+
assertSafeOutboundUrl(url);
|
|
126
|
+
const res = await safeFetch(url, {
|
|
127
|
+
headers: { accept: "application/json" },
|
|
128
|
+
timeoutMs: 6000,
|
|
129
|
+
});
|
|
130
|
+
if (res.status >= 300 && res.status < 400) {
|
|
131
|
+
return { points: 0, maxPoints, verified: false, url, error: "redirect_not_followed" };
|
|
132
|
+
}
|
|
133
|
+
if (!res.ok) {
|
|
134
|
+
return { points: 0, maxPoints, verified: false, url, error: `HTTP ${res.status}` };
|
|
135
|
+
}
|
|
136
|
+
const body = await res.json();
|
|
137
|
+
if (body && typeof body === "object") {
|
|
138
|
+
return { points: maxPoints, maxPoints, verified: true, url, error: null };
|
|
139
|
+
}
|
|
140
|
+
return { points: 0, maxPoints, verified: false, url, error: "invalid_json" };
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
return {
|
|
144
|
+
points: 0,
|
|
145
|
+
maxPoints,
|
|
146
|
+
verified: false,
|
|
147
|
+
url,
|
|
148
|
+
error: err instanceof Error ? err.message : "fetch_failed",
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const store = new Map();
|
|
2
|
+
export function cacheGet(key) {
|
|
3
|
+
const entry = store.get(key);
|
|
4
|
+
if (!entry)
|
|
5
|
+
return null;
|
|
6
|
+
if (Date.now() >= entry.expiresAt) {
|
|
7
|
+
store.delete(key);
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return entry.value;
|
|
11
|
+
}
|
|
12
|
+
export function cacheSet(key, value, ttlSec) {
|
|
13
|
+
store.set(key, { value, expiresAt: Date.now() + ttlSec * 1000 });
|
|
14
|
+
}
|
|
15
|
+
export function cacheKey(parts) {
|
|
16
|
+
return parts.map((p) => String(p ?? "")).join(":");
|
|
17
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Official ERC-8004 Base Mainnet — do not use Sepolia addresses in production. */
|
|
2
|
+
export declare const ERC8004_CAIP2: "eip155:8453";
|
|
3
|
+
export declare const ERC8004_CHAIN_ID = 8453;
|
|
4
|
+
export declare const DEFAULT_IDENTITY_REGISTRY: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
|
|
5
|
+
export declare const DEFAULT_REPUTATION_REGISTRY: "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63";
|
|
6
|
+
export declare const TRUST_TIERS: readonly ["PLATINUM", "GOLD", "SILVER", "BRONZE", "UNVERIFIED", "UNKNOWN"];
|
|
7
|
+
export type TrustTier = (typeof TRUST_TIERS)[number];
|
|
8
|
+
export declare const TIER_THRESHOLDS: {
|
|
9
|
+
tier: Exclude<TrustTier, "UNKNOWN">;
|
|
10
|
+
minScore: number;
|
|
11
|
+
}[];
|
|
12
|
+
export declare const TRUST_SCORE_WEIGHTS: {
|
|
13
|
+
readonly onChainRegistration: 30;
|
|
14
|
+
readonly reputation: 25;
|
|
15
|
+
readonly walletVerified: 15;
|
|
16
|
+
readonly agentCard: 15;
|
|
17
|
+
readonly domainWellKnown: 10;
|
|
18
|
+
readonly paymentHistory: 5;
|
|
19
|
+
};
|
|
20
|
+
export declare function tierForScore(score: number): Exclude<TrustTier, "UNKNOWN">;
|
|
21
|
+
export declare function tierRank(tier: TrustTier): number;
|
|
22
|
+
export declare function isEvmAddress(addr: string): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Official ERC-8004 Base Mainnet — do not use Sepolia addresses in production. */
|
|
2
|
+
export const ERC8004_CAIP2 = "eip155:8453";
|
|
3
|
+
export const ERC8004_CHAIN_ID = 8453;
|
|
4
|
+
export const DEFAULT_IDENTITY_REGISTRY = "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432";
|
|
5
|
+
export const DEFAULT_REPUTATION_REGISTRY = "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63";
|
|
6
|
+
export const TRUST_TIERS = ["PLATINUM", "GOLD", "SILVER", "BRONZE", "UNVERIFIED", "UNKNOWN"];
|
|
7
|
+
export const TIER_THRESHOLDS = [
|
|
8
|
+
{ tier: "PLATINUM", minScore: 85 },
|
|
9
|
+
{ tier: "GOLD", minScore: 70 },
|
|
10
|
+
{ tier: "SILVER", minScore: 50 },
|
|
11
|
+
{ tier: "BRONZE", minScore: 30 },
|
|
12
|
+
{ tier: "UNVERIFIED", minScore: 0 },
|
|
13
|
+
];
|
|
14
|
+
export const TRUST_SCORE_WEIGHTS = {
|
|
15
|
+
onChainRegistration: 30,
|
|
16
|
+
reputation: 25,
|
|
17
|
+
walletVerified: 15,
|
|
18
|
+
agentCard: 15,
|
|
19
|
+
domainWellKnown: 10,
|
|
20
|
+
paymentHistory: 5,
|
|
21
|
+
};
|
|
22
|
+
export function tierForScore(score) {
|
|
23
|
+
for (const { tier, minScore } of TIER_THRESHOLDS) {
|
|
24
|
+
if (score >= minScore)
|
|
25
|
+
return tier;
|
|
26
|
+
}
|
|
27
|
+
return "UNVERIFIED";
|
|
28
|
+
}
|
|
29
|
+
export function tierRank(tier) {
|
|
30
|
+
const order = ["PLATINUM", "GOLD", "SILVER", "BRONZE", "UNVERIFIED", "UNKNOWN"];
|
|
31
|
+
return order.indexOf(tier);
|
|
32
|
+
}
|
|
33
|
+
export function isEvmAddress(addr) {
|
|
34
|
+
return /^0x[a-fA-F0-9]{40}$/.test(addr.trim());
|
|
35
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Address } from "viem";
|
|
2
|
+
export declare function identityRegistryAddress(): Address;
|
|
3
|
+
export declare function reputationRegistryAddress(): Address;
|
|
4
|
+
export declare function readOwnerOf(agentId: bigint): Promise<Address | null>;
|
|
5
|
+
export declare function readTokenUri(agentId: bigint): Promise<string | null>;
|
|
6
|
+
export declare function readAgentWallet(agentId: bigint): Promise<Address | null>;
|
|
7
|
+
export declare function readBalanceOf(wallet: Address): Promise<bigint>;
|
|
8
|
+
export type ReputationSummary = {
|
|
9
|
+
count: bigint;
|
|
10
|
+
summaryValue: bigint;
|
|
11
|
+
summaryValueDecimals: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function readReputationSummary(agentId: bigint): Promise<ReputationSummary | null>;
|
|
14
|
+
export declare function chainMeta(): {
|
|
15
|
+
caip2: "eip155:8453";
|
|
16
|
+
chainId: number;
|
|
17
|
+
identityRegistry: `0x${string}`;
|
|
18
|
+
reputationRegistry: `0x${string}`;
|
|
19
|
+
};
|