Docs

Build with HUSH.

Sell an endpoint privately, give an agent a leashed wallet, and let Claude shop over MCP. Everything below runs today on Solana devnet.

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
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.

402 body
{ "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.

app/api/forecast/route.ts
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

agent.ts
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.

claude_desktop_config.json
{ "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