Technical design · Tempo chainId 4217

Architecture

Mandate is a policy engine that sits in front of Tempo TIP-20 transfers. Agents never hold treasury keys. Every paid HTTP request is an MPP challenge whose on-chain memo is the challenge id. This page is the design the Solidity in contracts/ implements 1:1 with the in-browser VM.

Control plane

Finance (owner) deposits pathUSD into MandateBook. Issuing a mandate creates a spend policy: spender, cap, validity window, hourly rate, department code, merchant allowlist. Empty allowlist is fail-closed. The spender key — typically an agent session key — may only call pay(id, merchant, amount, memo).

CompanyTreasury  (TIP-20 pathUSD)
        │
        ▼
   MandateBook
     ├── Mandate #n
     │     spender, spendMax, remaining
     │     validAfter / validUntil
     │     rateLimit / window
     │     allowlist[]   // empty = deny all
     │     paused / closed
     └── pay()
           checks policy
           transferWithMemo(merchant, amount, challengeId)
           feePayer = finance  (Tempo type 0x76)

Why these Tempo primitives

MPP flow

  1. Agent GET resource, no credential.
  2. Merchant 402 + WWW-Authenticate: Payment method="tempo" ...
  3. Agent calls MandateBook.pay with memo = bytes32(challengeId).
  4. On success, retry with Authorization: Payment carrying the tx hash.
  5. Merchant verifies transfer + memo, returns 200 and Payment-Receipt.
  6. On policy miss, pay() reverts a typed error. Merchant never sees funds.

Custom errors

Typed reverts are part of the UX. The console renders them next to the HTTP trace so finance can see why an agent was stopped — MerchantNotAllowed, CapExceeded, RateLimited, MandatePaused, MandateExpired, NotSpender, InsufficientTreasury, ZeroAmount.

Security notes

Protocol addresses

TIP-20 Factory
0x20Fc000000000000000000000000000000000000
pathUSD
0x20c0000000000000000000000000000000000000
USDC
0x20c0000000000000000000000000000000000001
Fee Manager
0xfeec000000000000000000000000000000000000
Stablecoin DEX
0xdec0000000000000000000000000000000000000
TIP-403 registry
0x403c000000000000000000000000000000000000