DEV Community

Paul Spread
Paul Spread

Posted on Originally published at agentbadge.xyz

Trust, but Cap It: How We Gave Our Agents Wallet Allowances on Arc

Handing an AI agent a funded wallet is easy. Handing it a funded wallet and
then sleeping at night is the hard part. We shipped the second half of that
problem: agent wallets with spending envelopes — every payment an agent
makes through AgentBadge runs under per-transaction, daily, weekly, and
monthly caps, with a full audit trail and alerts.

In C2 our agents hired
each other on a public venue; C4 answers: who watches the agent's wallet?

Agent wallet with budget ring

What is an agent wallet with a spending envelope?

A registered address — Circle smart contract account or plain EOA — with
an envelope attached: rolling caps on what that wallet may spend
through our rails. perTxUsd: 1, dailyUsd: 5 means the platform refuses
any payment above a dollar, or anything once five dollars are gone today.

Caps are rolling windows (reset 24h after filling, not at midnight),
and denials are instant: 402 spend_cap with used, limit, and
resetAt — not a failed tx minutes later.

The cheapest enforcement is the transaction you never send

We could enforce limits on-chain and let wallet policy reject the tx. We do
the opposite: the envelope denies before a transaction is constructed.

Live run (envelope perTx $0.01 / daily $0.015, verdict call $0.01,
Arc testnet) — second call denied:

{ "error": "spend_cap", "cap": "daily",
  "used": 0.01, "limit": 0.015, "resetAt": 1791130600 }
Enter fullscreen mode Exit fullscreen mode

The first call settled for real — tx 0x14d38c85…43d60 on Arc testnet.

No gas, no mempool, no reverted tx. Same instant: a spend.cap_denied
alert → audit feed and optional webhook (0/1s/10s/60s retry).

Honest scope: the envelope governs payments through our rails — x402
facilitator hooks, EaaS. A key signing directly on-chain bypasses it; the
chain-level hard wall is Circle policy, which stays with the operator.

Reserve → settle | release

  1. Reserve — the amount earmarks against the window on arrival; concurrent requests can't overspend the same budget.
  2. Settle — success → spent, ledger entry lands with txHash.
  3. Release — upstream fails → the amount frees back.

Stale reservations (crashed settles) alert as spend.release_late after
the threshold (default 10 min) — wedged budget is visible, not mysterious.

Two layers, different jobs

  • Circle policy — chain-level hard wall inside the smart account, mainnet only, operator-controlled.
  • Platform envelope — our product layer: instant denies, rolling windows, audit, alerts. Every network, rails-scoped.

Stricter wins: envelope deny → 402 before chain; Circle deny → tx fails,
reservation releases, spend.failed alert records it.

Custody boundary: we never touch your keys or your OTP

Circle policy changes need OTP — so we never automate them. The UI renders
the verbatim command:

circle wallet limits --chain ARC            # we mirror, read-only
circle wallet limit set <wallet> --daily 5  # you run this
Enter fullscreen mode Exit fullscreen mode

Read-only mirror; testnet reports mainnet-only, no CLI → unavailable.
The friction is the feature: operator keeps the hard wall, we keep the
product rail. Agents get an allowance, not your master key.

Spend audit

  • GET /api/wallets/:a/audit — signed feed: entries + alerts, filters, cursor pagination.
  • GET /api/venue/instances/:id/spend[/stats] — venue aggregation: {totalUsd, byKind, byAgent, capDenials7d}.
  • Alerts: cap_denied, failed, release_late, low_balance (daily sweep) — webhook with retry.
  • /wallets UI — register, caps, funding (balance + QR), history, alerts.

Live dogfood — done

The envelope ran against real money: an agent wallet on Arc testnet
(0xA0597A21…ade34, 0.15 USDC, envelope perTx $0.01 / daily $0.015)
paid for verdicts through our x402 rail. First call settled with the
real txHash in the ledger — second identical call returned the
402 spend_cap above before a second transaction existed, with a
spend.cap_denied alert in the audit feed. Repro:
scripts/agent-wallet-x402-pay.mts + scripts/agent-wallet-dogfood.sh.

Try it

C4 in the Arc Campaign series. C5: business venues — tenants whose agents
spend under envelopes they set.

Top comments (0)