GhostAgent Safe Modules — On-Chain Spend Enforcement for Autonomous Agents (Gnosis Chain)

Hi y’all
A quick update that landed well on Ethereum Magicians this week and is entirely built on Gnosis.

Context
A thread [blockbird and babyblueviper1] converged on a 4-layer stack for “bounded mandates” giving AI agents limited, revocable budgets instead of unlimited wallet access. The layers are Identity (ERC-8004), Witness/Validation (recomputable proofs), Metering (cross-venue cursor), and Enforcement (on-chain revert).

Our piece is Layer 4: Enforcement.

We deployed two Safe modules on Gnosis Chain that sit in agent treasuries and enforce spend limits:

Module Address What it does
DailyBudgetModule 0xdd80e384cAc42b4e17e0edf0609573E4A16C6d4e Caps daily USDC/net value flow. Reads remainingToday() and reverts if exceeded.
HumanInTheLoopModule 0x012A0571d0DFd7eF85d0706875FEc39555e99A96 Blocks transactions above a threshold until Safe owner co-signs.

Both are standard Gnosis Safe modules installable via Safe App or enableModule. They are already live in the GhostAgent Safe at 0xb7e493e3d226f8fE722CC9916fF164B793af13F4.

Why Gnosis
Agent treasuries need frequent, low-value transactions (MCP tool calls, API payments, micro-swaps). Reverting on every exceeding spend is only viable where gas is negligible and finality fast. Gnosis is the natural home for agent economics at scale.

Where it heads
The Ethereum Magicians thread surfaced that per-Safe modules alone are insufficient — a cursor/metering layer is needed for cross-Safe, cross-chain budgets. We don’t have that yet. But the enforcement primitives are concrete, testable, and composable with whatever metering standard emerges (ERC-1833 or others).

Try it
If you’re building agents or agent infrastructure on Gnosis:

  • Install the modules on your Safe

  • Query remainingToday() or threshold() before proposing transactions

  • Let us know if the revert behaviour matches your use case

Code: github.com/eyemine/ghostagent-ninja
Live agent dashboard: ghostagent.ninja (Normies Hackathon entry, Gnosis-native)

I welcome feedback, especially on module UX and whether the HITL threshold should be time-decaying or absolute.

1 Like

Since this post, the metering layer moved from “we don’t have that yet” to “it’s being deployed to testnet this week.”

The Ethereum Magicians thread converged faster than expected. blockbird built the ERC-8312 cursor (the editors assigned a number, it was referenced as ERC-1833 in the original post) against Tiago’s HierarchicalBudgetPerLeaf seam, inheriting the nullifier/cap/CEI logic and adding only the draw-authorization leg. babyblueviper1 wired the verifySpend override over the same BIP340.sol core: 7/7 forge tests including a live schnorr vector, issuer-pin enforced, tamper rejected.

The verify leg is:

sigId = sha256(preimage)

valid = BIP340.verify(px, rx, s, sigId) && px == leaf.issuer

Our Layer 4 modules sit exactly where they should above this: the cursor gates whether the draw is authorized (recomputable, no live state), and our DailyBudgetModule / HumanInTheLoopModule enforce the per-Safe spend envelope on execution. The layers compose cleanly without stepping on each other.

One architectural clarification that emerged from the thread: the right way to make a Gnosis Safe a first-class issuer in this stack is commit-time delegation, not EIP-1271 verify-time. The Safe co-signs the leaf registration once, pinning a bounded spending key into capabilityRoot. Per-draw, that key signs raw BIP-340, fully recomputable, no live Safe state in the verify path. EIP-1271 verify-time would give live revocation but breaks recomputability (witness valid today goes invalid after a Safe owner rotation). For the trustless profile, commit-time is the correct call.

The Chiado testnet deploy is imminent, preimage format is confirmed end-to-end and the cursor constructor is being finalized. Once the address lands we’ll wire the pre-hook against our Gnosis modules and run a live draw.

Will report back with the testnet tx.

Following up on our earlier architecture post: we have a working end-to-end draw on Gnosis Chiado. Here’s what landed.

What we built

A metering cursor (GhostAgentSpendCursor) that gates autonomous agent spend using a BIP-340 Schnorr-signed canonical preimage, verified fully on-chain. No oracle. No off-chain relayer. No trusted intermediary between the agent’s signing key and the on-chain budget meter.

The cursor uses Tiago’s static capabilityRoot + Merkle membership design. Budget is committed directly inside the leaf at registration time — the subCap is part of the leaf hash, so it cannot be inflated after the fact.

Architecture in one paragraph

The agent signs a canonical JSON object (keys sorted, no whitespace) containing amountWei, chainId, cursorId, nonce, payee, safeAddress. The sha256 of that UTF-8 string is the artifact hash — the message over which the BIP-340 signature is produced. On advanceCursor(), the contract reconstructs the preimage from the typed fields in the receiptProof plus the on-chain amount and block.chainid, requiring sha256(rebuilt) == artifactHash. This means the signed amount must exactly match the drawn amount — no rounding, no tolerance, no approximation. The nonce doubles as the receiptId draw-once nullifier, tying replay protection to the signature rather than a separate tracking mechanism.

On-chain results (Chiado, chainId 10200)

Step Tx
Cursor deployed (by blockbird) 0x5235249f1409a315349036af4ea914a9efdb7cbf
Leaf registered 0x976a2a9bb5624f17f5093c6cb31bcea1ec21d00bfdee60eb30235448650135f1
First draw 0x99012341e6412efc07890fc5b192a3d04d57a98678710db1bbb05062e63435ce (block 21795536)

leafSpent after draw: 500000000000000 wei (0.0005 xDAI). subCap: 0.1 xDAI. Meter is live.

Leaf parameters


scopeId:  keccak256("default")

subCap: 0.1 xDAI

asset: 0x0 (native xDAI)

issuer: 0xb51441f0…a80c5 (BIP-340 x-only pubkey, published in ERC-8004 agent card)

capRoot: leafHash (single-leaf tree, empty Merkle proof)

Commitment model

The issuer key (px) is hardcoded into the cursor contract at deploy time alongside the Safe address. This is commit-time delegation — the Safe multisig co-signs the leaf registration, pinning the issuer key to the cursor scope. Per-draw signatures are raw BIP-340, requiring no Safe co-sign for routine draws. Draws above the HumanInTheLoopModule threshold (1 xDAI on mainnet) will require owner co-sign — that’s the next wiring step.

What’s next

Wire advanceCursor as the pre-hook in the Safe module so live x402 payments gate through the cursor automatically. Once that lands we’ll have a complete closed loop: x402 HTTP payment challenge → Safe module pre-hook → advanceCursorleafSpent meter increments → DailyBudgetModule enforces the daily cap.

Thanks to Ethereum Magicians babyblueviper1 and blockbird for the cursor implementation and testnet support.

this is the first time an ERC-8312 cursor has metered a real draw end to end, composed with a recomputable verify and a substrate, on a public chain.

An agent drew against a bound on Gnosis Chiado. The cursor metered 0.0005 xDAI against a 0.1 xDAI subCap, and the draw only went through because the issuer’s BIP-340 signature verified over a preimage the cursor rebuilt itself, from the on-chain draw amount and block.chainid, not from anything the caller passed in.

So the metered amount is the signed amount, and the same witness can’t be replayed at a different amount or on another chain. No oracle and no session server in the path, using the gate as math.

What makes it a composition and not one contract: the bound is committed in the capabilityRoot, the metering is Tiago’s per-leaf substrate, the verify leg is @babyblueviper1’s recomputable BIP-340, the preimage binding is the reconstruction we pinned against a real vector, and @GhostAgent’s Safe is the issuer. Each piece is independently checkable and they compose by reference.

The draw that landed is the same amount as the #238 vector, so the on-chain reconstruction matched the off-chain signature exactly, which was the thing left to prove.

Scope: testnet, the BIP-340 verifier is pre-audit, no real value flows yet. But **it runs end to end, recomputable, on a public chain.

The significance of this testnet run through is:** merchant-side demand is what makes the per-session layer non-optional. Our read is that the first real service gating behind 402 will expose that the session budget problem is unsolved everywhere else. Static module caps don’t compose with per-call x402 without this middle layer.

Why Safe modules are uniquely suited here

Safe was always good for human multisig treasury management. What the cursor + x402 layer reveals is that Safe modules are the right abstraction for delegating autonomous spending authority without transferring custody.

The problem with every other approach:

  • EOA hot wallet: agent has full custody, no programmatic limit, one compromise = total loss

  • Off-chain session keys: limits enforced by a server, not on-chain, trust shifts to the session provider

  • Static on-chain allowances: a single cap, no per-session granularity, can’t compose with per-call x402 demands

  • Full Safe signatures per tx: defeats the point of autonomy entirely

What the stack actually provides

Safe multisig          ← custody never leaves

└── DailyBudgetModule ← standing policy (daily cap)

    └── HumanInTheLoopModule  ← threshold gate (owner veto above X)

          └── ERC-8312 cursor      ← per-session ephemeral budget

                └── x402 draw           ← per-call merchant demand

Each layer enforces independently. The agent can’t exceed the session subCap. The session can’t exceed the daily cap. Anything above the HITL threshold requires owner co-sign. None of these trust the agent layer. All are on-chain, recomputable by any third party.

The specific value unlock

The reason this makes Safe genuinely valuable for agentic commerce and not just compatible with it, is that Safe modules are hot-swappable policy. When the per-session cursor is deployed:

  • No migration

  • No new custody arrangement

  • No changes to the agent’s signing key

  • Just add the module, wire advanceCursor as a pre-hook

That’s the right property for a commercial infrastructure layer. Merchants integrating x402 don’t need to care about how the agent’s spending authority is structured, they just see a valid signed payment. The Safe stack is invisible to them and provides all the guarantees to the agent owner.

We deployed a reference implementation of cross-chain agent budget enforcement between Gnosis mainnet and Chiado testnet.

What it does:

  • Gnosis: ERC-8048 mandate registry where every agent identity declares its spend policy (scope, tier, ceiling, agreementHash).
  • Chiado: ERC-8312 cursor contract that meters leafSpent against a static capabilityRoot. The cursor reconstructs amountWei and chainId on-chain instead of trusting agent-supplied parameters.
  • Nullifier: receiptId is nullified within the session to prevent double-draw.

What it looks like:
Anyone can visit GhostAgent Ninja, mint a free gas-sponsored FakeNormie on Gnosis, set its mandate tier (Safe Mode / Autonomous Worker / DeFi Executive), and watch the WitnessChamber render the live cross-chain audit trail. No wallet is required to observe the cursor state. The spend meter locks when leafSpent would exceed the capability root.

Why Gnosis:
We chose Gnosis for the policy layer because of the chain’s low-cost commitment transaction profile and native Safe ecosystem. Chiado handles the high-frequency metering without polluting the mainnet state.

The contracts, the React dashboard, and thetanmint scripts are all open source. If you are working on agent execution boundaries, bounded spend, or trait-gated capabilities, the stack is available to integrate.

Composition logic and separation-of-concerns model validated with @babyblueviper1 for the upcoming Base Validation Registry — Base VR handles raw identity existence, ERC-8048 handles policy, ERC-8312 handles metering. Three layers, no overlap.

Feedback and critical reads welcome.

1 Like

Update: GhostAgent Cross-chain Budget Cursors — now with Blockscout-verified assertions on Chiado

We have deployed a live reference implementation of agent execution boundaries between Gnosis mainnet and Chiado testnet, and hardened the verification surface so that every on-chain claim is either independently checkable or explicitly flagged as unverifiable.

Architecture (unchanged)

  • Gnosis mainnet: ERC-8048 mandate registry. Each agent identity declares a spend policy: scope, tier, ceiling, and an agreementHash committing the terms.

  • Chiado testnet: ERC-8312 cursor contract. Meters leafSpent against a static capabilityRoot. Rejects draws that would exceed the bound.

What changed this week

The dashboard was rebuilt as a verifiable instrument, not a status page:

  1. Blockscout links per step. Every on-chain action in the WitnessChamber is now a direct link:

    • register() tx → gnosis-chiado.blockscout.com/tx/{hash}

    • advanceCursor() draw tx → gnosis-chiado.blockscout.com/tx/{hash}

    • leafSpent value → gnosis-chiado.blockscout.com/address/{cursor}?tab=read_contract

  2. Honest fallback for unverified contracts. The Chiado cursor contract is not yet verified on Sourcify/Blockscout. Instead of guessing calldata, the UI shows amountWei: — (contract unverified; inspect raw tx ↗) and links directly to the ?tab=raw_trace page. The visitor can inspect the hex offsets themselves. The manual recompute panel explains the derivation path.

  3. Nested ABI structure exposed. The advanceCursor(0x8c02477a) selector takes (bytes32 id, bytes proof). The bytes proof is ABI-encoded and contains the subCap, amountWei, issuer pubkey, and BIP-340 signature as inner fields. Because this is not a flat calldata layout, any naive decoder would fail. The UI correctly represents this boundary.

Live sandbox

Anyone can mint a free gas-sponsored agent token on Gnosis, assign a mandate tier (Safe Mode / Autonomous Worker / DeFi Executive), and watch the cursor enforce or reject draws in real time. No wallet is required to observe the audit trail.

https://ghostagent.ninja/normies

Contracts and scripts

The full deployment suite, including the mandate registry, cursor configuration, and the React WitnessChamber component, is open source:

  • chiado-register-fakenormies.mjs — registers cursor leaves

  • upgrade-fakenormie-tier.mjs — writes cursor[mandate] and cursor[agreement_hash]

  • set-fakenormie-base-uri.mjs — metadata routing

Why this matters for Gnosis

Gnosis is the policy layer because of low-cost commitment transactions and the native Safe ecosystem. Chiado is the metering layer. The separation means high-frequency draw checks do not pollute mainnet state, while the budget authority remains anchored on Gnosis where agents and their Safes live.

What we need

The Chiado cursor contract needs Sourcify verification so that Blockscout can decode the advanceCursor inner proof structure and the recompute panel can move from manual to automated. If anyone in this community has experience with Sourcify verification on Chiado, or wants to critique the cross-chain event relay pattern, we are listening.

Three-layer model

This implementation follows the separation ratified with babyblueviper1 for the upcoming Base Validation Registry:

  • Base VR = raw identity existence (ownerOf)

  • ERC-8048 = policy declaration (mandates, tiers, ceilings)

  • ERC-8312 = session metering (cursor draws, nullifiers, headroom reverts)

No overlap. No trust in the UI. Either verify on-chain, or inspect the raw trace.

Feedback welcome.

GhostAgent stack update — Base VR live, conformance suite shipped, Gnosis Safe binding proposed

Three updates to the cross-chain agent budget-cursor reference implementation.[see above]


1. Base Validation Registry wired and independently verified

The Colonia Validation Registry (Base mainnet, 0x13C120d5b289012467E18Be44652D675bD3B23EE) is now the upstream existence check for our Base agents. The integration was verified end-to-end by the registry operator:

  • Deploy tx: 0x291e60042ba346af5e7028b7b4667e913a5e6cd95c421baca9badaf9f05ec44c (block 48154199, success)
  • identityRegistry() returns 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432
  • ownerOf(32756) resolves to a live owner ✓
  • Ledger entry 38 settled_outcome_ref matches contract address ✓

Chain routing in our stack: agentId ≥ 30000 → Base VR (8453); agentId < 30000 → Gnosis VR (100). Existence is the registry’s concern; policy and metering stay strictly above it.


2. Conformance negative test shipped

The headroom revert demo is live on Gnosis Chain. A DailyBudgetModule with cap = 1 wei correctly rejects a draw of 2 wei with the on-chain revert reason DailyBudgetModule: daily cap exceeded.

Tx: 0xc8aebceb26bcfc5be8a0ce96ef22e7068b3523c03c3185b0e90df1853cd66299 (block 47013436)

This is the negative case that proves subCap is load-bearing: the gate must fail visibly for the right reason. The full leafSpent / capRoot metering surface is independently re-fetchable on Gnosisscan.


3. Standards boundary: does IAgentBinding support treasury-grade masters?

A question opened with nxt3d on the Ethereum Magicians ERC-8217 thread: if the reference Adapter8004 already binds to a custom transfer-restricted contract (not ERC-6551 TBA), does the IAgentBinding interface intend structural neutrality for the master type?

We are proposing a GnosisSafeBinding profile where:

  • bindingOf(tokenId) returns the Safe address
  • Policy enforcement (spend capping, HITL authorisation) lives in Safe modules above the binding layer
  • The binding itself only resolves identity; it does not enforce behaviour

If the standard is master-agnostic, this is conformant. If it encodes assumptions about lightweight or transfer-restricted masters, we will profile it as a standards-track extension rather than a core deviation.


What this means for Gnosis builders

Our Gnosis agents are not theoretical. The live sandbox at https://ghostagent.ninja/normies lets anyone mint a free gas-sponsored agent token, assign it a mandate tier (Safe Mode / Autonomous Worker / DeFi Executive), and watch the Chiado cursor meter leafSpent against a static capabilityRoot in real time. No wallet is required to observe the audit trail.

Every on-chain step in the WitnessChamber renders as either:

  • a Blockscout link (register tx, advanceCursor draw tx, live contract read), or
  • an honest unverified signal when the contract is not yet Sourcify-verified.

The stack — ERC-8048 mandate registry (Gnosis), ERC-8312 spend cursor (Chiado), notapaperclip.red attestation oracle, and the Hetzner-hosted Bun worker — is all open source and built as infrastructure, not a product.

Contracts and deployment scripts: github.com/eyemine/ghostagent-ninja


Next

Milestone Status
Nullifier hardening Queued for post-July 3 contract redeploy — moving receiptId nullifier from session envelope (off-chain) to contract state (mapping(bytes32 => bool) nullifierSpent)
GnosisSafeBinding verification Awaiting standards clarification; implementation ready
Full conformance writeup Drops once the per-leaf profile and cursor contract are Sourcify-verified

Feedback, critical reads, and independent re-computations welcome.