Agentic payments — from sandbox to the open web
This session took the project across its most important threshold: the agent stopped buying only from our own pretend store and started paying real, third-party merchants on the internet — under a real, signed human authorization.
The live buyer. We built a new “live buyer” tool with two commands: one that browses a public index of thousands of payment-enabled web services and lists what’s affordable, and one that actually buys. The buying command is deliberately paranoid. By default it only rehearses: it fetches the merchant’s price quote, checks it against every rule, and stops short of paying. Real money requires explicit opt-in flags, and even then the buyer enforces a per-purchase price ceiling, a durable running budget that survives restarts (recorded to disk before signing, so a crash can never cause overspending — at worst it undercounts what’s left), a wallet balance check, and — crucially — the same rules are re-checked inside the payment machinery at the instant of signing, with the recipient pinned to what was quoted. A merchant that changes its price or swaps its receiving address between “look” and “pay” gets nothing signed. This matters because these payments are like handing over cash: irreversible, to whoever the invoice names. It worked on the first real attempt — the agent found a stranger’s test service through the public index and paid it a fraction of a cent, settled on-chain, without the agent ever holding gas money.
The housecleaning. Before building further, we did a five-part simplification pass. We deleted an entire parallel implementation of the Proof identity integration that had been superseded when we adopted the vendor’s official SDK — hand-rolled token fetching, URL construction, and certificate-chain checking that nothing in production called anymore. We retired the original single-user demo app, which the newer wallet demo had fully replaced (keeping both meant fixing everything twice). We removed a database dependency that was declared but never actually used, plus assorted dead helper functions and a legacy alias. We collapsed duplicated purchase logic in the demo server — the single-buy endpoint and the autonomous shopping loop were the same code written twice — into one shared path. And we gathered roughly thirty scattered environment-variable reads into one typed configuration module, resolved when the app starts rather than when the file loads, which makes both testing and future deployment cleaner. Every step was committed separately with the whole test suite green.
Closing the thesis. The finale connected the project’s two halves. Until now, the “which human authorized this agent to spend?” machinery only guarded our own merchant. We added a grant command that runs the full identity ceremony — the human presents a verifiable credential once, selectively disclosing only the needed attributes, cryptographically bound to the specific budget being approved — and produces one durable, signed mandate: this wallet, these payees, this spending cap, this expiry. The live buyer then enforces that mandate on every open-web purchase, entirely on the buyer’s side, since random internet merchants have never heard of our authorization protocol. It refuses tampered mandates, expired ones, unlisted payees, over-cap spending, and wallets other than the one the human authorized. We proved it live: a mandate-bound payment to a real external service settled on-chain the same afternoon.
Learnings worth keeping. First, the ecosystem moved under us mid-session: the domain hosting the free test facilitator had been handed off to a foundation and its bare hostname now serves a placeholder website — the API only answers on the www host. A one-line fix thanks to the config seam, but a reminder that the payment layer’s infrastructure is young and drifts. Second, the wallet-side-enforcement framing turned out to be the honest one: the guarantee is “my agent cannot overspend or mis-spend,” not “a compromised machine cannot” — a distinction worth stating in any write-up. Third, the repo’s seam discipline paid for itself repeatedly: swapping the balance check for a stub made the entire real-money flow testable offline, and the simplification pass was mostly deleting alternatives the seams had made safe to abandon.