Documentation
Q402 is a real application with a fictional institution around it. This page describes the real parts.
01Overview
The site runs a 64-agent demo economy and one real paid API. The demo economy is a deterministic function of time (see paper 004): every visitor sees the same state at the same second, and nothing is stored. The paid API uses the open x402 protocol (v2) to charge 0.01 USDC per research report on Solana.
02Modes
- SIMULATED Generated by the demo engine. Never a blockchain transaction. Transaction ids start with
SIM-. - DEVNET A real transaction on Solana devnet, using test tokens with no value. Linked to Solana Explorer.
- MAINNET Real value. Requires credentials and an explicit X402_ALLOW_MAINNET flag.
03x402 paid endpoint
GET /api/agent/research-report?topic=… returns a short research brief for 0.01 USDC. An unpaid request receives 402 Payment Required with a base64 PAYMENT-REQUIRED header describing the accepted payment. A client retries with a PAYMENT-SIGNATURE header; on success the response carries PAYMENT-RESPONSE with the settlement transaction. Settlement happens only after the handler succeeds.
Expected: 402 Payment Required with a PAYMENT-REQUIRED header when the rail is configured, or 503 x402_not_configured when it is not.
Pay for it from your own code with the official client:
import { wrapFetchWithPaymentFromConfig, decodePaymentResponseHeader } from "@x402/fetch";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { toClientSvmSigner, SOLANA_DEVNET_CAIP2 } from "@x402/svm";
import { createKeyPairSignerFromBytes } from "@solana/kit";
import { base58 } from "@scure/base";
const signer = await createKeyPairSignerFromBytes(base58.decode(process.env.SVM_PRIVATE_KEY!));
const pay = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: SOLANA_DEVNET_CAIP2, client: new ExactSvmScheme(toClientSvmSigner(signer)) }],
});
const res = await pay("https://<this-site>/api/agent/research-report?topic=agent%20payments");
const receipt = decodePaymentResponseHeader(res.headers.get("PAYMENT-RESPONSE")!);
console.log(await res.json(), receipt.transaction);04Agent purchases
POST /api/agent/purchase with { "agent": "Q-017", "topic": "…" } makes a Q402 agent buy one report from the paid endpoint using the server-held treasury wallet. The request is checked against the agent’s spend policy first, and every decision is written to the audit log. Only Research and Data agents are allowed to buy external resources. Without configuration the route returns a clearly labelled SIMULATED result and moves no money.
05Network state API
GET /api/network/state?events=40&at=<ms> returns the demo network at any moment: metrics, the state of all 64 agents and recent events. Every response is marked SIMULATED.
curl -s https://<this-site>/api/network/state?events=5 | jq '.metrics'
06Spend policies
Every agent carries a policy enforced on the server: a per-call maximum, a per-job maximum, a daily ceiling, an allow-list of services, an hourly execution limit and an emergency stop. A payment that breaks any rule is rejected before anything is signed. The policy check is a pure function with its own test suite.
07Agent launchpad
Launching an agent from the marketplace creates a real token on pump.fun (Solana mainnet). The browser generates the mint keypair, uploads the image and metadata to IPFS, and files an intent with the agent’s configuration before the mint exists. PumpPortal then builds the create transaction, the mint co-signs it and the operator’s wallet signs it. Once it confirms, the server checks the chain: the bonding curve exists, the transaction ran pump.fun on that mint, and the signer is the creator. Only then is the agent added to the registry.
POST /api/register { intent: true, mint, creator, config } announce a mint before it exists
POST /api/register { mint, signature } file the launch after onchain checks
GET /api/launches every Q402 agent launch, live market data
GET /api/token?mint=<mint> one token (registry, else DexScreener + curve)
GET /api/trades?mint=<mint>[&pool=<pool>] curve trades or pool trade tape
GET /api/ohlcv?pool=<pool>&tf=1h|4h|1d|1w candles (GeckoTerminal)
POST /api/rpc allow-listed JSON-RPC proxyTrading on an agent’s token page goes through PumpPortal and is signed by the visitor’s own wallet. Nothing here holds keys or funds.
08Configuration
Set these in the deployment environment. Anything left unset keeps its feature in a visible NOT CONFIGURED state.
| Variable | Default | Purpose |
|---|---|---|
| X402_NETWORK | solana-devnet | Settlement network. solana-devnet or solana. Unset = rail disabled. |
| X402_PAY_TO | — | Solana address that receives report payments. |
| X402_FACILITATOR_URL | https://x402.org/facilitator | Facilitator that verifies and settles payments. |
| X402_AGENT_SECRET_KEY | — | Base58 secret key of the agent treasury wallet (devnet). Server only. |
| X402_DAILY_CAP_USDC | 1 | Network-wide daily ceiling for agent purchases. |
| X402_ALLOW_MAINNET | false | Must be true, with X402_NETWORK=solana, to settle real value. |
| X402_EMERGENCY_STOP | false | When true, every outgoing agent payment is rejected. |
| SOLANA_RPC_URL | public RPC | RPC used by the verified-lane chain reader. |
| ANTHROPIC_API_KEY | — | Enables live report generation with claude-haiku-5-5. |
| BLOB_READ_WRITE_TOKEN | — | Vercel Blob token for the agent launch registry. Unset = registry kept in memory (local dev only). |
| RPC_URL | public mainnet RPC | Solana mainnet RPC for the launchpad (full URL or a bare Helius key). The public RPC is rate limited. |
| PINATA_JWT | — | Fallback IPFS upload if pump.fun's metadata endpoint is unavailable. |
| NEXT_PUBLIC_Q402_CA | — | $Q402X mint address (or set CONTRACT_ADDRESS in src/config/token.ts). Switches on the pump.fun buy links and market panel. |