EIP-3009 gasless USDC, explained

When an agent pays an x402 invoice, it does not send a transaction. It signs a message. That message — an EIP-3009 transfer authorization — is what makes agentic payments practical: the payer proves intent with a signature, and someone else broadcasts it and pays the gas. The agent needs USDC and a key, and nothing else. No ETH, no nonce management, no mempool.

The gas-token problem

On any EVM chain, moving a token normally costs the sender gas in the chain's native coin. For an autonomous agent that is a nuisance squared: it would have to hold two assets (USDC to spend and ETH for gas), top up the gas balance, and track nonces across concurrent calls. EIP-3009 removes that entirely by separating who authorizes a transfer from who submits it.

transferWithAuthorization

USDC implements the EIP-3009 standard, which adds a function roughly shaped like this:

USDC · EIP-3009
transferWithAuthorization(
  from, to, value,
  validAfter, validBefore, // time window
  nonce,                    // random, single-use
  signature                 // EIP-712 over the above
)

The payer signs an EIP-712 typed-data message binding the recipient, the exact amount, a validity window, and a random nonce. Anyone holding that signature can call transferWithAuthorization on the USDC contract; the contract verifies the signature on-chain and moves the funds. The submitter pays the gas, never the payer.

How x402 uses it

This maps cleanly onto the 402 handshake. The server's accepts entry tells the client the payTo address, the amount, and the network. The client signs an EIP-3009 authorization for exactly that, base64-encodes it into the X-PAYMENT header, and retries:

flow
1. server →  402 { accepts:[{ payTo, amount:"1200000", network:"eip155:8453" }] }
2. agent  →  sign EIP-712 authorization (no broadcast)
3. agent  →  retry with X-PAYMENT: <authorization>
4. facilitator → submits transferWithAuthorization, pays gas
5. server →  201 once settlement confirms

At AgentMetal the facilitator is self-hosted: a relayer wallet we run submits the authorization and fronts the Base gas, then the USDC lands in the treasury. There is no Coinbase or third-party dependency in the settlement path, and we never see or hold your key — only your signature, which is useless for anything but the transfer you authorized.

Why this is safe for the payer

The signature is tightly scoped. It authorizes one transfer, to one address, for one amount, valid only inside a short window, and the random nonce makes it single-use — a replay just reverts. The agent commits to spending precisely the quoted price and nothing more. And because it all settles on Base as real USDC, the payment is a public transaction hash you can verify on a block explorer afterward.

You don't implement this by hand

Libraries like @x402/evm and @x402/fetch build and sign the EIP-3009 payload for you, and @agentmetal/mcp wraps it so a model just calls a tool. The cryptography here is the plumbing; the point is that an agent can settle a real payment with a single signature and zero gas management. See giving your agent a server for the practical setup, or the docs for the full reference.

All posts ↗