Sandbox

Write a grant's terms. Then try to break them.

Nothing here is a mock-up of the rules. The refusals below come out of validateSpend — the same function the payer runs before it builds a transaction — compiled into this page, and the address is derived by the same splice the Rust implementation produces. No node, no keys, no money.

checking this page against its own reference vectors…

The bench

Set the authority on the left. Try to spend it on the right.

The terms

kas
kas
kas
blocks
daa
daa

Who it may pay

Three real payees from this network. Tick the ones this grant is allowed to pay — the tick changes the Merkle root, and the root is part of the address.

The attempt

kas

    Where this grant lives right now

    Still spendable
    Spent
    This epoch
    Allowlist root

    The thing that surprises people

    Every payment moves the grant to a different address

    A Warda grant's address is a hash of its own state. Spend from it and the state changes, so the hash changes, so the coin is at a new address — there is no account that stays put and no balance that ticks down in place. Watch the address above while you pay: it is not a display refreshing, it is the grant relocating.

    Change a term instead and the same thing happens for a different reason: different terms are a different grant, at a different address, with a fresh budget. That is why editing anything on the left clears the ledger. There is no way to raise a budget in place, by anyone, including whoever issued it — the raised version is somewhere else and holds nothing.

    The practical edge of this: lose the terms and you lose the coin. Not the key — the terms. You cannot find a grant by watching an address, because the address is downstream of a state only the holder of the manifest knows. Every tool in this project writes the manifest to disk before it broadcasts, for this reason.

    The refusals

    What the covenant checks, in the order it checks them

    Each of these is a branch in the on-chain script, not a policy in a server. A refused payment is not a rejected request: there is no transaction that both spends the grant and breaks one of these, so nothing is ever submitted and nothing is ever declined.

    NOT_YET_VALID

    The grant has a start, in DAA score rather than wall-clock time. Before it, the agent holds an authority that cannot yet be used by anybody — including whoever issued it.

    EXPIRED

    And an end. After it the coin is still there and no spend of it exists; what is left goes back to the principal.

    EXCEEDS_MAX_PER_SPEND

    The per-payment cap. The most common thing a compromised agent tries is one large payment, and this is the check that makes that specific attack cost nothing.

    EXCEEDS_AVAILABLE_BUDGET

    Budget less what has been spent less what has been delegated to sub-agents. A child's budget is subtracted the moment it is issued, not when it is used.

    EXCEEDS_EPOCH_LIMIT

    A rate, expressed in blocks. Epochs are fixed windows rather than a sliding one, so the true worst case over a short span is twice the limit — spend it all at the end of one epoch and again at the start of the next. That is a known property, not a bug.

    RECIPIENT_NOT_AUTHORIZED

    The payee must prove membership in the tree whose root was committed before the grant was funded. A payee outside it has no proof to carry, so it has no transaction to build.

    REVOKED

    A separate key, held by whoever issued the grant, can end it at any time without the agent's agreement and without its cooperation.

    INVALID_SUCCESSOR

    The check that makes the rest real: the transaction must produce exactly the new state the rules say it should. Without it an agent simply rewrites its own remaining budget and every limit above is decorative.

    Honest limits

    What this page is not doing

    It is not building a transaction, signing anything, or talking to a node, so it cannot tell you a payment would go through — only that these rules would not be the thing stopping it. A real spend also needs a funded grant, a fee, and a node that has seen the grant where the manifest says it is.

    It does not simulate delegation, settlement, or the relay hop that x402 requires. The principal and revocation keys are held fixed: the covenant's template id is a hash over the script and its authority, so a page that let you edit those would be deriving addresses against somebody else's covenant and reporting them as yours.

    Want the same rules with a real grant behind them? /start funds one and makes a payment in about five minutes, and /attack hands you a live grant's private key and invites you to take more than it allows. This page is the version with nothing at stake.