Documentation Index
Fetch the complete documentation index at: https://docs.x402x.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
x402x-server is the server-side SDK that integrates token detection, payment verification, and settlement to complete the full x402x flow end-to-end: “create payment requirements → parse/verify/settle → return resource.”
Key features
- Simple API: two-argument starting point, handles complexity automatically
- Automatic token detection: powered by
x402x-detector, with built-in cache
- Complete payment pipeline:
parse → verify → settle all-in-one
- Dynamic requirements creation: supports both fixed and dynamic pricing
- Performance: warm-up cache, fast mode, non-blocking initialization
- Framework middleware: Express / Hono out of the box
- Type-safety: 100% TypeScript + Zod runtime validation
Install and deps
npm i x402x-server x402x-facilitator viem
Optional (on demand):
# Express
npm i express
# Hono
npm i hono
Quick start
Minimal usage (manual handling)
import { X402Server } from "x402x-server";
import { Facilitator } from "x402x-facilitator";
import { createPublicClient, http } from "viem";
import { bscTestnet } from "viem/chains";
const client = createPublicClient({ chain: bscTestnet, transport: http() });
const f = new Facilitator({ recipientAddress: "0xSeller", waitUntil: "confirmed" });
const server = new X402Server({ client, facilitator: f });
// 1) Create payment requirements (auto or manually specify paymentType)
const reqs = await server.createRequirements({
asset: "0xToken",
maxAmountRequired: "1000000",
description: "Premium API",
});
// 2) Process the payment (parse → verify → settle)
const result = await server.process(req.headers["x-payment"] as string, reqs);
// 3) Return by result
if (!result.success) {
return res.status(result.status).json(result.response);
}
return res.json({ data: "ok", payer: result.data.payer, txHash: result.data.txHash });
Express middleware (recommended)
import express from "express";
import { createExpressMiddleware, X402Server } from "x402x-server";
import { Facilitator } from "x402x-facilitator";
import { createPublicClient, http } from "viem";
import { bscTestnet } from "viem/chains";
const app = express();
const client = createPublicClient({ chain: bscTestnet, transport: http() });
const facilitator = new Facilitator({ recipientAddress: "0xSeller", waitUntil: "confirmed" });
const server = new X402Server({ client, facilitator });
const payment = createExpressMiddleware({
server,
getToken: () => "0xUSDC",
getAmount: () => "1000000", // 1 USDC (6 decimals)
// Optional: getConfig / onError / on402 / onPaymentSuccess
});
app.post("/premium", payment, (req, res) => {
const { payer, txHash } = req.x402!;
res.json({ success: true, payer, txHash, data: "Premium content" });
});
app.listen(3000);
Hono middleware
import { Hono } from "hono";
import { createHonoMiddleware } from "x402x-server";
const app = new Hono();
const middleware = createHonoMiddleware({
server,
getToken: (c) => c.req.query("token") || "0xUSDC",
getAmount: async (c) => {
const body = await c.req.json<{ complexity: number }>();
return (body.complexity * 100000).toString();
},
});
app.post("/api", middleware, (c) => {
const x402 = c.get("x402") as { payer: string; txHash: string };
return c.json({ data: "resource", payer: x402.payer, txHash: x402.txHash });
});
Core capabilities
1) Automatic token detection
const requirements = await server.createRequirements({
asset: "0xUSDC",
maxAmountRequired: "1000000",
// Default autoDetect: true — detector selects paymentType automatically
});
// Possible choice: eip3009 / permit / permit2 (priority: eip3009 > permit > permit2)
2) All-in-one: parse → verify → settle
const result = await server.process(paymentHeader, requirements);
// Success: { success: true, status: 200, data: { payer, txHash } }
// Failure (client): { success: false, status: 402, errorStage: "parse" | "verify", response }
// Failure (server settlement): { success: false, status: 500, errorStage: "settle", response, error }
3) Config and utilities
const server = new X402Server({ client, facilitator, network: "bsc-testnet" });
await server.initialize(["0xUSDC"]); // warm-up (non-blocking)
server.getCacheStats(); // { size, keys }
await server.clearCache(); // clear cache
server.get402Response(requirements, "reason"); // build standard 402 response
Utilities
initialize(tokens): warm up detector cache (cache hits in <1ms)
get402Response(reqs, message?): build standard 402 response body
getCacheStats/clearCache: inspect/clear cache
API reference (condensed)
class X402Server {
constructor(config: { client: PublicClient; facilitator: Facilitator; network?: string });
initialize(tokens: string[]): Promise<{ success: boolean; detected?: number; total?: number; error?: string }>;
createRequirements(config: {
asset: string;
maxAmountRequired: string;
network?: string;
scheme?: "exact";
outputSchema?: Record<string, unknown>;
paymentType?: "permit" | "eip3009" | "permit2" | "auto";
resource?: string;
description?: string;
mimeType?: string;
maxTimeoutSeconds?: number;
extra?: Record<string, unknown>;
autoDetect?: boolean;
}): Promise<PaymentRequirements>;
process(paymentHeader: string | undefined, requirements: PaymentRequirements): Promise<
| { success: true; status: 200; data: { payer: string; txHash: string } }
| { success: false; status: 402; errorStage: "parse" | "verify"; response: Response402 }
| { success: false; status: 500; errorStage: "settle"; response: Response402; error: string }
>;
parse(paymentHeader: string | undefined, requirements: PaymentRequirements): ParseResult;
verify(parsed: ParsedPayment): Promise<VerifyResult>;
settle(parsed: ParsedPayment): Promise<SettleResult>;
get402Response(requirements: PaymentRequirements, error?: string): Response402;
clearCache(tokenAddress?: string): Promise<void>;
getCacheStats(): { size: number; keys: string[] };
}
- Warm up cache:
initialize([tokens]) at service startup
- Fast mode:
createRequirements({ paymentType: "permit", autoDetect: false }) (<1ms)
- Reuse requirements: reuse the same
requirements for fixed-price endpoints
- Background initialization: don’t block startup; log once ready
Performance reference:
| Operation | First call | Cached call |
|---|
createRequirements(autoDetect: true) | 2–5s | <1ms |
createRequirements(autoDetect: false) | <1ms | <1ms |
process() | 2–5s + network | <1ms + network |
Best practices
- Use env vars for
recipientAddress, RPC, etc.
- Distinguish error stages:
parse/verify → 402; settle → 500
- Record on-chain tx hash; build reconciliation and retry mechanisms
- Centralize logs and metrics for observability and tuning
Resources
- Source:
https://github.com/WTFLabs-WTF/x402x/tree/main/typescript/packages/x402x-server
- Issues:
https://github.com/WTFLabs-WTF/x402x/issues