A Linux-first toolkit for Zcash development on Zebra with real blockchain transactions
Current Milestone: M2 Complete - Real Blockchain Transactions
** M1 - Foundation**
- Zebra regtest node in Docker
- Health check automation
- Basic smoke tests
- CI pipeline (self-hosted runner)
- Project structure and documentation
** M2 - Real Transactions**
zeckitCLI tool with automated setup- Real blockchain transactions via ZingoLib
- Faucet API with actual on-chain broadcasting
- Backend toggle (lightwalletd ↔ Zaino)
- Automated mining address configuration
- UA (ZIP-316) address generation
- Comprehensive test suite (M1 + M2)
** M3 - GitHub Action (Next)**
- Reusable GitHub Action
- Golden E2E shielded flows
- Pre-mined blockchain snapshots
- Backend parity testing
- OS: Linux (Ubuntu 22.04+), WSL2, or macOS with Docker Desktop 4.34+
- Docker: Engine ≥ 24.x + Compose v2
- Resources: 2 CPU cores, 4GB RAM, 5GB disk
# Clone repository
git clone https://github.com/Supercoolkayy/ZecKit.git
cd ZecKit
# Build CLI (one time)
cd cli
cargo build --release
cd ..
# Start devnet with automatic setup
./cli/target/release/zeckit up --backend zaino
# First run takes 10-15 minutes (mining 101+ blocks)
# ✓ Automatically extracts wallet address
# ✓ Configures Zebra mining address
# ✓ Waits for coinbase maturity
# Run test suite
./cli/target/release/zeckit test
# Verify faucet has funds
curl http://localhost:8080/stats# For users who prefer manual Docker Compose control
# 1. Setup mining address
./scripts/setup-mining-address.sh zaino
# 2. Start services manually
docker-compose --profile zaino up -d
# 3. Wait for 101 blocks (manual monitoring)
curl -s http://localhost:8232 -X POST \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"1.0","id":"1","method":"getblockcount","params":[]}' | jq .result
# 4. Run tests
./cli/target/release/zeckit test# M1 tests - Basic health
curl http://localhost:8232 # Zebra RPC
curl http://localhost:8080/health # Faucet health
# M2 tests - Real transactions
curl http://localhost:8080/stats # Should show balance
curl -X POST http://localhost:8080/request \
-H "Content-Type: application/json" \
-d '{"address": "tmXXXXX...", "amount": 10.0}' # Real TXID returned!Start Devnet (Automated):
# Build CLI first (one time)
cd cli && cargo build --release && cd ..
# Start with Zaino backend (recommended - faster)
./cli/target/release/zeckit up --backend zaino
# OR start with Lightwalletd backend
./cli/target/release/zeckit up --backend lwdWhat happens automatically:
- ✓ Starts Zebra regtest + backend + wallet + faucet
- ✓ Waits for wallet initialization
- ✓ Extracts wallet's transparent address
- ✓ Updates
zebra.tomlwith correct miner_address - ✓ Restarts Zebra to apply changes
- ✓ Mines 101+ blocks for coinbase maturity
- ✓ Ready to use!
Stop Services:
./cli/target/release/zeckit downRun Test Suite (M1 + M2):
./cli/target/release/zeckit test
# Expected output:
# [1/5] Zebra RPC connectivity... ✓ PASS (M1 test)
# [2/5] Faucet health check... ✓ PASS (M1 test)
# [3/5] Faucet stats endpoint... ✓ PASS (M2 test)
# [4/5] Faucet address retrieval... ✓ PASS (M2 test)
# [5/5] Faucet funding request... ✓ PASS (M2 test - real tx!)For users who want direct control:
# Setup mining address first
./scripts/setup-mining-address.sh zaino
# Start with Zaino profile
docker-compose --profile zaino up -d
# OR start with Lightwalletd profile
docker-compose --profile lwd up -d
# Stop services
docker-compose --profile zaino down
# or
docker-compose --profile lwd down# 1. Build CLI (one time)
cd cli && cargo build --release && cd ..
# 2. Start devnet (automatic setup!)
./cli/target/release/zeckit up --backend zaino
# Takes 10-15 minutes on first run (mining + sync)
# 3. Run test suite
./cli/target/release/zeckit test
# 4. Check faucet balance
curl http://localhost:8080/stats
# 5. Request funds (real transaction!)
curl -X POST http://localhost:8080/request \
-H "Content-Type: application/json" \
-d '{"address": "tmXXXXX...", "amount": 10.0}'
# 6. Stop when done
./cli/target/release/zeckit down# Stop services
./cli/target/release/zeckit down
# Remove volumes
docker volume rm zeckit_zebra-data zeckit_zaino-data
# Start fresh (automatic setup again)
./cli/target/release/zeckit up --backend zaino# Stop current backend
./cli/target/release/zeckit down
# Start with different backend
./cli/target/release/zeckit up --backend lwd
# Or back to Zaino
./cli/target/release/zeckit up --backend zaino./cli/target/release/zeckit testTest Breakdown:
| Test | Milestone | What It Checks |
|---|---|---|
| 1/5 Zebra RPC | M1 | Basic node connectivity |
| 2/5 Faucet health | M1 | Service health endpoint |
| 3/5 Faucet stats | M2 | Balance tracking API |
| 4/5 Faucet address | M2 | Address retrieval |
| 5/5 Faucet request | M2 | Real transaction! |
Expected Results:
- M1 tests (1-2): Always pass if services running
- M2 tests (3-4): Pass after wallet sync
- M2 test 5: Pass after 101+ blocks mined (timing dependent)
# M1 - Test Zebra RPC
curl -d '{"method":"getinfo","params":[]}' http://localhost:8232
# M1 - Check health
curl http://localhost:8080/health
# M2 - Check balance
curl http://localhost:8080/stats
# M2 - Get address
curl http://localhost:8080/address
# M2 - Real transaction test
curl -X POST http://localhost:8080/request \
-H "Content-Type: application/json" \
-d '{"address": "tmXXXXX...", "amount": 10.0}'http://localhost:8080
GET /health (M1)
curl http://localhost:8080/healthResponse:
{
"status": "healthy"
}GET /stats (M2)
curl http://localhost:8080/statsResponse:
{
"current_balance": 1628.125,
"transparent_balance": 1628.125,
"orchard_balance": 0.0,
"faucet_address": "tmYuH9GAxfWM82Kckyb6kubRdpCKRpcw1ZA",
"total_requests": 0,
"uptime": "5m 23s"
}GET /address (M2)
curl http://localhost:8080/addressResponse:
{
"address": "tmYuH9GAxfWM82Kckyb6kubRdpCKRpcw1ZA"
}POST /request (M2 - Real Transaction!)
curl -X POST http://localhost:8080/request \
-H "Content-Type: application/json" \
-d '{"address": "tmXXXXX...", "amount": 10.0}'Response includes real TXID from blockchain:
{
"success": true,
"txid": "a1b2c3d4e5f6789...",
"timestamp": "2025-12-15T12:00:00Z",
"amount": 10.0
}┌─────────────────────────────┐
│ Docker Compose │
│ │
│ ┌─────────────┐ │
│ │ Zebra │ │
│ │ (regtest) │ │
│ │ :8232 │ │
│ └─────────────┘ │
│ │
│ Health checks + RPC tests │
└─────────────────────────────┘
┌──────────────────────────────────────────┐
│ Docker Compose │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Zebra │◄───────┤ Faucet │ │
│ │ regtest │ │ Flask │ │
│ │ :8232 │ │ :8080 │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Zaino or │◄───────┤ Zingo │ │
│ │Lightwald │ │ Wallet │ │
│ │ :9067 │ │(pexpect) │ │
│ └──────────┘ └──────────┘ │
└──────────────────────────────────────────┘
▲
│
┌────┴────┐
│ zeckit │ (Rust CLI - M2)
└─────────┘
Components:
- Zebra: Full node with internal miner (M1)
- Lightwalletd/Zaino: Light client backends (M2)
- Zingo Wallet: Real transaction creation (M2)
- Faucet: REST API for test funds (M2)
- zeckit CLI: Automated orchestration (M2)
Zcash is migrating from zcashd to Zebra (official deprecation 2025), but builders lack a standard devnet + CI setup. ZecKit solves this by:
- Standardizing Zebra Development - One consistent way to run Zebra + light-client backends
- Enabling UA-Centric Testing - Built-in ZIP-316 unified address support
- Supporting Backend Parity - Toggle between lightwalletd and Zaino
- Catching Breakage Early - Automated E2E tests in CI
M1 Foundation:
- Basic Zebra regtest
- Health checks
- Manual Docker Compose
M2 Real Transactions:
- Automated CLI (
zeckit) - Real on-chain transactions
- Faucet API with pexpect
- Backend toggle
M3 CI/CD (Next):
- GitHub Action
- Golden shielded flows
- Pre-mined snapshots
When you run ./cli/target/release/zeckit up for the first time:
- Initial mining takes 10-15 minutes - This is required for coinbase maturity (Zcash consensus)
- Automatic configuration - The CLI extracts wallet address and configures Zebra automatically
- Monitor progress - Watch the CLI output or check block count:
curl -s http://localhost:8232 -X POST -H 'Content-Type: application/json' \ -d '{"jsonrpc":"1.0","id":"1","method":"getblockcount","params":[]}' | jq .result
To reset everything and start clean:
# Stop services
./cli/target/release/zeckit down
# Remove volumes (blockchain data)
docker volume rm zeckit_zebra-data zeckit_zaino-data
# Start fresh
./cli/target/release/zeckit up --backend zaino# Stop current backend
./cli/target/release/zeckit down
# Start with different backend
./cli/target/release/zeckit up --backend lwd
# Or back to Zaino
./cli/target/release/zeckit up --backend zainoReset blockchain and start fresh:
./cli/target/release/zeckit down
docker volume rm zeckit_zebra-data zeckit_zaino-data
./cli/target/release/zeckit up --backend zainoCheck service logs:
docker logs zeckit-zebra
docker logs zeckit-faucet
docker logs zeckit-zainoCheck wallet balance manually:
docker exec -it zeckit-zingo-wallet zingo-cli \
--data-dir /var/zingo \
--server http://zaino:9067 \
--chain regtest
# At prompt:
balance
addressesVerify mining progress:
# Check block count
curl -s http://localhost:8232 -X POST \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"1.0","id":"1","method":"getblockcount","params":[]}' | jq .result
# Check mempool
curl -s http://localhost:8232 -X POST \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"1.0","id":"1","method":"getrawmempool","params":[]}' | jqCheck port usage:
lsof -i :8232 # Zebra
lsof -i :8080 # Faucet
lsof -i :9067 # Backend- Architecture - System design and data flow
- Technical Spec - Implementation details (27 pages!)
- Acceptance Tests - Test criteria
- Repository structure
- Zebra regtest in Docker
- Health checks & smoke tests
- CI pipeline
- Manual Docker Compose workflow
zeckitCLI tool with automated setup- Real blockchain transactions
- Faucet API with balance tracking
- Backend toggle (lightwalletd ↔ Zaino)
- Automated mining address configuration
- UA (ZIP-316) address generation
- Comprehensive test suite
- Reusable GitHub Action for CI
- Golden E2E shielded flows
- Pre-mined blockchain snapshots
- Backend parity testing
- Auto-shielding workflow
- Quickstart guides
- Video tutorials
- Compatibility matrix
- Advanced workflows
- 90-day support window
- Version pin updates
- Community handover
- Zebra regtest with health checks
- Automated smoke tests
- CI pipeline integration
- Manual service control
Pexpect for Wallet Interaction:
# Reliable PTY control replaces flaky subprocess
child = pexpect.spawn('docker exec -i zeckit-zingo-wallet zingo-cli ...')
child.expect(r'\(test\) Block:\d+', timeout=90)
child.sendline('send [{"address":"tm...", "amount":10.0}]')
child.expect(r'"txid":\s*"([a-f0-9]{64})"')
txid = child.match.group(1) # Real TXID!Automated Setup:
- Wallet address extraction
- Zebra configuration updates
- Service restarts
- Mining to maturity
Ephemeral Wallet (tmpfs):
zingo-wallet:
tmpfs:
- /var/zingo:mode=1777,size=512mBenefits: Fresh state, fast I/O, no corruption
Contributions welcome! Please:
- Fork and create feature branch
- Test locally:
./cli/target/release/zeckit up --backend zaino && ./cli/target/release/zeckit test - Follow code style (Rust:
cargo fmt, Python:black) - Open PR with clear description
Q: What's the difference between M1 and M2?
A: M1 = Basic Zebra setup. M2 = Automated CLI + real transactions + faucet API.
Q: Are these real blockchain transactions?
A: Yes! Uses actual ZingoLib wallet with real on-chain transactions (regtest network).
Q: Can I use this in production?
A: No. ZecKit is for development/testing only (regtest mode).
Q: How do I start the devnet?
A: ./cli/target/release/zeckit up --backend zaino (or --backend lwd)
Q: How long does first startup take?
A: 10-15 minutes for mining 101 blocks (coinbase maturity requirement).
Q: Can I switch between lightwalletd and Zaino?
A: Yes! zeckit down then zeckit up --backend [lwd|zaino]
Q: How do I reset everything?
A: zeckit down && docker volume rm zeckit_zebra-data zeckit_zaino-data
Q: Where can I find the technical details?
A: Check specs/technical-spec.md for the full implementation (27 pages!)
Q: What tests are included?
A: M1 tests (RPC, health) + M2 tests (stats, address, real transactions)
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Community: Zcash Forum
Dual-licensed under MIT OR Apache-2.0
Built by: Dapps over Apps team
Thanks to:
- Zcash Foundation (Zebra)
- Electric Coin Company (lightwalletd)
- Zingo Labs (ZingoLib & Zaino)
- Zcash community
Last Updated: December 16, 2025
Status: M2 Complete - Real Blockchain Transactions Delivered