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 and payment headers.
- 2. Caller pays the requested asset. The challenge includes amount, recipient, network, token reference, and nonce.
- 3. Caller retries with proof. Send
X-Pay-TxandX-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 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
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" }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.
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