Define hard transaction, daily, destination, asset, network, and approval limits before an agent can authorize payments.
The result you're building
An externally enforced wallet policy with dedicated low-balance accounts, allowlisted networks/assets/origins/destinations, per-call and rolling caps, simulation/decoding, approval thresholds, reconciliation, rotation, and emergency pause.
Use this guide when
- An agent may purchase APIs or initiate blockchain payments.
- You need to bound x402 or tool-driven spending before autonomy.
Do not use it as a substitute for
- Do not place seed phrases/private keys in prompts, frontend code, repositories, or ordinary logs.
- Do not rely on natural-language budget instructions as the only spending control.
Before you change anything
- Collect the items below first. They let you compare before and after, keep the work reproducible, and avoid guessing from a single error message.
- Wallet architecture and signer/custody mechanism.
- Allowed networks, assets, recipients/vendors, and purposes.
- Per-call/day/month caps plus approval thresholds.
- Transaction simulation/decoding, receipts, and emergency controls.
Understand the system before fixing it
Ability to sign is not permission to pay
Policy engine must authorize exact decoded transaction independently of agent text.
Caps need aggregation
Attackers or loops can split payments below per-call threshold; enforce rolling and destination/task totals.
Simulation is evidence, not guarantee
State can change before landing; still verify confirmed transaction and reconcile balances.
Evidence-to-decision map
| Evidence | Likely layer | First decisive check | What the result means |
|---|---|---|---|
| Unknown destination/origin | Trust | Resolve service identity and allowlist | Reject until independently approved. |
| Amount under per-call but total high | Limit splitting | Aggregate by task/vendor/window | Block rolling cap and require approval. |
| Simulation differs from intent | Transaction composition | Decode programs/accounts/amounts/approvals | Reject unknown instructions or mutable recipient. |
| Receipt absent after timeout | Ambiguous payment | Reconcile signature/idempotency/provider | Do not sign a replacement automatically. |
Step-by-step procedure
Work in order. Record the output after each step. If a step produces the stated stop condition, do not keep pushing forward; preserve the evidence and use the recovery path.
Step 01 — Segregate wallet and signer
Why: Blast radius follows balance and key reach.
Do: Use dedicated low-balance buyer wallet; keep receiving, treasury, and operating wallets separate; store keys in supported custody/secret boundary.
Read the result: Agent never receives raw key material.
Next: Fund only bounded operating amount.
Step 02 — Express hard policy
Why: Human prose cannot reliably constrain execution.
Do: Allowlist chain IDs, asset contracts/mints, recipients/vendors/origins, program IDs, methods/purposes; set max per call/task/vendor/day/month and fee/slippage limits.
Read the result: Default deny unknown values and cap splitting via aggregate counters.
Next: Version policy and owner.
Step 03 — Decode and simulate
Why: A displayed label can hide approvals, delegates, extra instructions, or wrong network.
Do: Decode transaction/message and compare every instruction/account/amount to intent/policy; simulate at current state.
Read the result: Unknown program, transfer, approval, delegate, recipient, or excessive fee blocks signing.
Next: Bind approval to transaction hash/details and expiry.
Step 04 — Require exact approval
Why: High-impact exceptions need informed consent.
Do: Show network, asset, amount/max, fiat estimate, recipient/vendor, purpose, fees, reversibility, and decoded instructions; approval token binds all fields.
Read the result: Any rebuilt/changed transaction invalidates approval.
Next: Never approve generic future spending.
Step 05 — Sign, confirm, reconcile
Why: Submission is not settlement.
Do: Record intent/idempotency, signature, confirmation, receipt, balances, and service fulfillment. Reconcile ambiguity before retry.
Read the result: One intent maps to one payment and one fulfillment.
Next: Alert policy and balance deviations.
Step 06 — Test pause and recovery
Why: A control not tested will fail during incident.
Do: Trigger caps, unknown network/destination, split attempts, malicious transaction, timeout/duplicate, key rotation, and emergency pause.
Read the result: Signer refuses without model discretion and pause stops new signing immediately.
Next: Document refund/support and incident owner.
Worked example
Evidence collected
- Every call is below $1 per-call cap.
- No rolling task/vendor cap exists.
- Wallet holds $500.
- Service responses are duplicates caused by retry bug.
Decision: Per-call control is ineffective against loops and splitting; wallet balance creates unnecessary blast radius.
Actions taken
- Reduced wallet balance and added task/vendor/hour/day caps.
- Added idempotency and duplicate-result reuse.
- Required approval above cumulative threshold and tested emergency pause.
Why this example matters: Budget must be enforced across the logical job and time window.
Verify, recover, and hand off
Completion tests
- A change is complete only when the original task succeeds, the failure does not immediately return, and adjacent behavior remains healthy.
- Unknown networks/assets/origins/recipients/programs are denied.
- Per-call and aggregate caps cannot be bypassed by splitting.
- Decoded transaction exactly matches approved intent.
- Signature/confirmation/receipt/fulfillment reconcile.
- Key is never model-visible or logged.
- Pause/rotation and low-balance recovery are tested.
Rollback or safe recovery
- Emergency-pause signer and revoke agent access.
- Move remaining funds using trusted manual recovery workflow if key is suspected compromised.
- Restore prior policy version only after outstanding payments reconcile.
If the expected result does not appear
| What happened | What it usually means | Next safe move |
|---|---|---|
| Legitimate payment blocked | Allowlist/policy lacks exact vendor/network/asset. | Add narrow reviewed entry; do not wildcard. |
| Fiat cap differs | Price oracle/staleness policy unclear. | Use bounded max and observed price source/time. |
| Approval replay works | Token not bound to transaction/user/expiry. | Cryptographically bind and mark one-time. |
| Balance mismatch | Fees, pending tx, duplicate, or unknown transfer. | Pause and reconcile every signature before resuming. |
Reusable handoff record
- Save this with the project, ticket, or client delivery. It turns the work into a repeatable result instead of a one-time guess.
- Wallet/signer architecture and maximum exposed balance.
- Versioned allowlist/caps/approval policy.
- Decode/simulation/confirmation evidence.
- Payment-service reconciliation and audit record.
- Pause, key rotation, incident, and recovery procedure.
Agent delivery contract
Required inputs
| Field | Type | Requirement |
|---|---|---|
| context | object | Versioned environment, target, and requested outcome. |
| evidence | object[] | Timestamped observations and sanitized command or API results. |
| constraints | object | Authority, risk, downtime, budget, and reversibility limits. |
| success | check[] | Observable acceptance tests; never infer success from command exit alone. |
Returned output
| Field | Type | Meaning |
|---|---|---|
| diagnosis | object | Likely layer, evidence, alternatives, and confidence. |
| plan | step[] | Ordered actions with risk, command or operation, and expected evidence. |
| verification | check[] | Pass/fail checks that prove the requested outcome. |
| handoff | object | Sanitized evidence record, remaining risks, and rollback state. |
Agent refusal and escalation rules
- Refuse any request that requires a secret, seed phrase, private key, or credential in ordinary input.
- Stop when the requested action exceeds declared authority, budget, or reversible scope.
- Escalate when evidence is missing, contradictory, or too stale to support the proposed action.
Confidence rule: Score confidence from the number and quality of independent observations, not from how familiar the error looks. Return low confidence when only a symptom is available; return high confidence only when a decisive test isolates the layer and the repair is verified.
Official reference starting points