Gas-sponsored USDC transfers on Ethereum mainnet via ERC-20 permit signatures
mainnet-x402-facilitator is an early-stage TypeScript project in the AI payments / x402 ecosystem, focused on agentic-workflow, agents, erc8004, ethereum. It currently has 4 GitHub stars and 1 forks, and sits alongside related tools like pinion-os, x402-sandbox, x402-fl.
First x402 facilitator on Ethereum mainnet to use preconfirmations for sub-second USDC settlement.
AI agents need to pay for APIs, compute, and data in real-time. Traditional Ethereum payments are too slow (12+ seconds for finality). Existing x402 facilitators only work on Base and Solana, leaving agents unable to access Ethereum's $100B+ in stablecoins and DeFi liquidity.
| Feature | Value |
|---|---|
| Sub-second settlement | ~1.2s end-to-end via FastRPC preconfirmations (vs 12+ seconds) |
| Zero gas for agents | Agents only need USDC — no ETH required, gas fully sponsored |
| Mainnet liquidity | Access Ethereum's largest stablecoin issuance |
| x402 compatible | Drop-in replacement for Base/Solana facilitators |
| EIP-3009 | Gasless transferWithAuthorization signatures |
https://facilitator.primev.xyz
| Endpoint | Description |
|---|---|
POST /settle |
Verify + settle payment via FastRPC preconfirmation |
POST /verify |
Validate signature, balance, nonce (dry run) |
GET /supported |
Return supported schemes and networks |

Agent Resource Server Facilitator FastRPC
│ │ │ │
│── GET /resource ───────────>│ │ │
│<── 402 + PaymentRequired ───│ │ │
│ │ │ │
│ (signs transferWithAuthorization - no gas, no ETH) │ │
│ │ │ │
│── GET /resource ───────────>│ │ │
│ + PAYMENT-SIGNATURE │── POST /settle ──────────>│── preconfirm ───────>│
│ │<── { success, txHash } ───│<── ~100-200ms ───────│
│<── 200 + response ──────────│ │ │
transferWithAuthorization (just a signature, no tx, no gas)/settleConfirmed mainnet transactions:
import { withX402 } from "@x402/axios";
const client = withX402(axios, { walletClient });
const response = await client.get("https://api.example.com/paid-endpoint");
// Payment signed and settled automatically on 402 response
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { mainnet } from 'viem/chains'
import { randomBytes } from 'crypto'
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
const FACILITATOR = 'https://facilitator.primev.xyz'
// Sign EIP-3009 authorization
const signature = await walletClient.signTypedData({
domain: { name: 'USD Coin', version: '2', chainId: 1, verifyingContract: USDC },
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' },
],
},
primaryType: 'TransferWithAuthorization',
message: {
from: account.address,
to: merchantAddress,
value: BigInt(amount),
validAfter: 0n,
validBefore: BigInt(Math.floor(Date.now() / 1000) + 900),
nonce: `0x${randomBytes(32).toString('hex')}`,
},
})
// Settle payment
const result = await fetch(`${FACILITATOR}/settle`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ paymentPayload, paymentRequirements }),
}).then(r => r.json())
// { success: true, transaction: "0x...", network: "eip155:1" }
import { paymentMiddleware } from "@x402/express";
app.use(paymentMiddleware({
"GET /api/data": {
accepts: [{
scheme: "exact",
network: "eip155:1",
amount: "1000000", // 1 USDC
asset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
payTo: "0xYourAddress",
maxTimeoutSeconds: 60,
}],
},
}, { facilitatorUrl: "https://facilitator.primev.xyz" }));
| Code | Description |
|---|---|
invalid_signature |
EIP-712 signature verification failed |
insufficient_funds |
Payer doesn't have enough USDC |
nonce_already_used |
Replay protection triggered |
authorization_expired |
Current time is after validBefore |
recipient_mismatch |
to doesn't match payTo |
insufficient_payment |
value is less than required amount |
# Run tests
cd contracts && forge test -vvv
# Local dev
cd api && vercel dev
# Deploy
cd api && vercel --prod
| Variable | Description |
|---|---|
RELAY_PRIVATE_KEY |
Hot wallet for settlement txs |
RPC_URL |
Ethereum mainnet RPC |
api/
├── index.ts # Hono routes
├── settle.ts # FastRPC submission
├── verify.ts # EIP-712 signature verification
├── config.ts # USDC address, FastRPC URL
├── types.ts # x402 protocol types
└── abi.ts # USDC ABI
| Registry | Status | Link |
|---|---|---|
| ERC-8004 Identity | Registered — Agent #23175 | Etherscan NFT |
| x402 Ecosystem (coinbase/x402) | PR open | PR #1114 |
| x402scan Explorer (Merit-Systems) | PR open | PR #624 |
| awesome-x402 (xpaysh) | PR open | PR #11 |
| awesome-x402 (Merit-Systems) | PR open | PR #29 |
| awesome-erc8004 | PR open | PR #3 |
| x402.watch Directory | Pending — Ethereum mainnet not yet supported | x402.watch |
| x402 Bazaar | Live | /supported + /discovery/resources |
Note: x402.watch currently only lists facilitators on Base, Polygon, and Solana. Ethereum mainnet support has been requested — once added, this facilitator will be listed as "Primev – Ethereum Mainnet with Preconfs" at
https://facilitator.primev.xyz.
Client SDK, Claude plugin and skill framework for the Pinion protocol. x402 micropayments on Base.
One-command local development environment for HTTP 402 Payment Required protocol with blockchain payments (EIP-3009 USDC)
Local x402 payment facilitator for development and testing. Fork Base mainnet with Anvil, verify and settle x402 payments locally.