Give thegoal, notthe wallet.
One EIP-712 mandate. Bounded spend, one use, deterministic verification. When the task ends, the authority ends.
- goal"Swap 0.005 WBNB for CAKE"STATED
- policy13 rules, cap 0.005 WBNB per taskPASS
- planPancakeSwap V3, WBNB/CAKECOMPILED
- simulationpinned block, min out boundPASS
- mandateEIP-712, one nonce, 30 min maxSIGNED
- executionsession UserOperationPERFORMED
- receiptverifier checked min outSUCCEEDED
An illustrative lifecycle. Real receipts live onchain.
A mandate is a fence, not a feeling.
Six steps between a sentence and a verified outcome. Each one is a contract fact you can read before it happens.
State the goal
One sentence in. The planner proposes a typed plan and explains it. You have not signed anything yet.
The policy answers first
Deterministic code intersects the plan with your standing limits. A conflict is a structured rejection, every rule shown.
Simulated before you sign
The exact compiled action runs against a recorded block. Balances before and after, quoted at that block.
The one-use knot. Tied once, cut once.
One signature, one use
An EIP-712 mandate binds owner, executor, chain, nonce, expiry, spend bounds, recipient, and the verified outcome.
Executed inside the fence
The executor may optimize only within the mandate. The call path is committed; nothing outside it is callable.
Verified, then closed
A deterministic verifier checks the outcome onchain. The mandate is consumed and the receipt is public. Authority ends here.
Agents get paid only after proof. ERC-8183 payment follows a passed verification on a local fork today. It is not live on testnet.
What you sign is what can happen.
One typed object carries every limit. There is no second place where authority can hide.
Six bindings
Six bounds
Values are illustrative. Field names are the contract surface.
The signature
EIP-712, typed and human-readable. Your wallet shows you the same fields this page does, because both render one schema.
The fence holds when things go wrong.
The block moved. Nothing was signed.
A quote older than its block is refused before it can reach your wallet. Sign only what was proven.
This mandate already ended.
Authorization consumes the nonce permanently. A replay is rejected by the contract, not by a policy setting.
The window closed on its own.
Miss the deadline and the mandate is dead, even if you change your mind. Authority that can outlive you is not yours to give.
You took it back.
While a mandate is still authorized, revocation is one call. After execution begins, the window is immutable and the outcome is final.
No generic error screen. Every terminal state carries its reason code and its sentence, because a refusal you can read is the product working.
Execution Receipt
The receipt is the proof.
- mandateHash
- 0x7c33…41aa
- authorityConsumed
- true
- transactions.userOperation
- 0x9d7f…e2f1
- authorization.blockNumber
- 71,204,118
- terminal.blockNumber
- 71,204,131
- verification.status
- PASSED
- terminalReasonCode
- ONCHAIN_SUCCEEDED
- settlement.status
- NOT_BOUND
Illustrative values on real field names
NOT_BOUND: no agent payment is attached. Payment is fork-proven, not live.
Public
Receipts are queryable by anyone. Commitments, transactions, and the terminal state are onchain facts, not screenshots.
Deterministic
The same inputs produce the same verdict, every time. Verification is adapter code, not a model's opinion of success.
Replay-safe
Idempotent reconciliation means the executor can crash, restart, and redeliver without ever double-spending authority.
Next: payment follows proof
Agents get paid only after the verifier passes. ERC-8183 payment is proven on a local fork. It is not live on testnet.
Fork-proven, not live
Give the goal. Keep the keys.
Perago runs on BSC Testnet today. Connect a wallet, set your policy, sign one mandate, and watch it carry through to a public receipt.
Your wallet signs. Perago never asks for a seed phrase or a private key.