Two additive features on top of V2. V1 and V2 are untouched.
- x402 payment layer — the score API can charge USDC per query on Arc, so an agent pays for a trust score before hiring another agent.
- MCP server —
@proofgraph/mcp, so any MCP client (Claude Desktop, agents) can ask for a task-aware trust score conversationally.
Branch: v2.5 → PR → main → Vercel redeploy (same flow as V2).
# MCP server (read-only, no wallet)
npm run mcp
# x402 self-test — needs a funded Arc wallet in .env.local:
# X402_FACILITATOR_PRIVATE_KEY=0x…
# (the self-test / demo append ?x402=require, so the free allowance doesn't matter)
npm run dev -- --port 3100 # terminal 1
X402_BUYER_PRIVATE_KEY=0x… npm run x402:selftest # terminal 2
# x402 demo — orchestrator hires an auditor, paying per trust query
X402_BUYER_PRIVATE_KEY=0x… npm run x402:demo # terminal 2With X402_FACILITATOR_PRIVATE_KEY unset the API stays free and no wallet is
needed — V2 behaviour is unchanged.
USDC 0x3600000000000000000000000000000000000000 is a Circle FiatTokenProxy →
impl 0xc6ad664ac6679f4ce74e10e91449c93ec1ae3ca6, which implements the full
EIP-3009 set (transferWithAuthorization, receiveWithAuthorization,
authorizationState, cancelAuthorization) plus EIP-2612 permit.
name() = "USDC", version() = "2", DOMAIN_SEPARATOR() present → EIP-712 domain OK.
So the x402 exact scheme over EIP-3009 works on Arc: client signs a
transferWithAuthorization, a facilitator settles it.
Use the current scoped V2 line (2.25.0, actively maintained by the x402 team):
| Package | Role |
|---|---|
@x402/core |
x402Facilitator, x402ResourceServer, types |
@x402/evm |
ExactEvmScheme (server + facilitator) — caipFamily "eip155:*", works on any EVM chain, not an allowlist |
@x402/next |
Next.js integration |
@x402/evm deps viem ^2.48.11 (we have 2.55.19 ✓), zod, @x402/core.
The older unscoped x402 / x402-next (1.x) is the deprecated V1 line — don't use.
Arc isn't in any hosted facilitator's network list, but ExactEvmScheme is
chain-agnostic. For a single-instance deployment we verify + settle inline in
the route (no separate facilitator service):
x402ResourceServer+ExactEvmScheme(server) → build the 402 requirementsx402Facilitator+ExactEvmScheme(facilitator) + a viemFacilitatorEvmSigneron Arc →verify(check the EIP-712 sig / validAfter / validBefore / nonce) thensettle(submittransferWithAuthorizationfrom client → payTo)- Arc network registered as eip155:5042002, asset = USDC
0x3600…(6 decimals), via a custom money parser (registerMoneyParser) mapping"$0.01"→ amount
Facilitator signer wallet needs a little Arc USDC for gas (Arc gas is USDC; it pays to broadcast the settle tx). User funds it in Sprint 2.
Wraps src/lib/proofgraphV2.ts directly (no HTTP, no payment — local trust oracle).
Tools:
get_agent_score(agentId, capability)→{ score, confidence, reasons[], counts, evidence[] }get_agent_scorecard(agentId)→ all four capabilities + ERC-8004 profileresolve_agent(addressOrId)→ agentIdlist_capabilities()
Transport: stdio (Claude Desktop / local) + optional HTTP. @modelcontextprotocol/sdk.
README: how to add to an MCP client config. Publishable to npm.
withFreeAllowanceThenX402(handler, path, priceUsd, description)wraps/v2/api/score($0.01) and/v2/api/agents/[id]($0.02): first N requests / client / day are free (in-memory counter, envPROOFGRAPH_X402_FREE_PER_DAY), then a validx402payment is required → verify + settle on Arc → run scoring → return the score plus aPAYMENT-RESPONSEheader carrying the settlement tx. IfX402_FACILITATOR_PRIVATE_KEYis unset the wrapper is a no-op — the app runs free, exactly as V2 did.src/lib/x402.ts(server-only) — the in-process facilitator + resource server + a money parser mapping"$0.01"→ Arc USDC base units.src/lib/x402Gate.ts— the free-allowance-then-402 wrapper.src/lib/x402Client.ts—makePayingFetch(privateKey): afetchthat signs the EIP-3009 authorization with a viem account and auto-retries the 402.scripts/x402-selftest.ts(npm run x402:selftest) — unpaid ⇒ 402, paid ⇒ 200 + score + settlement header, against a running dev server.
Four things the first live run against Arc surfaced (all fixed):
PROOFGRAPH_X402_FREE_PER_DAY=0still let the first request through — the first-request branch returnedtrueunconditionally. Guarded withFREE_QUERIES_PER_DAY <= 0 ⇒ always charge; also added?x402=requireso a caller can force the paid path without exhausting the free tier (the/v2panel, the self-test and the demo use it).- The
exactscheme needs the token's EIP-712 domain to signtransferWithAuthorization. Arc USDC isn't in x402's built-in asset table, so we passextra: { name: "USDC", version: "2" }in the payment requirements — verified on-chain (recomputedDOMAIN_SEPARATORmatches;name() = "USDC",version() = "2"). @x402/fetchclient spend controls only trust default assets. Allow Arc USDC explicitly with a $1 / payment cap (setSpendControls({ allowedAssets: [...] })).- x402 v2 emits the settlement header as
PAYMENT-RESPONSE, notX-PAYMENT-RESPONSE. Fixed the self-test check and the CORS expose/allow lists.
- ✅ Demo:
scripts/x402-demo.ts(npm run x402:demo) — an orchestrator agent has a "Solidity Audit" task and three candidates, buys a ProofGraph score for each over x402, ranks by confidence then score, hires the best, and prints a decision receipt with an arcscan link for every query it paid for. - ✅ Docs: this file,
README.mdV2.5 section,SPEC.md§8,ROADMAP.md. - ✅
/v2"Query via x402" panel — "Simulate an agent request" → decoded 402 requirements (price / asset / network / scheme / payTo) + paying-client snippet. - ☐ PR
v2.5 → main, merge, Vercel redeploy.
Sybil resistance, ERC-8183 jobs, marketplace adapter (still V3). Mainnet deploy of
the paid API (later). Rewriting the scoring engine (frozen at v2.0).