x402 · merchants
Get paid by agents, in USDG.
Price an API, a dataset or an MCP tool. Agents pay per call with a signed transfer, the facilitator settles it on Robinhood Chain, and the money lands in your wallet.
Register a payTo
Your wallet signs one message. No transaction, no gas.1
Connect the wallet that gets paid
Payments go straight to this address, your payTo. It signs to prove it is yours. To be paid at another address, connect that wallet instead.
2
Describe what you sell
Shown in the public directory, as plain text. Only the name is required.
3
Sign, and get your API key
The facilitator sends a one-time message and your wallet signs it. Your middleware sends the key when it settles. Already registered? Registering again with the same wallet replaces your key.
Shown once. Copy it now and keep it as a secret, for example in
PRIORS_FACILITATOR_KEY. The facilitator stores only a hash of it, so nobody can show it to you again. Lost it? Register again with this wallet for a new one.
Add it to your server
Standard x402 middleware, with USDG on Robinhood Chain and your key.server.js
// npm i express @x402/express @x402/core @x402/evm @priors/x402 import express from "express"; import { paymentMiddleware, x402ResourceServer } from "@x402/express"; import { HTTPFacilitatorClient } from "@x402/core/server"; import { ExactEvmScheme } from "@x402/evm/exact/server"; import { registerUsdg, priorsFacilitator } from "@priors/x402"; // your key from this page, kept out of the code const facilitator = new HTTPFacilitatorClient( priorsFacilitator({ apiKey: process.env.PRIORS_FACILITATOR_KEY }), ); const usdg = new ExactEvmScheme(); registerUsdg(usdg); // "$0.05" now means 0.05 USDG on Robinhood Chain const server = new x402ResourceServer(facilitator).register("eip155:4663", usdg); const app = express(); app.use(paymentMiddleware({ "GET /report": { accepts: { scheme: "exact", price: "$0.05", network: "eip155:4663", payTo: "0xYourPayTo" }, description: "One report", }, }, server)); app.get("/report", (req, res) => res.json({ report: "…" })); app.listen(3000);
server.js
// npm i hono @hono/node-server @x402/hono @x402/core @x402/evm @priors/x402 import { Hono } from "hono"; import { serve } from "@hono/node-server"; import { paymentMiddleware, x402ResourceServer } from "@x402/hono"; import { HTTPFacilitatorClient } from "@x402/core/server"; import { ExactEvmScheme } from "@x402/evm/exact/server"; import { registerUsdg, priorsFacilitator } from "@priors/x402"; // your key from this page, kept out of the code const facilitator = new HTTPFacilitatorClient( priorsFacilitator({ apiKey: process.env.PRIORS_FACILITATOR_KEY }), ); const usdg = new ExactEvmScheme(); registerUsdg(usdg); // "$0.05" now means 0.05 USDG on Robinhood Chain const server = new x402ResourceServer(facilitator).register("eip155:4663", usdg); const app = new Hono(); app.use(paymentMiddleware({ "GET /report": { accepts: { scheme: "exact", price: "$0.05", network: "eip155:4663", payTo: "0xYourPayTo" }, description: "One report", }, }, server)); app.get("/report", (c) => c.json({ report: "…" })); serve({ fetch: app.fetch, port: 3000 });
tools.js
// npm i @modelcontextprotocol/sdk @x402/mcp @x402/core @x402/evm @priors/x402 zod import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { createPaymentWrapper, x402ResourceServer } from "@x402/mcp"; import { HTTPFacilitatorClient } from "@x402/core/server"; import { ExactEvmScheme } from "@x402/evm/exact/server"; import { registerUsdg, priorsFacilitator } from "@priors/x402"; import { z } from "zod"; // your key from this page, kept out of the code const facilitator = new HTTPFacilitatorClient( priorsFacilitator({ apiKey: process.env.PRIORS_FACILITATOR_KEY }), ); const usdg = new ExactEvmScheme(); registerUsdg(usdg); // "$0.05" now means 0.05 USDG on Robinhood Chain const server = new x402ResourceServer(facilitator); server.register("eip155:4663", usdg); await server.initialize(); // every tool wrapped in paid() costs $0.02 in USDG, paid before it runs const paid = createPaymentWrapper(server, { accepts: await server.buildPaymentRequirements({ scheme: "exact", network: "eip155:4663", payTo: "0xYourPayTo", price: "$0.02", }), }); const mcp = new McpServer({ name: "my-tools", version: "1.0.0" }); mcp.tool("lookup", "Look something up. Costs $0.02 in USDG.", { query: z.string() }, paid(async ({ query }) => ({ content: [{ type: "text", text: await lookup(query) }] })), ); await mcp.connect(new StdioServerTransport());
paid in USDGStraight to your payTo on Robinhood Chain, in the transfer the payer signed. The facilitator never holds it.
free to settleThe facilitator pays the gas. Settling is free while the hub is new.
a public recordYour name, link and description, with payments settled and volume, in the directory. Every payment in the live feed.
buyers with creditAgents with a Priors line can pay you even when their balance is short.
your keyOnly its hash is stored. Registering again with the same wallet issues a new key and retires the old one.
what you enterA name up to 60 characters, a link starting with https:// up to 200, a description up to 280.
settlingA minimum payment, a daily settle limit per merchant (2,000 by default) and a daily budget across all merchants, so nobody can spend the facilitator's gas on dust.
pending paymentsIf a settlement comes back pending, resend the same payment header. Never ask the payer to sign a second one for the same call.