architecture
The circuit is the law.
Five moves, three layers of enforcement, one payment rail. A record type can only be consumed by its own program’s transitions — so the permit is unusable outside spend(), and spend() is the policy.
you ──create_vault──▶ [ VaultPermit · encrypted ] ──▶ your agent ▲ │ GET /api/premium/… │ ▼ SpendReceipt ◀── spend() ◀── policy ok ◀── 402 + priced quote (view key) │ ├── in-circuit: cap · budget · category · expiry · revoked └── credits.aleo::transfer_private ──▶ merchant (sealed)
01 / create_vault
Seal
The owner signs once. The policy becomes an encrypted record only the agent can consume — and a private AdminCap only the owner holds.
assert(per_tx_cap > 0)
assert(category_mask > 0)
// the chain checks freshness, then seals
02 / HTTP 402 → spend
Spend
The paywall quotes a nonce-priced amount. The SDK pre-checks it against the permit locally — then proves the spend and the merchant unlocks on the payment’s proof.
"maxAmountRequired": "1579592",
"extra": { "programId": "agent_vault_v1.aleo",
"functionName": "spend" } }
03 / approval.requested
Ask
Above the owner’s threshold — set under the cap, changeable live from the console — the purchase pauses before any proving until the owner answers.
approval.resolved approved · 2.0s round-trip
// the cap is the law; the threshold is your say under it
04 / spend.refused
Refuse
Out-of-policy quotes die locally in about a millisecond — no proof, no payment, nothing sent — and every refusal lands in the owner’s decline feed with its rule.
// + owner_denied and approval_timeout, from the SDK layer
05 / revoke
Revoke
The AdminCap is consumed, one public bit flips — and the agent’s next spend is rejected at finalization with a valid proof. Consensus, not a prompt.
→ status: "rejected" · state reverted, fee only
where enforcement lives · every rule in its layer, on purpose
Three layers, no trust between them.
circuit — enforced by consensus
A violating spend cannot produce a valid proof; a revoked or expired one is rejected even with a valid proof. The chain will not accept it — nobody has to decline it.
amount ≤ per-tx cap
Asserted inside spend(). There is no valid proof of an over-cap payment; the transaction can't exist.
amount ≤ remaining budget
The successor permit carries the decremented budget; overdraw has no valid witness.
category ∈ allowlist
(mask >> category) & 1 == 1 — the 64-bit allowlist is checked in-circuit, without ever being revealed.
expiry height
Checked at finalization against real chain height — client clocks don't get a vote.
revocation
One public mapping bit. After revoke, finalization rejects valid proofs — the kill-switch judges the proof, not the intent.
spend-once
Records are UTXOs: consuming the permit produces a serial number the protocol will never accept twice.
sdk — the agent's runtime
Everything here fails fast and costs nothing — and none of it widens what the circuit allows.
local policy pre-check
The same asserts as the circuit, run in ~1 ms against the decrypted permit — a doomed spend never burns 30–75 s of proving.
approval threshold
The owner's comfort line UNDER the cap. Off-circuit on purpose: the deployed circuit is immutable, and your comfort line changes at dashboard speed. Every surface labels it this way.
quote-TTL guard
Refuses to start proving into a quote that would expire first — money never chases a dead offer.
private fees, always
A public fee would print the payer's address next to the vault id in the same transaction. The SDK refuses the combination.
facilitator — the merchant's policy
The paywall holds a view key only — it can read its own incoming payments and cannot move funds.
program + function gate
Only payments made through agent_vault_v1.aleo/spend unlock content. A direct transfer of the exact amount is refused — proven on-chain in the evidence.
amount-nonce quote binding
Every live quote gets a unique price tail; redemption requires the exact match. A copied txid off the explorer unlocks nothing.
one txid, one unlock
Replay is a refusal: a transaction id retires the moment it redeems a quote.
Everyone else’s spend policy is either their secret or everyone’s. Here, it is sealed — and consensus enforces it anyway.
honest limits
- Custody is Model A. The agent holds its own private records; a rogue agent could move them outside the vault — and compliant merchants reject those payments, as the circuit-bypass transaction proves on-chain.
- The threshold is not in the circuit. The cap is. That layering is the design, and every surface says so.
- Testnet only. No real value has ever touched this codebase.
sealed until agent_vault_v2
- ▚▞ private velocity — rolling windows whose tempo the chain never sees
- ▞▚ allowlist membership proofs — "this merchant is allowed" without the list
- ▚▞ reversible freeze · in-permit refill
- ▞▚ in-circuit quote binding — the payment commits to its quote