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). Inbound to SELAT is USDC on EVM via Circle Gateway. 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. A Gateway-capable upstream defaults to x402 (same-rail passthrough); otherwise MPP is the default and 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:
The payer takes
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.Same-rail passthrough vs cross-protocol routing
Every paid call goes through the SELAT Router via its/proxy?target= endpoint — including upstreams that themselves accept Gateway-batched x402. (Earlier selat-pay versions paid Gateway-capable upstreams directly, bypassing the router; that mode was removed so every call is quoted, recorded, and reconciled.) What the upstream’s accepts list controls is the outbound protocol: when it contains an exact entry on the expected eip155:<chainId> network whose extra.name is GatewayWalletBatched, the router settles the upstream leg as a same-rail Gateway passthrough (routed-x402, no cross-protocol translation); otherwise it translates to MPP or x402 exact on the outbound leg (EIP-3009 on EVM, TransferChecked on Solana). The payment payload is built by the SDK and sent base64-encoded in a payment-signature header, always signed in the one GatewayWalletBatched shape against the router’s own 402 quote.
Cross-protocol calls (Gateway in → MPP/erc-3009 out) carry the router’s flat, transparent ~5% markup. Same-rail Gateway passthrough is currently quoted at par (0%) — that is the operator’s live behavior, not a protocol guarantee. The per-call 402 quote is always authoritative; inspect it with
--probe-only.selat fund --method eco fast deposits (a ~30-second credit, settling into Gateway on Polygon).
Solana
Agents pay in on EVM via Circle Gateway. The router settles x402 exact on Solana (SPL) outbound. Solana is not a fund chain. x402 defines an SVMexact scheme: an account-based SPL Token transfer, not an EIP-712 authorization. Coinbase’s reference implementation and the @x402/svm package implement that path — a signed Solana transaction that transfers USDC (an SPL Token) to the accept’s payTo.
You still sign only the Gateway-batched quote.
When to prefer x402 vs MPP
- x402 is the open Coinbase standard. A Gateway-capable upstream defaults to
routed-x402— same-rail Gateway passthrough with no cross-protocol translation, currently quoted at par by the router. - MPP is SELAT’s default for upstreams without a Gateway-batched accept, and settles on Tempo.
- Route precedence in the payer: a free upstream is served as a logged passthrough (
routed-free); a Gateway-capable upstream defaults torouted-x402; otherwise MPP wins (routed-mpp), falling back torouted-x402when only non-Gateway x402 is offered.--prefer-x402and--prefer-mppoverride the default; they are mutually exclusive. - Pass
preferProtocol: "x402"(SDK) or--prefer-x402(CLI) to opt out of the MPP default.