402 Payment Required and a payment challenge; the client signs a payment payload that satisfies the challenge and resends it in an HTTP header; the server verifies and settles before returning the resource. The protocol is now stewarded under the Linux Foundation.
x402’s production scheme is exact — pay a specific amount of a specific asset (typically USDC). The settlement mechanics differ by ecosystem: EVM chains use off-chain EIP-712 signatures over an ERC-3009 authorization, while Solana uses a signed SPL Token transfer.
x402 is one of the two paid-rail protocols SELAT can use; the other is MPP on Tempo. Among routed rails, MPP is the default — x402 is opt-in (
preferProtocol: "x402" / --prefer-x402).The x402 challenge
A SELAT/x402 402 challenge is a JSON object with anx402Version and an accepts[] array. Each accept entry describes one way to pay:
| Field | Meaning |
|---|---|
scheme | The payment scheme — exact for x402 production payments. |
network | A CAIP-2 network id, e.g. eip155:8453 for Base. |
asset | The token contract to pay in (USDC on most chains). |
payTo | The recipient address. |
amount / maxAmountRequired | The price in token base units. v2 uses amount; v1 uses maxAmountRequired. |
maxTimeoutSeconds | How long the authorization stays valid. |
extra | Scheme metadata — extra.name, extra.verifyingContract, extra.version. |
asset, payTo, and the EIP-712 verifyingContract from the live challenge rather than a static table, so a per-chain address list is never hardcoded.
SELAT detects x402 from a probe in two forms:
- A base64-encoded JSON
payment-required:response header. - A
www-authenticate: X402 requirements="<base64 PaymentRequired JSON>"header (used by some services alongside the body header).
www-authenticate: Payment ... challenge.)
Base (EVM)
On Base and other EVM chains, x402 payments are signed off-chain with EIP-712 typed data and settled in USDC. The signed object is an ERC-3009TransferWithAuthorization:
transferWithAuthorization natively, so a facilitator can submit the signed authorization on-chain — the payer needs no gas. SELAT signs exactly this shape (see GATEWAY_AUTH_TYPES in the payer).
Signer paths
The SDK and CLI support three signer models — see the Signers reference:Circle Agent Wallet
The default. Signing goes through the Circle CLI (
circle wallet sign typed-data), keeping keys in Circle’s MPC and out of the application process.Raw private key
Dev only.
--raw-key / SELAT_PRIVATE_KEY signs in-process via viem, bypassing Circle MPC.Remote signer
For an HSM, KMS, or external wallet service that signs the typed data over a callback.
Circle Agent Wallets are smart-contract accounts (SCA). For a Gateway-batched payment, the authorization’s
from must be the owner EOA that the SCA signature recovers to — not the SCA address. SELAT resolves this by signing a throwaway authorization in the exact GatewayWalletBatched EIP-712 domain and recovering the signer.Direct (Gateway-batched) vs routed
When the upstream’saccepts list contains an exact entry on the expected eip155:<chainId> network whose extra.name is GatewayWalletBatched, SELAT settles DIRECT — batched through Circle Gateway, bypassing the router with no markup. Otherwise it routes the x402 payment through the SELAT Router via its /proxy?target= endpoint. Either way the payment payload is built by the SDK and sent base64-encoded in a payment-signature header.
Supported EVM chains track Circle Gateway plus Arc: Base, Optimism, Arbitrum, and Arc. Base, Optimism, and Arbitrum also support gasless selat fund --method eco deposits (settling into Gateway on Polygon); Arc requires --raw-key (Circle’s MPC signer can’t sign Arc yet) and has no Eco funding. For the authoritative list your runtime accepts, run npx @selat-ai/selat-pay --list-chains.
Solana
x402 also defines an SVM path. Coinbase’s reference implementation and the@x402/svm package implement the exact scheme using SPL Token transfers, and Coinbase’s hosted facilitator lists Solana among its supported networks.
The Solana model is account-based, not EIP-712: the client builds and signs a Solana transaction containing an SPL Token transfer, serializes it, and sends it in the payment header; the server deserializes, verifies, simulates, submits, and confirms. The payer needs a Solana keypair, a USDC Associated Token Account, USDC balance, and an RPC connection.
This is a protocol-level description of x402 on Solana, not a SELAT capability claim. In SELAT’s own code, Solana appears only in network normalization and discovery filters — there is no Solana signing or payment path in the payer or CLI today, and the supported settlement chains are EVM (Base/Optimism/Arbitrum/Arc). SELAT does not currently settle x402 on Solana.
When to prefer x402 vs MPP
- x402 is the open Coinbase standard. SELAT can settle it DIRECT (Gateway-batched, no router markup) on Circle-supported chains — making direct Gateway-batched x402 the no-markup default route.
- MPP is SELAT’s default among routed rails and settles on Tempo.
- Route precedence in the payer: a free upstream is served as a logged passthrough; otherwise the default (no flag) prefers direct Gateway-batched, then routed MPP, then routed x402.
--prefer-x402swaps the routed order to x402-then-MPP (direct still wins);--prefer-mppforces MPP even over direct. - Pass
preferProtocol: "x402"(SDK) or--prefer-x402(CLI) to opt out of the MPP default for routed payments.