Documentation Index
Fetch the complete documentation index at: https://docs.swiftpay.finance/llms.txt
Use this file to discover all available pages before exploring further.
The @swiftpayfi/x402-node-guard middleware adds HTTP 402 payment requirements to your Express or Fastify routes. Protect specific endpoints with per-request stablecoin payments.
Features
- Two-round payment flow — Return 402 + requirements, then serve on second request with payment
- Express & Fastify support — Works with both frameworks
- Server-agnostic signing — SwiftPay handles EIP-712 signature verification
- No key management — Your server never touches private keys
- Type-safe — Full TypeScript support
Installation
npm install @swiftpayfi/x402-node-guard @swiftpayfi/api-client
Quick Start
Express
import { SwiftPay } from '@swiftpayfi/api-client';
import { x402Express } from '@swiftpayfi/x402-node-guard/express';
const app = express();
const client = new SwiftPay({ secretKey: process.env.SWIFTPAY_SECRET_KEY });
const x402 = x402Express({ client });
app.get(
'/v1/analyze',
x402('https://api.example.com/v1/analyze'),
(req, res) => {
res.json({ sentiment: 'positive', score: 0.87 });
}
);
Fastify
import { SwiftPay } from '@swiftpayfi/api-client';
import { x402Fastify } from '@swiftpayfi/x402-node-guard/fastify';
const fastify = Fastify();
const client = new SwiftPay({ secretKey: process.env.SWIFTPAY_SECRET_KEY });
const x402 = x402Fastify({ client });
fastify.get(
'/v1/analyze',
{ preHandler: x402('https://api.example.com/v1/analyze') },
async () => ({ sentiment: 'positive', score: 0.87 })
);
How It Works
The x402 payment flow is a two-round process:
Client makes a request without the X-PAYMENT header:
Server responds with HTTP 402 and payment requirements:
HTTP/1.1 402 Payment Required
{
"x402-version": "v1",
"x402-nonce": "...",
"x402-payment-requirements": {
"asset": "USDC",
"network": "ethereum",
"amount": "0.05",
...
}
}
Round 2: With Payment Proof
Client signs the payment requirements and resends the request with the signed proof:
GET /v1/analyze
X-PAYMENT: <signed-eip712-payload>
Server validates the signature via SwiftPay’s API and serves the resource:
HTTP/1.1 200 OK
{
"sentiment": "positive",
"score": 0.87
}
Configuration
x402Express({
client: SwiftPayClient, // Required: SwiftPay API client
// Optional:
baseUrl?: 'https://api.swiftpay.finance', // API base URL
timeout?: 30_000, // Request timeout in ms
});
Usage Patterns
Protect Single Route
app.get(
'/api/premium-feature',
x402('https://api.example.com/api/premium-feature'),
(req, res) => {
res.json({ data: 'exclusive content' });
}
);
Protect Multiple Routes
const x402Guard = x402Express({ client });
app.get('/v1/analyze', x402Guard(...), handler1);
app.post('/v1/translate', x402Guard(...), handler2);
app.get('/v1/search', x402Guard(...), handler3);
Conditional Protection
app.get('/v1/feature', (req, res, next) => {
// Require payment only for non-authenticated users
if (req.headers.authorization) {
return next(); // Skip x402
}
// Protect the route
x402Guard('https://api.example.com/v1/feature')(req, res, next);
});
Error Handling
app.get(
'/v1/analyze',
x402('https://api.example.com/v1/analyze'),
(req, res) => {
try {
const result = performAnalysis(req.body);
res.json(result);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
);
// Global error handler
app.use((err, req, res, next) => {
if (err instanceof SwiftPayError) {
return res.status(402).json({
error: 'Payment required',
details: err.message,
});
}
next(err);
});
Client Implementation
Your frontend clients need to handle the 402 response and submit payment:
async function makePaymentRequest(url, options) {
// First request
let response = await fetch(url, options);
if (response.status === 402) {
// Extract payment requirements
const requirements = JSON.parse(response.headers.get('x402-payment-requirements'));
// User signs payment proof (using MetaMask, etc)
const signature = await window.ethereum.request({
method: 'eth_signTypedData_v4',
params: [userAddress, JSON.stringify(requirements)],
});
// Second request with payment proof
response = await fetch(url, {
...options,
headers: {
...options.headers,
'X-PAYMENT': signature,
},
});
}
return response;
}
Full API Reference
For complete type definitions, advanced error handling, and additional patterns, see the official x402 Node Guard on NPM.
All APIs are in v0.1.0-beta — stable and production-ready.