From 1f1993ed97ba4a4994ba922e166c96975ed4d3f1 Mon Sep 17 00:00:00 2001 From: Kayos Date: Mon, 4 May 2026 10:11:23 -0700 Subject: [PATCH] =?UTF-8?q?rename:=20sulkta-wallet=20=E2=86=92=20aldabra?= =?UTF-8?q?=20(per=20Cobb=202026-05-04)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aldabra giant tortoise (Aldabrachelys gigantea) — endemic to the Aldabra atoll, up to 250 kg, 150-year lifespan. Long-lived, defended, slow but unstoppable. Better metaphor for the wallet than 'sulkta-wallet' which was on-the-tin descriptive. All renames in one pass: - repo: Sulkta-Coop/sulkta-wallet → Sulkta-Coop/aldabra (via gitea API) - workspace dir: sulkta-wallet → aldabra - crate dirs: wallet-{core,chain,mcp} → aldabra-{core,chain,mcp} - crate names + path imports in Cargo.toml workspace + each crate - binary name: sulkta-wallet → aldabra - README, ROADMAP, docs/architecture: all references swept --- Cargo.toml | 21 +++++++++++------- README.md | 22 +++++++++---------- ROADMAP.md | 16 +++++++------- .../Cargo.toml | 4 ++-- .../src/lib.rs | 2 +- .../{wallet-core => aldabra-core}/Cargo.toml | 10 ++++----- .../{wallet-core => aldabra-core}/src/lib.rs | 2 +- crates/{wallet-mcp => aldabra-mcp}/Cargo.toml | 10 ++++----- .../{wallet-mcp => aldabra-mcp}/src/main.rs | 16 +++++++------- docs/architecture.md | 18 +++++++-------- 10 files changed, 63 insertions(+), 58 deletions(-) rename crates/{wallet-chain => aldabra-chain}/Cargo.toml (87%) rename crates/{wallet-chain => aldabra-chain}/src/lib.rs (97%) rename crates/{wallet-core => aldabra-core}/Cargo.toml (79%) rename crates/{wallet-core => aldabra-core}/src/lib.rs (98%) rename crates/{wallet-mcp => aldabra-mcp}/Cargo.toml (75%) rename crates/{wallet-mcp => aldabra-mcp}/src/main.rs (81%) diff --git a/Cargo.toml b/Cargo.toml index 96eb253..e83263f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,14 @@ -# Cargo workspace root for sulkta-wallet. +# Cargo workspace root for aldabra. # # Three crates: -# wallet-core — key derivation, signing, types, mnemonic handling -# wallet-chain — pluggable chain backends (Koios, Ogmios). Trait-first. -# wallet-mcp — binary; the MCP server, glues core+chain together. +# aldabra-core — key derivation, signing, types, mnemonic handling +# aldabra-chain — pluggable chain backends (Koios, Ogmios). Trait-first. +# aldabra-mcp — binary; the MCP server, glues core+chain together. +# +# Named for the Aldabra giant tortoise (Aldabrachelys gigantea) — endemic +# to the Aldabra atoll in the Seychelles, up to 250 kg, 150-year lifespan. +# Long-lived, defended, slow but unstoppable. Fitting metaphor for a +# wallet that holds your money. # # Workspace deps are pinned here so all three crates use the same versions. # Add a dep here, then reference it in each crate's Cargo.toml as @@ -11,16 +16,16 @@ [workspace] resolver = "2" members = [ - "crates/wallet-core", - "crates/wallet-chain", - "crates/wallet-mcp", + "crates/aldabra-core", + "crates/aldabra-chain", + "crates/aldabra-mcp", ] [workspace.package] version = "0.0.1" edition = "2021" license-file = "LICENSE" -repository = "http://192.168.0.5:3001/Sulkta-Coop/sulkta-wallet" +repository = "http://192.168.0.5:3001/Sulkta-Coop/aldabra" authors = ["Cobb ", "Kayos "] [workspace.dependencies] diff --git a/README.md b/README.md index bdf8588..a879230 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# sulkta-wallet +# aldabra Rust-native Cardano lite wallet with an MCP-server interface — built for LLM-first usage (send, receive, mint, Plutus interaction). @@ -25,20 +25,20 @@ Three crates in a Cargo workspace: | Crate | Responsibility | |---|---| -| `wallet-core` | Pure crypto + types. Mnemonic → root key (CIP-3), root → payment + stake key (CIP-1852), address construction, signing. **No I/O, no network.** This is the security boundary. | -| `wallet-chain` | Pluggable backends for chain queries. `ChainBackend` trait, with Koios as the phase-1 implementation. Ogmios + submission paths in phase 2. | -| `wallet-mcp` | Binary. MCP server speaking stdio. Glues core + chain together, exposes tools to the LLM client. | +| `aldabra-core` | Pure crypto + types. Mnemonic → root key (CIP-3), root → payment + stake key (CIP-1852), address construction, signing. **No I/O, no network.** This is the security boundary. | +| `aldabra-chain` | Pluggable backends for chain queries. `ChainBackend` trait, with Koios as the phase-1 implementation. Ogmios + submission paths in phase 2. | +| `aldabra-mcp` | Binary. MCP server speaking stdio. Glues core + chain together, exposes tools to the LLM client. | ``` ┌─────────────────────────────┐ -LLM client │ wallet-mcp (bin) │ stdio +LLM client │ aldabra-mcp (bin) │ stdio ─────────► │ tool handlers, lifecycle │ ────► └──────────┬──────────────────┘ │ ┌────────┴────────┐ ▼ ▼ ┌──────────────┐ ┌──────────────┐ - │ wallet-core │ │ wallet-chain │ + │ aldabra-core │ │ aldabra-chain │ │ keys, sign │ │ Koios/Ogmios │ └──────────────┘ └──────────────┘ ``` @@ -70,21 +70,21 @@ Phase 4: cargo build --release # Through crafting-table (preferred — validates the toolchain there) -crafting-table build sulkta-wallet +crafting-table build aldabra ``` ## Run ```bash # Direct invocation (smoke test only — does nothing useful in phase 1) -./target/release/sulkta-wallet +./target/release/aldabra # As an MCP server registered with Claude Code: # add to ~/.claude.json: -# "sulkta-wallet": { -# "command": "/path/to/sulkta-wallet", +# "aldabra": { +# "command": "/path/to/aldabra", # "env": { -# "SULKTA_WALLET_DATA": "/mnt/cache/appdata/sulkta-wallet" +# "ALDABRA_DATA": "/mnt/cache/appdata/aldabra" # } # } ``` diff --git a/ROADMAP.md b/ROADMAP.md index 47bee79..737ae6a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -# sulkta-wallet roadmap +# aldabra roadmap Phased buildout. Each phase ships a usable increment + leaves the codebase in a state where Phase N+1 picks up cleanly. @@ -9,12 +9,12 @@ codebase in a state where Phase N+1 picks up cleanly. end-to-end through the MCP transport. - [x] Cargo workspace -- [x] Crate skeletons: `wallet-core`, `wallet-chain`, `wallet-mcp` +- [x] Crate skeletons: `aldabra-core`, `aldabra-chain`, `aldabra-mcp` - [x] Type stubs + ZeroizeOnDrop scaffolding for keys -- [ ] `wallet-core::Mnemonic::into_root_key` — real CIP-3 derivation via `pallas-crypto` -- [ ] `wallet-core::derive_base_address` — real CIP-1852 + bech32 -- [ ] `wallet-chain::KoiosClient::get_utxos` — real `reqwest` to `/address_utxos` -- [ ] `wallet-chain::KoiosClient::get_balance` +- [ ] `aldabra-core::Mnemonic::into_root_key` — real CIP-3 derivation via `pallas-crypto` +- [ ] `aldabra-core::derive_base_address` — real CIP-1852 + bech32 +- [ ] `aldabra-chain::KoiosClient::get_utxos` — real `reqwest` to `/address_utxos` +- [ ] `aldabra-chain::KoiosClient::get_balance` - [ ] Interactive mnemonic bootstrap CLI: paste once, age-encrypt to disk - [ ] On-startup decryption — single passphrase prompt, derived key in RAM only @@ -30,8 +30,8 @@ a Koios query.** **Goal:** the wallet can spend. -- [ ] `wallet-chain::ChainBackend::submit_tx` — POST CBOR to Koios `/submittx` -- [ ] `wallet-chain::tx_status` — poll `/tx_info` +- [ ] `aldabra-chain::ChainBackend::submit_tx` — POST CBOR to Koios `/submittx` +- [ ] `aldabra-chain::tx_status` — poll `/tx_info` - [ ] Build + sign ADA-only payment via `pallas-txbuilder` - [ ] MCP tool `wallet.send` with `to_address`, `lovelace` args - [ ] MCP tool `wallet.tx_status` with `tx_hash` arg diff --git a/crates/wallet-chain/Cargo.toml b/crates/aldabra-chain/Cargo.toml similarity index 87% rename from crates/wallet-chain/Cargo.toml rename to crates/aldabra-chain/Cargo.toml index 1f29241..cc1e50d 100644 --- a/crates/wallet-chain/Cargo.toml +++ b/crates/aldabra-chain/Cargo.toml @@ -1,4 +1,4 @@ -# wallet-chain — pluggable backends for chain queries. +# aldabra-chain — pluggable backends for chain queries. # # A `ChainBackend` trait abstracts over Koios (HTTPS), Ogmios (WS/HTTP), # or any future option. Phase 1 ships with a Koios implementation since @@ -7,7 +7,7 @@ # Submission paths land in phase 2. Read-only queries first. [package] -name = "wallet-chain" +name = "aldabra-chain" version.workspace = true edition.workspace = true license-file.workspace = true diff --git a/crates/wallet-chain/src/lib.rs b/crates/aldabra-chain/src/lib.rs similarity index 97% rename from crates/wallet-chain/src/lib.rs rename to crates/aldabra-chain/src/lib.rs index e458596..22fb90b 100644 --- a/crates/wallet-chain/src/lib.rs +++ b/crates/aldabra-chain/src/lib.rs @@ -1,4 +1,4 @@ -//! sulkta-wallet chain backends — Koios first, Ogmios next. +//! aldabra chain backends — Koios first, Ogmios next. //! //! Trait-first design: the MCP server depends on `ChainBackend`, not on //! a specific implementation. Swapping Koios → Ogmios is a config change. diff --git a/crates/wallet-core/Cargo.toml b/crates/aldabra-core/Cargo.toml similarity index 79% rename from crates/wallet-core/Cargo.toml rename to crates/aldabra-core/Cargo.toml index 420a014..cf13388 100644 --- a/crates/wallet-core/Cargo.toml +++ b/crates/aldabra-core/Cargo.toml @@ -1,4 +1,4 @@ -# wallet-core — pure crypto + types. No I/O, no network. Deterministic +# aldabra-core — pure crypto + types. No I/O, no network. Deterministic # given the same mnemonic + derivation path. # # This crate is intentionally narrow: @@ -6,18 +6,18 @@ # - Root key → payment / stake key (CIP-1852 derivation) # - Address construction (mainnet, testnet) # - Transaction signing (given an unsigned TX builder output from -# wallet-chain or pallas-txbuilder) +# aldabra-chain or pallas-txbuilder) # # It deliberately does NOT: -# - Do any chain queries (that's wallet-chain's job) -# - Talk to MCP (that's wallet-mcp's job) +# - Do any chain queries (that's aldabra-chain's job) +# - Talk to MCP (that's aldabra-mcp's job) # - Touch files (the daemon owns disk I/O; we get keys handed in) # # Rationale: this is the most security-sensitive crate. Keeping it # narrow + I/O-free makes it auditable. [package] -name = "wallet-core" +name = "aldabra-core" version.workspace = true edition.workspace = true license-file.workspace = true diff --git a/crates/wallet-core/src/lib.rs b/crates/aldabra-core/src/lib.rs similarity index 98% rename from crates/wallet-core/src/lib.rs rename to crates/aldabra-core/src/lib.rs index dd2e087..e0349d9 100644 --- a/crates/wallet-core/src/lib.rs +++ b/crates/aldabra-core/src/lib.rs @@ -1,4 +1,4 @@ -//! sulkta-wallet core — keys, addresses, signing. +//! aldabra core — keys, addresses, signing. //! //! This crate is the security boundary. Everything that touches private //! key material lives here, and only here. No I/O, no network, no MCP. diff --git a/crates/wallet-mcp/Cargo.toml b/crates/aldabra-mcp/Cargo.toml similarity index 75% rename from crates/wallet-mcp/Cargo.toml rename to crates/aldabra-mcp/Cargo.toml index 39358ef..2e4000a 100644 --- a/crates/wallet-mcp/Cargo.toml +++ b/crates/aldabra-mcp/Cargo.toml @@ -1,4 +1,4 @@ -# wallet-mcp — the binary. MCP server speaking stdio that exposes +# aldabra-mcp — the binary. MCP server speaking stdio that exposes # the wallet's tools to an LLM. Spawned as a subprocess from any MCP # client (Claude Code, OpenClaw, etc.). # @@ -6,7 +6,7 @@ # between core + chain crates. [package] -name = "wallet-mcp" +name = "aldabra-mcp" version.workspace = true edition.workspace = true license-file.workspace = true @@ -14,12 +14,12 @@ repository.workspace = true authors.workspace = true [[bin]] -name = "sulkta-wallet" +name = "aldabra" path = "src/main.rs" [dependencies] -wallet-core = { path = "../wallet-core" } -wallet-chain = { path = "../wallet-chain" } +aldabra-core = { path = "../aldabra-core" } +aldabra-chain = { path = "../aldabra-chain" } tokio = { workspace = true } anyhow = { workspace = true } diff --git a/crates/wallet-mcp/src/main.rs b/crates/aldabra-mcp/src/main.rs similarity index 81% rename from crates/wallet-mcp/src/main.rs rename to crates/aldabra-mcp/src/main.rs index 129d747..d293679 100644 --- a/crates/wallet-mcp/src/main.rs +++ b/crates/aldabra-mcp/src/main.rs @@ -1,4 +1,4 @@ -//! sulkta-wallet — MCP server entry point. +//! aldabra — MCP server entry point. //! //! Speaks MCP over stdio. Any MCP client (Claude Code, OpenClaw, etc.) //! launches this as a subprocess and gets a wallet's worth of tools. @@ -6,7 +6,7 @@ //! ## Phase 1 tools //! //! - `wallet.address` — return the derived base address (placeholder -//! until wallet-core's CIP-1852 derivation lands) +//! until aldabra-core's CIP-1852 derivation lands) //! - `wallet.balance` — query balance via the configured chain backend //! //! ## Phase 2-4 tools (TODO) @@ -34,7 +34,7 @@ async fn main() -> Result<()> { .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) .init(); - tracing::info!("sulkta-wallet starting (phase 1 scaffold)"); + tracing::info!("aldabra starting (phase 1 scaffold)"); // TODO(phase 1): // 1. Load config (network, koios url, mnemonic path) @@ -47,9 +47,9 @@ async fn main() -> Result<()> { // For now: a smoke-test print so the binary actually does something // when invoked manually (not through MCP). tracing::info!( - target_address = %wallet_core::derive_base_address( + target_address = %aldabra_core::derive_base_address( &dummy_root_key()?, - wallet_core::Network::Mainnet, + aldabra_core::Network::Mainnet, 0, 0, )?, @@ -62,13 +62,13 @@ async fn main() -> Result<()> { /// Phase 1 only — produces a zero-bytes RootKey so the placeholder /// address derivation runs. Will be deleted once real mnemonic loading /// lands. -fn dummy_root_key() -> Result { +fn dummy_root_key() -> Result { // Need a way to construct one from this crate without exposing // private fields. Phase 1: temporary public constructor on - // wallet-core, gated behind a #[cfg(test)] or feature flag and + // aldabra-core, gated behind a #[cfg(test)] or feature flag and // removed before phase 2. // // For tonight: this fn is a TODO marker — the smoke test won't - // actually run until we finish wallet-core::Mnemonic::into_root_key. + // actually run until we finish aldabra-core::Mnemonic::into_root_key. anyhow::bail!("phase 1 scaffold: real mnemonic loading not yet implemented") } diff --git a/docs/architecture.md b/docs/architecture.md index f089e9b..d303062 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,4 +1,4 @@ -# sulkta-wallet architecture notes +# aldabra architecture notes Deeper design notes than the README. Read this before extending. @@ -7,15 +7,15 @@ Deeper design notes than the README. Read this before extending. The three-crate split exists to keep the security-sensitive code auditable in isolation. -- `wallet-core` — **no I/O.** Given a mnemonic + a derivation path, +- `aldabra-core` — **no I/O.** Given a mnemonic + a derivation path, produces keys + addresses + signatures. Deterministic, no dependencies on tokio, reqwest, MCP, or anything that could introduce side channels. Easy to audit because it's narrow. -- `wallet-chain` — **all the I/O lives here.** Trait-first so the MCP +- `aldabra-chain` — **all the I/O lives here.** Trait-first so the MCP layer never knows whether it's talking to Koios, Ogmios, or a future backend. Future contributors swap implementations without touching the security-sensitive crate. -- `wallet-mcp` — **the binary glue.** Owns process lifecycle, config +- `aldabra-mcp` — **the binary glue.** Owns process lifecycle, config loading, MCP transport, tool registration, error mapping. The thinnest layer. @@ -36,7 +36,7 @@ roughly in order: `--dry-run` flag for any state-changing tool. 2. **Daemon process compromise.** If the wallet binary is exploited (e.g. via a malformed Koios response triggering memory corruption), - the keys are at risk. Mitigations: keep `wallet-core` narrow + the keys are at risk. Mitigations: keep `aldabra-core` narrow (smaller attack surface), zeroize on drop, future: drop privileges + seccomp the daemon. 3. **Disk read.** The encrypted mnemonic on disk could be exfiltrated. @@ -56,18 +56,18 @@ roughly in order: First run: user pastes mnemonic at interactive prompt ↓ - wallet-mcp asks for an encryption passphrase + aldabra-mcp asks for an encryption passphrase ↓ age-encrypt the mnemonic phrase ↓ - write to $SULKTA_WALLET_DATA/mnemonic.age + write to $ALDABRA_DATA/mnemonic.age ↓ derive RootKey, hold in RAM, zeroize the source phrase ↓ daemon ready Subsequent runs: - read $SULKTA_WALLET_DATA/mnemonic.age + read $ALDABRA_DATA/mnemonic.age ↓ prompt for passphrase ↓ @@ -114,7 +114,7 @@ phase-2 design is: 2. Returns the unsigned CBOR + a one-line human summary ("send 100 ADA to addr1xyz, fee 0.17 ADA, expected balance after: …"). 3. LLM relays the summary to Cobb, gets approval. -4. Cobb runs a separate `sulkta-wallet-cold-sign` CLI on a different +4. Cobb runs a separate `aldabra-cold-sign` CLI on a different box (offline laptop, cardano-signer, whatever) — paste the CBOR, approve, paste back the signed CBOR. 5. `wallet.submit_signed_tx` takes the signed CBOR + submits.