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,57 @@
|
|
|
1
|
+
import { claimNonceKey, extractIdempotencyKey, isNonceKeyUsed, } from "./nonce-store.js";
|
|
2
|
+
export { extractIdempotencyKey };
|
|
3
|
+
/** True if this nonce was already used for a successful settlement. */
|
|
4
|
+
export function isNonceAlreadyUsed(nonce) {
|
|
5
|
+
return isNonceKeyUsed(`pay:${nonce}`);
|
|
6
|
+
}
|
|
7
|
+
/** Record nonce only after facilitator settlement succeeds. */
|
|
8
|
+
export async function markNonceUsed(nonce, network) {
|
|
9
|
+
await claimNonceKey(`pay:${nonce}`, network || "unknown");
|
|
10
|
+
}
|
|
11
|
+
export async function checkAndConsumeNonce(nonce, network) {
|
|
12
|
+
if (!nonce || nonce.length < 8)
|
|
13
|
+
return true;
|
|
14
|
+
if (isNonceKeyUsed(`pay:${nonce}`))
|
|
15
|
+
return false;
|
|
16
|
+
return claimNonceKey(`pay:${nonce}`, network);
|
|
17
|
+
}
|
|
18
|
+
export function idempotencyCompositeKey(req, resourcePath) {
|
|
19
|
+
const key = extractIdempotencyKey(req);
|
|
20
|
+
if (!key)
|
|
21
|
+
return undefined;
|
|
22
|
+
return `idem:${resourcePath}:${key}`;
|
|
23
|
+
}
|
|
24
|
+
/** Block only after a prior request with this key completed settlement. */
|
|
25
|
+
export function isIdempotencyKeyConsumed(req, resourcePath) {
|
|
26
|
+
const composite = idempotencyCompositeKey(req, resourcePath);
|
|
27
|
+
return composite ? isNonceKeyUsed(composite) : false;
|
|
28
|
+
}
|
|
29
|
+
export async function markIdempotencyKeyUsed(req, resourcePath) {
|
|
30
|
+
const composite = idempotencyCompositeKey(req, resourcePath);
|
|
31
|
+
if (!composite)
|
|
32
|
+
return;
|
|
33
|
+
await claimNonceKey(composite, "idempotency", 86_400);
|
|
34
|
+
}
|
|
35
|
+
export function extractNonceFromPaymentHeader(header) {
|
|
36
|
+
try {
|
|
37
|
+
const parsed = JSON.parse(Buffer.from(header, "base64").toString("utf8"));
|
|
38
|
+
const payload = parsed.payload;
|
|
39
|
+
const accepted = parsed.accepted;
|
|
40
|
+
const nonce = (typeof payload?.nonce === "string" && payload.nonce) ||
|
|
41
|
+
(typeof parsed.nonce === "string" && parsed.nonce) ||
|
|
42
|
+
undefined;
|
|
43
|
+
const network = (typeof accepted?.network === "string" && accepted.network) ||
|
|
44
|
+
(typeof parsed.network === "string" && parsed.network) ||
|
|
45
|
+
undefined;
|
|
46
|
+
const payTo = (typeof accepted?.payTo === "string" && accepted.payTo) ||
|
|
47
|
+
(typeof payload?.authorization === "object" &&
|
|
48
|
+
payload.authorization !== null &&
|
|
49
|
+
typeof payload.authorization.to === "string" &&
|
|
50
|
+
payload.authorization.to) ||
|
|
51
|
+
undefined;
|
|
52
|
+
return { nonce, network, payTo };
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** x402gle / Dexter host claim — set in Railway when verifying domain ownership */
|
|
2
|
+
export function x402gleChallengeToken() {
|
|
3
|
+
return (process.env.X402GLE_CHALLENGE_TOKEN ?? "").trim();
|
|
4
|
+
}
|
|
5
|
+
export function registerX402gleHostVerification(app) {
|
|
6
|
+
const token = x402gleChallengeToken();
|
|
7
|
+
const serveToken = (_req, res) => {
|
|
8
|
+
if (!token) {
|
|
9
|
+
res.status(404).type("text/plain").send("X402GLE_CHALLENGE_TOKEN not configured");
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
res.type("text/plain").send(token);
|
|
13
|
+
};
|
|
14
|
+
const serveJson = (_req, res) => {
|
|
15
|
+
if (!token) {
|
|
16
|
+
res.status(404).json({ error: "X402GLE_CHALLENGE_TOKEN not configured" });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
res.json({ challenge: token });
|
|
20
|
+
};
|
|
21
|
+
app.get("/.well-known/x402-host-challenge", serveToken);
|
|
22
|
+
app.get("/.well-known/x402gle-challenge", serveToken);
|
|
23
|
+
app.get("/.well-known/x402-host-challenge.txt", serveToken);
|
|
24
|
+
app.get("/.well-known/x402gle-challenge.txt", serveToken);
|
|
25
|
+
app.get("/.well-known/x402-host-challenge.json", serveJson);
|
|
26
|
+
app.get("/.well-known/x402gle-challenge.json", serveJson);
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type AgentPassport = {
|
|
2
|
+
did: string;
|
|
3
|
+
agentId: string;
|
|
4
|
+
publicKey: string;
|
|
5
|
+
ownerIdentity: string;
|
|
6
|
+
capabilities: string[];
|
|
7
|
+
permissions: string[];
|
|
8
|
+
metadata: Record<string, unknown>;
|
|
9
|
+
riskTier: "LOW" | "MEDIUM" | "HIGH";
|
|
10
|
+
reputationProfileId: string;
|
|
11
|
+
issuedAt: string;
|
|
12
|
+
credentialType: "AgentPassportVC";
|
|
13
|
+
signature: string;
|
|
14
|
+
};
|
|
15
|
+
export type IssuePassportInput = {
|
|
16
|
+
agentId: string;
|
|
17
|
+
publicKey?: string;
|
|
18
|
+
ownerIdentity?: string;
|
|
19
|
+
walletAddress?: string;
|
|
20
|
+
capabilities?: string[];
|
|
21
|
+
permissions?: string[];
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
export declare function issueAgentPassport(input: IssuePassportInput): Promise<AgentPassport>;
|
|
25
|
+
export declare function verifyAgentPassport(did: string): Promise<{
|
|
26
|
+
valid: boolean;
|
|
27
|
+
passport: AgentPassport | null;
|
|
28
|
+
reason?: string;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function hardwareAttestationStub(agentId: string): {
|
|
31
|
+
attestationType: "tpm-simulated";
|
|
32
|
+
quote: string;
|
|
33
|
+
agentId: string;
|
|
34
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { hmacSign, newDid, sha256Hex, verifyHmac } from "./crypto.js";
|
|
3
|
+
import { readProtocolStore, writeProtocolStore } from "./store.js";
|
|
4
|
+
export async function issueAgentPassport(input) {
|
|
5
|
+
const store = await readProtocolStore("passports", {});
|
|
6
|
+
const did = newDid(input.agentId);
|
|
7
|
+
const publicKey = input.publicKey ?? sha256Hex(`${input.agentId}:${input.walletAddress ?? "anon"}`);
|
|
8
|
+
const payload = {
|
|
9
|
+
did,
|
|
10
|
+
agentId: input.agentId,
|
|
11
|
+
publicKey,
|
|
12
|
+
ownerIdentity: input.ownerIdentity ?? input.walletAddress ?? "unknown",
|
|
13
|
+
capabilities: input.capabilities ?? ["x402.pay", "x402.preflight", "tool.invoke"],
|
|
14
|
+
permissions: input.permissions ?? ["spend:usdc", "attest:issue"],
|
|
15
|
+
metadata: input.metadata ?? {},
|
|
16
|
+
riskTier: "MEDIUM",
|
|
17
|
+
reputationProfileId: sha256Hex(did).slice(0, 16),
|
|
18
|
+
issuedAt: new Date().toISOString(),
|
|
19
|
+
credentialType: "AgentPassportVC",
|
|
20
|
+
};
|
|
21
|
+
const signature = hmacSign(JSON.stringify(payload));
|
|
22
|
+
const passport = { ...payload, signature };
|
|
23
|
+
store[did] = passport;
|
|
24
|
+
await writeProtocolStore("passports", store);
|
|
25
|
+
return passport;
|
|
26
|
+
}
|
|
27
|
+
export async function verifyAgentPassport(did) {
|
|
28
|
+
const store = await readProtocolStore("passports", {});
|
|
29
|
+
const passport = store[did] ?? null;
|
|
30
|
+
if (!passport)
|
|
31
|
+
return { valid: false, passport: null, reason: "DID not found" };
|
|
32
|
+
const { signature, ...payload } = passport;
|
|
33
|
+
if (!verifyHmac(JSON.stringify(payload), signature)) {
|
|
34
|
+
return { valid: false, passport, reason: "Invalid credential signature" };
|
|
35
|
+
}
|
|
36
|
+
return { valid: true, passport };
|
|
37
|
+
}
|
|
38
|
+
export function hardwareAttestationStub(agentId) {
|
|
39
|
+
return {
|
|
40
|
+
attestationType: "tpm-simulated",
|
|
41
|
+
quote: sha256Hex(`tpm:${agentId}:${randomBytes(8).toString("hex")}`),
|
|
42
|
+
agentId,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type ComplianceAssessInput = {
|
|
2
|
+
organizationId: string;
|
|
3
|
+
agentId: string;
|
|
4
|
+
jurisdiction?: string;
|
|
5
|
+
monthlyVolumeUsdc?: number;
|
|
6
|
+
rails?: string[];
|
|
7
|
+
requiresKyc?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type ComplianceAssessResult = {
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
amlRisk: "low" | "medium" | "high";
|
|
12
|
+
kycRequired: boolean;
|
|
13
|
+
auditTrailId: string;
|
|
14
|
+
policyDecisions: string[];
|
|
15
|
+
regulatoryReporting: {
|
|
16
|
+
sarThresholdUsdc: number;
|
|
17
|
+
ctrThresholdUsdc: number;
|
|
18
|
+
};
|
|
19
|
+
forensicLogRef: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function assessCompliance(input: ComplianceAssessInput): ComplianceAssessResult;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function assessCompliance(input) {
|
|
2
|
+
const volume = input.monthlyVolumeUsdc ?? 0;
|
|
3
|
+
const amlRisk = volume > 10000 ? "high" : volume > 1000 ? "medium" : "low";
|
|
4
|
+
const kycRequired = input.requiresKyc === true || volume > 5000;
|
|
5
|
+
const allowed = amlRisk !== "high" || kycRequired;
|
|
6
|
+
return {
|
|
7
|
+
allowed,
|
|
8
|
+
amlRisk,
|
|
9
|
+
kycRequired,
|
|
10
|
+
auditTrailId: `comp_${input.organizationId}_${Date.now().toString(36)}`,
|
|
11
|
+
policyDecisions: [
|
|
12
|
+
kycRequired ? "kyc_gate_required" : "kyc_optional",
|
|
13
|
+
`aml_risk_${amlRisk}`,
|
|
14
|
+
"ledger_export_via_compliance_ledger",
|
|
15
|
+
],
|
|
16
|
+
regulatoryReporting: { sarThresholdUsdc: 5000, ctrThresholdUsdc: 10000 },
|
|
17
|
+
forensicLogRef: `forensic://${input.organizationId}/${input.agentId}`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type CreditScoreInput = {
|
|
2
|
+
agentId: string;
|
|
3
|
+
walletAddress: string;
|
|
4
|
+
disputeCount?: number;
|
|
5
|
+
settlementCount?: number;
|
|
6
|
+
uptimePct?: number;
|
|
7
|
+
};
|
|
8
|
+
export type CreditScoreResult = {
|
|
9
|
+
creditScore: number;
|
|
10
|
+
band: "exceptional" | "good" | "fair" | "poor" | "high_risk";
|
|
11
|
+
range: "300-900";
|
|
12
|
+
factors: Record<string, number>;
|
|
13
|
+
limits: {
|
|
14
|
+
suggestedDailyCapUsdc: number;
|
|
15
|
+
suggestedPerCallCapUsdc: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare function computeAgentCreditScore(input: CreditScoreInput): Promise<CreditScoreResult>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { computeTrustScoreV2 } from "./trust-score-v2.js";
|
|
2
|
+
import { readProtocolStoreKey, writeProtocolStoreKey } from "./store.js";
|
|
3
|
+
export async function computeAgentCreditScore(input) {
|
|
4
|
+
const trust = await computeTrustScoreV2({
|
|
5
|
+
agentId: input.agentId,
|
|
6
|
+
walletAddress: input.walletAddress,
|
|
7
|
+
disputeRatePct: (input.disputeCount ?? 0) * 2,
|
|
8
|
+
uptimePct: input.uptimePct ?? 95,
|
|
9
|
+
});
|
|
10
|
+
const key = input.agentId;
|
|
11
|
+
const agentHistory = await readProtocolStoreKey("credit-bureau", key, { scores: [] });
|
|
12
|
+
const prev = agentHistory.scores ?? [];
|
|
13
|
+
const settlements = input.settlementCount ?? prev.length;
|
|
14
|
+
const reliability = Math.min(200, settlements * 4);
|
|
15
|
+
const disputePenalty = Math.min(150, (input.disputeCount ?? 0) * 25);
|
|
16
|
+
const raw = 300 + trust.trustScore * 4 + reliability - disputePenalty;
|
|
17
|
+
const creditScore = Math.round(Math.max(300, Math.min(900, raw)));
|
|
18
|
+
const band = creditScore >= 800
|
|
19
|
+
? "exceptional"
|
|
20
|
+
: creditScore >= 700
|
|
21
|
+
? "good"
|
|
22
|
+
: creditScore >= 600
|
|
23
|
+
? "fair"
|
|
24
|
+
: creditScore >= 500
|
|
25
|
+
? "poor"
|
|
26
|
+
: "high_risk";
|
|
27
|
+
const updatedHistory = { scores: [...prev, creditScore].slice(-50) };
|
|
28
|
+
await writeProtocolStoreKey("credit-bureau", key, updatedHistory);
|
|
29
|
+
return {
|
|
30
|
+
creditScore,
|
|
31
|
+
band,
|
|
32
|
+
range: "300-900",
|
|
33
|
+
factors: {
|
|
34
|
+
trust_v2: trust.trustScore,
|
|
35
|
+
settlement_history: reliability,
|
|
36
|
+
dispute_penalty: -disputePenalty,
|
|
37
|
+
uptime: input.uptimePct ?? 95,
|
|
38
|
+
},
|
|
39
|
+
limits: {
|
|
40
|
+
suggestedDailyCapUsdc: creditScore >= 700 ? 50 : creditScore >= 600 ? 10 : 2,
|
|
41
|
+
suggestedPerCallCapUsdc: creditScore >= 700 ? 2 : creditScore >= 600 ? 0.5 : 0.1,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function sha256Hex(input: string | Buffer): string;
|
|
2
|
+
export declare function hmacSign(payload: string): string;
|
|
3
|
+
export declare function verifyHmac(payload: string, signature: string): boolean;
|
|
4
|
+
export declare function merkleRoot(leaves: string[]): string;
|
|
5
|
+
export declare function newDid(agentId: string): string;
|
|
6
|
+
export declare function randomNonce(): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
export function sha256Hex(input) {
|
|
4
|
+
return createHash("sha256").update(input).digest("hex");
|
|
5
|
+
}
|
|
6
|
+
export function hmacSign(payload) {
|
|
7
|
+
return createHmac("sha256", config.attestationHmacSecret).update(payload).digest("hex");
|
|
8
|
+
}
|
|
9
|
+
export function verifyHmac(payload, signature) {
|
|
10
|
+
const expected = hmacSign(payload);
|
|
11
|
+
if (expected.length !== signature.length)
|
|
12
|
+
return false;
|
|
13
|
+
try {
|
|
14
|
+
return timingSafeEqual(Buffer.from(expected, "utf8"), Buffer.from(signature, "utf8"));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function merkleRoot(leaves) {
|
|
21
|
+
if (leaves.length === 0)
|
|
22
|
+
return sha256Hex("empty");
|
|
23
|
+
let layer = leaves.map((l) => sha256Hex(l));
|
|
24
|
+
while (layer.length > 1) {
|
|
25
|
+
const next = [];
|
|
26
|
+
for (let i = 0; i < layer.length; i += 2) {
|
|
27
|
+
const left = layer[i];
|
|
28
|
+
const right = layer[i + 1] ?? left;
|
|
29
|
+
next.push(sha256Hex(`${left}:${right}`));
|
|
30
|
+
}
|
|
31
|
+
layer = next;
|
|
32
|
+
}
|
|
33
|
+
return layer[0];
|
|
34
|
+
}
|
|
35
|
+
export function newDid(agentId) {
|
|
36
|
+
const slug = agentId.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 48);
|
|
37
|
+
return `did:agent:${slug}:${randomBytes(8).toString("hex")}`;
|
|
38
|
+
}
|
|
39
|
+
export function randomNonce() {
|
|
40
|
+
return randomBytes(16).toString("hex");
|
|
41
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const ESCROW_STATES: readonly ["CREATED", "FUNDED", "LOCKED", "EXECUTING", "DELIVERED", "VERIFIED", "SETTLED", "REFUNDED", "DISPUTED", "CANCELLED"];
|
|
2
|
+
export type EscrowState = (typeof ESCROW_STATES)[number];
|
|
3
|
+
export type ProtocolEscrow = {
|
|
4
|
+
escrowId: string;
|
|
5
|
+
payerAgentId: string;
|
|
6
|
+
payeeMerchant: string;
|
|
7
|
+
amountUsdc: number;
|
|
8
|
+
state: EscrowState;
|
|
9
|
+
resourceHash?: string;
|
|
10
|
+
sessionId?: string;
|
|
11
|
+
multiSigRecovery?: string[];
|
|
12
|
+
history: Array<{
|
|
13
|
+
state: EscrowState;
|
|
14
|
+
at: string;
|
|
15
|
+
note?: string;
|
|
16
|
+
}>;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
stateProof: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function createProtocolEscrow(input: {
|
|
22
|
+
payerAgentId: string;
|
|
23
|
+
payeeMerchant: string;
|
|
24
|
+
amountUsdc: number;
|
|
25
|
+
resourceHash?: string;
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
}): Promise<ProtocolEscrow>;
|
|
28
|
+
export declare function transitionEscrow(escrowId: string, nextState: EscrowState, note?: string): Promise<{
|
|
29
|
+
ok: boolean;
|
|
30
|
+
escrow?: ProtocolEscrow;
|
|
31
|
+
error?: string;
|
|
32
|
+
}>;
|
|
33
|
+
export declare function getEscrowStatus(escrowId: string): Promise<ProtocolEscrow | null>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { hmacSign } from "./crypto.js";
|
|
3
|
+
import { recordEscrowTransition, syncProtocolEscrow } from "../lib/escrow-unified.js";
|
|
4
|
+
import { readProtocolStore, writeProtocolStore } from "./store.js";
|
|
5
|
+
export const ESCROW_STATES = [
|
|
6
|
+
"CREATED",
|
|
7
|
+
"FUNDED",
|
|
8
|
+
"LOCKED",
|
|
9
|
+
"EXECUTING",
|
|
10
|
+
"DELIVERED",
|
|
11
|
+
"VERIFIED",
|
|
12
|
+
"SETTLED",
|
|
13
|
+
"REFUNDED",
|
|
14
|
+
"DISPUTED",
|
|
15
|
+
"CANCELLED",
|
|
16
|
+
];
|
|
17
|
+
const VALID_TRANSITIONS = {
|
|
18
|
+
CREATED: ["FUNDED", "CANCELLED"],
|
|
19
|
+
FUNDED: ["LOCKED", "CANCELLED"],
|
|
20
|
+
LOCKED: ["EXECUTING", "DISPUTED", "CANCELLED"],
|
|
21
|
+
EXECUTING: ["DELIVERED", "DISPUTED", "CANCELLED"],
|
|
22
|
+
DELIVERED: ["VERIFIED", "DISPUTED"],
|
|
23
|
+
VERIFIED: ["SETTLED", "REFUNDED", "DISPUTED"],
|
|
24
|
+
SETTLED: [],
|
|
25
|
+
REFUNDED: [],
|
|
26
|
+
DISPUTED: ["SETTLED", "REFUNDED", "CANCELLED"],
|
|
27
|
+
CANCELLED: [],
|
|
28
|
+
};
|
|
29
|
+
export async function createProtocolEscrow(input) {
|
|
30
|
+
const store = await readProtocolStore("escrow-fsm", {});
|
|
31
|
+
const escrowId = randomUUID();
|
|
32
|
+
const now = new Date().toISOString();
|
|
33
|
+
const escrow = {
|
|
34
|
+
escrowId,
|
|
35
|
+
payerAgentId: input.payerAgentId,
|
|
36
|
+
payeeMerchant: input.payeeMerchant,
|
|
37
|
+
amountUsdc: input.amountUsdc,
|
|
38
|
+
state: "CREATED",
|
|
39
|
+
resourceHash: input.resourceHash,
|
|
40
|
+
sessionId: input.sessionId,
|
|
41
|
+
history: [{ state: "CREATED", at: now }],
|
|
42
|
+
createdAt: now,
|
|
43
|
+
updatedAt: now,
|
|
44
|
+
stateProof: "",
|
|
45
|
+
};
|
|
46
|
+
escrow.stateProof = hmacSign(`${escrowId}:${escrow.state}:${now}`);
|
|
47
|
+
store[escrowId] = escrow;
|
|
48
|
+
await writeProtocolStore("escrow-fsm", store);
|
|
49
|
+
syncProtocolEscrow({
|
|
50
|
+
escrowId,
|
|
51
|
+
payerAgentId: input.payerAgentId,
|
|
52
|
+
payeeId: input.payeeMerchant,
|
|
53
|
+
amountUsdc: input.amountUsdc,
|
|
54
|
+
state: escrow.state,
|
|
55
|
+
resourceHash: input.resourceHash,
|
|
56
|
+
sessionId: input.sessionId,
|
|
57
|
+
stateProof: escrow.stateProof,
|
|
58
|
+
metadata: { source: "protocol-fsm" },
|
|
59
|
+
});
|
|
60
|
+
return escrow;
|
|
61
|
+
}
|
|
62
|
+
export async function transitionEscrow(escrowId, nextState, note) {
|
|
63
|
+
const store = await readProtocolStore("escrow-fsm", {});
|
|
64
|
+
const escrow = store[escrowId];
|
|
65
|
+
if (!escrow)
|
|
66
|
+
return { ok: false, error: "Escrow not found" };
|
|
67
|
+
const allowed = VALID_TRANSITIONS[escrow.state];
|
|
68
|
+
if (!allowed.includes(nextState)) {
|
|
69
|
+
return {
|
|
70
|
+
ok: false,
|
|
71
|
+
error: `Invalid transition ${escrow.state} -> ${nextState}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const now = new Date().toISOString();
|
|
75
|
+
const fromState = escrow.state;
|
|
76
|
+
escrow.state = nextState;
|
|
77
|
+
escrow.updatedAt = now;
|
|
78
|
+
escrow.history.push({ state: nextState, at: now, note });
|
|
79
|
+
escrow.stateProof = hmacSign(`${escrowId}:${nextState}:${now}`);
|
|
80
|
+
store[escrowId] = escrow;
|
|
81
|
+
await writeProtocolStore("escrow-fsm", store);
|
|
82
|
+
recordEscrowTransition(escrowId, fromState, nextState, note, escrow.stateProof);
|
|
83
|
+
syncProtocolEscrow({
|
|
84
|
+
escrowId,
|
|
85
|
+
payerAgentId: escrow.payerAgentId,
|
|
86
|
+
payeeId: escrow.payeeMerchant,
|
|
87
|
+
amountUsdc: escrow.amountUsdc,
|
|
88
|
+
state: nextState,
|
|
89
|
+
resourceHash: escrow.resourceHash,
|
|
90
|
+
sessionId: escrow.sessionId,
|
|
91
|
+
stateProof: escrow.stateProof,
|
|
92
|
+
metadata: { source: "protocol-fsm", historyLen: escrow.history.length },
|
|
93
|
+
});
|
|
94
|
+
return { ok: true, escrow };
|
|
95
|
+
}
|
|
96
|
+
export async function getEscrowStatus(escrowId) {
|
|
97
|
+
const store = await readProtocolStore("escrow-fsm", {});
|
|
98
|
+
return store[escrowId] ?? null;
|
|
99
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type FraudScanInput = {
|
|
2
|
+
agentId?: string;
|
|
3
|
+
walletAddress?: string;
|
|
4
|
+
merchantHost?: string;
|
|
5
|
+
transactionHashes?: string[];
|
|
6
|
+
amountUsdc?: number;
|
|
7
|
+
peerWallets?: string[];
|
|
8
|
+
};
|
|
9
|
+
export type FraudScanResult = {
|
|
10
|
+
fraudScore: number;
|
|
11
|
+
riskScore: number;
|
|
12
|
+
confidence: number;
|
|
13
|
+
signals: Array<{
|
|
14
|
+
code: string;
|
|
15
|
+
severity: "low" | "medium" | "high";
|
|
16
|
+
detail: string;
|
|
17
|
+
}>;
|
|
18
|
+
graph: {
|
|
19
|
+
nodes: number;
|
|
20
|
+
edges: number;
|
|
21
|
+
circularPaymentDetected: boolean;
|
|
22
|
+
washTradingSuspected: boolean;
|
|
23
|
+
walletClusterSuspected: boolean;
|
|
24
|
+
};
|
|
25
|
+
recommendation: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function runFraudScan(input: FraudScanInput): Promise<FraudScanResult>;
|
|
28
|
+
export declare function fingerprintAgent(agentId: string, wallet?: string): string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { sha256Hex } from "./crypto.js";
|
|
2
|
+
import { readProtocolStore, writeProtocolStore } from "./store.js";
|
|
3
|
+
export async function runFraudScan(input) {
|
|
4
|
+
const graph = await readProtocolStore("fraud-graph", { wallets: {} });
|
|
5
|
+
const signals = [];
|
|
6
|
+
let fraudScore = 8;
|
|
7
|
+
let riskScore = 12;
|
|
8
|
+
const wallet = input.walletAddress?.toLowerCase();
|
|
9
|
+
if (wallet) {
|
|
10
|
+
const entry = graph.wallets[wallet] ?? { peers: [], volumeUsdc: 0, txCount: 0 };
|
|
11
|
+
entry.txCount += 1;
|
|
12
|
+
entry.volumeUsdc += input.amountUsdc ?? 0;
|
|
13
|
+
for (const peer of input.peerWallets ?? []) {
|
|
14
|
+
if (!entry.peers.includes(peer))
|
|
15
|
+
entry.peers.push(peer);
|
|
16
|
+
}
|
|
17
|
+
graph.wallets[wallet] = entry;
|
|
18
|
+
await writeProtocolStore("fraud-graph", graph);
|
|
19
|
+
if (entry.peers.length > 8 && entry.volumeUsdc < 1) {
|
|
20
|
+
signals.push({
|
|
21
|
+
code: "WALLET_CLUSTER_LOW_VALUE",
|
|
22
|
+
severity: "high",
|
|
23
|
+
detail: "Many peers with low aggregate volume — possible Sybil cluster",
|
|
24
|
+
});
|
|
25
|
+
fraudScore += 35;
|
|
26
|
+
riskScore += 30;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const hashes = input.transactionHashes ?? [];
|
|
30
|
+
if (hashes.length >= 3) {
|
|
31
|
+
const unique = new Set(hashes.map((h) => h.slice(0, 12)));
|
|
32
|
+
if (unique.size <= 1) {
|
|
33
|
+
signals.push({
|
|
34
|
+
code: "CIRCULAR_OR_REPEATED_TX",
|
|
35
|
+
severity: "high",
|
|
36
|
+
detail: "Repeated transaction hash prefix pattern",
|
|
37
|
+
});
|
|
38
|
+
fraudScore += 28;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if ((input.amountUsdc ?? 0) > 0 && (input.amountUsdc ?? 0) < 0.02 && hashes.length > 5) {
|
|
42
|
+
signals.push({
|
|
43
|
+
code: "WASH_MICRO_PAYMENTS",
|
|
44
|
+
severity: "medium",
|
|
45
|
+
detail: "High txn count with micro amounts",
|
|
46
|
+
});
|
|
47
|
+
fraudScore += 22;
|
|
48
|
+
}
|
|
49
|
+
const circularPaymentDetected = signals.some((s) => s.code === "CIRCULAR_OR_REPEATED_TX");
|
|
50
|
+
const washTradingSuspected = signals.some((s) => s.code === "WASH_MICRO_PAYMENTS");
|
|
51
|
+
const walletClusterSuspected = signals.some((s) => s.code === "WALLET_CLUSTER_LOW_VALUE");
|
|
52
|
+
fraudScore = Math.min(100, fraudScore);
|
|
53
|
+
riskScore = Math.min(100, Math.max(fraudScore, riskScore));
|
|
54
|
+
const nodeSet = new Set(Object.keys(graph.wallets));
|
|
55
|
+
const edgeCount = Object.values(graph.wallets).reduce((a, w) => a + w.peers.length, 0);
|
|
56
|
+
return {
|
|
57
|
+
fraudScore,
|
|
58
|
+
riskScore,
|
|
59
|
+
confidence: signals.length ? 0.78 : 0.55,
|
|
60
|
+
signals,
|
|
61
|
+
graph: {
|
|
62
|
+
nodes: nodeSet.size,
|
|
63
|
+
edges: edgeCount,
|
|
64
|
+
circularPaymentDetected,
|
|
65
|
+
washTradingSuspected,
|
|
66
|
+
walletClusterSuspected,
|
|
67
|
+
},
|
|
68
|
+
recommendation: fraudScore >= 50
|
|
69
|
+
? "Block or require manual review before x402 settlement"
|
|
70
|
+
: fraudScore >= 25
|
|
71
|
+
? "Require escrow + elevated guard caps"
|
|
72
|
+
: "Proceed with standard pre-x402 guard",
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function fingerprintAgent(agentId, wallet) {
|
|
76
|
+
return sha256Hex(`${agentId}:${wallet ?? ""}`).slice(0, 20);
|
|
77
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type MetricEvent = {
|
|
2
|
+
name: string;
|
|
3
|
+
at: string;
|
|
4
|
+
labels: Record<string, string>;
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function recordProtocolMetric(name: string, labels?: Record<string, string>, value?: number): Promise<void>;
|
|
8
|
+
export declare function getProtocolMetricsSnapshot(): Promise<{
|
|
9
|
+
openTelemetryCompatible: boolean;
|
|
10
|
+
traceFormat: string;
|
|
11
|
+
recent: MetricEvent[];
|
|
12
|
+
counters: Record<string, number>;
|
|
13
|
+
}>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readProtocolStore, writeProtocolStore } from "./store.js";
|
|
2
|
+
export async function recordProtocolMetric(name, labels = {}, value = 1) {
|
|
3
|
+
const store = await readProtocolStore("otel-metrics", { events: [] });
|
|
4
|
+
store.events.push({ name, at: new Date().toISOString(), labels, value });
|
|
5
|
+
if (store.events.length > 5000)
|
|
6
|
+
store.events = store.events.slice(-3000);
|
|
7
|
+
await writeProtocolStore("otel-metrics", store);
|
|
8
|
+
}
|
|
9
|
+
export async function getProtocolMetricsSnapshot() {
|
|
10
|
+
const store = await readProtocolStore("otel-metrics", { events: [] });
|
|
11
|
+
const counters = {};
|
|
12
|
+
for (const e of store.events) {
|
|
13
|
+
counters[e.name] = (counters[e.name] ?? 0) + e.value;
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
openTelemetryCompatible: true,
|
|
17
|
+
traceFormat: "x402-trust-layer-trace-v1",
|
|
18
|
+
recent: store.events.slice(-50),
|
|
19
|
+
counters,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type FullTrustPipelineInput = {
|
|
2
|
+
agentId: string;
|
|
3
|
+
walletAddress: string;
|
|
4
|
+
targetUrl: string;
|
|
5
|
+
estimatedCostUsdc: number;
|
|
6
|
+
organizationId?: string;
|
|
7
|
+
policy: {
|
|
8
|
+
dailyCapUsdc: number;
|
|
9
|
+
perCallCapUsdc: number;
|
|
10
|
+
allowedHosts?: string[];
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export declare function runFullTrustPipeline(input: FullTrustPipelineInput): Promise<{
|
|
14
|
+
status: string;
|
|
15
|
+
allowed: boolean;
|
|
16
|
+
summary: string;
|
|
17
|
+
passport: {
|
|
18
|
+
did: string;
|
|
19
|
+
riskTier: "LOW" | "MEDIUM" | "HIGH";
|
|
20
|
+
};
|
|
21
|
+
trustV2: import("./trust-score-v2.js").TrustScoreV2Result;
|
|
22
|
+
fraud: import("./fraud-engine.js").FraudScanResult;
|
|
23
|
+
oracle: import("./trust-oracle.js").OracleConsensusResult;
|
|
24
|
+
credit: import("./credit-bureau.js").CreditScoreResult;
|
|
25
|
+
compliance: import("./compliance-v2.js").ComplianceAssessResult;
|
|
26
|
+
replayBinding: {
|
|
27
|
+
bindingId: string;
|
|
28
|
+
header: string;
|
|
29
|
+
nonce: string;
|
|
30
|
+
expiresAt: string;
|
|
31
|
+
};
|
|
32
|
+
guard: {
|
|
33
|
+
allowed: boolean;
|
|
34
|
+
securityGrade: string;
|
|
35
|
+
summary: string;
|
|
36
|
+
};
|
|
37
|
+
nextSteps: string[];
|
|
38
|
+
protocolVersion: string;
|
|
39
|
+
docs: string;
|
|
40
|
+
}>;
|