# aldabra Rust-native Cardano lite wallet with an MCP-server interface. Built for LLM-first usage — send/receive ADA + native assets, mint, Plutus script interaction, Conway governance, and a full Agora-on-Cardano DAO client. Named for the Aldabra giant tortoise: long-lived, defended, slow but unstoppable. ## What it does - **Wallet primitives.** Address derivation (CIP-1852), balance + UTXO queries, ADA + native-asset transfers, multi-sig partial signing, encrypted-at-rest mnemonic. - **Minting.** CIP-25 + CIP-68 native assets, custom timelock / multisig policies, unsigned-tx flows for cold signing. - **Plutus V3.** Spending script-locked UTXOs with redeemers, reference scripts, inline datum support. - **Stake + Conway governance.** Pool delegation, DRep registration + deregistration, vote delegation, DRep vote casting on governance actions. - **DAO.** Agora-on-Cardano client — register multiple DAOs, view stakes, create + cosign + vote on proposals, advance state-machine, retract votes, destroy stakes. - **Escrow.** Two-party agreement-with-veto Plutus V3 validator with off-chain builders for the full open / deposit / agree / veto / settle / refund lifecycle. ## Architecture Cargo workspace with four crates: | Crate | Responsibility | |---|---| | `aldabra-core` | Pure crypto + types. Mnemonic → root key (CIP-3), root → payment + stake keys (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 default implementation. | | `aldabra-dao` | Off-chain side of the Agora DAO + escrow validators. Codecs + unsigned-tx builders. | | `aldabra-mcp` | Binary. MCP server speaking stdio. Wires the other crates together and exposes tools to the LLM client. | ``` ┌─────────────────────────────┐ LLM client │ aldabra-mcp (bin) │ stdio ─────────► │ tool handlers, lifecycle │ ────► └──────────┬──────────────────┘ │ ┌────────┼────────┐ ▼ ▼ ▼ ┌──────────┐ ┌──────┐ ┌─────────┐ │ -core │ │-chain│ │ -dao │ │ keys/sig │ │ Koios│ │ Agora/ │ │ │ │ │ │ escrow │ └──────────┘ └──────┘ └─────────┘ ``` ## Build ```bash # Requires rustc 1.75+ cargo build --release ``` For the Plutus validators (escrow) you also need [Aiken](https://aiken-lang.org/): ```bash cd aiken-escrow aiken build # produces plutus.json blueprint ``` ## Run ```bash # Smoke test (does nothing useful standalone — needs an MCP client) ./target/release/aldabra # As an MCP server registered with Claude Code, add to ~/.claude.json: # "aldabra": { # "command": "/path/to/aldabra", # "env": { # "ALDABRA_DATA": "/path/to/wallet-data-dir", # "ALDABRA_NETWORK": "preprod", # "ALDABRA_KOIOS_BASE": "https://preprod.koios.rest/api/v1" # } # } ``` Bootstrap a wallet on first run by setting `ALDABRA_BOOTSTRAP=new` or `ALDABRA_BOOTSTRAP=import` in env — the binary prompts for a passphrase, generates or imports a mnemonic, and writes an age-encrypted `mnemonic.age` to `ALDABRA_DATA`. ## Configuration Environment variables consumed at startup: | Var | Required | Default | Notes | |---|---|---|---| | `ALDABRA_DATA` | yes | — | Directory holding `mnemonic.age`. Must exist; bootstrap before first MCP run. | | `ALDABRA_NETWORK` | no | `preprod` | One of `mainnet`, `preview`, `preprod`. | | `ALDABRA_KOIOS_BASE` | no | public Koios for the chosen network | Override to point at a self-hosted Koios. | | `ALDABRA_PASSPHRASE` | yes | — | Unlocks `mnemonic.age`. Source from a docker secret or systemd `EnvironmentFile` — never commit it. | | `ALDABRA_BOOTSTRAP` | no | (unset) | Set to `new` or `import` to enter bootstrap mode on next launch. | | `ALDABRA_MAX_SEND_LOVELACE` | no | mainnet 10 ADA / preprod\|preview 100 tADA | Hard cap on lovelace flowing to any non-self destination. Enforced by every tool that signs or submits; pass `force=true` per-tool to override. | | `ALDABRA_SAFE_READS_ROOT` | no | `$ALDABRA_DATA/scripts/` | Sandbox dir for the `reference_script_path` / `policy_cbor_path` tool args. Files outside this dir (canonical) are refused. Created with 0o700 at startup if missing. | ## MCP tools The server exposes ~40 tools across four prefixes. A summary: - `wallet_*` — read (address/balance/utxos/network/stake_address), send (with optional inline datum for script locks), mint, Plutus script spending, stake delegation, Conway governance (vote delegation, DRep operations). - `chain_*` — read-only Koios passthroughs (tx info, address info, pool list/info, epoch params, asset info, account info, tip). - `dao_*` — Agora DAO client. Multi-DAO via config files. Live reads (governor state, stake list, my stake) plus the full write set: proposal create / cosign / vote / advance / retract-votes / stake-destroy. - `escrow_*` — two-party agreement-with-veto escrow. Build unsigned txs for open / deposit / agree / veto / settle / refund-timeout. Every write tool produces an unsigned tx for the caller to sign + submit. No tool ever holds private keys outside the in-memory derived-key scope. ## Security model - **Mnemonic source:** interactive bootstrap on first run, paste once or generate, encrypted at rest with [age](https://github.com/FiloSottile/age). Never written to disk in plaintext. - **Derived keys:** in-memory only, `ZeroizeOnDrop` on every container. - **Network exposure:** stdio MCP transport — the binary never opens a TCP listener. Only the spawning client process can talk to it. - **Multi-network:** safe to point at preprod for development; the same binary handles mainnet when you flip `ALDABRA_NETWORK`. ## Status Wallet + governance paths exercised on **mainnet**. DAO + escrow paths exercised end-to-end on **preprod**; the escrow validator has undergone internal review (`audits/`) but **no third-party audit**. Treat the escrow flows as use-at-own-risk until external review lands — see `aiken-escrow/README.md` for the WIP threat model. ## License See `LICENSE`. ## Dependencies of note - [txpipe/pallas](https://github.com/txpipe/pallas) — Rust Cardano primitives. Aldabra uses a [fork](https://github.com/Sulkta-Coop/pallas) on the `feat-aux-data` branch that adds `auxiliary_data` + `voting_procedures` support to `pallas-txbuilder`. PR upstream pending. - [Aiken](https://aiken-lang.org/) — Plutus V3 validator language used for the escrow contract. - [modelcontextprotocol/rust-sdk](https://github.com/modelcontextprotocol/rust-sdk) (`rmcp`) — MCP server framework. - [age](https://github.com/FiloSottile/age) — at-rest encryption.