Local end-to-end testing of the full Z3 stack (Zebra, Zaino, Zallet, and the rpc-router) in regtest mode.
Uses the base docker-compose.yml with docker-compose.regtest.yml overlay and .env.regtest for regtest-specific configuration. Volumes are isolated via COMPOSE_PROJECT_NAME=z3-regtest, so regtest data never conflicts with mainnet or testnet.
- Docker with Docker Compose (v2.24.0+)
- rage for generating Zallet encryption keys
- TLS certificates generated (see Quick Start in the main README)
- For gRPC testing: grpcurl and the zaino submodule initialized (
git submodule update --init zaino)
From the repo root:
./scripts/regtest-init.shThis will:
- Generate a Zallet encryption identity (if not already present)
- Generate and inject the Zallet RPC password hash in
config/regtest/zallet.toml - Start Zebra in regtest mode
- Mine 1 block (activates Orchard at height 1)
- Initialize the Zallet wallet (
init-wallet-encryption+generate-mnemonic)
Optionally override the RPC password (default is zebra):
RPC_PASSWORD='your-password' ./scripts/regtest-init.shFrom the repo root:
docker compose --env-file .env.regtest up -dZebra, Zaino, and Zallet use pre-built images. The rpc-router builds from source on first run (takes a few minutes; subsequent runs use the Docker layer cache).
Note
Regtest uses the same host ports as mainnet/testnet. If other Z3 services are running, stop them first (docker compose down) or override port variables in .env.regtest.
| Service | Endpoint | Description |
|---|---|---|
| rpc-router | http://localhost:8181 | JSON-RPC router (Zebra + Zallet) |
| Zaino gRPC | https://localhost:8137 | lightwalletd-compatible gRPC (TLS) |
| Zebra RPC | http://localhost:18232 | Direct Zebra JSON-RPC |
| Zallet RPC | http://localhost:28232 | Direct Zallet JSON-RPC |
These commands go through the rpc-router, which forwards to Zebra or Zallet based on the method:
# Route to Zebra (full node)
curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"getblockchaininfo","params":[],"id":1}' \
http://127.0.0.1:8181
# Route to Zallet (wallet)
curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"getwalletinfo","params":[],"id":2}' \
http://127.0.0.1:8181
# Merged OpenRPC schema
curl -s -X POST -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"rpc.discover","params":[],"id":3}' \
http://127.0.0.1:8181 | grep -o '"title":"[^"]*"'Zaino exposes the lightwalletd-compatible gRPC protocol on port 8137 with TLS. The --insecure flag tells grpcurl to accept the self-signed certificate.
Initialize the zaino submodule if you haven't already (needed for the proto files):
git submodule update --init zainoTest with GetLightdInfo (from the repo root):
grpcurl -insecure \
-import-path zaino/zaino-proto/proto \
-proto service.proto \
127.0.0.1:8137 \
cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfoGet the latest block height:
grpcurl -insecure \
-import-path zaino/zaino-proto/proto \
-proto service.proto \
-d '{}' \
127.0.0.1:8137 \
cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlockOpen the playground pointed at your locally running router:
The playground calls rpc.discover on http://127.0.0.1:8181 to load the live merged schema.
# Stop containers (keeps volumes/wallet data)
docker compose --env-file .env.regtest down
# Full reset (deletes all regtest data; re-run scripts/regtest-init.sh afterwards)
docker compose --env-file .env.regtest down -vgetblockchaininfo (routed to Zebra, truncated):
{"jsonrpc":"2.0","id":1,"result":{"chain":"test","blocks":1,"headers":1,...,"upgrades":{"5ba81b19":{"name":"Overwinter","activationheight":1,"status":"active"},...}}}getwalletinfo (routed to Zallet):
{"jsonrpc":"2.0","result":{"walletversion":0,"balance":0.00000000,"unconfirmed_balance":0.00000000,"immature_balance":0.00000000,"shielded_balance":"0.00","shielded_unconfirmed_balance":"0.00","txcount":0,"keypoololdest":0,"keypoolsize":0,"mnemonic_seedfp":"TODO"},"id":1}To enable monitoring, add the metrics endpoint to .env.regtest:
ZEBRA_METRICS__ENDPOINT_ADDR=0.0.0.0:9999Then start with both flags:
docker compose --env-file .env.regtest --profile monitoring up -dThe port (9999) must match the Prometheus scrape target configured in observability/prometheus/prometheus.yaml.
- Credentials:
zebra/zebra(hardcoded for regtest only) - Zallet uses regtest nuparams activating all upgrades at block 1
- Zaino uses username/password auth in regtest (not cookie auth)
- Zaino gRPC uses TLS with the same self-signed certificate as mainnet/testnet
- The rpc-router source is in
rpc-router/; it is built automatically on firstdocker compose up