- Marked submodules ai-mcp-pmm-controller, explorer-monorepo, and smom-dbis-138 as dirty to reflect recent changes. - Updated documentation to clarify operator script usage, including dotenv loading and task execution instructions. - Enhanced the README and various index files to provide clearer navigation and task completion guidance. Made-with: Cursor
4.8 KiB
x402 Endpoint Contract — Alltra (651940) + USDC
Purpose: Spec for Alltra-native x402 paid endpoints: 402 challenge, retry with PAYMENT-SIGNATURE, and local verification on chain 651940 with USDC. Settlement is on Alltra; no dependency on Base or external facilitator.
References: coinbase/x402, HTTP 402 — x402, ADDRESS_MATRIX_AND_STATUS.md §2.3 (Alltra USDC).
1. Overview
- Chain:
eip155:651940(ALL Mainnet / Alltra) - Payment token: USDC at
0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881 - Recipient: Server treasury (e.g.
SERVER_WALLET_ADDRESS) - Verification: Local (recommended): server verifies signature, intent, and on-chain settlement; optional facilitator-like
/verifylater.
2. Step 1 — Client calls paid endpoint (unpaid)
Request: GET /api/resource (or any paid route)
Response when unpaid: 402 Payment Required
Headers:
PAYMENT-REQUIRED: <base64 PaymentRequired>
PaymentRequired (JSON, then base64-encoded):
| Field | Type | Description |
|---|---|---|
network |
string | eip155:651940 |
asset |
string | USDC contract address (0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881) |
amount |
string | Price in base units (e.g. "10000" for 0.01 USDC if 6 decimals) |
recipient |
string | Treasury address |
nonce |
string | Unique per request (e.g. UUID) |
expiresAt |
string | ISO 8601 (e.g. now + 5 minutes) |
resourceId |
string | Identifies the resource (e.g. URL or hash) so payment is bound to the request |
Example (decoded):
{
"network": "eip155:651940",
"asset": "0xa95EeD79f84E6A0151eaEb9d441F9Ffd50e8e881",
"amount": "10000",
"recipient": "0x...",
"nonce": "550e8400-e29b-41d4-a716-446655440000",
"expiresAt": "2026-03-04T12:05:00.000Z",
"resourceId": "GET /api/premium"
}
3. Step 2 — Client pays and retries
Client performs USDC transfer (or authorization) on chain 651940 to recipient for amount, then retries the same request with:
Headers:
PAYMENT-SIGNATURE: <base64 PaymentPayload>
PaymentPayload (JSON, then base64-encoded):
| Field | Type | Description |
|---|---|---|
payer |
string | Payer wallet address |
signature |
string | Signature over the payment intent (e.g. EIP-191 or EIP-712 of PaymentRequired or its hash) |
paymentRequired |
object | Copy of PaymentRequired so server can verify match |
txHash |
string (optional) | Transaction hash on 651940 proving transfer (for on-chain verification) |
Server uses txHash to verify settlement via eth_getTransactionReceipt on 651940 when doing local verification.
4. Step 3 — Server verification (Alltra-native local)
- Decode PaymentPayload from base64.
- Verify signature — signature belongs to
payer(recover signer from signature over payment intent). - Verify intent — PaymentPayload.paymentRequired matches the server-issued PaymentRequired (same amount, asset, chain, recipient, resourceId);
expiresAtis in the future. - Verify settlement:
- If
txHashpresent: call 651940 RPCeth_getTransactionReceipt(txHash); confirm success and that transfer is torecipientforamount(USDC) frompayer. - If authorization-based: verify authorization and that a transfer occurred (per your scheme).
- If
- Replay: Mark
(payer, resourceId, nonce)as consumed (store in DB or cache with TTL); reject if already consumed. - Respond: Return 200 with resource body; optionally set
PAYMENT-RESPONSEheader (per x402) with settlement response.
5. Replay protection
- Key:
(payer, resourceId, nonce). - Store consumed keys with expiry ≥
expiresAtso the same nonce cannot be reused. - Production: use Redis or DB; development: in-memory Map with TTL is acceptable.
6. PAYMENT-RESPONSE (optional)
Per docs.x402.org, server may return PAYMENT-RESPONSE header with settlement confirmation (e.g. txHash, status). Optional for minimal implementation.
7. Separation from sponsorship
- Sponsorship (paymaster): Covers gas for app actions (e.g. CoreApp writes) on 651940.
- x402: User-paid USDC for API/service access; validated by this flow.
The two are independent: x402 payment tx is user-funded; sponsored txs are paymaster-funded.
8. Implementation
- x402-api: When
X402_USE_ALLTRA=true, the server can use this local verification path: return 402 + PAYMENT-REQUIRED when unpaid; on PAYMENT-SIGNATURE, run steps 1–6 and serve the resource on success. - USDC decimals: 6 for Alltra USDC;
amountin PaymentRequired is in base units (e.g. 10000 = 0.01 USDC).