Turn any agent's Ed25519 identity key into its own self-custodied wallets. One command, no third party holding anything.
Status: v0.3.2. The spec is SPEC_V1.md; the daemon, the agent client library, the KDF, and the installer below are built and tested. EVM testnet drill green — the §10 on-chain drill passed on Robinhood Chain testnet 46630 (2026-09-20) with throwaway funds; Sage/XCH steps still pending. No release is published until Speechless tests first.
- Primary deliverable: every agent's own native EVM wallet, derived from its existing Ed25519 key.
- Bonus: native Chia via Sage (headless CLI) — same root, same daemon, same policy engine.
- Per-agent custody: each agent runs its own daemon, its own Sage, its own keys, on its own machine. No central authority — one compromised agent is one compromised wallet, never the town.
- Policy in code, not prompts: a local non-LLM daemon is the only process that holds secrets or signs. It enforces caps, allowlists, velocity limits, and a human-approval queue. Conversational agents only ever call its API.
- Agent-agnostic: the only input is a 32-byte seed. Musebook muses,
Claude-based agents, anything — same derivation, same wallets. Any
MCP client (Claude Code / Desktop, Cursor, Codex, Gemini CLI, VS Code,
OpenAI Agents SDK) plugs in with
spellbook-mcp; function-calling loops use the same tool schemas; shell agents use the CLI — docs/AGENT_INTEGRATIONS.md.
The wallet belongs to the agent; the human interacts with it from chat:
agent surfaces intent (read-only) → human approves (their own tooling)
→ daemon executes → agent reports
The agent can request and relay but never approve — the two-token split is enforced by the daemon, not by convention.
Never curl | bash. Verify first, then run:
curl -fsSL -o install.sh \
https://raw.githubusercontent.com/awizardxch/Spellbook/0.3.2/install.sh
# check the sha256 against the pinned town thread, then:
bash install.sh 0.3.2 --agent-user <agent-os-user> --human-user <your-login>Releases are signed with the Spellbook release key. The fingerprint is the trust anchor — cross-check it against the pinned town thread, never against a value that arrived inside a release:
7DEA43CA62DF3F8FB041C1551FCF79089E54DC35
Import the key and hand the installer the fingerprint you verified:
curl -fsSL https://raw.githubusercontent.com/awizardxch/Spellbook/main/docs/release-key.asc | gpg --import
sudo SPELLBOOK_RELEASE_KEY_FPR=7DEA43CA62DF3F8FB041C1551FCF79089E54DC35 \
bash install.sh 0.3.2 --agent-user <agent-os-user> --human-user <your-login>Full key details and custody: docs/RELEASE_KEY.md.
Add --no-sage for an EVM-only install (the default build compiles the
Sage CLI from the pinned commit — needs a Rust toolchain and build time;
an operator-supplied binary is accepted only with SAGE_PIN_VERIFIED=1). The installer:
- verifies the release tarball (checksum + release-key signature — fail closed),
- creates the dedicated
spellbookOS user and the 0600/0700 layout, - generates the wallet seed once and prints the 24-word paper backup once,
- installs the daemon into an isolated venv, writes the default-off policy,
- runs the §10 off-chain drill with a throwaway key (KDF vectors + daemon lifecycle) — install completes when the drill passes.
pip install spellbook # once a release is published; until then: pip install git+https://github.com/awizardxch/Spellbook@0.3.2from spellbook.client import AgentClient, HumanClient
# The agent: request token only. Surfaces intent, never approves.
agent = AgentClient("/run/spellbook/spellbook.sock", request_token_hex)
agent.request_spend(chain="evm-4663", destination="0x...",
amount_wei=10**15, purpose="invoice #42")
agent.queue() # decoded intent: chain/destination/asset/amount/purpose
agent.status()
agent.addresses() # {label: {chain: address}}
agent.ledger() # decision rows, read through the API never the file
# The human: approve token only, on their own tooling (separate device).
human = HumanClient("/run/spellbook/spellbook.sock", approve_token_hex)
human.approve(queue_id)
human.reject(queue_id)Or the CLI: spellbook status | queue | ledger | addresses | request-spend …
(request token via $SPELLBOOK_REQUEST_TOKEN) and
spellbook approve|reject <queue_id> (approve token via
$SPELLBOOK_APPROVE_TOKEN). Full guide: docs/agent-quickstart.md.
SPEC_V1.md— the build plan (canonical)src/spellbook/— the pip packagedaemon.py—spellbookd: Unix-socket policy daemon (token auth, per-role peer-UID enforcement, policy engine, persistent queue, 24h velocity, decision ledger, KDF-wired addresses)kdf.py— §2 KDF: HKDF-SHA256 + reject/resample, then audited curve libs (libsecp256k1, py_ecc, Keccak). Third implementation reproducingvectors/vectors.jsonbyte-for-bytesign.py— signing primitives (ECDSA, BLS, Ed25519 identity signing behind the S1 gate; fixed domain prefixes)seed.py— seed loading (0600, fail closed) + BIP-39 paper backupclient.py—AgentClient/HumanClient: the two-token split as codecli.py— thespellbookoperator CLIdrill.py— the §10 off-chain drill runnerpolicy.py,ledger.py,tokens.py,config.py
tests/— 30 tests: all 10 KDF vectors, signing, full daemon lifecyclevectors/— canonical KDF vectors + the two independent generatorsinstall.sh— verified installer (see above)docs/— reviews and guides
Real: KDF (3rd impl, vectors green), signing primitives, daemon (auth, policy, persistent queue, velocity, ledger, addresses), EVM chain layer (live balances, eth_estimateGas-based limits, sign + submit + receipts, testnet-guarded), agent client + CLI, installer, off-chain drill, and the §10 on-chain testnet drill — green on Robinhood Chain testnet 46630 (2026-09-20).
Next, each needing explicit authorization: Sage/XCH drill steps (the pinned-commit build path is implemented as of 2026-09-20; the live drill run is still pending), then — separately authorized — mainnet dust with Speechless-approved amounts. The O9 single-device fallback still awaits a decision (§12a).