x402-payments — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited x402-payments (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Build paid APIs and agent payment infrastructure using the x402 protocol. Deploy on Base (EVM), Solana, and/or Stellar with USDC. Optionally add Sentinel Payment Router for multi-endpoint orchestration, budget caps, and cryptographic audit trails.
x402 is an open payment protocol (by Coinbase) built on the HTTP 402 status code. Any API can charge per-request in USDC — no API keys, no subscriptions, no accounts. Clients (humans or AI agents) pay at the moment of use, and the server verifies payment before granting access.
Client → GET /api/data → Server
Client ← 402 Payment Required (pricing in headers) ← Server
Client → GET /api/data + X-PAYMENT header (signed authorization) → Server
Server → verifies via Facilitator → settles USDC on-chain
Client ← 200 OK (data) ← ServerWhen a user asks for x402 help, determine three things:
→ Read references/base-evm.md
→ Read references/solana.md
→ Read references/stellar.md
→ Read the relevant reference files
→ Add Sentinel Payment Router. Read references/sentinel-router.md
Read references/packages.md for the complete package matrix covering V1 (simple) and V2 (modular) packages, with install commands and compatibility notes.
This is the fastest path — monetize a Next.js API route on Base mainnet:
npm install x402-next// middleware.ts
import { paymentMiddleware } from "x402-next";
export const middleware = paymentMiddleware(
"0xYourWalletAddress",
{
"/api/premium": {
price: "$0.01",
network: "base",
config: { description: "Premium API access" },
},
},
{ url: "https://x402.org/facilitator" }
);
export const config = {
matcher: ["/api/premium/:path*"],
};// app/api/premium/route.ts
import { NextResponse } from "next/server";
export async function GET() {
return NextResponse.json({
data: "This endpoint costs $0.01 per call",
timestamp: Date.now(),
});
}Deploy to Vercel. Any request without payment gets a 402 with pricing. Clients with valid X-PAYMENT headers get data.
Stellar-only, fee-free for clients (facilitator covers fees). Use the OZ Channels facilitator:
npm install @x402/express @x402/core expressimport express from "express";
import { paymentMiddleware } from "@x402/express";
const app = express();
app.use(
paymentMiddleware(
{
"GET /weather": {
accepts: [
{
scheme: "exact",
price: "$0.001",
network: "stellar:testnet",
payTo: process.env.STELLAR_PAY_TO_ADDRESS!,
},
],
description: "Weather report",
},
},
{
url: "https://channels.openzeppelin.com/x402/testnet",
headers: process.env.OZ_RELAYER_API_KEY
? { "x-api-key": process.env.OZ_RELAYER_API_KEY }
: undefined,
}
)
);
app.get("/weather", (_req, res) => {
res.json({ city: "London", temperature: 22, conditions: "Partly cloudy", timestamp: Date.now() });
});
app.listen(3000);Set STELLAR_PAY_TO_ADDRESS (your G... address) and optionally OZ_RELAYER_API_KEY. Clients sign auth entries (e.g. with Freighter); no XLM needed.
npm install x402-fetch viemimport { wrapFetchWithPayment } from "x402-fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain: base, transport: http() });
const paidFetch = wrapFetchWithPayment(wallet);
const response = await paidFetch("https://example.com/api/premium");
const data = await response.json();npm install @x402sentinel/routerimport { PaymentRouter } from "@x402sentinel/router";
const router = new PaymentRouter({
paymentFetch: paidFetch,
getPaymentInfo: () => null,
agentId: "my-agent",
apiKey: "sk_...",
});
const result = await router.execute({
name: "research-pipeline",
maxBudgetUsd: "0.05",
strategy: "parallel",
endpoints: [
{ label: "email-verify", url: "https://api.example.com/[email protected]" },
{ label: "dns-lookup", url: "https://api.example.com/dns?domain=google.com" },
{ label: "ssl-check", url: "https://api.example.com/ssl?domain=google.com" },
],
});
// result.receipt — unified SHA-256 receipt linking all payments
// result.receipt.receiptHash — tamper-proof hash
// result.receipt.sentinelSig — HMAC server signatureRead references/sentinel-router.md for the full Router API.
| Testnet | Mainnet | |
|---|---|---|
| Base | base-sepolia / eip155:84532 | base / eip155:8453 |
| Solana | solana-devnet | solana-mainnet |
| Stellar | stellar:testnet | stellar:pubnet |
| Facilitator | https://x402.org/facilitator | https://x402.org/facilitator |
| Stellar Facilitator | https://channels.openzeppelin.com/x402/testnet | Coming soon |
| Token | Testnet USDC (free from faucets) | Real USDC |
Always start on testnet. Switch to mainnet by changing the network string.
x402.org/facilitator is free. Stellar uses OZ Channels.exact = fixed price per request.eip155:8453 = Base. solana:5eykt... = Solana mainnet. stellar:pubnet / stellar:testnet = Stellar.max_ledger expiration bounds instead of full transactions. Lighter than Solana's transaction signing.export const middleware = paymentMiddleware(
"0xYourAddress",
{
"/api/basic": { price: "$0.001", network: "base" },
"/api/premium": { price: "$0.01", network: "base" },
"/api/bulk": { price: "$0.10", network: "base" },
},
facilitator
);Base and Solana use x402.org; Stellar uses OZ Channels. Configure both.
import { paymentProxy, x402ResourceServer } from "@x402/next";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";
const x402Facilitator = new HTTPFacilitatorClient({ url: "https://x402.org/facilitator" });
const server = new x402ResourceServer(x402Facilitator)
.register("eip155:8453", new ExactEvmScheme())
.register("solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", new ExactSvmScheme());
export const middleware = paymentProxy({
"/api/data": {
accepts: [
{ scheme: "exact", price: "$0.01", network: "eip155:8453", payTo: "0xEvmAddress" },
{ scheme: "exact", price: "$0.01", network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", payTo: "SolanaAddress" },
{ scheme: "exact", price: "$0.01", network: "stellar:testnet", payTo: process.env.STELLAR_PAY_TO_ADDRESS! },
],
description: "Multi-chain premium data",
},
}, server);Stellar routes require the OZ Channels facilitator (separate client); see references/stellar.md for full tri-chain setup with both facilitators.
| Problem | Fix |
|---|---|
| 402 but no payment details | Check middleware matcher covers the route |
| "facilitator unreachable" | Verify https://x402.org/facilitator is accessible |
| Payment succeeds but 401 | Increase maxTimeoutSeconds |
| "EIP-3009 not supported" | Use USDC only |
| Solana tx fails | Check SOL balance for rent + USDC balance for payment |
| V1 vs V2 confusion | V1: x402-next. V2: @x402/next. Don't mix them |
| Stellar: "auth entry expired" | Increase max_ledger bounds in auth entry |
| Stellar: "wallet doesn't support signAuthEntry" | Use Freighter browser extension (not mobile) |
| Stellar: facilitator 401 | Check OZ_RELAYER_API_KEY is set and valid |
| Stellar: "unsupported network" | Use CAIP-2 format: stellar:pubnet or stellar:testnet |
| Stellar: need XLM? | No — facilitator covers all fees. Client needs zero XLM. |
references/base-evm.md — Complete Base/EVM setup (V1 + V2)references/solana.md — Complete Solana setupreferences/stellar.md — Complete Stellar setup (Soroban, Freighter, OZ Channels, Smart Accounts)references/sentinel-router.md — Payment Router APIreferences/packages.md — All npm packages~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.