01
Quickstart
1. Open the app, connect Phantom (devnet), sign in. 2. Create an agent, copy its API key. 3. Fund it (Phantom transfer or devnet airdrop). 4. Allowlist a seller and press Buy. The agent gets a 402, pays a one-time address, and the gate serves the answer.
curl -X POST https://<host>/api/agent/buy \
-H "x-agent-key: hush_…" -H "content-type: application/json" \
-d '{"listing":"market-brief"}'02
Private x402 flow
A call without payment gets 402 and an accepts array, x402 style. HUSH adds extra.legs: one stealth payTo per seller, derived from the gate secret and a fresh nonce, plus a signed quote.
{ "x402Version": 1, "accepts": [{
"scheme": "exact", "network": "solana-devnet", "currency": "SOL",
"asset": "native", "maxAmountRequired": "3000000",
"extra": { "privacy": "stealth-one-time-payee", "quote": "eyJ2Ijox…",
"legs": [{ "seller": "oracle.hush", "amount": "1000000", "payTo": "8sQ2…" }, …] } }] }The client pays every leg in one transaction, then retries with X-PAYMENT: base64url({quote, signature}). The gate re-derives each address, reads the transaction over RPC, checks amounts, asset, expiry and replay, and serves.
03
Hush Gate (sellers)
Framework-agnostic: it wraps any (Request) => Response. Next.js route handlers, Hono, Workers, Bun.
import { hushGate } from "@hush/gate";
export const GET = hushGate({
resource: "/api/forecast", price: "0.001", currency: "SOL", seller: "forecast-lab",
secret: process.env.HUSH_SECRET!, rpcUrl: process.env.RPC_URL!,
network: "solana", usdcMint: "EPjFWdd5AufqSSqeM2qZqWAquxHnWsZXsP6ehNkN5Mkj6",
onReceipt: (r) => saveReceipt(r),
}, async () => Response.json(await forecast()));Composite: pass legs: [{ seller, amount }, …] instead of price. USDC: currency: "USDC"; buyers pay into each payee's associated token account.
04
Per-call escrow
Funds sit on the one-time address, which only the gate can sign for. If your handler throws or returns non-2xx, the gate refunds the payer (SOL) from the stealth key and answers 502 with the refund signature. Sellers sweep settled addresses on their own schedule.
05
Buyers & agents
import { hushFetch } from "@hush/gate/client";
const { res } = await hushFetch(url, { keypair, rpcUrl,
approve: (req) => BigInt(req.maxAmountRequired) <= 1_000_000n });06
Leash
Each agent wallet is derived server-side and funded by its owner. Before any payment the server checks: kill switch (agent and owner-wide), allowlist, per-call cap, daily budget. The check runs twice, against the list price and against the seller's actual 402. Owners edit limits with a Phantom-signed session.
07
MCP server
A stdio MCP server ships in mcp/server.mjs. Tools: hush_shop, hush_buy, hush_wallet, hush_receipts.
{ "mcpServers": { "hush": { "command": "node", "args": ["/path/to/hush/mcp/server.mjs"],
"env": { "HUSH_URL": "http://localhost:4046", "HUSH_AGENT_KEY": "hush_…" } } } }08
Hush Score & receipts
Every verified call yields a receipt. Publicly only its commitment sha256(nonce|signature|payer) exists. Hush Score (0 to 1000) weighs success rate, latency and refund rate, and ships with a hash-chain root over the commitments it was computed from. Owners see full receipts of their own agents.
09
HTTP API
GET /api/shop listings + scores
GET /api/shop/:id Hush-Gated seller endpoint (402)
POST /api/auth { pubkey, ts, signature } -> session
GET /api/agents | POST list / create (owner)
PATCH /api/agents/:id dailyBudget, perCallCap, allowlist, frozen
POST /api/agents/:id/withdraw sweep agent SOL to owner
POST /api/agents/freeze-all { on }
POST /api/agent/buy { listing, input?, agentId? } x-agent-key
GET /api/receipts public commitments | owner receipts
GET /api/stats Agent GDP + Hush Scores