How to let an AI agent pay without handing it your money
An AI agent that can pay per call is useful: it buys a price, a forecast or a check the moment it needs one. It is also an easy target. A web page, a tweet or a tool answer can tell it to pay someone else, and on 4 May 2026 a reply in Morse code on X got an agent to carry out a transfer. So the question isn't whether the agent may pay, but who holds the key, where the limits live, and who says yes.
Three designs, and what happens when the agent is fooled
| Design | Who holds the key | Where limits live | A fooled agent can… |
|---|---|---|---|
| Key in the agent | the agent's own environment | often only in the prompt | spend everything the key holds |
| Key at a provider | the wallet provider | the provider's policy engine | spend up to the policy, if the policy itself can't be changed by the agent |
| Owner keeps the key, agent asks | the owner's own wallet | a server the agent can't edit, before any signature | ask; the owner sees what and to whom before signing |
A limit written in a prompt is a suggestion: an injected instruction can talk the agent past it. A limit is only real when it is enforced in code, outside the model, before a signature exists. With a provider-held key, also ask how the policy is changed. If a reset link goes to an inbox the agent can read, the agent can change its own limits.
A checklist for any agent wallet
- Where is the key? In the agent, at a provider, or in your own wallet.
- Where are the limits enforced? In code before signing, per purchase and per day, for every agent together. Two agents mustn't both fit in the last of a budget.
- What happens above the limit? The agent should wait for you, on a channel you actually see (phone, Telegram, dashboard). No answer must mean no signature.
- What happens when the limit server is down? The agent must stop, not sign anyway.
- Is the payment checked before signing? The amount, the payee and the token against what the seller asked, and the payee against sanctions lists.
- Is the answer checked? Did the seller deliver what was paid for, and does the answer try to instruct the agent?
- Is there a receipt? What was bought, from whom, for how much, who approved it.
A real purchase: Grok buys a bitcoin price
On 30 October 2026 we gave Grok the Fizzl Agent Wallet's MCP connector and asked it to buy a bitcoin price as a customer would, with every step reported. This is the "owner keeps the key" design: the connector never pays by itself.
- Pick. Fizzl Buy's free pick suggested a seller with a clean payout record, at $0.001.
- Ask. Grok called
pay_x402. The wallet read the seller's price, checked the seller against the OFAC sanctions list and x402 Doctor's payout record, and returned a link for the owner. Nothing was signed yet. - Sign. The owner opened the link and signed one payment of exactly $0.001 in their own wallet.
- Answer. One second after the signature the seller's answer was back. The wallet checked it matched the request and contained no instructions for the agent, and Grok showed it.
The test also found two problems, both fixed the same day:
- A lost input. Grok passed the seller's example input as the body of a GET request, and the wallet dropped it. The seller would have been paid for a request without the input. The wallet now puts a GET's input in the URL. The pick now says where an example input goes.
- A scary but harmless alert. MetaMask showed "High-risk approval: the spender is untrusted EOA" for the payment. It does that for almost every x402 payment, because sellers are paid to plain wallets. The approval page now explains it. Why, and what to check instead.
How the Fizzl Agent Wallet does it
- No keys, no funds. The server holds neither. In the connector the owner signs each payment in their own wallet: USDC on Base from an Ethereum wallet, USDC on Solana from Phantom, or RLUSD on the XRP Ledger in Xaman.
- Agents that sign themselves (with presign-guard-wallet) ask the server "may I?" first: a maximum per purchase and a daily budget per token, one budget for all agents, an optional allow list. If the server can't be reached, the agent stops.
- Approvals above the limit on the dashboard, a phone notification or Telegram buttons; the agent waits up to 10 minutes, and no answer means no signature.
- Checks before and after: the seller's sanctions status and payout record before, the answer and any injected instructions after.
- Receipts for every signature: what, how much, to whom, who approved, the settlement and the answer.
How we checked
- The purchase: Grok with the Fizzl Agent Wallet's MCP connector, 30 October 2026, 0.001 USDC on Base; times from the wallet's own event log (signed 10:49:24 UTC, answer 10:49:25 UTC, answer check "delivered").
- The designs: how each one stores keys and enforces limits, as their own documentation describes it. We don't name other providers; the checklist applies to all of them, ours included.
Questions
Can an AI agent overspend if its limit is in the prompt?
Yes. A prompt is not an enforcement point: an injected instruction in a web page, tweet or tool answer can talk the agent past it. A limit is only real when code outside the model checks it before a signature exists.
What should happen when an agent wants to pay more than its limit?
It should wait for its owner's decision on a channel the owner sees, such as a phone notification or Telegram, and treat no answer as no. The Fizzl Agent Wallet waits up to 10 minutes and then doesn't sign.
Does the Fizzl Agent Wallet hold my keys or money?
No. In the connector the owner signs each payment in their own wallet; agents that sign with their own key only ask the server for permission first, and stop if it can't be reached.
Give an agent a wallet with limits and your approval at wallet.fizzl.eu, check a payment before signing with presign-guard, and let it buy with Fizzl Buy.