Agent Developer Guide
This guide explains how to build an agent that pays x402-protected resources automatically.
Prerequisites
Section titled “Prerequisites”- A Quantoz account with an API key and funded managed account → Sign up
npm install x402-quantoz-euro→ npmjs.com/package/x402-quantoz-euro- For EVM payments: an EVM private key holding EURQ/USDQ, and
vieminstalled (optional peer dependency)
The easy path — withEurPayment()
Section titled “The easy path — withEurPayment()”The withEurPayment() wrapper detects the schemes offered in the 402 response and pays with the first one it can satisfy.
import { withEurPayment } from "x402-quantoz-euro";
const fetch = withEurPayment(globalThis.fetch, { apiKey: process.env.QUANTOZ_API_KEY, fromAccount: process.env.QUANTOZ_ACCOUNT, // Only needed for EVM (eip155:*) payments: evm: { privateKey: process.env.EVM_PRIVATE_KEY },});
// Works for the euro scheme and EVM permit paymentsconst res = await fetch("https://merchant.example.com/premium-resource");What it does per scheme:
| Scheme in 402 | What withEurPayment() does |
|---|---|
euro | Pays via Quantoz API, builds proof with paymentRequestCode |
exact + eip155:1 / eip155:137 | Signs an EIP-2612 permit for the facilitator spender, builds proof with the permit signature |
Paying the Algorand exact scheme is not part of the package — it requires an Algorand wallet signing its own transactions (manual recipe below). Note that EURO and the on-chain tokens are separate rails: a EURO account cannot pay a blockchain address.
Spending guardrail: the onBeforePayment hook lets you approve or reject each payment before it happens. Today it fires on the euro path; treat your account balance (and, once available, your agentic key’s daily limit) as the hard protection.
How the payment works per scheme
Section titled “How the payment works per scheme”euro scheme (off-chain)
Section titled “euro scheme (off-chain)”The 402 response contains a paymentRequestCode. The agent pays it via the Quantoz API:
1. Hit resource → 402 with { scheme: "euro", paymentRequestCode: "pr_...", amount: "0.10" }
2. POST /transaction/payment { toType: "PaymentRequestCode", paymentTo: "pr_...", amount: 0.10 }
3. Build X-PAYMENT proof: { "x402Version": 2, "scheme": "euro", "network": "quantoz:mainnet", "payload": { "paymentRequestCode": "pr_..." } }
4. base64url-encode → X-PAYMENT header → retryexact scheme on Algorand — direct on-chain (manual)
Section titled “exact scheme on Algorand — direct on-chain (manual)”If your agent holds EURQ/USDQ directly in a whitelisted Algorand wallet, sign the transfer yourself (e.g. with algosdk or Algorand MCP tools). Amounts are atomic — EURQ/USDQ have 6 decimals, so €0.50 = 500000:
1. Hit resource → 402 with { scheme: "exact", network: "algorand:mainnet", asset: "2768422954", maxAmountRequired: "500000" }
2. make_asset_transfer_txn (EURQ ASA 2768422954, amount in atomic units, to merchant payTo) wallet_sign_transaction
3. Build X-PAYMENT proof: { "x402Version": 2, "scheme": "exact", "network": "algorand:mainnet", "payload": { "transaction": "<base64 signed txn>", "paymentIndex": 0 } }
4. base64url-encode → X-PAYMENT header → retryThe facilitator sponsors the network fee when settling grouped transactions, so the wallet needs no ALGO beyond the minimum balance.
exact scheme on Ethereum / Polygon — EIP-2612 permit
Section titled “exact scheme on Ethereum / Polygon — EIP-2612 permit”EURQ/USDQ on EVM chains implement permit. The agent signs a typed-data permit authorizing the facilitator (the extra.spender from the 402) to pull the amount; the facilitator submits it on-chain and pays the gas. The agent’s wallet needs tokens but no ETH/POL.
1. Hit resource → 402 with { scheme: "exact", network: "eip155:137", asset: "0xd571...3db3", maxAmountRequired: "500000", extra: { spender: "0xFACILITATOR" } }
2. Read nonces(owner) from the token contract; sign EIP-712 permit { owner, spender: extra.spender, value: maxAmountRequired, nonce, deadline } (domain: name from contract, version "1", chainId, verifyingContract)
3. Build X-PAYMENT proof: { "x402Version": 2, "scheme": "exact", "network": "eip155:137", "payload": { "owner": "0x...", "permit": { ...values }, "signature": "0x..." } }
4. base64url-encode → X-PAYMENT header → retry (the merchant's settle call executes permit + transferFrom on-chain)withEurPayment() implements this when configured with evm: { privateKey } (requires the optional viem peer dependency; custom RPC endpoints via evm.rpcUrls).
Using the MCP pay_x402_challenge tool
Section titled “Using the MCP pay_x402_challenge tool”For agents using the Quantoz MCP server directly (e.g. Claude with the connector), the pay_x402_challenge tool handles the pay-and-proof flow in one step for the euro scheme:
Tool: pay_x402_challengeArguments: challenge: <paste the full 402 response body> paymentFrom: <your account code>Returns:
{ "xPaymentHeader": "<base64url proof>", "amount": "0.10", "instruction": "Retry your request with the header: X-PAYMENT: <proof>"}The tool requires a euro entry in the 402’s accepts. For on-chain schemes, use withEurPayment() in your own code instead.
System prompt snippet
Section titled “System prompt snippet”When you receive an HTTP 402 response, call the pay_x402_challenge MCP toolwith the full 402 response body and your account code. Then retry the originalrequest with the X-PAYMENT header value it returns.Error handling
Section titled “Error handling”| Response | Meaning |
|---|---|
{ valid: false, reason: "Payment not confirmed (status: Open)" } | Payment not yet processed — wait briefly and retry verify |
{ valid: false, reason: "Payment request already used" } | Replay attempt — request a fresh 402 |
{ valid: false, reason: "Payment request expired" } | Timed out — request a fresh 402 and pay again |
402 on retry | Verification failed — check account balance |
Environment variables
Section titled “Environment variables”QUANTOZ_API_KEY=<your-api-key>QUANTOZ_ACCOUNT=<your-account-code> # e.g. ACC_xxxxxQUANTOZ_BASE_URL=https://api.quantozpay.comEVM_PRIVATE_KEY=<0x...> # only for eip155:* payments