Quickstart
This guide will help you integrate x402 payments into your application.
Step 1: Choose Your Scheme
Not sure? Use escrow if you want to accept multiple tokens or need swap support. Use exact for simple USDC-only payments.
Environment Setup
Environment Chain Network ID Status Production Base Mainnet eip155:8453✅ Live Testnet Base Sepolia eip155:84532✅ Live
Facilitator URL: https://facilitator.agentokratia.com
Installation
npm install @x402/core @x402/next @x402/fetch @x402/evm @agentokratia/x402-escrow viem
Test Your Setup (2 minutes)
Before integrating, verify everything works:
Get testnet USDC (for Sepolia testing)
You need testnet USDC on Base Sepolia for testing:
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 .
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, WETH, DAI, or USDT on Base for payments. For non-USDC tokens, the escrow scheme automatically swaps to USDC for the receiver.
Exact Scheme Quickstart
The exact scheme is standard x402 - one signature per request, USDC only.
Client (exact)
import { wrapFetchWithPayment , x402Client } from '@x402/fetch' ;
import { ExactEvmScheme } from '@x402/evm/exact/client' ;
import { privateKeyToAccount } from 'viem/accounts' ;
const account = privateKeyToAccount ( process . env . PRIVATE_KEY );
const client = new x402Client ()
. register ( 'eip155:8453' , new ExactEvmScheme ( account ));
const paidFetch = wrapFetchWithPayment ( fetch , client );
// 402 responses are handled automatically
const response = await paidFetch ( 'https://api.example.com/premium' );
const data = await response . json ();
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 { ExactEvmScheme } from '@x402/evm/exact/server' ;
import { paymentProxy } from '@x402/next' ;
const facilitator = new HTTPFacilitatorClient ({
url: 'https://facilitator.agentokratia.com' ,
createAuthHeaders : async () => ({
verify: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
settle: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
}),
});
const server = new x402ResourceServer ( facilitator )
. register ( 'eip155:8453' , new ExactEvmScheme ());
export const middleware = paymentProxy ({
'/api/premium' : {
accepts: {
scheme: 'exact' ,
network: 'eip155:8453' ,
price: '$0.01' ,
payTo: '0xYourWallet...' ,
},
},
}, server );
Escrow Scheme Quickstart
The escrow scheme enables multi-token payments - payers use any supported token, you receive USDC.
Client (escrow)
Node.js (Balance-Aware)
Browser (wagmi)
import { wrapFetchWithPayment , x402Client } from '@x402/fetch' ;
import { ExactEvmScheme } from '@x402/evm/exact/client' ;
import { createWalletClient , createPublicClient , http } from 'viem' ;
import { privateKeyToAccount } from 'viem/accounts' ;
import { base } from 'viem/chains' ;
import {
EscrowScheme ,
createBalanceSelector ,
preferTokenPolicy ,
} from '@agentokratia/x402-escrow/client' ;
const WETH = '0x4200000000000000000000000000000000000006' ;
const USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ;
const account = privateKeyToAccount ( process . env . PRIVATE_KEY );
const walletClient = createWalletClient ({
account , chain: base , transport: http (),
});
const publicClient = createPublicClient ({
chain: base , transport: http (),
});
// Balance-aware: auto-picks USDC (gasless) or WETH/DAI (swap)
const client = new x402Client (
createBalanceSelector ( publicClient , account . address )
)
. register ( 'eip155:8453' , new ExactEvmScheme ( account ))
. register ( 'eip155:8453' , new EscrowScheme ( walletClient ))
. registerPolicy ( preferTokenPolicy ([ WETH , USDC ]));
const paidFetch = wrapFetchWithPayment ( fetch , client );
const response = await paidFetch ( 'https://api.example.com/premium' );
const data = await response . json ();
Balance-aware selection: The createBalanceSelector checks on-chain balances and picks the first token the wallet can afford. Combined with preferTokenPolicy, you control the priority order.
Server (escrow)
import { x402ResourceServer , HTTPFacilitatorClient } from '@x402/core/server' ;
import { ExactEvmScheme } from '@x402/evm/exact/server' ;
import { EscrowScheme } from '@agentokratia/x402-escrow/server' ;
import { paymentProxy } from '@x402/next' ;
const facilitator = new HTTPFacilitatorClient ({
url: 'https://facilitator.agentokratia.com' ,
createAuthHeaders : async () => ({
verify: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
settle: { Authorization: `Bearer ${ process . env . X402_API_KEY } ` },
}),
});
const escrow = new EscrowScheme ({ facilitator });
const USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' ;
const server = new x402ResourceServer ( facilitator )
. register ( 'eip155:8453' , new ExactEvmScheme ())
. register ( 'eip155:8453' , escrow );
// Auto-discovers supported tokens (USDC, WETH, DAI...)
const escrowAccepts = await escrow . buildAccepts ({
network: 'eip155:8453' ,
price: '$0.01' ,
payTo: '0xYourWallet...' ,
asset: USDC , // settlement token
});
export const middleware = paymentProxy ({
'/api/premium' : {
accepts: [
{ scheme: 'exact' , network: 'eip155:8453' ,
price: '$0.01' , payTo: '0xYourWallet...' },
... escrowAccepts ,
],
},
}, server );
Accept Both Schemes
Servers can accept both schemes, letting clients choose:
const escrow = new EscrowScheme ({ facilitator });
const escrowAccepts = await escrow . buildAccepts ({
network: 'eip155:8453' ,
price: '$0.01' ,
payTo: '0xYourWallet...' ,
});
const server = new x402ResourceServer ( facilitator )
. register ( 'eip155:8453' , new ExactEvmScheme ())
. register ( 'eip155:8453' , escrow );
export const middleware = paymentProxy ({
'/api/premium' : {
accepts: [
{ scheme: 'exact' , network: 'eip155:8453' , price: '$0.01' , payTo: '0x...' },
... escrowAccepts , // Adds USDC, WETH, DAI, USDT options
],
},
}, server );
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