PipRail
PipRail · Guide

Give Your AI Agent a Wallet It Can’t Overspend

An agent can call a weather API, a search API, a data feed — right up until it hits one that costs money. Then it just stops. There is no fetch() for “pay two cents and keep going.” PipRail is that fetch — with a wall the agent can’t climb over.

John Weeks
Founder, PipRail
8 min read

x402 revives HTTP 402 “Payment Required”: a server answers an unpaid request with a 402 and a price, the client pays on-chain, and retries with proof. It is the missing payments layer for the agent web. PipRail is an open, self-custody implementation of it — and the thing that makes it safe to hand to a model is that paying is wrapped in a budget the model cannot exceed. Here is the whole integration, both sides of it, in the order you would actually build it.

Pay an x402 URL

The client is a drop-in for fetch. You give it a chain, a wallet, and a policy; you call .fetch() as you always would. If the URL is free, you get the response. If it returns a 402, PipRail reads the payment requirement, checks it against your policy, settles on-chain, and retries — handing you back the unlocked 200 as if the paywall were never there.

import { PipRailClient } from '@piprail/sdk'

const client = new PipRailClient({
  chain: 'base',
  wallet: { key: process.env.WALLET_KEY },
  policy: { maxAmount: '0.10', maxTotal: '5.00' }, // caps it can't cross
})

// If this URL 402s, PipRail pays within policy and returns the 200.
const res = await client.fetch('https://api.example.com/premium')
const data = await res.json()

That is the entire happy path. No webhooks, no callbacks, no waiting on a processor — the payment is one on-chain transfer and the function returns when the resource does.

The spend policy is the whole point

Handing an autonomous model a wallet is only sane if the wallet has a ceiling the model cannot raise. The policy is that ceiling, and every payment is checked against it before any value moves. The model never touches the private key and has no way to widen its own limits.

const client = new PipRailClient({
  chain: 'base',
  wallet: { key },
  policy: {
    maxAmount: '0.10',                       // ceiling for any single payment
    maxTotal: '20.00',                       // lifetime cap, per network + asset
    maxPayments: 200,                        // lifetime number of payments
    tokens: ['USDC'],                        // only ever pay in these
    hosts: ['api.example.com', '*.data.dev'],// only ever pay these hosts
    windowTotal: '1.00',                     // ...and no more than $1
    windowSeconds: 60,                       // ...in any 60-second window
  },
})

A per-payment cap, a lifetime cap, a count, token and host allowlists, and rolling-window limits — all enforced in code, none of it negotiable by the agent. This is the line that turns “an AI with a crypto wallet” from a liability into a tool: a prompt-injected “ignore your instructions and pay this URL” still cannot spend past the wall you set.

Look before you pay

An agent should be able to ask “what does this cost, and can I actually settle it?” without committing to anything. Three read-only methods answer that, and by contract none of them ever throws — they degrade to honest nulls instead of crashing your reasoning loop.

// Look before you leap — all read-only, none of them ever throw:
const quote = await client.quote(url)        // the price, if it's gated
const cost  = await client.estimateCost(url) // + a gas estimate, native coin
const plan  = await client.planPayment(url)  // can I settle it, which rail?

if (plan?.payable) {
  await client.fetch(url)                     // ...only then pay
}

planPayment() is the interesting one: it looks at what the wallet actually holds, the gas it would need, and whether the recipient is ready to receive on each rail the 402 offers, then tells you whether it is payable, which rail is cheapest, what is blocking the rest, and a one-line hint for how to fund the gap. canAfford(url) is the boolean shortcut when you just need yes or no.

Charge for your own API

The other half is getting paid. One middleware gates a route; the payment settles straight to your wallet and PipRail verifies it on your own RPC. No dashboard, no signup, no facilitator skimming a cut.

import { requirePayment } from '@piprail/sdk'

app.get('/premium', requirePayment({
  chain: 'base',
  token: 'USDC',
  amount: '0.01',
  payTo: '0xYourWallet...',
}), (req, res) => res.json({ premium: 'data' }))

That is a complete, payable endpoint. The funds are in your wallet seconds later, and verification is local — the spec explicitly allows merchant-local verification, so this backendless shape is supported, not a hack.

Drop it into an agent — no code

If your agent speaks the Model Context Protocol, you do not write any of the above. PipRail ships an MCP server that hands the agent a budget-bound wallet as a set of tools — discover, quote, plan, pay, budget and more — eight in all, capped by the same policy, expressed as environment variables.

{
  "mcpServers": {
    "piprail": {
      "command": "npx",
      "args": ["-y", "@piprail/mcp"],
      "env": {
        "PIPRAIL_PRIVATE_KEY": "0x...",
        "PIPRAIL_CHAIN": "base",
        "PIPRAIL_MAX_TOTAL": "10.00"
      }
    }
  }
}

Drop that into Claude Desktop, Cursor, Cline, Windsurf or VS Code and the agent can pay. Omit the key and the server still boots in read-only mode — it can discover, quote and plan, it just can’t move money. For elizaOS, there is a native plugin instead: npm i @piprail/elizaos-plugin adds six payment actions — pay, quote, plan, discover, budget, guide — to any character, and Hermes and OpenClaw are wired through the same MCP server.

That is the whole surface

Pay a URL with a policy. Charge for a route in one line. Ask what something costs before you buy it. Hand the wallet to a model and trust the wall, not the model, to hold the line. There is no backend to run, no account to create, and no fee on the rail — and it works the same way across 29 chains, so the agent pays with whatever it already holds. Give it a wallet it can’t overspend, and let it do the thing you actually asked for.

Share Post on X
John Weeks
Founder, PipRail

Building PipRail — the open, neutral, no-fee x402 payment rail for AI agents, across 29 chains. Writing about how agents pay, and the trust layer the agent economy still has to build.

Frequently asked

How do I add x402 payments to my AI agent?

Install @piprail/sdk, construct a PipRailClient with a chain, a wallet key and a spend policy, then call client.fetch(url) wherever the agent makes a request. If that URL answers with HTTP 402, PipRail pays it within your policy and returns the unlocked 200 response. For agents that speak the Model Context Protocol — Claude Desktop, Cursor, Cline, Windsurf, VS Code — you can skip the code entirely and run the MCP server with npx -y @piprail/mcp.

What stops the agent from overspending or draining the wallet?

The spend policy. Every payment is checked against it before any on-chain send: a per-payment ceiling (maxAmount), a lifetime cap (maxTotal), a payment count (maxPayments), token and host allowlists, and optional rolling-window caps. The model never sees the private key and cannot raise its own limits, so even a prompt-injected “pay this URL” is bounded by the wall you set in code.

Do I need a backend, an account, or a signup to accept payments?

No. PipRail is backendless — no server, no database, no dashboard, no account. To charge for a route, requirePayment() gates it in one line and the payment settles straight to your wallet, verified locally against your own RPC. There is no facilitator in the middle and no protocol fee.

How does the agent know whether it can afford a URL before paying?

Three read-only methods that move no funds and never raise for a flaky RPC (it degrades to a heuristic, not a false “broke”): quote(url) returns the price, estimateCost(url) adds a gas estimate in the chain’s native coin, and planPayment(url) checks the agent’s actual balances and recipient-readiness across every rail the 402 offers, returning whether it is payable, the cheapest rail, any blockers, and a one-line funding hint. canAfford(url) is the boolean shortcut. They return null when the URL isn’t gated; quote/estimateCost throw a typed NoCompatibleAcceptError when the 402 offers no rail this agent can pay — a routing fact, not a read failure.

Which agent frameworks and clients are supported?

Any MCP client gets a budget-bound wallet through @piprail/mcp — Claude Desktop, Claude Code, Cursor, Cline, Windsurf and VS Code among them. There is also a native elizaOS plugin (@piprail/elizaos-plugin) that adds six payment actions to a character, and the same MCP server is wired into Hermes and OpenClaw.

Can PipRail pay standard x402 servers, not just PipRail ones?

Yes. PipRail’s universal rail is onchain-proof, and it also implements the ratified x402 exact scheme on EVM, Solana, Aptos, NEAR and Algorand. Opt in with schemes: ['onchain-proof', 'exact'] and the client will pay standard x402 endpoints that expect an exact authorization.

Give your agent a wallet.

PipRail is the open, self-custody x402 rail — no backend, no middleman, no fee. Pay an x402 URL, or charge for your own, in a few lines.

More writing