Developers
x402 on Robinhood Chain, open.
The no-code gateway covers most sellers. If you run your own server, use the same public facilitator and discovery feed.
Behind the gateway
Paid calls reach your API with two extra headers: X-X402Fi-Secret (from your listing) and X-X402Fi-Payer. Check the secret so the paywall can't be bypassed.
// Your API, behind the x402Fi gateway: reject calls that skip the paywall.
app.use((req, res, next) => {
if (req.get("x-x402fi-secret") !== process.env.X402FI_SECRET) return res.status(403).end();
// Optional: who paid for this call
req.payer = req.get("x-x402fi-payer");
next();
});Facilitator
x402 v2, scheme exact, network eip155:4663, asset USDG. x402Fi pays the gas for settlement and never holds funds.
- POST /api/facilitator/verify
- POST /api/facilitator/settle
- GET /api/facilitator/supported
// Self-hosted paywall that uses the x402Fi facilitator (Robinhood Chain, USDG).
const FACILITATOR = "https://x402fi.dev/api/facilitator";
const requirements = {
scheme: "exact",
network: "eip155:4663",
amount: "10000", // 0.01 USDG (6 decimals); x402Fi minimum
asset: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
payTo: "0xYourWallet",
maxTimeoutSeconds: 120,
extra: { name: "Global Dollar", version: "1" },
};
app.get("/rates", async (req, res) => {
const header = req.get("payment-signature") ?? req.get("x-payment");
if (!header) {
const pr = { x402Version: 2, resource: { url: req.url, description: "FX rates", mimeType: "application/json" }, accepts: [requirements] };
return res.status(402).set("PAYMENT-REQUIRED", Buffer.from(JSON.stringify(pr)).toString("base64")).json(pr);
}
const paymentPayload = JSON.parse(Buffer.from(header, "base64").toString());
const body = JSON.stringify({ paymentPayload, paymentRequirements: requirements });
const v = await fetch(FACILITATOR + "/verify", { method: "POST", headers: { "content-type": "application/json" }, body }).then(r => r.json());
if (!v.isValid) return res.status(402).json({ error: v.invalidReason });
const data = await computeRates(); // do the work
const s = await fetch(FACILITATOR + "/settle", { method: "POST", headers: { "content-type": "application/json" }, body }).then(r => r.json());
if (!s.success) return res.status(402).json({ error: s.errorReason });
res.set("PAYMENT-RESPONSE", Buffer.from(JSON.stringify(s)).toString("base64")).json(data);
});Discovery
Every paid endpoint is published in a Bazaar-style feed that agents and indexers can crawl: /api/discovery/resources (JSON), with a readable view at /discovery.
Verified payee
// Name the payee in your 402 so agents can verify you (x402 payee-name extension)
"extensions": { "payee-name": { "info": { "name": "yourco.402api.eth" } } }
// Agents check it with:
import { verifyPayee, viemReader } from "@x402identity/payee";
const verdicts = await verifyPayee(paymentRequired, origin, viemReader(mainnetClient));Spec: payee-name extension. Records: org.x402.origins and the Robinhood Chain address (coin type 2147488311).
USDG details
- Address
- 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168
- Decimals
- 6
- EIP-712 domain
- name "Global Dollar", version "1", chainId 4663
- Transfer
- transferWithAuthorization (EIP-3009, v/r/s)