Skip to main content

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

EnvironmentChainNetwork IDStatus
ProductionBase Mainneteip155:8453✅ Live
TestnetBase Sepoliaeip155: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:
1

Get testnet USDC (for Sepolia testing)

You need testnet USDC on Base Sepolia for testing:
  1. Get testnet ETH from Alchemy Faucet
  2. Get testnet USDC from Circle Faucet
USDC Contract (Base Sepolia): 0x036CbD53842c5426634e7929541eC2318f3dCF7e
2

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..."] }
}
3

Get your API key (servers only)

If you’re protecting an API, get an API key from the Dashboard.

Supported Networks

NetworkChain IDCAIP-2 ID
Base Mainnet8453eip155:8453
Base Sepolia (testnet)84532eip155: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:
WalletStatusNotes
MetaMaskFully supportedBrowser extension + Mobile
Coinbase WalletFully supportedNative Base integration
RainbowFully supported
WalletConnect v2Fully supported400+ wallets
LedgerFully supportedVia MetaMask integration
Safe (Gnosis)PartialRequires multi-sig threshold
FrameFully 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:
  1. Connecting your wallet via SIWE
  2. Creating a new API key in the dashboard
  3. 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)

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

.env
# Facilitator URL
FACILITATOR_URL=https://facilitator.agentokratia.com

# Your API key (from dashboard)
X402_API_KEY=x402_...

# Your receiving wallet address
PAYMENT_ADDRESS=0xYourWalletAddress

x402 Headers

The protocol uses these HTTP headers (handled automatically by the SDK):
HeaderDirectionContent
PAYMENT-REQUIREDServer → ClientPayment requirements (base64 JSON)
PAYMENT-SIGNATUREClient → ServerPayment payload (base64 JSON)
PAYMENT-RESPONSEServer → ClientSettlement result (base64 JSON)

Next Steps