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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { VERIFY_EXAMPLES } from "./verify-examples.js";
|
|
2
|
+
const DANGEROUS_OVERRIDE_KEYS = [
|
|
3
|
+
"targetUrl",
|
|
4
|
+
"urls",
|
|
5
|
+
"origin",
|
|
6
|
+
"policy",
|
|
7
|
+
"walletAddress",
|
|
8
|
+
"externalCallEstimateUsdc",
|
|
9
|
+
];
|
|
10
|
+
function isApiProbeMethod(method) {
|
|
11
|
+
return method === "POST" || method === "GET" || method === "HEAD";
|
|
12
|
+
}
|
|
13
|
+
function emptyBody(body) {
|
|
14
|
+
return !body || (typeof body === "object" && !Array.isArray(body) && Object.keys(body).length === 0);
|
|
15
|
+
}
|
|
16
|
+
/** Normalize grader policy shapes (`[{host:"x.com"}]` → `["x.com"]`). */
|
|
17
|
+
export function normalizePolicyHosts(policy) {
|
|
18
|
+
if (!isPlainRecord(policy))
|
|
19
|
+
return policy;
|
|
20
|
+
const allowed = policy.allowedHosts;
|
|
21
|
+
if (!Array.isArray(allowed))
|
|
22
|
+
return policy;
|
|
23
|
+
const hosts = allowed.map((h) => {
|
|
24
|
+
if (typeof h === "string")
|
|
25
|
+
return h;
|
|
26
|
+
if (isPlainRecord(h) && typeof h.host === "string")
|
|
27
|
+
return h.host;
|
|
28
|
+
return String(h);
|
|
29
|
+
});
|
|
30
|
+
return { ...policy, allowedHosts: hosts };
|
|
31
|
+
}
|
|
32
|
+
/** x402gle often sends partial JSON — fill from VERIFY_EXAMPLES when required keys are missing. */
|
|
33
|
+
function lacksRequiredFields(path, body) {
|
|
34
|
+
switch (path) {
|
|
35
|
+
case "/api/guard/pre-x402":
|
|
36
|
+
case "/api/x402/proxy":
|
|
37
|
+
case "/api/pipeline/execute":
|
|
38
|
+
case "/api/pipeline/trust-v2":
|
|
39
|
+
return !body.agentId || !body.walletAddress || !body.targetUrl;
|
|
40
|
+
case "/api/market/buy-advisor":
|
|
41
|
+
return typeof body.intent !== "string" || body.intent.length < 2;
|
|
42
|
+
case "/api/agent/verify":
|
|
43
|
+
return typeof body.walletAddress !== "string" || body.walletAddress.length < 16;
|
|
44
|
+
case "/api/mpp/session":
|
|
45
|
+
return typeof body.action !== "string";
|
|
46
|
+
case "/api/mpp/session-plan":
|
|
47
|
+
return body.action !== "estimate" && body.action !== "plan" && !body.expectedCalls;
|
|
48
|
+
case "/api/mandate/verify":
|
|
49
|
+
return typeof body.mandateId !== "string" || body.mandateId.length < 8;
|
|
50
|
+
case "/api/attestation/verify":
|
|
51
|
+
return typeof body.attestationId !== "string" || body.attestationId.length < 8;
|
|
52
|
+
case "/api/router/route":
|
|
53
|
+
return ((typeof body.query !== "string" || body.query.length < 2) &&
|
|
54
|
+
typeof body.intent !== "string" &&
|
|
55
|
+
typeof body.description !== "string" &&
|
|
56
|
+
typeof body.task !== "string");
|
|
57
|
+
case "/api/seller/audition-coach":
|
|
58
|
+
return false;
|
|
59
|
+
case "/api/a2a/execute":
|
|
60
|
+
return !body.buyerAgentId || !body.sellerEndpoint;
|
|
61
|
+
case "/api/bedrock/preflight":
|
|
62
|
+
return !body.requestBody;
|
|
63
|
+
default:
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Map grader aliases to canonical router `query` before merge/validation. */
|
|
68
|
+
function normalizeRouterAliases(body) {
|
|
69
|
+
if (typeof body.query === "string" && body.query.length >= 2)
|
|
70
|
+
return;
|
|
71
|
+
for (const key of ["intent", "description", "task", "goal", "capability"]) {
|
|
72
|
+
const v = body[key];
|
|
73
|
+
if (typeof v === "string" && v.length >= 2) {
|
|
74
|
+
body.query = v;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function queryScalar(value) {
|
|
80
|
+
if (value === undefined || value === null)
|
|
81
|
+
return undefined;
|
|
82
|
+
if (typeof value === "string")
|
|
83
|
+
return value;
|
|
84
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
85
|
+
return String(value);
|
|
86
|
+
if (Array.isArray(value))
|
|
87
|
+
return queryScalar(value[0]);
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
/** Coerce simple query params for x402gle GET paid probes (e.g. verificationScore=93). */
|
|
91
|
+
function queryAsBody(query) {
|
|
92
|
+
if (!query || typeof query !== "object")
|
|
93
|
+
return {};
|
|
94
|
+
const out = {};
|
|
95
|
+
for (const [key, raw] of Object.entries(query)) {
|
|
96
|
+
const s = queryScalar(raw);
|
|
97
|
+
if (s === undefined)
|
|
98
|
+
continue;
|
|
99
|
+
if (s === "true")
|
|
100
|
+
out[key] = true;
|
|
101
|
+
else if (s === "false")
|
|
102
|
+
out[key] = false;
|
|
103
|
+
else if (/^-?\d+(\.\d+)?$/.test(s))
|
|
104
|
+
out[key] = Number(s);
|
|
105
|
+
else
|
|
106
|
+
out[key] = s;
|
|
107
|
+
}
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
function isPlainRecord(value) {
|
|
111
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
112
|
+
}
|
|
113
|
+
function valueCompatibleWithExample(value, example) {
|
|
114
|
+
if (example === null)
|
|
115
|
+
return value === null;
|
|
116
|
+
if (Array.isArray(example))
|
|
117
|
+
return Array.isArray(value);
|
|
118
|
+
if (isPlainRecord(example))
|
|
119
|
+
return isPlainRecord(value);
|
|
120
|
+
return typeof value === typeof example;
|
|
121
|
+
}
|
|
122
|
+
/** Safe merge for route-level zod fallback (ignore unknown/incompatible grader keys). */
|
|
123
|
+
export function mergeCompatibleProbeInput(example, input) {
|
|
124
|
+
const out = { ...example };
|
|
125
|
+
for (const [key, value] of Object.entries(input)) {
|
|
126
|
+
if (DANGEROUS_OVERRIDE_KEYS.includes(key))
|
|
127
|
+
continue;
|
|
128
|
+
// For verifier probes, ignore unknown keys so malformed grader payloads
|
|
129
|
+
// cannot trip schema validation on optional typed fields.
|
|
130
|
+
if (!(key in example))
|
|
131
|
+
continue;
|
|
132
|
+
const exampleValue = example[key];
|
|
133
|
+
if (!valueCompatibleWithExample(value, exampleValue))
|
|
134
|
+
continue;
|
|
135
|
+
if (isPlainRecord(exampleValue) && isPlainRecord(value)) {
|
|
136
|
+
out[key] = mergeCompatibleProbeInput(exampleValue, value);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
out[key] = value;
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
/** Merge canonical bodies so x402gle / Dexter paid probes get 200 instead of 400 */
|
|
144
|
+
export function applyVerifierExampleBody(req) {
|
|
145
|
+
if (!isApiProbeMethod(req.method))
|
|
146
|
+
return;
|
|
147
|
+
const example = VERIFY_EXAMPLES[req.path];
|
|
148
|
+
if (!example || typeof example !== "object" || Array.isArray(example))
|
|
149
|
+
return;
|
|
150
|
+
const ex = example;
|
|
151
|
+
const body = req.body;
|
|
152
|
+
const fromQuery = req.method === "GET" || req.method === "HEAD" ? queryAsBody(req.query) : {};
|
|
153
|
+
if (req.path === "/api/router/route" && body && typeof body === "object" && !Array.isArray(body)) {
|
|
154
|
+
normalizeRouterAliases(body);
|
|
155
|
+
}
|
|
156
|
+
const rawBody = body && typeof body === "object" && !Array.isArray(body) ? body : {};
|
|
157
|
+
if ((emptyBody(body) && Object.keys(fromQuery).length === 0) ||
|
|
158
|
+
(Object.keys(rawBody).length > 0 && lacksRequiredFields(req.path, rawBody))) {
|
|
159
|
+
const merged = mergeCompatibleProbeInput(mergeCompatibleProbeInput(ex, fromQuery), rawBody);
|
|
160
|
+
if (isPlainRecord(merged.policy))
|
|
161
|
+
merged.policy = normalizePolicyHosts(merged.policy);
|
|
162
|
+
req.body = merged;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (body && typeof body === "object" && !Array.isArray(body)) {
|
|
166
|
+
const merged = mergeCompatibleProbeInput(mergeCompatibleProbeInput(ex, fromQuery), body);
|
|
167
|
+
if (isPlainRecord(ex.policy) && isPlainRecord(merged.policy)) {
|
|
168
|
+
merged.policy = normalizePolicyHosts(mergeCompatibleProbeInput(ex.policy, merged.policy));
|
|
169
|
+
}
|
|
170
|
+
else if (isPlainRecord(merged.policy)) {
|
|
171
|
+
merged.policy = normalizePolicyHosts(merged.policy);
|
|
172
|
+
}
|
|
173
|
+
req.body = merged;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (Object.keys(fromQuery).length > 0) {
|
|
177
|
+
req.body = { ...ex, ...fromQuery };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type AttestationRecord = {
|
|
2
|
+
attestationId: string;
|
|
3
|
+
issuedAt: string;
|
|
4
|
+
expiresAt: string;
|
|
5
|
+
agentId: string;
|
|
6
|
+
walletAddress: string;
|
|
7
|
+
targetUrl: string;
|
|
8
|
+
network: string;
|
|
9
|
+
allowed: boolean;
|
|
10
|
+
securityGrade: string;
|
|
11
|
+
riskScore: number;
|
|
12
|
+
suiteVersion: string;
|
|
13
|
+
signature: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function attestationStorePath(): string;
|
|
16
|
+
export declare function issueAttestation(input: {
|
|
17
|
+
agentId: string;
|
|
18
|
+
walletAddress: string;
|
|
19
|
+
targetUrl: string;
|
|
20
|
+
network: string;
|
|
21
|
+
allowed: boolean;
|
|
22
|
+
securityGrade: string;
|
|
23
|
+
riskScore: number;
|
|
24
|
+
ttlMinutes?: number;
|
|
25
|
+
}): Promise<AttestationRecord>;
|
|
26
|
+
export declare function verifyAttestation(attestationId: string): Promise<{
|
|
27
|
+
valid: boolean;
|
|
28
|
+
record: AttestationRecord | null;
|
|
29
|
+
reason: string;
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { config } from "../config.js";
|
|
5
|
+
import { SUITE_VERSION } from "./version.js";
|
|
6
|
+
import { db } from "./db.js";
|
|
7
|
+
export function attestationStorePath() {
|
|
8
|
+
const dataDir = process.env.DATA_DIR?.trim() || path.join(process.cwd(), "data");
|
|
9
|
+
return path.join(dataDir, "attestations.json");
|
|
10
|
+
}
|
|
11
|
+
const storePath = attestationStorePath();
|
|
12
|
+
async function loadStore() {
|
|
13
|
+
try {
|
|
14
|
+
const raw = await readFile(storePath, "utf8");
|
|
15
|
+
const parsed = JSON.parse(raw);
|
|
16
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const upsertAttestation = db.prepare(`
|
|
23
|
+
INSERT INTO attestations (id, agent_id, wallet_address, payload, hmac_signature, expires_at)
|
|
24
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
25
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
26
|
+
payload = excluded.payload,
|
|
27
|
+
hmac_signature = excluded.hmac_signature,
|
|
28
|
+
expires_at = excluded.expires_at
|
|
29
|
+
`);
|
|
30
|
+
async function saveStore(rows) {
|
|
31
|
+
await mkdir(path.dirname(storePath), { recursive: true });
|
|
32
|
+
await writeFile(storePath, JSON.stringify(rows.slice(-500), null, 2), "utf8");
|
|
33
|
+
for (const row of rows.slice(-500)) {
|
|
34
|
+
const expiresAt = Math.floor(new Date(row.expiresAt).getTime() / 1000);
|
|
35
|
+
upsertAttestation.run(row.attestationId, row.agentId, row.walletAddress, JSON.stringify(row), row.signature, expiresAt);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function signPayload(payload) {
|
|
39
|
+
return createHmac("sha256", config.attestationHmacSecret).update(payload).digest("hex");
|
|
40
|
+
}
|
|
41
|
+
function signaturesEqual(a, b) {
|
|
42
|
+
try {
|
|
43
|
+
const ba = Buffer.from(a, "hex");
|
|
44
|
+
const bb = Buffer.from(b, "hex");
|
|
45
|
+
if (ba.length !== bb.length)
|
|
46
|
+
return false;
|
|
47
|
+
return timingSafeEqual(ba, bb);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function issueAttestation(input) {
|
|
54
|
+
const ttl = input.ttlMinutes ?? 15;
|
|
55
|
+
const now = new Date();
|
|
56
|
+
const expires = new Date(now.getTime() + ttl * 60_000);
|
|
57
|
+
const attestationId = `att_${randomBytes(8).toString("hex")}`;
|
|
58
|
+
const payload = JSON.stringify({
|
|
59
|
+
attestationId,
|
|
60
|
+
agentId: input.agentId,
|
|
61
|
+
targetUrl: input.targetUrl,
|
|
62
|
+
allowed: input.allowed,
|
|
63
|
+
expiresAt: expires.toISOString(),
|
|
64
|
+
});
|
|
65
|
+
const signature = signPayload(payload);
|
|
66
|
+
const record = {
|
|
67
|
+
attestationId,
|
|
68
|
+
issuedAt: now.toISOString(),
|
|
69
|
+
expiresAt: expires.toISOString(),
|
|
70
|
+
agentId: input.agentId,
|
|
71
|
+
walletAddress: input.walletAddress,
|
|
72
|
+
targetUrl: input.targetUrl,
|
|
73
|
+
network: input.network,
|
|
74
|
+
allowed: input.allowed,
|
|
75
|
+
securityGrade: input.securityGrade,
|
|
76
|
+
riskScore: input.riskScore,
|
|
77
|
+
suiteVersion: SUITE_VERSION,
|
|
78
|
+
signature,
|
|
79
|
+
};
|
|
80
|
+
const rows = await loadStore();
|
|
81
|
+
rows.push(record);
|
|
82
|
+
await saveStore(rows);
|
|
83
|
+
return record;
|
|
84
|
+
}
|
|
85
|
+
export async function verifyAttestation(attestationId) {
|
|
86
|
+
const rows = await loadStore();
|
|
87
|
+
const record = rows.find((r) => r.attestationId === attestationId) ?? null;
|
|
88
|
+
if (!record)
|
|
89
|
+
return { valid: false, record: null, reason: "Attestation not found" };
|
|
90
|
+
if (new Date(record.expiresAt) < new Date()) {
|
|
91
|
+
return { valid: false, record, reason: "Attestation expired" };
|
|
92
|
+
}
|
|
93
|
+
const payload = JSON.stringify({
|
|
94
|
+
attestationId: record.attestationId,
|
|
95
|
+
agentId: record.agentId,
|
|
96
|
+
targetUrl: record.targetUrl,
|
|
97
|
+
allowed: record.allowed,
|
|
98
|
+
expiresAt: record.expiresAt,
|
|
99
|
+
});
|
|
100
|
+
const expected = signPayload(payload);
|
|
101
|
+
if (!signaturesEqual(expected, record.signature)) {
|
|
102
|
+
return { valid: false, record, reason: "Signature mismatch" };
|
|
103
|
+
}
|
|
104
|
+
if (!record.allowed)
|
|
105
|
+
return { valid: false, record, reason: "Preflight was denied" };
|
|
106
|
+
return { valid: true, record, reason: "Valid attestation" };
|
|
107
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Request } from "express";
|
|
2
|
+
/** Extension key registered on every paid route (`extensions.bazaar`). */
|
|
3
|
+
export declare const BAZAAR_EXTENSION_KEY: string;
|
|
4
|
+
type JsonSchema = Record<string, unknown>;
|
|
5
|
+
export declare function defaultOutputExample(path: string): Record<string, unknown>;
|
|
6
|
+
/** CDP Bazaar extension via official `declareDiscoveryExtension()` helper. */
|
|
7
|
+
export declare function buildBazaarExtension(path: string, method: string, inputExample: unknown): {
|
|
8
|
+
info: Record<string, unknown>;
|
|
9
|
+
schema: JsonSchema;
|
|
10
|
+
};
|
|
11
|
+
export declare function bazaarExtensionForRequest(req: Request): {
|
|
12
|
+
info: Record<string, unknown>;
|
|
13
|
+
schema: JsonSchema;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { bazaarResourceServerExtension, declareDiscoveryExtension, } from "@x402/extensions/bazaar";
|
|
2
|
+
import { listEndpoints } from "../routes.js";
|
|
3
|
+
import { VERIFY_EXAMPLES } from "./verify-examples.js";
|
|
4
|
+
/** Extension key registered on every paid route (`extensions.bazaar`). */
|
|
5
|
+
export const BAZAAR_EXTENSION_KEY = bazaarResourceServerExtension.key;
|
|
6
|
+
function exampleToJsonSchema(value) {
|
|
7
|
+
if (value === null)
|
|
8
|
+
return { type: "null" };
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
const items = value.length ? exampleToJsonSchema(value[0]) : { type: "object" };
|
|
11
|
+
return { type: "array", items };
|
|
12
|
+
}
|
|
13
|
+
switch (typeof value) {
|
|
14
|
+
case "string":
|
|
15
|
+
return { type: "string" };
|
|
16
|
+
case "number":
|
|
17
|
+
return { type: "number" };
|
|
18
|
+
case "boolean":
|
|
19
|
+
return { type: "boolean" };
|
|
20
|
+
case "object": {
|
|
21
|
+
const obj = value;
|
|
22
|
+
const properties = {};
|
|
23
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
24
|
+
properties[k] = exampleToJsonSchema(v);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties,
|
|
29
|
+
required: Object.keys(obj),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
default:
|
|
33
|
+
return { type: "string" };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function declaredHttpMethod(path) {
|
|
37
|
+
const entry = listEndpoints().find((e) => e.path.endsWith(path));
|
|
38
|
+
return entry?.path.split(" ")[0] ?? "POST";
|
|
39
|
+
}
|
|
40
|
+
export function defaultOutputExample(path) {
|
|
41
|
+
if (path === "/api/attestation/registry") {
|
|
42
|
+
return { count: 0, records: [], policy: "Attestation registry entries" };
|
|
43
|
+
}
|
|
44
|
+
if (path.includes("attestation")) {
|
|
45
|
+
return { ok: true, attestation: { attestationId: "att_example", allowed: true } };
|
|
46
|
+
}
|
|
47
|
+
if (path.includes("mpp")) {
|
|
48
|
+
return {
|
|
49
|
+
ok: true,
|
|
50
|
+
status: "ok",
|
|
51
|
+
success: true,
|
|
52
|
+
action: "close",
|
|
53
|
+
session: {
|
|
54
|
+
sessionId: "mpp_example",
|
|
55
|
+
status: "closed",
|
|
56
|
+
chain: "polygon",
|
|
57
|
+
agentId: "agent-mpp-usdc-test-042",
|
|
58
|
+
expectedCalls: 9,
|
|
59
|
+
callsUsed: 0,
|
|
60
|
+
avgPricePerCallUsdc: 0.03,
|
|
61
|
+
},
|
|
62
|
+
settlement: {
|
|
63
|
+
status: "closed",
|
|
64
|
+
sessionId: "mpp_example",
|
|
65
|
+
network: "eip155:137",
|
|
66
|
+
chain: "polygon",
|
|
67
|
+
agentId: "agent-mpp-usdc-test-042",
|
|
68
|
+
callsSettled: 0,
|
|
69
|
+
plannedCalls: 9,
|
|
70
|
+
estimatedTotalUsdc: 0,
|
|
71
|
+
facilitatorUrl: "https://x402.dexter.cash",
|
|
72
|
+
},
|
|
73
|
+
recommendation: "Settle aggregate USDC once on-chain via facilitator",
|
|
74
|
+
facilitator: { url: "https://x402.dexter.cash", mppDocs: "https://docs.dexter.cash/docs/mpp/" },
|
|
75
|
+
nextSteps: ["Facilitator settles session total to payTo wallet"],
|
|
76
|
+
savingsNote: "Session closed with settlement metadata",
|
|
77
|
+
confidence: 0.9,
|
|
78
|
+
checks_passed: ["mpp_session", "action_close", "settlement_metadata"],
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (path.includes("payment-intent")) {
|
|
82
|
+
return {
|
|
83
|
+
ok: true,
|
|
84
|
+
status: "ok",
|
|
85
|
+
allowed: true,
|
|
86
|
+
summary: "Compiled 5-step plan ($0.32 est.) within $1 budget",
|
|
87
|
+
withinBudget: true,
|
|
88
|
+
totalEstimatedUsdc: 0.45,
|
|
89
|
+
steps: [{ step: 1, path: "/api/guard/pre-x402", priceUsdc: 0.05 }],
|
|
90
|
+
executionOrder: [`POST ${path}`],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (path.includes("mandate/verify")) {
|
|
94
|
+
return {
|
|
95
|
+
ok: true,
|
|
96
|
+
allowed: true,
|
|
97
|
+
valid: true,
|
|
98
|
+
withinScope: true,
|
|
99
|
+
reason: "Valid mandate, proposed payment within scope",
|
|
100
|
+
violations: [],
|
|
101
|
+
mandateId: "mdt_verifier_probe_example",
|
|
102
|
+
proposed: { amountUsdc: 0.05, merchant: "api.myceliasignal.com", category: "oracle", rail: "base-x402" },
|
|
103
|
+
confidence: 0.93,
|
|
104
|
+
checks_passed: ["signature_ok", "scope_ok", "not_expired"],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if (path.includes("buy-advisor")) {
|
|
108
|
+
return {
|
|
109
|
+
status: "ok",
|
|
110
|
+
ok: true,
|
|
111
|
+
allowed: true,
|
|
112
|
+
summary: "Best catalog match: Mycelia ETH/USD Oracle at ~$0.05 on eip155:8453.",
|
|
113
|
+
intent: "ETH USD spot price oracle",
|
|
114
|
+
checkedAt: new Date(0).toISOString(),
|
|
115
|
+
recommendation: {
|
|
116
|
+
action: "pay_external",
|
|
117
|
+
url: "https://api.example.com/oracle/eth/usd",
|
|
118
|
+
network: "eip155:8453",
|
|
119
|
+
allInCostUsdc: 0.05,
|
|
120
|
+
confidence: 0.85,
|
|
121
|
+
rationale: "Best catalog match within policy caps",
|
|
122
|
+
},
|
|
123
|
+
quotes: [{ rank: 1, name: "Example API", allInCostUsdc: 0.05, requiresPayment: true }],
|
|
124
|
+
policy: { evaluated: true, allowed: true, summary: "Within daily and per-call limits" },
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
if (path.includes("audition-coach")) {
|
|
128
|
+
return {
|
|
129
|
+
status: "ok",
|
|
130
|
+
ok: true,
|
|
131
|
+
coached: true,
|
|
132
|
+
allowed: true,
|
|
133
|
+
hostScoreEstimate: 78,
|
|
134
|
+
summary: "3 routes audited; ~78 avg score; 0 need fixes before Dexter/x402gle pass (75+).",
|
|
135
|
+
discovery: { openapiOk: true, wellKnownOk: true, resourceCount: 38, openapiPathCount: 38 },
|
|
136
|
+
routes: [
|
|
137
|
+
{
|
|
138
|
+
url: "https://x402trustlayer.xyz/api/guard/pre-x402",
|
|
139
|
+
method: "POST",
|
|
140
|
+
scoreEstimate: 85,
|
|
141
|
+
status: "pass",
|
|
142
|
+
issues: [],
|
|
143
|
+
fixInstructions: [],
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
routeAudits: [
|
|
147
|
+
{
|
|
148
|
+
url: "https://x402trustlayer.xyz/api/guard/pre-x402",
|
|
149
|
+
method: "POST",
|
|
150
|
+
scoreEstimate: 85,
|
|
151
|
+
status: "pass",
|
|
152
|
+
issues: [],
|
|
153
|
+
fixInstructions: [],
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
coaching: { hostScoreEstimate: 78, failCount: 0, passCount: 3, warnCount: 0, topFixes: [] },
|
|
157
|
+
confidence: 0.88,
|
|
158
|
+
checks_passed: ["openapi_checked", "well_known_checked", "routes_audited"],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
if (path.includes("semantic-settle")) {
|
|
162
|
+
return {
|
|
163
|
+
status: "ok",
|
|
164
|
+
ok: true,
|
|
165
|
+
allowed: true,
|
|
166
|
+
mode: "semantic",
|
|
167
|
+
summary: "Semantic+schema score 88 ≥ 72 — release approved",
|
|
168
|
+
semanticScore: 92,
|
|
169
|
+
schemaScore: 100,
|
|
170
|
+
qualityScore: 88,
|
|
171
|
+
escrowStatus: "released",
|
|
172
|
+
decision: "release-to-merchant",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (path.includes("mandate/diff")) {
|
|
176
|
+
return {
|
|
177
|
+
ok: true,
|
|
178
|
+
allowed: true,
|
|
179
|
+
liabilityTier: "allow",
|
|
180
|
+
mandateValid: true,
|
|
181
|
+
withinMandateScope: true,
|
|
182
|
+
violations: [],
|
|
183
|
+
summary: "Tool trace within mandate scope — proceed to x402 payment",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (path.includes("merchant-trust/certify")) {
|
|
187
|
+
return {
|
|
188
|
+
ok: true,
|
|
189
|
+
certified: true,
|
|
190
|
+
badgeId: "cert_example",
|
|
191
|
+
host: "api.myceliasignal.com",
|
|
192
|
+
policy: { requireAttestation: true, minAgentTier: "SILVER", minTrustScore: 50, minSecurityGrade: "C" },
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (path.includes("buyer-gate")) {
|
|
196
|
+
return {
|
|
197
|
+
ok: true,
|
|
198
|
+
allowed: true,
|
|
199
|
+
certifiedSeller: true,
|
|
200
|
+
summary: "Buyer passes certified seller gate — proceed to x402 payment",
|
|
201
|
+
violations: [],
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (path.includes("quality-escrow")) {
|
|
205
|
+
return {
|
|
206
|
+
status: "ok",
|
|
207
|
+
ok: true,
|
|
208
|
+
allowed: true,
|
|
209
|
+
summary: "Quality score 100 ≥ 70 — released $0.05 to api.myceliasignal.com",
|
|
210
|
+
action: "settle",
|
|
211
|
+
escrowId: "qesc_example",
|
|
212
|
+
escrowStatus: "released",
|
|
213
|
+
decision: "release-to-merchant",
|
|
214
|
+
qualityScore: 100,
|
|
215
|
+
releaseThreshold: 70,
|
|
216
|
+
amountUsdc: 0.05,
|
|
217
|
+
reasons: ["All required keys present"],
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
if (path.includes("x402/proxy")) {
|
|
221
|
+
return {
|
|
222
|
+
status: "ok",
|
|
223
|
+
ok: true,
|
|
224
|
+
allowed: true,
|
|
225
|
+
summary: "Proxy preflight passed — safe to pay downstream x402 endpoint",
|
|
226
|
+
securityGrade: "A",
|
|
227
|
+
riskScore: 12,
|
|
228
|
+
targetProbe: { status: 402, requiresPayment: true, priceUsdc: 0.05 },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
return { ok: true, allowed: true, summary: "Paid response after x402 settlement" };
|
|
232
|
+
}
|
|
233
|
+
/** CDP Bazaar extension via official `declareDiscoveryExtension()` helper. */
|
|
234
|
+
export function buildBazaarExtension(path, method, inputExample) {
|
|
235
|
+
const outputExample = defaultOutputExample(path);
|
|
236
|
+
const outputSchema = exampleToJsonSchema(outputExample);
|
|
237
|
+
if (method.toUpperCase() === "GET") {
|
|
238
|
+
const queryParams = path === "/api/attestation/registry"
|
|
239
|
+
? { minGrade: "C", limit: 20 }
|
|
240
|
+
: {};
|
|
241
|
+
const declared = declareDiscoveryExtension({
|
|
242
|
+
queryParams,
|
|
243
|
+
output: { example: outputExample, schema: outputSchema },
|
|
244
|
+
});
|
|
245
|
+
return declared.bazaar;
|
|
246
|
+
}
|
|
247
|
+
const body = inputExample && typeof inputExample === "object" ? inputExample : {};
|
|
248
|
+
const declared = declareDiscoveryExtension({
|
|
249
|
+
bodyType: "json",
|
|
250
|
+
body,
|
|
251
|
+
output: { example: outputExample, schema: outputSchema },
|
|
252
|
+
});
|
|
253
|
+
return declared.bazaar;
|
|
254
|
+
}
|
|
255
|
+
export function bazaarExtensionForRequest(req) {
|
|
256
|
+
const example = VERIFY_EXAMPLES[req.path];
|
|
257
|
+
const declared = declaredHttpMethod(req.path);
|
|
258
|
+
/** Agentic / Bazaar crawlers probe POST routes with GET — declare GET input for probes. */
|
|
259
|
+
const method = declared === "GET"
|
|
260
|
+
? "GET"
|
|
261
|
+
: req.method === "POST"
|
|
262
|
+
? "POST"
|
|
263
|
+
: "GET";
|
|
264
|
+
return buildBazaarExtension(req.path, method, example);
|
|
265
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
export declare function buildBazaarRoutes(): {
|
|
2
|
+
resource: string;
|
|
3
|
+
method: string;
|
|
4
|
+
path: string;
|
|
5
|
+
priceUsdc: number;
|
|
6
|
+
priceDisplay: string;
|
|
7
|
+
tier: string;
|
|
8
|
+
summary: string;
|
|
9
|
+
category: string;
|
|
10
|
+
tags: string[];
|
|
11
|
+
networks: string[];
|
|
12
|
+
payTo: string;
|
|
13
|
+
facilitatorUrl: string;
|
|
14
|
+
extensions: {
|
|
15
|
+
bazaar: {
|
|
16
|
+
discoverable: boolean;
|
|
17
|
+
category: string;
|
|
18
|
+
tags: string[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}[];
|
|
22
|
+
export declare function buildServicesManifest(): {
|
|
23
|
+
x402Version: number;
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
facilitatorUrl: string;
|
|
28
|
+
payTo: string;
|
|
29
|
+
networks: string[];
|
|
30
|
+
openapi: string;
|
|
31
|
+
discover: string;
|
|
32
|
+
routes: {
|
|
33
|
+
resource: string;
|
|
34
|
+
method: string;
|
|
35
|
+
path: string;
|
|
36
|
+
priceUsdc: number;
|
|
37
|
+
priceDisplay: string;
|
|
38
|
+
tier: string;
|
|
39
|
+
summary: string;
|
|
40
|
+
category: string;
|
|
41
|
+
tags: string[];
|
|
42
|
+
networks: string[];
|
|
43
|
+
payTo: string;
|
|
44
|
+
facilitatorUrl: string;
|
|
45
|
+
extensions: {
|
|
46
|
+
bazaar: {
|
|
47
|
+
discoverable: boolean;
|
|
48
|
+
category: string;
|
|
49
|
+
tags: string[];
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
}[];
|
|
53
|
+
updatedAt: string;
|
|
54
|
+
};
|
|
55
|
+
export declare function buildWellKnownX402(): {
|
|
56
|
+
x402Version: number;
|
|
57
|
+
name: string;
|
|
58
|
+
version: "5.1.0";
|
|
59
|
+
description: string;
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
paymentRequired: boolean;
|
|
62
|
+
facilitator: string;
|
|
63
|
+
payTo: Record<string, string>;
|
|
64
|
+
networks: string[];
|
|
65
|
+
discovery: {
|
|
66
|
+
services: string;
|
|
67
|
+
discover: string;
|
|
68
|
+
openapi: string;
|
|
69
|
+
};
|
|
70
|
+
agenticMarket: {
|
|
71
|
+
validateUrl: string;
|
|
72
|
+
note: string;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
export declare function buildDiscoverCatalog(): {
|
|
76
|
+
service: string;
|
|
77
|
+
version: "5.1.0";
|
|
78
|
+
endpointCount: number;
|
|
79
|
+
resources: {
|
|
80
|
+
url: string;
|
|
81
|
+
method: string;
|
|
82
|
+
description: string;
|
|
83
|
+
priceUsdc: number;
|
|
84
|
+
category: string;
|
|
85
|
+
tags: string[];
|
|
86
|
+
accepts: {
|
|
87
|
+
scheme: string;
|
|
88
|
+
network: string;
|
|
89
|
+
payTo: string;
|
|
90
|
+
amountUsdc: number;
|
|
91
|
+
}[];
|
|
92
|
+
extensions: {
|
|
93
|
+
bazaar: {
|
|
94
|
+
discoverable: boolean;
|
|
95
|
+
category: string;
|
|
96
|
+
tags: string[];
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
}[];
|
|
100
|
+
};
|