Drops the ~60 ticket-prefix comments (CRIT-N, HIGH-N, MED-N, LOW-N, L-N, M-N, AUDIT-N, PLUTUS-N, "audit fix (date):", "Phase N" labels, "Adversarial-review fix:") that had accumulated in inline + doc comments over several audit cycles. Where the surrounding prose still carried useful WHY context it gets kept and tightened; where the ticket WAS the comment it gets dropped entirely. No logic, no renames, no behavior change. Audit history lives in commit messages and the audits/ tree where it belongs — eternal comments don't need to mirror it. Net 138 LOC shorter. 253 tests pass, no new clippy or fmt warnings. |
||
|---|---|---|
| .cargo | ||
| aiken-escrow | ||
| audits | ||
| crates | ||
| docs | ||
| .dockerignore | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
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
# Requires rustc 1.75+
cargo build --release
For the Plutus validators (escrow) you also need Aiken:
cd aiken-escrow
aiken build # produces plutus.json blueprint
Run
# 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. Never written to disk in plaintext.
- Derived keys: in-memory only,
ZeroizeOnDropon 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 — Rust Cardano
primitives. Aldabra uses a fork
on the
feat-aux-databranch that addsauxiliary_data+voting_proceduressupport topallas-txbuilder. PR upstream pending. - Aiken — Plutus V3 validator language used for the escrow contract.
- modelcontextprotocol/rust-sdk
(
rmcp) — MCP server framework. - age — at-rest encryption.