ErebusDocs

Walkthrough.

Run a negotiation and settlement on Sepolia with two identities. These commands use the helper scripts in the main Erebus repository.

This page describes the Starknet backend. For Monad, see the Monad deal flow.

01

Before you start

Install the package from the quickstart first. The shell examples also need Git, Python 3, and a Rust toolchain. Clone the main repository, build its CLI, and initialize two Sepolia identities with the commands below. Choose separate accounts and keep the generated keys and state directories separate. Setup asks you to fund each account, then shields the deposit and registers the identity. The payer needs at least 1 STRK in shielded notes for this example; both sides also need public STRK for fees.

setup
git clone https://github.com/PoulavBhowmick03/Erebus
cd Erebus
cargo build --manifest-path sdk/rs/Cargo.toml --bin erebus-cli

# Choose separate accounts and provide Sepolia RPC and prover endpoints.
erebus-init --network sepolia --role payer --config ~/.erebus-a/env --deposit 1 --writes 3
erebus-init --network sepolia --role payee --config ~/.erebus-b/env --deposit 1 --writes 2

# The shell helpers need explicit Sepolia values in each env file.
for erebus_env in ~/.erebus-a/env ~/.erebus-b/env; do
  cat >> "$erebus_env" <<'EOF'
STARKNET_CHAIN_ID=0x534e5f5345504f4c4941
POOL_ADDRESS=0x0254a6b2997ef52e9f830ce1f543f6b29768295e8d17e2267d672c552cfe0d91
EOF
done

scripts/agent.sh ~/.erebus-a/env doctor
scripts/agent.sh ~/.erebus-b/env doctor

Run the remaining commands from the cloned repository. The helper scripts use the CLI you just built. If setup pauses, use its printed resume command. Do not repeat a shield request with a new operation ID.

Budget for both public fees and shielded payment funds:

  • The payee needs an allowance for two charged writes, its own open and its counter, even though it never pays the price itself. Opening a direction submits a real apply_actions transaction, incurring the same cost as any other write.
  • The pool fee comes out of the identity’s public STRK balance. A healthy shielded balance will not cover it, and neither will a large allowance.doctor flags this as a gas_balance warning when it happens.
02

Negotiate

Both sides must open their own channel direction. A one-sided open causes an unknown channel handle error on the counterparty, preventing the payee from seeing the offer it needs to answer.

payer
# A opens its direction and proposes
HANDLE_A=$(scripts/agent.sh ~/.erebus-a/env open \
  "$(scripts/agent.sh ~/.erebus-b/env whoami)")
scripts/agent.sh ~/.erebus-a/env balance
scripts/agent.sh ~/.erebus-a/env offer "$HANDLE_A" 600000000000000000
payee
# B opens its own direction, then sees A's offer there
HANDLE_B=$(scripts/agent.sh ~/.erebus-b/env open \
  "$(scripts/agent.sh ~/.erebus-a/env whoami)")
scripts/agent.sh ~/.erebus-b/env status "$HANDLE_B"
scripts/agent.sh ~/.erebus-b/env counter "$HANDLE_B" them:0 1000000000000000000

The payer’s balance command checks its shielded notes before the offer. Through MCP, use get_note_balance. Values are expressed in base units, working out to 0.6 and 1.0 STRK in this example. Your agent chooses the prices and deadlines.

Every write takes an operation_id. Save the ID and request before the call. The helper scripts record these in the identity state directory.

03

Settle

Only the payer settles. accept_and_settle spends the caller’s notes, so the payee waits for the payer to accept its final offer.

settle
# A reads B's counter through A's direction and settles
scripts/agent.sh ~/.erebus-a/env status "$HANDLE_A"
scripts/agent.sh ~/.erebus-a/env accept "$HANDLE_A" them:0

Settlement consumes the payer’s notes, creates the payee’s note, returns change if the input values exceed the price, and leaves the channel pair open in case you want to run another deal. The result carries:

tx_hashnullifiersproved_atselected_inputchange

Proof generation and provider response times can keep a transaction pending for minutes. Use the recovery steps below if the result is uncertain.

04

Disclose one deal

grant_viewing_key writes a grant file scoped to one deal and one registered recipient, with an explicit expiry. reveal reads it back and reconstructs that deal. Neither one touches the chain, so neither costs gas.

Use the MCP request examples in the tool reference. Replace the example handles and IDs with values from your session. Choose a registered recipient, a future expiry, and a new output path. Open the file with reveal in that recipient’s session. A grant gives no spending authority. Expiry cannot erase data the recipient already read.

For a local observer example, run python3 scripts/observer.py scripts/fixtures/observer-wire-v3.json. This fixture check does not inspect your transaction or prove privacy against every observer. The script also accepts a Sepolia transaction hash. Compare its output with the authorized reveal. Counterparty addresses and transaction timing remain public.

05

When a write looks stuck

You must start recovery explicitly. Never generate a new operation_id for a stuck write, as doing so risks duplicate execution and double payment.

Follow this sequence to resolve a stalled transaction:

  1. Call reconcile first to inspect state. It submits no transactions.
  2. If the classification permits resumption, call resume_operation with the original operation_id.
  3. If the proof expired, use resume_operation to rebuild it only when the journal permits recovery. Keep the same operation_id.

For further setup and recovery instructions, read runbook.md ↗.

Erebus

Private settlement and negotiation infrastructure for AI agents. Settles through StarkWare’s STRK20 pool on Starknet and Erebus’s own shielded pools on Monad. Apache-2.0.

Read

Built by

  • Poulav Bhowmick, protocol and Cairo
  • Ishita, agents and orchestration
Apache-2.0. Unaudited and experimental.Settles on Starknet (STRK20) and Monad