Gasless payments, one signed request.
Q402 developer docs. Stablecoin payments across 12 EVM chains — USDC, USDT, RLUSD, USDG. One API key, one signature. Q402 submits the transaction and pays the gas.
Overview
A managed relay for USDC / USDT / RLUSD / USDG across 12 EVM chains. Users hold no native token; Q402 submits the TX and pays the gas.
- 1Sign EIP-712 in your wallet
POST /api/payment/intentlock the quote, plan the chainPOST /api/payment/activatescan the TX, grant credits - 2Get your API key from the dashboardsandboxorlive
- 3Call pay() from the SDK or MCP
POST /api/relayverify · decrement credits · cap checksEIP-7702 Type-4 TXQ402 relayer pays the gas↓stablecoin transferyour EOA → recipient↓Trust ReceiptEIP-191 signed, verifiablewebhook relay.successHMAC-signed → your app
intent locks the quote · activate grants credits after the on-chain transfer · relay submits each payment. Every relay can fire an HMAC-signed webhook.
Agentic Wallet
A dedicated signing wallet for each AI agent, with on-chain guardrails so an agent can transact without holding your main keys. Each owner can provision up to 10 agent wallets; every payment settles gaslessly through the same EIP-712 + EIP-7702 relay.
Manage wallets, caps, and reputation gates from /dashboard, or introspect them from an MCP client with q402_agentic_info.
Yield · Curated lending vaults
Supply and withdraw stablecoins straight from an Agent Wallet across curated DeFi lending vaults on BNB Chain (USDC / USDT) and Base (a curated USDC vault). The EIP-7702 relay sponsors the gas, so idle balances compound while you pay $0 to move them.
From an MCP client: q402_yield_reserves, q402_yield_positions, q402_yield_deposit, q402_yield_withdraw.
Bridge · Chainlink CCIP
Move native USDC across chains in a single signed request over Chainlink CCIP. Quote, send, and track a transfer from the dashboard or an MCP client — no manual bridge hops.
From an MCP client: q402_bridge_quote, q402_bridge_send, q402_bridge_history, q402_bridge_gas_tank.
Payment Requests
The receive side of Q402. Publish a payment request (a fixed amount on a chain, with an optional memo) and Q402 returns a shareable /pay/req_… link plus a req_ id. Creating one moves no funds; anyone can fulfill it later.
Two ways to get paid. A Q402 agent settles a request gaslessly from its own Agent Wallet with q402_request_pay: the agent-to-agent flow. Or open the /pay link — terms are fixed, a payer can never redirect funds or change the sum.
From an MCP client: q402_request_create, q402_request_status, q402_request_pay.
How It Works
Three actors. One transaction. Zero gas for your users.
Quick Start
Pick a key, load the SDK, call pay(). Under 5 minutes.
0 · Trial key vs Multichain key
Trial API Key
BNB + Base · 500 sponsored TX · Q402 pays gas. /event.
Multichain API Key
12 chains · USDC / USDT / RLUSD (eth) · USDG (robinhood) · self-funded Gas Tank. /payment.
TRIAL_BNB_ONLY. Use Multichain for those.1 · Load the SDK
<script src="https://q402.quackai.ai/q402-sdk.js"></script>2a · Trial key — sponsored payment (BNB Chain + Base)
// Trial keys cover BNB Chain + Base. No Gas Tank needed — Q402 sponsors gas.
const q402 = new Q402Client({
apiKey: "q402_live_YOUR_TRIAL_KEY", // from /event (your Trial API Key)
chain: "bnb",
});
const result = await q402.pay({
to: recipientAddress,
amount: "1.00",
token: "USDT", // or "USDC"
});
// result → { success: true, txHash: "0x...", chain: "bnb", method: "eip7702" }2b · Multichain key — full 12-chain payment
// Multichain keys work across all supported chains. Each chain needs
// a funded Gas Tank — deposit at /dashboard → Treasury.
const q402 = new Q402Client({
apiKey: "q402_live_YOUR_KEY",
chain: "bnb", // "bnb" | "avax" | "eth" | "xlayer" | "stable" | "mantle" | "injective" | "monad" | "scroll" | "arbitrum" | "base" | "robinhood"
});
// Note: Injective supports both USDC and USDT (native Circle USDC via CCTP).
// amount MUST be a human-readable decimal STRING (e.g. "50.00", "0.123456").
// Never pass a JS Number — IEEE-754 loses precision on 18-decimal tokens.
const result = await q402.pay({
to: recipientAddress,
amount: "50.00",
token: "USDC",
});
// result → { success: true, txHash: "0xabc...", tokenAmount: "50", chain: "bnb" }
3 · Injective EVM
Native Circle USDC (CCTP) and USDT are both supported on Injective EVM. Cosmos and EVM share one balance via the MultiVM Token Standard.
const q402 = new Q402Client({
apiKey: "q402_live_YOUR_KEY",
chain: "injective",
});
const result = await q402.pay({
to: recipientAddress,
amount: "50.00",
token: "USDC", // USDC and USDT both supported on Injective
});4 · Ethereum RLUSD (NY DFS regulated)
Ripple USD, NY DFS regulated. Ethereum mainnet only — rejects on any other chain. Decimals = 18; the SDK handles conversion, pass amount as a decimal string.
const q402 = new Q402Client({
apiKey: "q402_live_YOUR_KEY",
chain: "eth",
});
const result = await q402.pay({
to: recipientAddress,
amount: "10.00",
token: "RLUSD", // Ethereum-only — throws on any other chain
});5 · That's it
// Full result shape:
// {
// success: true,
// txHash: "0xdef456...",
// chain: "bnb",
// blockNumber: "38482910",
// tokenAmount: "50",
// token: "USDC",
// gasCostNative: 0.000021,
// method: "eip7702",
// }
console.log("Paid! TX:", result.txHash);MCP for AI Clients
An MCP server for Claude / Codex / Cursor / Cline / Copilot / Hermes. @quackai/q402-mcp · quackai-org/q402-mcp.
1 · Install
Same package, one snippet per client. No secrets here.
# Claude Code / Claude Desktop
claude mcp add q402 -- npx -y @quackai/q402-mcp
# OpenAI Codex CLI
codex mcp add q402 -- npx -y @quackai/q402-mcp
# Cursor — paste into ~/.cursor/mcp.json (or .cursor/mcp.json for per-project scope)
# Cline — Cline → Settings → MCP Servers → Edit JSON. Same shape.
{
"mcpServers": {
"q402": {
"command": "npx",
"args": ["-y", "@quackai/q402-mcp"]
}
}
}
# GitHub Copilot (VS Code) — .vscode/mcp.json. Root key is "servers", NOT mcpServers.
{
"servers": {
"q402": {
"command": "npx",
"args": ["-y", "@quackai/q402-mcp"]
}
}
}
# Hermes Agent (Nous Research) — ~/.hermes/config.yaml (YAML). Reload with /reload-mcp.
mcp_servers:
q402:
command: "npx"
args: ["-y", "@quackai/q402-mcp"]
enabled: true2 · First-time setup — ask your AI
Restart the client, then say “Set up Q402”. The agent runs q402_doctor → creates + opens ~/.q402/mcp.env → walks you through pasting keys into the file. Auto-loaded for every client.
3 · Wallet modes — which signing path?
Three paths. q402_doctor asks once; change later in ~/.q402/mcp.env.
Q402 holds an encrypted Agent Wallet for you. No private key in your env. No MetaMask popup. Best for AI agents and most users.
Q402_MULTICHAIN_API_KEY=q402_live_...
Same Agent Wallet as Mode C, but you hold the PK. Export from the dashboard once. Signs locally — key never leaves your machine. MetaMask never touched.
Q402_AGENTIC_PRIVATE_KEY=0x... Q402_MULTICHAIN_API_KEY=q402_live_...
Your existing EOA signs directly via EIP-7702. The "Smart account" marker after first use is normal + reversible with q402_clear_delegation. Use a fresh wallet.
Q402_PRIVATE_KEY=0x... Q402_MULTICHAIN_API_KEY=q402_live_...
4 · Tools exposed
| Tool | Auth | Purpose |
|---|---|---|
q402_doctor | none | First-install onboarding + ongoing health check (quota, EIP-7702 state, relay reachability). |
q402_quote | none | Compare gas + supported tokens across 12 chains. |
q402_balance | api key | Verify key + remaining quota. Returns Trial + Multichain in one read when both keys set. |
q402_pay | live mode | Single-recipient gasless USDC / USDT / RLUSD / USDG send. Sandbox by default. |
q402_batch_pay | live mode | Up to 20 recipients per call (trial: 5 with your own key; server-managed Agent Wallet batch is paid Multichain-only). 6+ BNB batches with Trial → status="ambiguous" so the agent asks how to split. |
q402_receipt | none | Fetch + locally verify a Trust Receipt by rct_… id (ECDSA recovery against the relayer EOA). |
q402_wallet_status | private key | Per-chain EIP-7702 delegation state for the EOA derived from Q402_PRIVATE_KEY. Read-only. |
q402_clear_delegation | private key / api key | Clear EIP-7702 delegation on a single chain (Mode A/B local key OR Mode C api key, server-signed). Sponsored except Ethereum (billed to Gas Tank). Two-phase consentToken (preview then execute). |
q402_agentic_info | api key | Agent Wallet info (addresses, caps, daily-spend used, ERC-8004 id). Drives Mode C. |
q402_memory_summary | api key | Treasury overview over a window: USD-stablecoin spend by chain/source, top vendors, scheduled payouts, open requests/escrow, failures. Read-only. |
q402_vendor_history | api key | Total paid to one vendor (or a vendor leaderboard) with recurring cadence. Read-only. |
q402_agent_spend_report | api key | Per-Agent-Wallet spend report with each wallet's caps. Read-only. |
q402_recurring_list | api key | List scheduled rules. |
q402_recurring_create | api key | Author a rule. Paid Multichain on EVERY chain (BNB included). |
q402_recurring_fires | api key | Last 50 fires per rule (timestamp + txHashes + amount). |
q402_recurring_pause | api key | Pause a rule. Reversible. |
q402_recurring_resume | api key | Resume a paused / stopped rule. |
q402_recurring_skip_next | api key | Skip ONLY the next scheduled fire. Cadence preserved. |
q402_recurring_cancel | api key | Permanently stop a rule. |
q402_bridge_quote | none | Quote a Chainlink CCIP USDC bridge across the eth/avax/arbitrum triangle (LINK + native fee + ETA). |
q402_bridge_send | live mode | Execute a CCIP USDC bridge from the Agent Wallet (Mode C). Sandbox by default. |
q402_bridge_history | api key | Recent CCIP bridge attempts for the Agent Wallet (src/dst/amount/CCIP msgId/status). |
q402_bridge_gas_tank | api key | Per-chain Gas Tank native balance + auto-fund window so the agent can top up before bridging. |
q402_yield_reserves | none | List Q402 Yield lending markets + live supply APY across curated lending vaults on BNB and Base. |
q402_yield_positions | api key | The Agent Wallet's current Q402 Yield positions — value + live supply APY. Read-only. |
q402_yield_deposit | live mode | Supply the Agent Wallet's stablecoins into a curated lending vault (BNB USDC/USDT, Base USDC). Mode C, PAID feature — Trial cannot deposit. Confirm-gated + sandbox by default. |
q402_yield_withdraw | live mode | Withdraw supplied stablecoin out of a lending vault (amount="max" = the max currently redeemable, which vault caps or queues can leave below the full position). Always allowed, even after a plan downgrade. |
q402_stake | live mode | Gasless Q (QuackAI) staking on BNB Chain. Lock tiers 0-3 (30d/10%, 60d/15%, 120d/32%, 180d/40% APR). amount "max" supported. Confirm-gated + sandbox by default. |
q402_unstake | live mode | Gasless unstake of matured Q on BNB by record index (ith), or all matured (per-record exit, not a withdraw). |
q402_stake_positions | live mode | Read-only: the Agent Wallet's Q stakes (indices, maturity, exitable) + liquid Q balance. |
q402_request_create | api key | Publish a payment request (invoice). No funds move; returns a /pay link + req_ id. Recipient defaults to the Agent Wallet. |
q402_request_status | none | Look up a request by req_ id (amount, token, chain, recipient, status). Read-only; notFound instead of throwing. |
q402_request_pay | live mode | Pay a request gaslessly from your own Agent Wallet (Mode C). Two-phase consent, same as q402_pay. |
q402_escrow_create | api key | Create a gasless non-custodial escrow (pending record, moves no funds); optional walletId funds it from an Agent Wallet. |
q402_escrow_status | none | Read an escrow's state, parties, amount, and tx hashes. |
q402_escrow_lock | live mode | Fund a pending escrow gaslessly (EIP-7702); the server signs for an Agent-Wallet buyer. |
q402_escrow_release | live mode | Buyer releases a locked escrow to the seller (gasless). |
q402_escrow_refund | live mode | Permissionless refund to the buyer after the timeout / resolve window. |
q402_escrow_dispute | live mode | A party disputes an open escrow (requires a named arbiter). |
q402_redstone_feeds | none | List RedStone NAV/price feeds a trigger can watch (allowlisted ids + sanity bands). Read-only. |
q402_redstone_trigger_create | api key | Author a feed-crossing trigger that fires a gasless payout when a RedStone NAV/price crosses a threshold. Edge-latched, exactly-once. |
q402_redstone_trigger_list | api key | List the Agent Wallet's RedStone triggers + recent fires. Read-only. |
q402_redstone_trigger_cancel | api key | Cancel a RedStone trigger (terminal). |
5 · Sandbox vs live mode
Default is sandbox — fake txHash, sandbox: true, no funds move. Live = API key + a signing path. Pick ONE mode:
- Mode A —
Q402_PRIVATE_KEY= your MetaMask EOA. Shows “Smart account” in MetaMask after first use (reversible viaq402_clear_delegation). - Mode B —
Q402_AGENTIC_PRIVATE_KEY= exported Agent Wallet PK. Local signing; MetaMask untouched. - Mode C — paid Multichain key only. Q402 holds the AES-GCM-encrypted Agent Wallet key server-side.
# ~/.q402/mcp.env — what q402_doctor creates on first install.
# Paste your values on the right of `=`. Q402_ENABLE_REAL_PAYMENTS
# already defaults to 1 — the gate refuses empty values, so partial
# setups stay in sandbox automatically.
# ── API key (pick one or both for auto-routing) ──
Q402_TRIAL_API_KEY= # Free Trial, BNB Chain + Base (from /event)
Q402_MULTICHAIN_API_KEY= # Paid Multichain, all 12 chains (from /payment)
# ── Signing path — pick ONE of Mode A / B / C ──
# Mode A: your MetaMask EOA's hex private key
Q402_PRIVATE_KEY=
# Mode B: exported Agent Wallet pk from dashboard (keeps MetaMask untouched)
Q402_AGENTIC_PRIVATE_KEY=
# Mode C: no PK needed. Paid Multichain key alone + server-managed Agent Wallet.
# Optional picker when you have multiple wallets:
# Q402_AGENT_WALLET_ADDRESS=0x...
# Live mode switch:
# 0 = sandbox (test mode, no funds move)
# 1 = real on-chain payments
# Default 1 — safe because mode only flips to live when an API key AND
# at least one valid signing path (A/B/C) are populated above.
Q402_ENABLE_REAL_PAYMENTS=1
# Default Q402 deployment. Only change for self-hosted.
Q402_RELAY_BASE_URL=https://q402.quackai.ai/apiq402_pay requires explicit in-chat confirmation. Four guards total: confirm + sandbox default + per-call cap + allowlist.Trust Receipt
A verifiable proof page for every Q402 settlement — signed by the relayer EOA, recoverable in any browser.
What's on a receipt
- Settlement facts — payer, recipient, amount, chain, EIP method.
- On-chain proof — tx hash, block, sponsored gas, explorer link.
- Signature — EIP-191 ECDSA over the canonical hash, recoverable locally in your browser.
- Delivery trace — webhook state, retry count, last response code.
Receipt URL
/api/relay responses include receiptId + receiptUrl:
{
"success": true,
"txHash": "0x9afd...52a4",
"tokenAmount": "0.10",
"token": "USDT",
"chain": "bnb",
"receiptId": "rct_afa5f50bc49a65ebba3b28ab",
"receiptUrl": "https://q402.quackai.ai/receipt/rct_afa5f50bc49a65ebba3b28ab"
}Mirrored in the webhook payload — no second lookup needed.
JSON endpoint
curl https://q402.quackai.ai/api/receipt/rct_afa5f50bc49a65ebba3b28abRate limited 120/min per IP. The id is unguessable (12 random bytes) — the URL doubles as a shareable audit link.
Verify any receipt from Claude
The @quackai/q402-mcp server (v0.11.15) exposes a q402_receipt tool:
> Send 0.10 USDT to alice on BNB via Q402, then verify the receipt.
Claude → q402_pay → settles + returns rct_afa5...
Claude → q402_receipt → verified: true · signed by 0xfc77...74ff466Live demo
q402.quackai.ai/receipt/rct_afa5f50bc49a65ebba3b28ab ↗
Gas Pool
Deposit native tokens into your per-wallet Gas Tank. Every relay deducts the actual gas cost.
Send BNB / ETH / AVAX / OKB / MNT / INJ / MON (or USDT0 on Stable) to the Gas Tank address on the dashboard. The Tank is a cold wallet, NOT the relayer — never send to the relayer directly.
Per-relay native-token deduction, real-time balance.
Manual via business@quackai.ai. Funds remain yours.
EIP-7702 Delegation
EIP-7702 set-code delegation (Pectra) lets your EOA settle gasless payments without a per-user smart-account deploy. Persists across payments, reversible anytime.
Inspect or clear
From your AI client (MCP) — ask in plain English:
"Show my Q402 wallet status."
"Clear my Q402 delegation on BNB Chain."q402_wallet_status reads state. q402_clear_delegation signs locally (Mode A/B) or server-side (Mode C, api key); Q402 sponsors the clear TX on every chain except Ethereum, where it's billed to your Gas Tank. The next payment recreates the delegation automatically.
From the terminal (CLI):
PRIVATE_KEY=0x<yourKey> node scripts/undelegate-7702.mjs --chain bnbAll 12 chains, self-paid (~$0.001 native gas).
Why we use it
One primitive, 12 chains, no per-user contract deploy. Each chain's impl is source-verified on Sourcify. The delegation marker is the only on-chain trace.
▸Troubleshooting (things to know)
- • Your wallet's eth_getCode returns 0xef0100…<impl> instead of 0x while the delegation is active.
- • MetaMask / OKX may display a Smart account indicator — the delegation is to Q402's vetted impl, not a third-party contract.
- • Native gas tokens (BNB / ETH / etc.) sent directly to a delegated EOA will not land — the impl doesn't accept native receives. Clear the delegation first if you want to receive native to that EOA.
Authentication
API key goes in the request body's apiKey field. Sandbox keys (q402_test_*) on wallet connect. Live keys (q402_live_*) from /event (Trial, BNB + Base) or /payment (Multichain, 12 chains).
// POST /api/relay
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "avax",
"token": "USDC",
...
}Agent Trust Check
A pay-per-query x402 endpoint that returns verifiable trust data for any EVM address or ERC-8004 agent. Pay $0.02 USDC on Base per call via the x402 standard (exact scheme, EIP-3009). No API key required.
X402_PAYTO_ADDRESS. Only buckets (never raw counts, amounts, or counterparty addresses) are returned. Zero PII.Price: 0.02 USDC
Network: eip155:8453 (Base mainnet)
Cache: 60 s per address
Step 1 — Receive 402 Challenge
// GET /api/x402/agent-trust/0xYourAddress (no payment header)
// Response: HTTP 402
{
"x402Version": 1,
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6,
"amount": "20000",
"maxAmountRequired": "20000",
"payTo": "0x<X402_PAYTO_ADDRESS>",
"maxTimeoutSeconds": 300
}]
}Step 2 — Sign EIP-3009 & Replay
curl https://q402.quackai.ai/api/x402/agent-trust/0xAddress \
-H "X-PAYMENT: <base64-x402-payload>"Response 200
{
"address": "0x...",
"erc8004": {
"isRegistered": true,
"registrations": [{
"network": "bsc",
"agentId": "1234",
"agentUriDomain": "q402.quackai.ai",
"source": "ERC-8004 IdentityRegistry on bsc (0x8004A1...)"
}]
},
"reputation": {
"feedbackCount": 5,
"summaryValue": "500",
"source": "ERC-8004 ReputationRegistry on BSC"
},
"onChainActivity": {
"txCountBucket": "10-49",
"recentActivityDetected": true,
"source": "Base mainnet eth_getTransactionCount"
},
"q402Wallet": {
"settlementCountBucket": "5-9",
"hasVerifiableTrustReceipts": true,
"source": "Q402 relay history, past 12 months"
},
"receipt": "atx_<hex>",
"paidAt": "2026-08-07T12:00:00.000Z",
"priceUsdc": 0.02
}Agent Trust — Additional Tiers
Higher-value tiers with richer data and access controls.
Deep Report: risk flags, change indicators (ERC-8004, reputation, on-chain activity)
Monitoring: per-check ERC-8004, reputation, activity
API Reference
Base URL: https://q402.quackai.ai/api
Submit a signed EIP-712 + EIP-7702 payload. Q402 verifies and relays on-chain.
// Request body
{
"apiKey": "q402_live_YOUR_API_KEY",
"chain": "avax", // avax | bnb | eth | xlayer | stable | mantle | injective | monad | scroll | arbitrum | base | robinhood
"token": "USDC", // USDC | USDT
"from": "0xUserWallet...",
"to": "0xRecipient...",
"amount": "50000000", // atomic units (6 decimals = 50 USDC)
"deadline": 1751289600,
"witnessSig": "0xabc123...",
"authorization": { ... } // EIP-7702 authorization object
}
// Response 200
{
"success": true,
"txHash": "0xdef456...",
"chain": "avax",
"blockNumber": "54540550",
"tokenAmount": "50",
"gasCostNative": "0.000021",
"method": "eip7702"
}Returns the relayer (facilitator) address. The facilitator field in your EIP-712 payload must match.
// GET /api/relay/info
{ "facilitator": "0xRelayerAddress..." }Chain Support
Same API, same SDK. Switch with one parameter. All 12 chains are mainnet live.
| Chain | chain param | Chain ID | Gas token | Status | Avg gas/tx |
|---|---|---|---|---|---|
BNB Chain | bnb | 56 | BNB | Mainnet Live | ~$0.001 |
Ethereum | eth | 1 | ETH | Mainnet Live | ~$0.19 |
Avalanche | avax | 43114 | AVAX | Mainnet Live | ~$0.002 |
X Layer | xlayer | 196 | OKB | Mainnet Live | ~$0.001 |
Stable | stable | 988 | USDT0 ★ | Mainnet Live | ~$0.001 |
Mantle | mantle | 5000 | MNT | Mainnet Live | ~$0.001 |
Injective | injective | 1776 | INJ | Mainnet Live | ~$0.10 |
Monad | monad | 143 | MON | Mainnet Live | ~$0.001 |
Scroll | scroll | 534352 | ETH | Mainnet Live | ~$0.001 |
Arbitrum | arbitrum | 42161 | ETH | Mainnet Live | ~$0.001 |
Base | base | 8453 | ETH | Mainnet Live | ~$0.001 |
Robinhood Chain | robinhood | 4663 | ETH | Mainnet Live | ~$0.001 |
EIP-712 Signing
EIP-712 typed structured data (same standard as Uniswap, Compound). User signs a human-readable message — no gas, no on-chain TX.
Contract Addresses & Domain Names
// Implementation contract per chain
const CONTRACTS = {
avax: "0x96a8C74d95A35D0c14Ec60364c78ba6De99E9A4c", // Q402 Avalanche (chainId: 43114)
bnb: "0x6cF4aD62C208b6494a55a1494D497713ba013dFa", // Q402 BNB Chain (chainId: 56)
eth: "0x8E67a64989CFcb0C40556b13ea302709CCFD6AaD", // Q402 Ethereum (chainId: 1)
xlayer: "0x8D854436ab0426F5BC6Cc70865C90576AD523E73", // Q402 X Layer (chainId: 196)
stable: "0x2fb2B2D110b6c5664e701666B3741240242bf350", // Q402 Stable (chainId: 988)
mantle: "0xE5b90D564650bdcE7C2Bb4344F777f6582e05699", // Q402 Mantle (chainId: 5000)
injective: "0xa9a7dcE76DEF2AC36057FeF0d8103dF10581d61e", // Q402 Injective (chainId: 1776)
monad: "0xc5d4dFA6D2e545409C1abf86f336Dd43bb87621f", // Q402 Monad (chainId: 143)
scroll: "0x7635F32D893B64b5944CB8cbF2AC4cd3dA41B2f1", // Q402 Scroll (chainId: 534352)
arbitrum: "0x8D854436ab0426F5BC6Cc70865C90576AD523E73", // Q402 Arbitrum (chainId: 42161)
base: "0x2fb2B2D110b6c5664e701666B3741240242bf350", // Q402 Base (chainId: 8453)
robinhood: "0x2fb2B2D110b6c5664e701666B3741240242bf350", // Q402 Robinhood Chain (chainId: 4663)
};
// verifyingContract is ALWAYS the user's own EOA — same for all chains under EIP-7702.Witness Type (unified across all chains)
const types = {
TransferAuthorization: [
{ name: "owner", type: "address" }, // token sender (user's EOA)
{ name: "facilitator", type: "address" }, // gas sponsor (Q402 relayer)
{ name: "token", type: "address" }, // ERC-20 contract (USDC / USDT / USDT0)
{ name: "recipient", type: "address" }, // payment destination
{ name: "amount", type: "uint256" }, // atomic units
{ name: "nonce", type: "uint256" }, // random uint256, replay protection
{ name: "deadline", type: "uint256" }, // unix timestamp
],
};Signing with ethers.js
const { facilitator } = await fetch("https://q402.quackai.ai/api/relay/info").then(r => r.json());
const domain = {
name: DOMAIN_NAMES[chain],
version: "1",
chainId: chainId,
verifyingContract: userAddress, // user's own EOA — same for all chains under EIP-7702
};
const nonce = ethers.toBigInt(ethers.randomBytes(32)); // random uint256
const signature = await signer.signTypedData(domain, types, {
owner: userAddress,
facilitator,
token: tokenAddress,
recipient: recipientAddress,
amount: ethers.parseUnits("50", decimals),
nonce,
deadline: BigInt(Math.floor(Date.now() / 1000) + 600),
});eip3009Nonce instead of authorization).ethers.parseUnits(amount, 18). Gas Tank also in USDT0. (Mantle USDT0 = 6 decimals.)Error Responses
JSON body: { "error": string, "code"?: string }. error is human-readable; code is a stable machine-readable tag (when present).
Codes below are the currently-emitted set; most failures return only error.
Governance Analysis
Paid API that reads a full DAO proposal and returns a structured voting recommendation with reasons. Pay $0.05 USDC on Base per call via the x402 standard (exact scheme). No API key required.
Price: 0.05 USDC per call (atomic 50000, 6 decimals) on Base mainnet (eip155:8453), settled via the CDP x402 facilitator.
Input: either dao + proposalId (any Snapshot proposal ID) or raw Proposal_Content text, plus four weight fields (0 to 100) or a customPrompt persona.
Cache: repeated calls for the same proposal and weights are served from cache (cached: true); the fee still applies on every call.
Works with any Snapshot space; DAOs without text proposals (e.g. gauge-vote-only systems like Aerodrome) are not supported.
Output is an analysis, not financial or voting advice; the vote is always yours (or your agent's).
Note: before sending native tokens to a wallet that has an active EIP-7702 delegation, clear the delegation first (see EIP-7702 Delegation section).
FAQ
Q1Do users need BNB, ETH, or AVAX to use Q402?+
No. Users only need USDC (or USDT) in their wallet. All gas is paid from your gas pool. The user signs a message — that's it.
Q2Who pays gas?+
You — from your per-chain Gas Tank. Withdrawals are manual via business@quackai.ai.
Q3Does Q402 hold my keys?+
Your personal wallet is non-custodial — you connect it (MetaMask / OKX) and Q402 never holds its key; the EIP-712 signature authorizes one transfer A→C, so Q402 only pays gas and relays and cannot redirect funds. Agent Wallets (Mode C) are managed: Q402 custodies an AES-256-GCM-encrypted key you can export or archive anytime.
Q4What if a transaction fails?+
Failed relays discard the payload — no funds move. Common causes: empty Gas Tank or expired deadline.
Q5Which tokens are supported?+
USDC + USDT on most chains (Injective added native Circle USDC via CCTP). RLUSD on Ethereum only (18 decimals, NY DFS regulated). USDG on Robinhood Chain only (Paxos Global Dollar, 6 decimals).
Q6How do I get an API key?+
Connect a wallet → sandbox key (q402_test_*). For a live key: /event (Trial, BNB Chain + Base, 500 TX free) or /payment (Multichain, 12 chains).
Q7How does billing work?+
Each paid purchase = 30-day window + TX credits for the tier. Top up within the window to upgrade. Plans never downgrade mid-window; cumulative resets on lapse.
Ready to go gasless?
Get a live API key on payment. Sandbox key is free to test first.