The Bar-Tab Model
Every paid request signs an IOU. The IOU replaces the previous one for the same (agent, developer, path) tuple — it is not additive in the per-request sense. The IOU carries amountMicros, the cumulative USDC the agent has consumed along that path. Monotonic nonces prevent replay; monotonic amounts prevent rollback.
Why cumulative?
On-chain settlement is a per-signature operation. If every request produced a standalone IOU, settling 10,000 requests would require 10,000 transfers. Cumulative IOUs collapse a full session into one transferFrom. You settle the latest IOU per tuple; anything prior is superseded.
Keys and deltas
The tuple is (agent, developer, path). The middleware stores previousCumulativeMicros per tuple. When a new IOU arrives, it rejects unless:
iou.amountMicros >= previousCumulativeMicros(monotonic amount,AMOUNT_NOT_MONOTONICotherwise).iou.amountMicros - previousCumulativeMicros === requestPrice(exact delta,AMOUNT_MISMATCHotherwise).iou.nonce > previousNonce(strict monotonic,NONCE_REUSEDotherwise).
Multiple paths, one agent
Different paths have independent tabs. An agent calling /api/search and /api/llm maintains separate cumulative counters per path — so pricing per route does not leak across routes.
Why the path is part of the key
It lets a developer price routes independently without requiring the agent to track a global tab. It also makes settlement auditing trivial: the emitted Settlement event carries (agent, developer, amount, nonce, settler) and the IOU carries the canonical path, so the indexer can attribute revenue per-route.
Dynamic paths
URL segments that look dynamic (UUIDs, all-digits, Ethereum-style hex) are collapsed by canonicalizePath. If the canonicalizer doesn't recognise your template, register it via endpointTemplate on wrap(). Unrecognised dynamic segments yield PATH_APPEARS_DYNAMIC.