Quickstart
This guide will help you integrate x402 payments into your application.
Step 1: Choose Your Scheme
Not sure? Use escrow if you’re building AI agents or making frequent API calls. Use exact for simple one-off payments.
Environment Setup
Currently Base Sepolia only. The facilitator is live on Base Sepolia (testnet). Base Mainnet support coming soon.
Environment Chain Network ID Status Testnet Base Sepolia eip155:84532✅ Live Production Base Mainnet eip155:8453🔜 Soon
Facilitator URL: https://facilitator.agentokratia.com
Installation
npm install @x402/core @agentokratia/x402-escrow
Test Your Setup (2 minutes)
Before integrating, verify everything works:
Get testnet USDC
You need testnet USDC on Base Sepolia for deposits:
Get testnet ETH from Alchemy Faucet
Get testnet USDC from Circle Faucet
USDC Contract (Base Sepolia): 0x036CbD53842c5426634e7929541eC2318f3dCF7e
Verify facilitator is accessible
curl https://facilitator.agentokratia.com/api/supported
Expected response (truncated): {
"kinds" : [{ "scheme" : "exact" , ... }, { "scheme" : "escrow" , ... }],
"extensions" : [ "agentokratia" ],
"signers" : { "eip155:8453" : [ "0x..." ] }
}
Get your API key (servers only)
If you’re protecting an API, get an API key from the Dashboard .
Deposit amounts: The default is 10000000 atomic units = 10 U S D C . F o r t e s t i n g , t r y ‘ 1000000 ‘ ( 10 USDC. For testing, try `1000000` ( 10 U S D C . F or t es t in g , t ry ‘1000000‘ ( 1) to conserve testnet funds.
Supported Networks
Network Chain ID CAIP-2 ID Base Mainnet 8453 eip155:8453Base Sepolia (testnet) 84532 eip155:84532
Use Base Sepolia for development. Testnet USDC is free from the faucets above.
Supported Wallets
Any wallet supporting EIP-712 typed data signing works with x402:
Wallet Status Notes MetaMask Fully supported Browser extension + Mobile Coinbase Wallet Fully supported Native Base integration Rainbow Fully supported WalletConnect v2 Fully supported 400+ wallets Ledger Fully supported Via MetaMask integration Safe (Gnosis) Partial Requires multi-sig threshold Frame Fully supported
All wallets must support EIP-712 typed data signing , which is standard for modern wallets. No special wallet features required.
Prerequisites
Before starting, you’ll need:
Get an API key from the Dashboard by:
Connecting your wallet via SIWE
Creating a new API key in the dashboard
Storing it securely (shown only once)
Note: Clients don’t need an API key - only servers protecting endpoints.
A viem WalletClient with an account and chain. Example setup: // Browser (with wagmi)
import { useWalletClient } from 'wagmi' ;
const { data : walletClient } = useWalletClient ();
// Node.js (with private key)
import { createWalletClient , http } from 'viem' ;
import { base } from 'viem/chains' ;
import { privateKeyToAccount } from 'viem/accounts' ;
const walletClient = createWalletClient ({
account: privateKeyToAccount ( process . env . PRIVATE_KEY ),
chain: base ,
transport: http (),
});
USDC on Base for payments. No approval needed - x402 uses ERC-3009 gasless signatures.
Exact Scheme Quickstart
The exact scheme is standard x402 - one signature per request.
Client (exact)
import { useWalletClient } from 'wagmi' ;
import { wrapFetchWithPayment } from '@x402/fetch' ;
import { x402Client } from '@x402/core/client' ;
const { data : walletClient } = useWalletClient ();
if ( walletClient ) {
const x402 = new x402Client ( walletClient );
const paidFetch = wrapFetchWithPayment ( fetch , x402 );
// User signs each request
const response = await paidFetch ( 'https://api.example.com/premium' );
}
The exact scheme requires user signature per request - best for browser dApps where users approve each payment.
Server (exact)
import { x402ResourceServer , HTTPFacilitatorClient } from '@x402/core/server' ;
import { paymentMiddleware } from '@x402/express' ;
const facilitator = new HTTPFacilitatorClient ({
url: process . env . FACILITATOR_URL ! ,
createAuthHeaders : async () => ({
verify: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
settle: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
supported: {},
}),
});
const x402 = new x402ResourceServer ( facilitator );
app . use ( paymentMiddleware ({
'GET /api/premium' : {
accepts: {
scheme: 'exact' ,
price: '$0.10' ,
network: 'eip155:8453' ,
payTo: process . env . PAYMENT_ADDRESS ! ,
},
},
}, x402 ));
app . get ( '/api/premium' , ( req , res ) => {
res . json ({ data: 'Premium content' });
});
Escrow Scheme Quickstart
The escrow scheme enables session-based payments - sign once, unlimited calls.
Client (escrow)
import { useWalletClient } from 'wagmi' ;
import { createEscrowFetch } from '@agentokratia/x402-escrow/client' ;
const { data : walletClient } = useWalletClient ();
if ( walletClient ) {
const { fetch : escrowFetch } = createEscrowFetch ( walletClient , {
depositAmount: '10000000' , // $10 USDC deposit
storage: 'localStorage' , // Persist sessions across reloads
});
// First call: signs once, creates session
const response1 = await escrowFetch ( 'https://api.example.com/premium' );
// Subsequent calls: instant, no signature needed
const response2 = await escrowFetch ( 'https://api.example.com/premium' );
}
Sign once, pay forever: Users sign a single ERC-3009 authorization, then make unlimited API calls with zero additional signatures or gas.
What Happens Automatically
First request - Signs ERC-3009, creates session, stores session.token
Subsequent requests - Uses stored token (instant, no signature)
Session expired - Automatically creates new session
Insufficient balance - Creates new session with fresh deposit
Session Control
// Force new session (e.g., when user wants fresh deposit)
await escrowFetch ( url , { session: 'new' });
// Use specific session
await escrowFetch ( url , { session: 'session-id-here' });
Server (escrow)
import { x402ResourceServer , HTTPFacilitatorClient } from '@x402/core/server' ;
import { paymentMiddleware } from '@x402/express' ;
import { EscrowScheme } from '@agentokratia/x402-escrow/server' ;
const facilitator = new HTTPFacilitatorClient ({
url: process . env . FACILITATOR_URL ! ,
createAuthHeaders : async () => ({
verify: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
settle: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
supported: {},
}),
});
// Register escrow scheme
const x402 = new x402ResourceServer ( facilitator )
. register ( 'eip155:8453' , new EscrowScheme ());
app . use ( paymentMiddleware ({
'GET /api/premium' : {
accepts: {
scheme: 'escrow' ,
price: '$0.01' ,
network: 'eip155:8453' ,
payTo: process . env . PAYMENT_ADDRESS ! ,
},
},
}, x402 ));
app . get ( '/api/premium' , ( req , res ) => {
res . json ({ data: 'Premium content' });
});
Accept Both Schemes
Servers can accept both schemes, letting clients choose:
const x402 = new x402ResourceServer ( facilitator )
. register ( 'eip155:8453' , new EscrowScheme ());
app . use ( paymentMiddleware ({
'GET /api/premium' : {
accepts: [
{ scheme: 'escrow' , price: '$0.01' , network: 'eip155:8453' , payTo: '0x...' },
{ scheme: 'exact' , price: '$0.01' , network: 'eip155:8453' , payTo: '0x...' },
],
},
}, x402 ));
Environment Variables
# Facilitator URL
FACILITATOR_URL = https://facilitator.agentokratia.com
# Your API key (from dashboard)
X402_API_KEY = x402_...
# Your receiving wallet address
PAYMENT_ADDRESS = 0xYourWalletAddress
The protocol uses these HTTP headers (handled automatically by the SDK):
Header Direction Content PAYMENT-REQUIREDServer → Client Payment requirements (base64 JSON) PAYMENT-SIGNATUREClient → Server Payment payload (base64 JSON) PAYMENT-RESPONSEServer → Client Settlement result (base64 JSON)
Next Steps