Open-source library for AI-native x402 integrations on Solana — Python & Node.js.
Wrapped x402 standardizes AI micropayments using the x402 protocol (HTTP 402: Payment Required) so any API, model endpoint, or agent can gate premium features with verifiable on-chain credits.
Uniform, trustless pay-per-use for AI endpoints. No proprietary gateways; open verification.
SDKs, verifiers, and FastAPI/Express templates that ship in minutes, not weeks.
Builders of AI apps/agents, API vendors, and Solana-native dApps needing metering.
Simple API surface, open verification, lightweight runtime, AI-native mindset.
PyPI
pip install wrappedx402-core wrappedx402-fastapi wrappedx402-langchain
npm
npm install wrappedx402-core wrappedx402-express wrappedx402-langchain
Node ≥ 18, Python ≥ 3.10, public Solana RPC (or custom), and server runtime (serverless OK).
Both stacks ship with minimal samples so you can unlock an endpoint with 1-2 functions.
Both SDKs expose a minimal Client to initiate payments and a Verifier for proof checks.
from wrappedx402_core import X402Client
client = X402Client(
receiver="FCRJ287uSoeF6qKuDcjV8kh54eaNBkDVYCNr3LCoQyu8",
rpc="https://api.mainnet-beta.solana.com"
)
payment = client.create_payment(amount="0.001 SOL", memo="AI Query #42")
print(payment)
import { X402Client } from "wrappedx402-core";
const client = new X402Client({
receiver: "FCRJ287uSoeF6qKuDcjV8kh54eaNBkDVYCNr3LCoQyu8",
rpc: "https://api.mainnet-beta.solana.com"
});
const payment = await client.createPayment({ amount: "0.001 SOL", memo: "AI Query #42" });
console.log(payment);
from wrappedx402_core import verify_proof
valid = verify_proof(signature="5rTxQ...xyz", ttl=180, min_amount=0.001)
print("valid:", valid)
import { verifyProof } from "wrappedx402-core";
const valid = await verifyProof({ signature:"5rTxQ...xyz", ttl:180, minAmount:0.001 });
console.log("valid:", valid);
The verifier reads a Solana transaction and checks: receiver, amount, recent block time (TTL), and replay-safety (nonce/signature).
| Param | Type | Description |
|---|---|---|
| signature | string | Solana transaction signature (hash). |
| ttl | int (sec) | Max age allowed for the proof (e.g., 120–300s). |
| minAmount | number | Minimum SOL/SPL expected by receiver. |
| nonce | string (opt) | Optional unique challenge to bind a single request. |
from fastapi import FastAPI, Request
from wrappedx402_fastapi import x402_middleware
from wrappedx402_core import verify_proof
app = FastAPI()
app.middleware("http")(x402_middleware)
@app.get("/premium")
async def premium(req: Request):
proof = req.headers.get("x402-proof")
if not verify_proof(signature=proof, ttl=120, min_amount=0.001):
return {"error":"invalid or expired"}
return {"ok": True, "content":"Unlocked via x402"}
import express from "express";
import { x402Middleware } from "wrappedx402-express";
import { verifyProof } from "wrappedx402-core";
const app = express();
app.use(x402Middleware());
app.get("/premium", async (req, res) => {
const proof = req.header("x402-proof");
const valid = await verifyProof({ signature:proof, ttl:120, minAmount:0.001 });
if(!valid) return res.status(402).json({ error:"invalid or expired" });
res.json({ ok:true, content:"Unlocked via x402" });
});
Allow origins you trust only. Apply small token-bucket limits to 402 endpoints to avoid spam prior to payment.
Compatible with serverless (Vercel/Cloudflare/Render). Keep RPC & receiver in env vars.
When a client requests a premium endpoint without proof, respond with HTTP 402 and payment instructions.
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"x402": {
"receiver":"FCRJ...Qyu8",
"amount":"0.001 SOL",
"memo":"AI Query #42",
"ttl":180,
"nonce":"abc123"
}
}
# Client retries after paying
GET /premium
x402-proof: 5rTxQ...xyz
x402-nonce: abc123
HTTP/1.1 200 OK
{
"ok":true,
"content":"Unlocked via x402"
}
HTTP/1.1 402 Payment Required
{ "error":"invalid or expired" }
Solana address (wallet/program) that receives payments.
Public RPC or private node URL for signature lookups.
Lower bound per call (e.g., 0.001 SOL). Prevents dust.
Proof expiration (e.g., 120–300s). Shorter = safer.
| Key | Example | Purpose |
|---|---|---|
| SOLANA_RPC | https://api.mainnet-beta.solana.com | RPC for verifier lookups |
| SOL_RECEIVER | FCRJ...Qyu8 | Destination for payments |
| MIN_AMOUNT | 0.001 | Minimum required amount |
| TTL_SECONDS | 180 | Max proof age |
| CORS_ORIGINS | https://example.com | Allowed web origins |
Client → GET /premium
Server → 402 with receiver/amount/ttl/nonce
Client pays on Solana; obtains signature
Server verifies signature + TTL + minAmount
Client retries with x402-proof
Server returns 200 OK + content
| Status | Code | Meaning |
|---|---|---|
| 402 | X402_REQUIRED | Payment required; no/invalid proof |
| 402 | X402_EXPIRED | TTL elapsed |
| 402 | X402_UNDERPAID | Amount below minimum |
| 400 | X402_MALFORMED | Malformed headers/body |
| 429 | RATE_LIMIT | Too many attempts before payment |
| 500 | RPC_ERROR | Upstream RPC failure |
Optional server callback when a signature passes verification, e.g., for analytics or credits ledgering.
Emit events on repeated invalid proofs to block IP/keys temporarily.
Mirror successful calls to internal billing for dashboards.
Idempotent handlers recommended to avoid double-counting on client retries.
Use a dev RPC or a mock verifier that asserts header shapes and TTL math.
Mock verify_proof/verifyProof to simulate valid/expired/underpaid flows.
Benchmark 402 → pay → verify → 200 to tune cache & RPC pool.
Inject env via secrets; never commit keys or private RPC URLs.
wrappedx402 check --sig 5rTxQ... --ttl 180 --min 0.001
wrappedx402 nonce --len 24
wrappedx402 tx --sig 5rTxQ...
wrappedx402 config --rpc <URL> --receiver <ADDR>
from fastapi import FastAPI, Request
from wrappedx402_fastapi import x402_middleware
from wrappedx402_core import verify_proof
app = FastAPI()
app.middleware("http")(x402_middleware)
@app.get("/ai/answer")
async def ai_answer(req: Request):
proof = req.headers.get("x402-proof")
ok = verify_proof(signature=proof, ttl=180, min_amount=0.001)
return {"answer":"42"} if ok else {"error":"payment required"}
import express from "express";
import { x402Middleware } from "wrappedx402-express";
import { verifyProof } from "wrappedx402-core";
const app = express();
app.use(x402Middleware());
app.get("/ai/answer", async (req, res) => {
const sig = req.header("x402-proof");
const ok = await verifyProof({ signature:sig, ttl:180, minAmount:0.001 });
res.json(ok ? { answer:"42" } : { error:"payment required" });
});
const res = await fetch("/premium");
if(res.status === 402){
const x = await res.json(); // { x402: { receiver, amount, ttl, nonce } }
// show pay modal → obtain signature → retry
}
const data = await fetch("/premium", { headers:{ "x402-proof":signature } });
# pseudocode
if not verify_proof(sig, ttl=120, min_amount=0.001):
raise PaymentRequired()
llm.invoke(prompt)
120–300s is typical; shorter for high-value endpoints.
Reject underpay to avoid ambiguous pricing.
Bind proof to request to kill reuse.
Pool connections or add small cache for lookups.
Only allow your production origins.
Log proof age, tx latency, reject reasons.
Use at your own risk for testing. Production should be mainnet with strict envs.
Yes, as long as the verifier checks mint + amount. Examples focus on SOL for brevity.
Typical ~200ms with healthy RPC; add small caches for bursts.
No. All logic is open-source with reproducible verification paths.
Wrapped x402 is released under the MIT License. Contributions and PRs are welcome.
index.html@Wrappedx402