Development environment for Zcash protocol changes. Combines Zebra (node), Zaino (indexer), zcash-devtool (wallet/CLI), and local forks of orchard and librustzcash.
Current Goal: Add native tag field to Orchard actions for PIR-based transaction detection.
Create your own forks of all repositories so you can push changes:
# 1. Clone the template repo
git clone --recursive https://github.com/greg-nagy/zforge.git
cd zforge
# 2. Fork all repos to your GitHub account (requires gh CLI)
./dev fork
# 3. Initialize submodules with your forks
./dev setup
# 4. Build and run
./dev build
./dev up
./dev testThe ./dev fork command will:
- Fork zforge and all 5 submodules to your GitHub account
- Configure
origin→ your fork,upstream→ official repos - Update
.gitmodulesto use your forks
If you just want to explore without pushing changes:
git clone --recursive https://github.com/greg-nagy/zforge.git
cd zforge
./dev setup && ./dev build && ./dev up# Onboarding
./dev fork # Fork all repos to your GitHub account
./dev setup # Initialize submodules, configure remotes
# Services
./dev up # Start all services (zebra + zaino)
./dev stop # Stop all services
./dev restart # Restart services
./dev status # Show service status
./dev logs # Follow all logs
./dev logs zaino # Follow specific service
# Development
./dev build # Build zcash-devtool
./dev test # Run integration tests
# Git (multi-repo)
./dev git status # Status across all repos
./dev git branch <name> # Create feature branch
./dev git commit <msg> # Commit across submodules
./dev git push # Push all repos (to your forks)
./dev git sync # Fetch upstream, show drift- Services running (Zebra mining, Zaino indexing)
- Local patches active (orchard, librustzcash)
- Wallet initialization on Regtest
- Full data flow: Zebra → Zaino → zcash-devtool
# 1. Start feature branch
./dev git branch add-tag-field # Creates feature/add-tag-field in orchard + librustzcash
# 2. Start services
./dev up
# 3. Make changes
cd orchard
# ... edit src/action.rs ...
# 4. Rebuild and test
./dev restart # Picks up orchard changes
./dev test
# 5. Commit and push
./dev git commit "Add tag field to Action struct"
./dev git push# Via ./dev (recommended)
./dev up # Start all services
./dev restart # Restart all
./dev stop # Stop all
./dev logs zaino # Follow one service's logs
# Direct overmind (if needed)
overmind restart zaino # Restart specific service
overmind echo zebra # Follow specific service# Terminal 1 - Zebra
cargo run --release -p zebrad --features internal-miner \
--manifest-path zebra/Cargo.toml -- -c config/zebra-regtest.toml
# Terminal 2 - Zaino
cargo run --release -p zainod \
--manifest-path zaino/Cargo.toml -- -c config/zaino-regtest.tomlDEVTOOL=./zcash-devtool/target/release/zcash-devtool
# Initialize wallet on Regtest
$DEVTOOL wallet -w .wallet init \
--name test \
--identity .wallet/id.age \
--network regtest \
--server localhost:8137 \
--mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
# Generate address
$DEVTOOL wallet -w .wallet generate-address
# Sync wallet
$DEVTOOL wallet -w .wallet sync --server localhost:8137
# Check balance
$DEVTOOL wallet -w .wallet balancezforge/
├── dev # CLI entry point (./dev setup, ./dev up, etc.)
├── mise.toml # Tool versions (protobuf)
├── Procfile # overmind process definitions
├── zebra/ # Full node (submodule)
├── zaino/ # Indexer (submodule)
├── zcash-devtool/ # Wallet CLI (submodule)
├── orchard/ # Orchard protocol (submodule) ← tag field goes here
├── librustzcash/ # Zcash primitives (submodule)
├── config/ # Service configs (regtest, docker)
├── scripts/ # Setup scripts
├── tests/ # Integration tests
├── docs/ # Planning docs
└── docker-compose.yml # Docker deployment (CI/staging)
| File | Purpose |
|---|---|
config/zebra-regtest.toml |
Zebra: Regtest, internal miner, no auth |
config/zaino-regtest.toml |
Zaino: connects to local Zebra |
config/*-docker.toml |
Docker deployment variants |
Default: Regtest mode - No sync, instant blocks, isolated network.
After running ./dev fork, each repo has two remotes:
| Remote | Points To | Purpose |
|---|---|---|
origin |
Your fork | Push your changes here |
upstream |
Official repo | Sync upstream changes |
Submodule upstreams:
zebra→ ZcashFoundation/zebrazaino→ zingolabs/zainoorchard→ zcash/orchardlibrustzcash→ zcash/librustzcashzcash-devtool→ zcash/zcash-devtool
Branches:
main/dev- Zforge development (pinned to compatible versions)feature/*- Your feature branchespr/*- For upstream contributions (branch fromupstream/main)
# Start feature (creates branch in orchard + librustzcash by default)
./dev git branch my-feature
# Or specify repos
./dev git branch my-feature orchard zebra zaino
# Work, then commit across all dirty repos
./dev git commit "My changes"
# Push everything (goes to your forks)
./dev git push
# Check upstream drift
./dev git sync| Component | Version | Constraint |
|---|---|---|
| zebra | main | - |
| zaino | main | - |
| orchard | 0.11.x | Zebra compatibility |
| librustzcash | zcash_transparent-0.6.3 | Zebra compatibility |
| zcash-devtool | main | - |
Run ./scripts/setup-fork-branches.sh to verify/reset submodule versions.
For automated testing or deployment (not daily dev):
docker compose build
docker compose up -dUses config/*-docker.toml with container-appropriate paths.
Run ./dev setup to check all prerequisites.
Required:
- Rust: Managed per-submodule via
rust-toolchain.toml(rustup handles automatically) - tmux:
brew install tmux(required by overmind) - overmind:
brew install overmind(process manager) - protobuf:
brew install protobuf(for gRPC compilation)
Required for ./dev fork:
- gh:
brew install gh(GitHub CLI for forking repos) - Run
gh auth loginto authenticate
Optional:
- mise:
https://mise.jdx.dev(manages tool versions viamise.toml)
MIT OR Apache-2.0