AI Payments

    Beyond the Wallet: A Builder's Guide to Policy-Controlled Agent Payments with x402

    10 min read
    Aggelos Kappos(Founder @ QBT Labs)
    x402AI AgentsAgent PaymentsMCPStablecoinsAPI MonetizationPayment Infrastructure
    Beyond the Wallet: A Builder's Guide to Policy-Controlled Agent Payments with x402
    Share:

    A practical post for engineers shipping AI agents that need to spend money on paid APIs, MCP tools, and execution venues.

    Wallets are easy. Policy is the real product.

    If you have spent any time wiring an LLM up to a paid API, you have already discovered the boring truth: giving an agent a wallet is the easy part. The hard part is everything that surrounds the signature.

    What can the agent buy? From whom? How often? Under what budget? What happens at 2 a.m. when a tool starts charging ten times more than it did yesterday and the agent dutifully keeps paying? Who signs off on the seventh consecutive call to a paid analytics endpoint?

    These are not edge cases. They are the core of any production agent that touches money.

    Most agent payment demos show a 402 challenge, a signed payload, a happy 200, and then leave you to figure out the policy layer yourself.

    This post is about that policy layer, the open x402 protocol it sits on top of, and the specific pieces QBT Labs ships in @qbtlabs/x402 today.

    The x402 protocol, briefly

    x402 reuses the long-dormant HTTP 402 Payment Required status code to negotiate per-request payments between a client and a server.

    The current shape is simple:

    1. Client makes a normal HTTP request.
    2. Server responds 402 Payment Required and includes payment terms in a PAYMENT-REQUIRED header: chain, asset, amount, recipient, expiry, and a token the client must echo back.
    3. Client signs an authorization for that exact payment and retries the same request with a PAYMENT-SIGNATURE header.
    4. Server, optionally via a facilitator, verifies and settles the payment, then returns the resource. It may include a PAYMENT-RESPONSE header with settlement metadata such as a transaction hash.

    That is the whole wire protocol. There is no new RPC, no new stack, no new transport. Any client that already speaks fetch and any server that already speaks Express, Hono, or an MCP framework can opt into it.

    The interesting design decisions are not in the protocol. They are in everything the protocol assumes you will build yourself.

    The policy engine problem

    A naive x402 client looks like this:

    If you get a 402, sign the payment and retry.

    That works exactly once — for a demo.

    Then real life happens:

    • A buggy agent loops on a 402 and drains its wallet in seconds.
    • A malicious or compromised tool starts asking for ADA on Cardano when the agent expected USDC on Base.
    • A normally cheap endpoint suddenly demands 100x its usual price.
    • The agent silently spends $300 on a tool the user never approved.
    • An audit asks “what did we pay for last Tuesday?” and you have nothing.

    The fix is not a bigger wallet.

    The fix is a policy layer between the agent and the signer that answers four questions before any signature is produced:

    • Who is being paid? Recipient allowlists.
    • What are we paying with? Chain and asset allowlists.
    • How much? Per-call, per-session, and per-day caps.
    • What just happened? Durable audit logs and receipts.

    Once that layer exists, the wallet itself can be boring.

    Boring is exactly what you want from a wallet.

    Why financial agents make this urgent

    Most agent-payment demos use one paid API, one tool, and one chain.

    That is not the load profile that breaks things.

    Market-making, trading, and research agents are a better stress test, because a single decision may fan out across many paid services:

    • Market data APIs: price feeds, orderbook snapshots, on-chain data.
    • Execution venues: CEX REST endpoints, DEX routers, RFQ desks.
    • Routing and aggregation engines.
    • Risk and pre-trade checks.
    • Analytics and signal services.
    • Post-trade reporting and compliance.

    A single “should I rebalance this pair?” prompt can easily touch ten paid endpoints in a few seconds.

    At that fan-out, per-call payment without policy is not a feature. It is a liability.

    Per-request authorization, session-level budgets, and signed receipts move from nice-to-have to the only reason this is safe to run unattended.

    This is the world @qbtlabs/x402 is built for.

    What @qbtlabs/x402 ships today

    The current package is @qbtlabs/x402. The usable pieces break down into five areas.

    Client side

    • createPaymentFetch — a fetch-compatible wrapper that handles 402 challenges and retries automatically.
    • createClientProxy — a local HTTP proxy so existing clients, including LLM agents that only know how to call URLs, can transparently pay for upstream calls.
    • createPassthroughProxy — a non-paying variant for routing and observability when you want to inspect traffic without enabling payment.

    Server side

    • withX402Server — middleware that gates routes behind x402 payment requirements.
    • MCP middleware that lets MCP tool servers price individual tools.
    • Four tool pricing tiers out of the box: free, read, analysis, write.

    That lets a server declare “discovery is free, reads cost a little, analysis costs more, writes cost the most” without inventing a pricing schema.

    Security

    • An encrypted on-disk vault at ~/.x402/vault.enc so private keys are not sitting in environment variables or shell history.
    • An isolated signer process, x402-signer, so the agent never holds the key.
    • A policy engine with spend caps, chain and recipient allowlists, and queryable audit/spending history.

    The agent asks the signer to sign. The signer applies policy first.

    Chains

    • Base and other EVM chains via USDC and EIP-3009 transferWithAuthorization.
    • Solana via USDC and the partially signed transaction / facilitator pattern.
    • Cardano via Lucid-signed transactions covering ADA, iUSD, USDM, DJED, and USDCx.

    CLIs

    • x402-proxy — run the local payment proxy.
    • x402-vault — initialize, unlock, and rotate the encrypted vault.
    • x402-signer — run the isolated signer process.
    • x402-policy — author and inspect policy rules.

    Everything above is in the package today.

    Anything not on this list — including high-frequency payment-channel layers — is a direction, not a current product.

    A minimal end-to-end example

    Server side, a price feed that charges per call:

    import express from "express";
    import { withX402Server } from "@qbtlabs/x402";
    
    const app = express();
    
    app.use(
      withX402Server({
        chain: "base",
        asset: "USDC",
        recipient: process.env.QBT_RECEIVE_ADDRESS!,
        pricing: {
          "/price/:symbol": { tier: "read", amount: "0.001" },
          "/analytics/:symbol": { tier: "analysis", amount: "0.05" },
        },
      }),
    );
    
    app.get("/price/:symbol", (req, res) => {
      res.json({ symbol: req.params.symbol, price: 1.2345 });
    });
    
    app.listen(8080);
    

    Client side, an agent that pays automatically — but only within policy:

    import { createPaymentFetch } from "@qbtlabs/x402";
    
    const pay = createPaymentFetch({
      signer: { transport: "ipc", endpoint: "/tmp/x402-signer.sock" },
      policy: {
        allowedChains: ["base"],
        allowedAssets: ["USDC"],
        allowedRecipients: [process.env.QBT_RECEIVE_ADDRESS!],
        perCallMax: "0.10",
        perSessionMax: "5.00",
        perDayMax: "25.00",
      },
    });
    
    const res = await pay("https://feed.example.com/price/SOL-USDC");
    const data = await res.json();
    

    The agent never sees the private key.

    The signer never signs without consulting the policy.

    The vault never decrypts unless x402-vault unlock has been run by a human or another tightly scoped operator.

    Three concerns. Three processes. One boring fetch call from the agent’s perspective.

    What happens on a paid request

    A production payment flow should look like this:

    1. Agent calls a paid API or MCP tool.
    2. Server returns 402 Payment Required with quote and terms.
    3. Client validates the quote against local policy.
    4. Signer checks budgets, allowlists, limits, and recent spend.
    5. Signer produces a scoped authorization for that exact request.
    6. Client retries with the payment signature.
    7. Server verifies, settles, returns the resource, and emits a receipt.

    Step 3 and step 4 are the ones most stacks skip.

    They are also the steps that determine whether your agent is safe to leave running.

    A note on AMP and high-frequency flows

    Per-request settlement is fine for one or two paid calls.

    It starts to feel heavy when an agent is making hundreds of small calls per minute against the same provider.

    The natural answer is a payment-channel-style layer that batches or nets payments while preserving per-request authorization semantics.

    At QBT Labs, this is the direction we think production x402 tooling needs for high-frequency flows — something AMP-shaped — but it is not in the current @qbtlabs/x402 package.

    Today the package focuses on practical MCP and API payments:

    • client proxy
    • server middleware
    • encrypted vault
    • isolated signer
    • policy engine
    • multi-chain support

    If your workload is high-frequency enough that per-call settlement is a bottleneck, talk to us before you build around the current shape.

    Start with policy, not the wallet

    If you are building agents that need to call paid APIs, do not start with the wallet.

    Start with the policy layer:

    • What can the agent buy?
    • From whom?
    • How often?
    • Under what budget?
    • How would you prove, after the fact, that it stayed inside those rules?

    Once you have answers, the wallet is a much smaller problem.

    If you would rather not implement that layer yourself, @qbtlabs/x402 is open source, MIT licensed, multi-chain, and shipped.

    We are using it ourselves for the same financial-agent workloads described above.

    If you are working on something similar, we would like to hear what your policy looks like.

    Get started

    Related Articles