Rust implementation of arkd by the Arkade team — Ark protocol server for Bitcoin Layer 2 scaling.
dark is a server implementation of the Ark protocol, a Bitcoin scaling solution that enables fast, low-cost off-chain Bitcoin transactions with on-chain security guarantees.
Beyond behavioral parity with Go arkd, dark adds a Confidential VTXO layer: amounts and recipients are hidden behind Pedersen commitments, range proofs, and stealth ephemeral pubkeys, while operators retain the validation guarantees they need to run the network.
dark ships first-class confidential outputs as an additive extension to the transparent Ark protocol. Existing Go arkd clients keep interoperating; new clients can opt in to the confidential variant on a per-output basis.
What's wired up:
dark-confidentialcrate — secp256k1 Pedersen commitments, Back-Maxwell range proofs (viasecp256k1-zkp), Schnorr balance proofs, deterministic nullifiers, stealth scanning, viewing-key issuance, and selective-disclosure helpersVtxo::Confidentialdomain variant indark-corecarrying commitment, range proof, owner / ephemeral pubkeys, encrypted memo, and nullifierproto/ark/v1/confidential.proto— additiveConfidentialVtxopayload behind avtxo_bodyoneof onVtxoandIndexerVtxo, with reserved field-number ranges for future confidential-only extensions- SQLite + PostgreSQL migrations for the confidential columns alongside the existing transparent rows; indexed nullifier lookups for VTXO resolution
dark-clientconfidential transaction builder, encrypted local cache for owned confidential VTXOs, deterministic blinding derivation from seed, ChaCha20-Poly1305 memo AEAD per ADR-0003ark-cliconfidentialsend/receive/scanand stealth-address commands; confidential-aware balance + history- Real Bitcoin tapscript builder for confidential VTXO unilateral exits; gRPC validator wired through the API path
- Property-based test suite, Criterion benchmarks, and end-to-end regtest tests covering confidential + compliance + exit flows
- Architecture decisions captured in
docs/adr/(secp256k1-zkp integration, nullifier derivation, encrypted-memo wire format, confidential fees, exit script) anddocs/protocol/
See the SDK guide and migration guide below to integrate from a transparent client.
Advantages over the Go implementation:
- Memory safety at compile time: no null pointers, no data races, no memory leaks without
unsafe - Deterministic, zero-GC performance: no garbage collector pauses during round finalization or signing sessions
- Native Bitcoin ecosystem:
rust-bitcoin,BDK,secp256k1are first-class; Go relies onbtcdports - Stronger type system: protocol invariants encoded in types, not just documentation
- Single static binary: no runtime dependencies, simpler deployment than Go's dynamic linking
dark is a full behavioral-parity Rust reimplementation of the Go arkd server. It covers the complete Ark protocol: VTXO tree construction, round management, MuSig2 signing (BIP-327), fraud detection, forfeit verification (Tapscript), SQLite/PostgreSQL persistence, Esplora scanning, gRPC API (ArkService + AdminService + WalletService + IndexerService + SignerManagerService), CEL-based fee programs, macaroon auth + TLS auto-generation, Nostr VTXO notifications, OpenTelemetry scaffolding, and a regtest E2E integration test suite.
Beyond Go parity: the confidential VTXO subsystem (Pedersen commitments, range and balance proofs, nullifiers, stealth addressing, selective disclosure) plus the protobuf, domain, storage, client, CLI, and exit-script extensions that carry confidential outputs end-to-end on the wire and at rest.
dark/
├── src/
│ ├── main.rs # Server binary entry point
│ ├── cli.rs # CLI argument parsing
│ ├── config.rs # Configuration loading
│ └── telemetry.rs # OpenTelemetry setup
├── crates/
│ ├── dark-core/ # Core domain models and business logic (rounds, VTXOs, exits)
│ ├── dark-confidential/ # Confidential-VTXO primitives (Pedersen, range/balance proofs, nullifiers, stealth, disclosure)
│ ├── dark-bitcoin/ # Bitcoin primitives (PSBTs, Tapscript, MuSig2, TxBuilder)
│ ├── dark-wallet/ # BDK-based Bitcoin wallet service (UTXO management, signing)
│ ├── dark-wallet-bin/ # Standalone wallet binary entrypoint
│ ├── dark-wallet-rest/ # REST + SSE wallet daemon
│ ├── dark-rest-client/ # HTTP client for the REST wallet surface
│ ├── dark-api/ # gRPC API layer (tonic + prost) — all gRPC services
│ ├── dark-client/ # gRPC client library — incl. confidential tx builder + encrypted local cache
│ ├── dark-signer/ # Remote-signer crate (key isolation over gRPC)
│ ├── dark-db/ # Database layer (SQLite, PostgreSQL, migrations — incl. confidential columns)
│ ├── dark-live-store/ # Ephemeral round state (in-memory + Redis)
│ ├── dark-fee-manager/ # Fee estimation (static + Bitcoin Core RPC + CEL programs)
│ ├── dark-scanner/ # Blockchain scanner for on-chain VTXO watching (Esplora)
│ ├── dark-scheduler/ # Time-based and block-height-based round schedulers
│ ├── dark-nostr/ # Nostr event publishing for VTXO notifications
│ └── ark-cli/ # Command-line client (transparent + confidential send/receive/scan, stealth)
├── proto/ # Protocol Buffer definitions (Ark v1, incl. confidential.proto)
├── tests/
│ ├── e2e_regtest.rs # E2E regtest integration test suite
│ └── integration/ # Integration tests
├── scripts/
│ ├── e2e-test.sh # E2E test runner
│ └── gen-tls-certs.sh # TLS certificate generation
├── contrib/
│ ├── dark.service # systemd service unit
│ ├── config.example.toml
│ └── install.sh # Bare-metal install script
├── config/
│ └── dark.light.toml # Light-mode config template
├── docs/
│ ├── adr/ # Architecture Decision Records (confidential primitives, fees, exit script)
│ ├── protocol/ # Wire-format references (confidential VTXO schema, confidential fees)
│ ├── sdk/ # Integrator guides (confidential transactions)
│ ├── migration/ # Migration guides (transparent → confidential)
│ ├── security/ # Threat models (confidential threat model)
│ ├── compliance/ # Compliance guides (selective disclosure)
│ ├── observability/ # Operational signals (confidential validation errors)
│ ├── benchmarks/ # Criterion baselines (confidential primitives)
│ ├── conventions/ # Workspace conventions
│ ├── architecture.md # Crate-graph and data-flow overview
│ ├── compliance-source-proofs.md # Selective-disclosure source-of-funds proofs
│ ├── rest-api.md # REST wallet API reference
│ ├── light-mode.md # Light-mode deployment guide
│ ├── runbook.md # Operational runbook
│ └── testing.md # Testing guide
├── benches/ # Benchmarks
├── config.example.toml # Fully documented config template
├── Justfile # Task runner (build, test, e2e, lint)
├── Dockerfile # Dev image
├── Dockerfile.prod # Distroless production image
├── docker-compose.yml # Full stack (dark + Bitcoin Core + Postgres + Redis)
├── docker-compose.prod.yml # Production compose
├── docker-compose.light.yml # Light mode (no external deps)
├── docker-compose.ci.yml # CI compose
├── prometheus.yml # Prometheus scrape config
├── deny.toml # cargo-deny config (licenses, advisories)
├── buf.work.yaml # Buf workspace config (proto linting)
├── SECURITY.md
├── WORKFLOW.md
└── Cargo.toml # Workspace configuration
- Rust 1.75+ (install: https://rustup.rs/)
- Nigiri (Bitcoin regtest + Esplora):
curl https://getnigiri.vulpem.com | bash - grpcurl (for API testing):
brew install grpcurl - Docker (required by Nigiri)
- PostgreSQL (optional, can use SQLite)
- Redis (optional, can use in-memory cache)
# Clone the repo
git clone https://github.com/lobbyclawy/dark.git
cd dark
# Build
cargo build --release
# Run tests
cargo test
# Run the server (dev mode)
cargo run -- --network regtest --config config.example.tomljust build # Build the binary
just test # Run all tests
just e2e # Run E2E regtest suite
just lint # Run clippy + fmt checkCreate config.toml (see config.example.toml for full reference):
[server]
port = 7070
admin_port = 7071
[bitcoin]
network = "regtest"
rpc_url = "http://localhost:18443"
rpc_user = "bitcoin"
rpc_password = "bitcoin"
[database]
type = "postgres" # or "sqlite"
url = "postgres://user:pass@localhost/dark"
[cache]
type = "redis" # or "inmemory"
url = "redis://localhost:6379"
[ark]
vtxo_expiry_seconds = 604800 # 7 days
unilateral_exit_delay = 86400 # 24 hours
round_max_participants = 128# Start Nigiri (Bitcoin regtest + explorer)
nigiri start
# Run dark
cargo run
# In another terminal, test the API
grpcurl -plaintext localhost:7070 list# Unit + integration tests (no external dependencies)
cargo test --workspaceRequires: nigiri, docker, grpcurl
# 1. Start Nigiri (keep running in background)
nigiri start
# 2. Build the binary (once, or after code changes)
cargo build --release
# 3. Run the e2e test
./scripts/e2e-test.shThe script starts dark, hits GetInfo via gRPC, and cleans up on exit.
Two BIP-340-signed slot attestations sharing a cohort_id but committing to
different schedule roots are publicly verifiable proof of operator
equivocation - PSAR's central accountability object. A runnable demo builds
the pair from a real cohort setup and verifies it with exactly two BIP-340
checks and no other state:
cargo run -p dark-psar --bin equivocation-demoThe demo prints the serialized evidence and its exact size: 200 B per
attestation, 400 B for the standalone pair (200 B incremental when the
legitimate attestation is already public). The same boundary runs on every
CI build via crates/dark-psar/tests/equivocation_evidence.rs plus a
dedicated demo step in the CI workflow.
# Build production image
docker build -f Dockerfile.prod -t dark .
# Run with your config
docker run -d --name dark \
-p 7070:7070 -p 7071:7071 \
-v ./config.toml:/home/dark/.dark/config.toml:ro \
-v dark-data:/home/dark/.dark \
darkOr use the production compose file (includes Bitcoin Core regtest):
docker compose -f docker-compose.prod.yml up -dFor single-process deployments with no Postgres or Redis:
docker compose -f docker-compose.light.yml up -dSee docs/light-mode.md for details.
Pre-built images are published on version tags:
docker pull ghcr.io/lobbyclawy/dark:v0.1.0For bare-metal / VM deployments:
# 1. Build the binary
cargo build --release
# 2. Install binary, config, and service
sudo cp target/release/dark /usr/local/bin/
sudo bash contrib/install.sh
# 3. Edit configuration
sudo nano /etc/dark/config.toml
# 4. Start the service
sudo systemctl enable --now dark
# 5. Check status / logs
systemctl status dark
journalctl -u dark -fSee config.example.toml for a fully documented template.
| Section | Key Fields | Description |
|---|---|---|
[server] |
network, grpc_addr, admin_addr, round_interval |
Core server settings |
[bitcoin] |
rpc_url, rpc_user, rpc_password, esplora_url |
Bitcoin node connection |
[database] |
type, url |
Storage backend (sqlite/postgres) |
[wallet] |
descriptor |
BDK wallet configuration |
[nostr] |
relay_url, private_key_hex |
Optional Nostr integration |
[fees] |
base_fee, *_input_fee, *_output_fee |
Fee schedule |
| Feature | arkd (Go) | dark (Rust) |
|---|---|---|
| Language | Go 1.23+ | Rust 1.75+ |
| Bitcoin lib | btcd, btcsuite | rust-bitcoin, BDK |
| gRPC | google.golang.org/grpc | tonic + prost |
| Database | sqlc | sqlx |
| Async runtime | goroutines | tokio |
| Performance | ~Good | Excellent |
| Memory safety | Runtime checks | Compile-time |
| Confidential VTXOs | Not supported | Pedersen + range/balance proofs, stealth, nullifiers |
- Architecture Overview — Crate structure, data flow, and design decisions
- REST API — REST + SSE wallet daemon reference
- Testing Guide — Unit tests, E2E tests, and manual testing
- Light Mode — Simplified deployment without external dependencies
- Operational Runbook — Monitoring, maintenance, and troubleshooting
- Confidential VTXO Schema — Wire-format reference for the additive
ConfidentialVtxopayload - SDK: Confidential Transactions — Step-by-step integrator guide for building confidential txs with
dark-client - Migration: Transparent → Confidential — What changes for existing wallet integrations; backwards-compatibility guarantees
- Confidential Threat Model — What is hidden, from whom, under which assumptions; adversary models
- Selective Disclosure Compliance Guide — Confidential-VTXO disclosure primitives for compliance officers and regulators (MiCA, FATF Travel Rule, GENIUS Act)
- Source-of-Funds Proofs — Commitment-path proofs over the confidential graph
- ADRs — Architecture Decision Records (secp256k1-zkp, nullifier derivation, encrypted memo format, fees, exit script)
Original arkd (Go):
Ark Protocol:
Rust Bitcoin:
- rust-bitcoin: https://github.com/rust-bitcoin/rust-bitcoin
- BDK: https://bitcoindevkit.org/
MIT
- Lobby (lobbyclawy@gmail.com) - Rust implementation
- Andrea Carotti (ac.carotti@gmail.com) - Core contributor
Based on arkd by Arkade team.