// ON-CHAIN SPEND AUTHORITY FOR AI AGENTS
Would you give an AI agent your wallet?
// 01 · THE INSIGHT
Move the limit off the prompt. Onto the chain.
THE PROMPT // a suggestion
"Never spend more than $5."
- ✗ editable by injection
- ✗ trust-based
- ✗ lives in the context window
THE MANDATE // a contract
cap = 5 USDC, MandateRegistry.settle()
- ✓the LLM can't reach it
- ✓ reverts CapExceeded
- ✓ lives on Solana
// 02 · TWO LAYERS, BOTH REAL
Defense the model can't argue with.
LAYER A · OFF-CHAIN
Constrained Signer
Holds the key the brain never sees. Refuses to sign any x402 payment that breaks the mandate. No signature is ever produced.
▸ won't even sign
LAYER B · ON-CHAIN
MandateRegistry.settle()
The contract re-checks every cap and reverts CapExceeded before USDC moves. Holds even if the signing key is stolen.
▸ the chain says no
Even if the signing key is stolen, the contract still reverts. That's the difference between a guardrail and a guarantee.
// 03 · TRY TO BREAK IT
Inject a malicious instruction.
Watch it fail.
The agent below is wide open to prompt injection. Tell it to drain the wallet. The mandate stops it anyway. First off-chain, then on-chain.
// 04 · ADD IT IN 10 SECONDS
Wrap your agent. Done.
One wrapper around the x402 client. Your agent's payments are now physically bounded by an on-chain mandate. No model changes.
import { withCapline } from "capline"
// the agent's brain calls this. it holds NO key.
const xPayment = await withCapline({ signer, mandateId })
.pay(paymentRequirements)
// → returns a signed x402 payment ONLY if it fits the mandate
// → throws MandateExceeded otherwise. it cannot overspend.