SDK for the x402 HTTP Payment Protocol - monetize APIs with crypto payments.
x402 is a payment protocol built on HTTP status code 402 Payment Required. It enables:
- Pay-per-request APIs: Charge for individual API calls
- No accounts needed: Just sign and pay
- Instant settlement: Sub-second on Fast, ~15s on EVM
- Multi-chain: Fast, Arbitrum, Base, and more
| Package | Description | npm |
|---|---|---|
| x402-client | Client SDK - sign and pay for 402 content | npm i @fastxyz/x402-client |
| x402-server | Server SDK - protect routes, verify payments | npm i @fastxyz/x402-server |
| x402-facilitator | Facilitator - verify signatures, settle on-chain | npm i @fastxyz/x402-facilitator |
The facilitator verifies payment signatures and settles EVM payments on-chain.
import express from 'express';
import { createFacilitatorServer } from '@fastxyz/x402-facilitator';
const app = express();
app.use(express.json());
app.use(createFacilitatorServer({
// Private key for settling EVM payments (pays gas)
evmPrivateKey: process.env.FACILITATOR_KEY as `0x${string}`,
}));
app.listen(4020, () => console.log('Facilitator on :4020'));import express from 'express';
import { paymentMiddleware } from '@fastxyz/x402-server';
const app = express();
app.use(paymentMiddleware(
'0x1234...', // Your payment address
{
'GET /api/premium/*': { price: '$0.10', network: 'arbitrum-sepolia' },
},
{ url: 'http://localhost:4020' } // Facilitator URL
));
app.get('/api/premium/data', (req, res) => {
res.json({ data: 'Premium content!' });
});
app.listen(3000);import { x402Pay } from '@fastxyz/x402-client';
const result = await x402Pay({
url: 'https://api.example.com/api/premium/data',
wallet: {
type: 'evm',
privateKey: '0x...',
address: '0x...',
},
});
console.log(result.body); // Your paid contentProvide both wallets to automatically bridge fastUSDC → USDC when paying for EVM endpoints:
import { x402Pay } from '@fastxyz/x402-client';
const result = await x402Pay({
url: 'https://api.example.com/api/premium/data', // EVM endpoint
wallet: [
{
type: 'fast',
privateKey: '...', // 32-byte Ed25519 key (hex)
publicKey: '...', // 32-byte pubkey (hex)
address: 'fast1...', // bech32m address
},
{
type: 'evm',
privateKey: '0x...',
address: '0x...',
},
],
verbose: true, // See bridge progress logs
});
// Flow:
// 1. Detects EVM endpoint requires USDC
// 2. Checks EVM USDC balance (insufficient)
// 3. Bridges fastUSDC → USDC via AllSet (~3-4s)
// 4. Signs EIP-3009 authorization
// 5. Sends payment → 200 OK┌─────────┐ ┌─────────┐ ┌─────────────┐
│ Client │ │ Server │ │ Facilitator │
└────┬────┘ └────┬────┘ └──────┬──────┘
│ │ │
│ GET /api/data │ │
│─────────────────────────────>│ │
│ │ │
│ 402 Payment Required │ │
│ { accepts: [...] } │ │
│<─────────────────────────────│ │
│ │ │
│ Sign payment │ │
│ (EIP-3009 or Fast tx) │ │
│ │ │
│ GET /api/data │ │
│ X-PAYMENT: <signed> │ │
│─────────────────────────────>│ │
│ │ │
│ │ POST /verify │
│ │─────────────────────────────────>
│ │ │
│ │ { isValid: true } │
│ │<─────────────────────────────────
│ │ │
│ 200 OK (Fast) │ │
│<─────────────────────────────│ │
│ │ │
│ │ POST /settle (EVM only) │
│ │─────────────────────────────────>
│ │ │
│ 200 OK (EVM) │ { txHash: 0x... } │
│<─────────────────────────────│<─────────────────────────────────
Uses EIP-3009 transferWithAuthorization - client signs, facilitator settles.
Client Server Facilitator
│ │ │
│ Sign EIP-3009 authorization │ │
│ (EIP-712 typed data) │ │
│ │ │
│ X-PAYMENT: { signature, │ │
│ authorization: {from,to, │ │
│ value,validAfter, │ │
│ validBefore,nonce} } │ │
│──────────────────────────────>│ │
│ │ /verify │
│ │ - Recover signer from sig │
│ │ - Check recipient matches │
│ │ - Check amount sufficient │
│ │ - Check timing valid │
│ │ - Check on-chain balance │
│ │────────────────────────────────>
│ │ { isValid: true } │
│ │<────────────────────────────────
│ │ │
│ │ /settle │
│ │ - Re-verify payment │
│ │ - Check nonce not used │
│ │ - Call transferWithAuth() │
│ │ - Wait for confirmation │
│ │────────────────────────────────>
│ │ { txHash: 0x... } │
│ │<────────────────────────────────
│ 200 OK + content │ │
│<──────────────────────────────│ │
Client submits transaction directly, sends certificate as proof.
Client Server Facilitator
│ │ │
│ Submit TokenTransfer to │ │
│ Fast network │ │
│ (transaction already on-chain)│ │
│ │ │
│ X-PAYMENT: { │ │
│ transactionCertificate: { │ │
│ envelope: "0x...", │ │
│ signatures: [...] │ │
│ } │ │
│ } │ │
│──────────────────────────────>│ │
│ │ /verify │
│ │ - Check certificate structure │
│ │ - (TODO: on-chain verify) │
│ │────────────────────────────────>
│ │ { isValid: true } │
│ │<────────────────────────────────
│ │ │
│ 200 OK + content │ (no /settle needed - │
│<──────────────────────────────│ already on-chain) │
The facilitator exposes three endpoints:
| Endpoint | Method | Description |
|---|---|---|
/verify |
POST | Verify payment signature/certificate |
/settle |
POST | Settle payment on-chain (EVM only) |
/supported |
GET | List supported networks |
EVM payments:
- Recover signer from EIP-712 signature (
verifyTypedData) - Check recipient matches
paymentRequirement.payTo - Check amount ≥
paymentRequirement.maxAmountRequired - Check
validAfter ≤ now < validBefore - Query on-chain USDC balance
Fast payments:
- Check certificate structure (envelope + signatures)
- Validate scheme and network match
- (TODO: Query Fast RPC for on-chain verification)
EVM: Re-verify → Check nonce unused → Call transferWithAuthorization() → Wait for confirmation
Fast: No-op (transaction already on-chain when certificate was created)
Accept payments on both EVM and Fast:
app.use(paymentMiddleware(
{
evm: '0x1234...', // EVM payment address
fast: 'fast1abc...', // Fast payment address
},
{
'GET /api/evm/*': { price: '$0.10', network: 'arbitrum-sepolia' },
'GET /api/fast/*': { price: '$0.01', network: 'fast-testnet' },
},
{ url: 'http://localhost:4020' }
));| Network | Type | Chain ID | Token | Settlement |
|---|---|---|---|---|
fast-testnet |
Fast | - | fastUSDC | ~300ms |
fast-mainnet |
Fast | - | fastUSDC | ~300ms |
arbitrum-sepolia |
EVM | 421614 | USDC | ~15s |
arbitrum |
EVM | 42161 | USDC | ~15s |
base-sepolia |
EVM | 84532 | USDC | ~15s |
base |
EVM | 8453 | USDC | ~15s |
ethereum |
EVM | 1 | USDC | ~15s |
# Install dependencies
npm install
# Build all packages
npm run build --workspaces
# Run tests
npm test --workspacesSee SKILL.md for detailed API documentation, troubleshooting, and integration examples.
See RELEASING.md for the npm release workflow.
MIT