README + supporting docs were written for ourselves (deployment paths,
internal product comparisons, internal task lists, build pipeline
artifacts) instead of for users of the software. This pass refocuses
them on what the software is, how to install, configure, and use it.
- README.md: full rewrite. New shape — What it does / Architecture /
Build / Run / Configuration / MCP tools / Security model / Status /
License / Dependencies. Drops the internal "why we built it"
narrative, drops phase-status claims that drifted stale, drops
internal deployment paths.
- ROADMAP.md: deleted. Was an internal task-list with [x]/[ ] items
showing incremental private development. The README's Status
section now communicates what's actually shipped.
- docs/architecture.md: scrub cross-project comparisons referencing
unrelated internal Sulkta codebases.
- aiken-escrow/README.md: drop reference to a non-existent spec file;
rewrite the Status checklist to reflect what's actually done
rather than what was open at the time of writing.
- audits/2026-05-09-escrow-e2e.md: scrub internal image names +
container paths; the audit findings (chain hashes, validator hash,
what each tx proved) are the public-useful part and stay.
- audits/2026-05-09-escrow-internal-audit.md: drop references to
feature-flag-gated branches that no longer exist.
- Dockerfile: drop the dead `escrow_wip surface` phrase from comments.
- Cargo.toml: drop the cross-project comparison comment that named
an unrelated internal service.
- crates/aldabra-{core,dao}: scrub internal preprod-test naming from
source comments — same technical content, generic phrasing.
160 lines
6.6 KiB
Markdown
160 lines
6.6 KiB
Markdown
# 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. |
|
|
|
|
## 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.
|