EVM Scheme (USDC on Base)
The EVM scheme uses USDC on Base with EIP-3009 TransferWithAuthorization for gasless, signature-based payments.
Network Parameters
| Parameter | Value |
|---|---|
| Network | base (Chain ID: 8453) |
| Currency | USDC |
| Asset (contract) | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Decimals | 6 (1000000 = 1.0 USDC) |
| Token name | USD Coin |
| Token version | 2 |
| CAIP-2 | eip155:8453 |
| Testnet | base-sepolia (Chain ID: 84532, USDC: 0x036CbD53842c5426634e7929541eC2318f3dCF7e) |
402 Response Example
When a server requires EVM payment, it returns:
json
{
"x402Version": 1,
"accepts": [
{
"x402Version": 1,
"scheme": "exact",
"network": "base",
"maxAmountRequired": "10000",
"resource": "/api/data",
"description": "API access fee",
"payTo": "0xRecipientAddress...",
"maxTimeoutSeconds": 60,
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"extra": {
"name": "USD Coin",
"version": "2"
}
}
]
}X-Payment Payload
The client constructs and base64-encodes the following JSON as the X-Payment header:
json
{
"x402Version": 1,
"scheme": "exact",
"network": "base",
"payload": {
"signature": "0x...",
"authorization": {
"from": "0xPayerWallet...",
"to": "0xRecipientAddress...",
"value": "10000",
"validAfter": "1700000000",
"validBefore": "1700000060",
"nonce": "0x<32-byte-random-hex>"
}
}
}Payload Fields
| Field | Type | Description |
|---|---|---|
signature | 0x{string} | EIP-712 signature over the authorization |
authorization.from | address | Payer's wallet address |
authorization.to | address | Recipient address (payTo from 402 response) |
authorization.value | uint256 | Amount in USDC atomic units (6 decimals) |
authorization.validAfter | uint256 | Unix timestamp — signature valid after this time |
authorization.validBefore | uint256 | Unix timestamp — signature expires at this time |
authorization.nonce | bytes32 | Random 32-byte nonce (0x + 64 hex chars) |
Validity Window
- Default: 60 seconds
- Minimum: 30 seconds
- Maximum: configurable (default 300 seconds)
validAfter = now - 1,validBefore = now + windowSeconds
EIP-712 Type Definition
The signature uses the USDC EIP-3009 TransferWithAuthorization typed data:
json
{
"domain": {
"name": "USD Coin",
"version": "2",
"chainId": 8453,
"verifyingContract": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
},
"primaryType": "TransferWithAuthorization",
"types": {
"TransferWithAuthorization": [
{ "name": "from", "type": "address" },
{ "name": "to", "type": "address" },
{ "name": "value", "type": "uint256" },
{ "name": "validAfter", "type": "uint256" },
{ "name": "validBefore", "type": "uint256" },
{ "name": "nonce", "type": "bytes32" }
]
}
}Verification
The facilitator recovers the signer from the EIP-712 signature and verifies:
- Recovered address matches
authorization.from authorization.tomatches the expected recipientauthorization.valuematches the required amount- Current time is within
validAfter/validBeforewindow - Nonce has not been used
Settlement
Settlement executes an on-chain USDC transferWithAuthorization call on Base using the signed authorization. The facilitator submits the transaction and returns the on-chain txHash.
After settlement, the server includes the transaction hash in the X-Payment-Response header:
json
{
"success": true,
"transaction": "0x..."
}