This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a multi-language monorepo for Seedelf, a Cardano stealth wallet. Two top-level components:
- seedelf-contracts/ — on-chain validators written in Aiken.
- seedelf-platform/ — a Cargo workspace of Rust crates implementing the CLI, GUI, and supporting libraries.
The on-chain contract and the off-chain Rust code must stay in sync: the Rust code hardcodes the compiled script hashes produced by compile.sh (see seedelf-contracts/README.md for current version-1 hashes). Changing validator code or the acabcafe random seed changes the hashes, which must then be updated in the Rust constants.
Aiken contracts (seedelf-contracts/)
aiken check # run all on-chain tests
aiken check -m <module> # run tests in a specific module
./compile.sh # full rebuild: aiken build + apply seed + emit plutus.json, contracts/, hashes/compile.sh requires aiken, cardano-cli, python3, and the cbor2 python package. It bakes the seed acabcafe into each validator via aiken blueprint apply and writes the resulting script hashes to hashes/.
Rust workspace (seedelf-platform/)
Cargo workspace rooted at seedelf-platform/Cargo.toml. The workspace [patch.crates-io] section rewrites the inter-crate deps to local paths, so local edits propagate immediately — don't remove this when bumping versions.
cargo build --release --bin seedelf-cli
cargo install --path seedelf-cli --bin seedelf-cli
cargo run -- help # run the CLI from the workspace root
cargo test -p <crate> # run tests for one crate
cargo test -p seedelf-crypto <name> # single testTauri 2 + React/Vite frontend. The Rust side (src-tauri) is a workspace member.
npm install
npm run tauri # cargo tauri dev — dev build of the desktop app
npm run build # tsc + vite build of the frontend
npm run lint # prettierCrate boundaries (seedelf-platform/)
- seedelf-crypto — BLS12-381 primitives. register.rs defines the
Register { generator, public_value }datum type; schnorr.rs implements the non-interactive Schnorr Σ-protocol (Fiat-Shamir) used to prove spendability. Thevkhone-time pad in proofs prevents rollback-replay attacks. - seedelf-koios — thin client for the Koios REST API (UTxO queries, tx submission/evaluation). Koios is the sole data layer; no local node.
- seedelf-core — wallet-level domain logic: address types, asset handling, UTxO selection, on-chain
constants(script hashes, network params), transaction building atop Pallas. - seedelf-display — TUI/text formatting, color, version-check helpers shared by CLI and GUI.
- seedelf-cli — binary entrypoint. One module per subcommand in src/commands/ (
create,fund,transfer,sweep,remove,balance,welcome,util/,external/). web_server.rs spins up a local static site at127.0.0.1:44203to bridge CIP30 browser wallets for signing. - seedelf-gui/src-tauri — Tauri shell re-exposing CLI flows to a React frontend.
Dependency direction: cli/gui → core → crypto + koios + display. Crypto and koios are leaf crates.
On-chain contracts (seedelf-contracts/)
- validators/wallet.ak — spending validator. Verifies a Schnorr NIZK proof of knowledge of the discrete log for the UTxO's
Register. - validators/seedelf.ak — minting policy for the
5eed0e1f…-prefixed identifier tokens (see root README.md for the token-name scheme). - validators/always_false.ak — utility script.
- lib/schnorr.ak, lib/token_name.ak — shared on-chain logic; the schnorr verifier here must match
seedelf-crypto's prover exactly.
These constraints are load-bearing for correctness and safety — a mistake here can create permanently locked UTxOs (see README.md §Wallet Limitations):
- A re-randomized register must apply the same scalar
dto bothgeneratorandpublic_value.(g^d, u^d)spendable;(g^d, u^d')is a dead UTxO. - Points pushed into a
Registermust be torsion-free (in the BLS12-381 prime-order subgroup). The validator rejects non-prime-order points, which also yields a dead UTxO. The CLI enforces this; callers constructing registers directly must callis_torsion_free()or multiply by the cofactor first. - Proof
z = r + c·x;ccomes from Fiat-Shamir including the one-time signing key hashvkh— omittingvkhreintroduces the rollback-replay vector.
- Rust workspace version is pinned in
[workspace.package]of seedelf-platform/Cargo.toml; the inter-crate deps in[workspace.dependencies]must match. Bump them together. - Contract versioning is exposed via the CLI's
--variantflag (defaults to1); the core crate selects script hashes per variant.