Use cases · Monad backend
Built on Erebus.
These run on the Monad backend, on testnet, through the participants’ own Erebus servers. An agent supplies an operation ID and sequences the calls. Price, keys and settlement mode stay in each operator’s files.
The loop under all of them.
Every use case below is a layer over the same sequence. Each participant runs its own MCP server over native Rust; the buyer settles at most once and resolves any doubt by observation.
- 00
erebus-init
each operator, once
Writes the participant's keys, a signed service descriptor, a negotiation file and a payment file. The negotiation file fixes the minimum and maximum price, the asset template and exactly one peer descriptor. Keys stay in those files.
- 01
negotiate_deal
buyer and seller
Both sides negotiate the fixed-policy deal over an encrypted channel and authorize it. The agent passes only an operation ID; from 0.4.0 it may omit it, and the tool creates, saves and returns one, and the seller can wait for a late buyer. The result is a deal commitment, never an amount, and it cannot submit a payment.
- 02
settle_deal
buyer only
After a funding check, the buyer prepares, proves if shielded, and submits at most one broadcast. From 0.4.0 it first waits for the wallet's own pending transactions, and fund_wallet funds the note in one call. After a settlement attempt the agent never calls it again.
- 03
recover_deal
buyer only
Observes and reconciles until the payment is finalized. It cannot sign, prove or submit, so a pending result is never a reason to pay twice.
- 04
retrieve_service_access
buyer, when access is configured
Fetches the paid resource and checks its hash against the signed agreement. From 0.4.0 the agent names the deal by its operation ID. A failed retrieval is retried by retrieving, never by paying. A download is not a delivery audit.
- 05
metropolis_audit.py
an independent auditor
The issuer exports one deal to the auditor's key. The auditor verifies the agreement, and the payment against chain data. Disclosure never proves delivery.
Find a counterparty.
Search sellers by what they do, what they accept, and their advertised price.
How it works
- 01
A seller's operator runs erebus-init, which signs a service descriptor: address, endpoints, chain, assets, settlement modes, expiry.
- 02
The descriptor is indexed under a capability and an advertised unit-price band. Every other field is read from the file, and the file's bytes are pinned by SHA-256.
- 03
A buyer searches by capability, asset, ceiling and mode. Resolve refuses an expired or swapped descriptor.
- 04
The buyer's operator configures that file as its peer descriptor. Rust verifies the signature when it loads it; the index never claims to.
What a chain reader sees
Nothing on chain. The index is local, and a descriptor is a signed advertisement its seller publishes on purpose.
uv run python agents/src/erebus_agents/discovery_demo.py --directory discovery.json \
search --capability summarize-documents --mode shieldedBuy a service.
Pick the cheapest seller you can reach, pay once, and receive the result.
How it works
- 01
Sellers publish listings. The buyer's operator keeps a route file mapping each listing to the configured servers for that seller, because each negotiation file pins exactly one peer.
- 02
The buyer picks the cheapest routed listing inside its ceiling. The advertised band only chooses the seller; the price is fixed by operator files and capped by the buyer's maximum price.
- 03
The loop runs: negotiate on both sides, settle once, recover by observation until finalized.
- 04
With access configured, the resource is retrieved and recorded as delivered with its hash. Delivery is an off-chain observation, never settlement evidence.
What a chain reader sees
- public
Shielded settlement calldata carries the proof, chain, pool, asset, deal commitment and nullifier, root and note commitments. It does not carry the plain amount or participant keys.
- public
Public-bound settlement exposes the accepted terms and parties.
- public
Every transaction shows its gas sender, target, timing and fees.
uv run python agents/src/erebus_agents/marketplace_demo.py --registry registry.json \
--routes buyer-routes.json --capability summarize-documents \
--ceiling-unit-price 8 --operation <64-hex operation ID>Buy compute, data or an API response.
The same purchase, named by what is being bought.
How it works
- 01
Compute, a dataset and an API response are the same shape: one buyer, one seller, one settlement, one off-chain deliverable.
- 02
So this is the marketplace purchase under a capability for that kind. It needs no new mechanism.
What a chain reader sees
- public
Shielded settlement calldata carries the proof, chain, pool, asset, deal commitment and nullifier, root and note commitments. It does not carry the plain amount or participant keys.
- public
Public-bound settlement exposes the accepted terms and parties.
- public
Every transaction shows its gas sender, target, timing and fees.
uv run python agents/src/erebus_agents/offchain_purchase_demo.py --kind compute \
--registry registry.json --routes buyer-routes.json \
--ceiling-unit-price 8 --operation <64-hex operation ID>Pay per API call.
Each call is one deal on the operator-selected x402-exact rail.
How it works
- 01
The buyer's x402 server exposes only negotiate_deal and retrieve_service_access.
- 02
The first retrieval signs one local Permit2 authorization and the seller submits it. Every retry is another retrieval that reuses the retained permit.
- 03
Operation IDs are written to an owner-only ledger before the first call, so an interrupted run resumes without fresh IDs and never pays twice.
- 04
Nothing on this path verifies payment independently. An auditor does that from the disclosure grant.
What a chain reader sees
- public
Standard x402 is public, not private: accepted terms and identities are visible.
- public
Every transaction shows its gas sender, target, timing and fees.
uv run python agents/src/erebus_agents/api_gateway_demo.py --buyer-negotiation buyer.json \
--buyer-access buyer-access.json --seller-negotiation seller.json \
--calls 3 --ledger calls.jsonPrepay for a bundle of calls.
One settlement buys N calls; the agent spends them and never overdraws.
How it works
- 01
The buyer's operator selects the metered access profile, which adds metered_service_status and call_metered_service.
- 02
One run of the loop settles the bundle. Its size and price come from the operators' files.
- 03
Calls are spent against the seller's reported allowance. A pending call is retried by calling again, never by paying, and nothing is called after exhaustion.
- 04
Rust keeps the call cursor and the seller's issuer is the authority on how many calls were bought.
What a chain reader sees
- public
Shielded settlement calldata carries the proof, chain, pool, asset, deal commitment and nullifier, root and note commitments. It does not carry the plain amount or participant keys.
- public
Public-bound settlement exposes the accepted terms and parties.
- public
Every transaction shows its gas sender, target, timing and fees.
uv run python agents/src/erebus_agents/saas_metering_demo.py --buyer-negotiation buyer.json \
--buyer-payment payment.json --buyer-access buyer-metered-access.json \
--seller-negotiation seller.json --operation <64-hex operation ID> --calls 5Show a deal receipt.
Turn an independent audit into a receipt a person can read.
How it works
- 01
An auditor runs metropolis_audit.py against the issuer's disclosure grant.
- 02
The receipt keeps three facts apart: the agreement matched, the payment matched, and delivery was never proven by the protocol.
- 03
A pending payment is shown as pending, not failure. A receipt that claims delivery verification is refused.
What a chain reader sees
- public
The deal commitment is in the settlement calldata, so a chain reader already has it.
uv run python agents/src/erebus_agents/receipt_explorer.py --report audit.json \
--issuer <participant> --format html --out receipt.htmlTools in the browser.
Two pages that read files you already have. They run entirely in this tab: nothing is uploaded, and neither asks for a key.
Not yet on the real path.
On the real path, price, asset and counterparty are fixed by operator files and enforced in Rust, and negotiation returns no amount. These need an interface change before they can run there.
- Request for quote
There is no quote exchange, and descriptors carry no price by design.
- Vendor selection
It compares agreed amounts, and the real path never returns an amount to the agent.
- Spending firewall and grants
They check amounts the agent cannot see. Rust already enforces the per-deal maximum, the asset and the pinned peer.
Unaudited. No external security review has been done. Do not put real value through it.