Build paid APIs for agents, apps, and users.
Verge is an HTTP 402 gateway and SDK. Your server returns a payment challenge, the caller pays on a supported rail, then retries with the transaction proof. Robinhood Chain + USDG is the default; other rails are selected with a single network option.
Overview
What is x402?
A protocol pattern for HTTP 402 Payment Required: request → challenge → payment → retry → access.
Who pays?
Agents, apps, scripts, or humans. The protocol is not agent-only; agents are the strongest use case because they can pay per request automatically.
What does Verge add?
Express/Hono middleware, stablecoin verification, replay protection hooks, wallet console, marketplace listings, API keys, receipts, and a machine-readable catalog.
Install
Pick the adapter for your server framework. Both adapters call the same @vergex402/core verifier.
npm install @vergex402/express npm install @vergex402/hono hono
Environment you normally need:
WALLET=0xYourRecipientWallet # optional: overrides the public/default RPC for the selected network ROBINHOOD_RPC_URL=https://rpc.mainnet.chain.robinhood.com # optional: used as primary RPC when configured ALCHEMY_API_KEY=...
Express quickstart
import express from "express";
import { paywall } from "@vergex402/express";
const app = express();
const recipient = process.env.WALLET;
if (!recipient) throw new Error("WALLET is required");
app.use("/api/premium", paywall({
amount: 0.001,
recipient,
network: "robinhood-mainnet", // default rail: USDG on chain 4663
}));
app.get("/api/premium", (_req, res) => {
res.json({ ok: true, message: "unlocked" });
});
app.listen(3000);Hono quickstart
import { Hono } from "hono";
import { paywall } from "@vergex402/hono";
const app = new Hono();
const recipient = process.env.WALLET;
if (!recipient) throw new Error("WALLET is required");
app.use("/api/premium", paywall({
amount: 0.001,
recipient,
network: "robinhood-mainnet",
}));
app.get("/api/premium", (c) => c.json({ ok: true, message: "unlocked" }));The x402 request flow
- 1. Caller requests a protected route. Without proof, Verge returns HTTP 402 with both wire formats: the x402 v2
PAYMENT-REQUIREDheader (base64 JSON) and the legacyX-Pay-*headers. - 2. Caller pays the requested asset. The challenge includes amount, recipient, network (CAIP-2 in the v2 header), token reference, and nonce.
- 3. Caller retries with proof. Standard agents send
PAYMENT-SIGNATURE(base64 PaymentPayload with the settlement tx); Verge-native callers can sendX-Pay-Tx+X-Pay-Nonce. - 4. Middleware verifies settlement. EVM rails check stablecoin Transfer logs; Solana and Sui use their own transaction/balance verification paths.
curl -i http://localhost:3000/api/premium
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi4uLg== (base64 of:)
{ "x402Version": 2, "resource": { "url": "..." },
"accepts": [{ "scheme": "exact", "network": "eip155:4663",
"amount": "1000", "asset": "0x5fc5...d168", "payTo": "0x...",
"maxTimeoutSeconds": 600, "extra": { "paymentFlow": "upfront",
"nonce": "8f3c2d" } }],
"extensions": { "x-verge": { "info": { "nonce": "8f3c2d" } } } }
WWW-Authenticate: x402 realm="verge", nonce="8f3c2d", amount="0.001", recipient="0x...", network="robinhood-mainnet"
X-Pay-Token: USDG
X-Pay-Network: robinhood-mainnet
X-Pay-Chain-Id: 4663
X-Pay-Amount: 0.001
X-Pay-Recipient: 0x...
X-Pay-Nonce: 8f3c2d# Standard x402 v2 agent style:
curl -i http://localhost:3000/api/premium \
-H "PAYMENT-SIGNATURE: <base64 of PaymentPayload JSON>
{ x402Version: 2, accepted: { scheme: exact, network: eip155:4663 },
payload: { tx: 0xYourSettlementTx, nonce: 8f3c2d } }"
# Verge-native style (equivalent):
curl -i http://localhost:3000/api/premium \
-H "X-Pay-Tx: 0xYourSettlementTx" \
-H "X-Pay-Nonce: 8f3c2d"
HTTP/1.1 200 OK
{ "ok": true, "message": "unlocked" }Facilitator API (hosted)
Vergesnowy.com runs a public x402 v2 facilitator. Any resource server — including your paywall() middleware — can delegate verification and settlement commitment to it, the same role Coinbase CDP or thirdweb facilitators play, but for Robinhood Chain USDG plus six more rails. Zero protocol fees.
curl https://vergesnowy.com/api/facilitator/supported
{ "kinds": [ { "x402Version": 2, "scheme": "exact",
"network": "eip155:4663" }, "..." ],
"extensions": ["x-verge"] }
# Read-only check (spec 7.1):
curl -X POST https://vergesnowy.com/api/facilitator/verify \
-H "content-type: application/json" \
-d '{ "x402Version": 2,
"paymentPayload": { "payload": { "tx": "0x...", "nonce": "..." } },
"paymentRequirements": { "scheme": "exact", "network": "eip155:4663",
"amount": "1000", "asset": "0x5fc5...d168", "payTo": "0x..." } }
{ "isValid": true, "payer": "0x..." }
# Commit settlement (spec 7.2) - consumes the nonce, blocks replay:
curl -X POST https://vergesnowy.com/api/facilitator/settle -d "...same body..."Client retry helper
A caller does not need a Verge account. It only needs to understand the 402 response, pay the requested rail, then retry with the proof headers. The core package now exports helpers for parsing the challenge and building retry headers.
import { parseX402Authenticate, paymentProofHeaders } from "@vergex402/core";
const first = await fetch("https://api.example.com/premium");
if (first.status === 402) {
const challenge = parseX402Authenticate(first.headers.get("www-authenticate") || "");
// Your wallet/payment engine sends challenge.amount to challenge.recipient
// on challenge.network, then returns the settlement transaction hash.
const txHash = await payStablecoin(challenge);
const unlocked = await fetch("https://api.example.com/premium", {
headers: paymentProofHeaders(txHash, challenge.nonce),
});
}Security model
Issued nonce required
A paid retry must present a nonce that the middleware actually issued. Unknown or already-consumed nonces return NONCE_INVALID.
Replay-safe transaction hashes
Each tx hash is keyed by network and rejected after the first successful unlock. Use a durable ReplayStore in multi-process production.
Settlement verification
EVM rails inspect stablecoin Transfer logs; Solana inspects SPL token-balance deltas; Sui inspects finalized balance changes.
Stateless option
The built-in stores are in-memory for simple servers. Bring Redis/Postgres stores when running multiple workers or serverless replicas.
Multichain: one option, not a different command
You were right to ask: every chain has its own identifier, token, verifier path, and RPC. In Verge, you do not run a different command for each chain. You set network in the SDK options. If omitted, Verge uses robinhood-mainnet. The 402 response tells the caller which network, token, recipient, amount, and nonce to use.
| Network string | Chain | Chain ID | Asset | Notes |
|---|---|---|---|---|
| robinhood-mainnet | Robinhood Chain | 4663 | USDG | Default / flagship rail |
| ethereum-mainnet | Ethereum | 1 | USDC | Explicit opt-in EVM rail |
| base-mainnet | Base | 8453 | USDC | Explicit opt-in EVM rail |
| arbitrum-mainnet | Arbitrum One | 42161 | USDC | Explicit opt-in EVM rail |
| polygon-mainnet | Polygon | 137 | USDC | Explicit opt-in EVM rail |
| solana-mainnet | Solana | SVM | USDC | Explicit opt-in SVM rail |
| sui-mainnet | Sui | Move | USDC | Explicit opt-in Move rail |
app.use("/api/premium", paywall({
amount: 0.001,
recipient,
network: "base-mainnet", // or ethereum-mainnet, arbitrum-mainnet, polygon-mainnet, solana-mainnet, sui-mainnet
}));Current app reality: the public catalog shows all supported rails; private wallet balances and transaction history in the console are Robinhood Chain-focused today.
AI SDK middleware
Use @vergex402/ai-sdk to wrap any Vercel AI SDK model or gate your own AI routes with per-call USDG payments.
npm install @vergex402/ai-sdk @vergex402/fetch
Client — pay to call a gated model endpoint
import { wrapWith402 } from "@vergex402/ai-sdk";
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
const model = wrapWith402(openai("gpt-4o-mini"), {
endpoint: "https://your-api.com/api/ai",
privateKey: process.env.AGENT_KEY as `0x${string}`,
maxAmountUsdg: 0.01,
});
const { text } = await generateText({ model, prompt: "Hello" });Server — monetize your AI route (Next.js)
import { createX402Gate } from "@vergex402/ai-sdk";
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
const { POST: gateCheck } = createX402Gate({
amount: 0.001, // USDG per call
recipient: "0xYOUR_WALLET",
});
export async function POST(req: Request) {
const gateRes = await gateCheck(req.clone());
if (gateRes.status === 402) return gateRes; // sends PAYMENT-REQUIRED
const { messages } = await req.json();
return streamText({ model: openai("gpt-4o-mini"), messages }).toDataStreamResponse();
}MCP server
Verge exposes an MCP-over-HTTP server at /api/mcp that any AI agent (Claude, Cursor, ChatGPT) can use as a tool server.
Add to Claude Code / Cursor
# In your MCP config (claude_desktop_config.json or .cursor/mcp.json):
{
"mcpServers": {
"verge": {
"url": "https://vergesnowy.com/api/mcp",
"transport": "http"
}
}
}Available tools: inspect_endpoint, list_marketplace, create_invoice, get_reputation
@vergex402/fetch — buyer SDK
The fetch SDK is for agents or scripts that need to pay for x402-gated endpoints. It handles the full challenge-sign-retry loop automatically.
npm install @vergex402/fetch viem
import { payAndFetch } from "@vergex402/fetch";
const res = await payAndFetch("https://vergesnowy.com/x/crypto-price", {
privateKey: process.env.AGENT_KEY as `0x${string}`,
maxAmount: 0.01, // USDG ceiling — throws if challenge > this
});
const data = await res.json();Revenue splits
Automatically distribute incoming USDG to multiple wallets. Configure splits in basis points (10,000 = 100%). Applied on every facilitator settlement.
// POST /api/splits — create a split rule
fetch("/api/splits", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
recipient: "0xCOFOUNDER_WALLET",
basisPoints: 2000, // 20%
label: "Co-founder share",
}),
});
// GET /api/splits — list all splits for connected wallet
// DELETE /api/splits?id=spl_xxx — remove a split ruleSplits are enforced server-side at settlement. Max 10 recipients per wallet, sum ≤ 10,000 bps.
Developer portal / console
The console is the user-facing workspace. Visitors can explore payment rails and the marketplace before connecting. Wallet connection is only required for private actions.
API keys
API keys are for apps that want Verge-managed access without forcing every request to carry a payment transaction. A wallet signs into the console, creates a key, and your server can introspect it.
curl -X POST https://vergesnowy.com/api/keys/verify -H "content-type: application/json" -d '{"key": "vg_live_..."}'
{ "ok": true, "wallet": "0xabc...", "remaining": 998, "limit": 1000 }Introspection reports validity, revocation state, and remaining quota. Unknown, revoked, or exhausted keys return HTTP 401.
Marketplace and catalog
The marketplace is the human UI for paid endpoints. /api/catalog is the machine-readable version for agents and crawlers. Use it to discover endpoints, supported rails, docs URL, gateway URL, and demo routes.
curl https://vergesnowy.com/api/catalog curl https://vergesnowy.com/api/marketplace curl https://vergesnowy.com/api/demo