Berachain Merkle Proof Generator - Generate cryptographic proofs for validator existence and balances on Berachain's beacon-kit implementation.
This library generates Merkle proofs that are compatible with Berachain's specific SSZ implementation. Due to significant differences between Berachain's beacon-kit and the ETH2 specification, standard tools don't work - this library bridges that gap.
# Install and setup
git clone <repository-url>
cd bera-proofs
poetry install
# Option 1: Generate proofs with CLI
poetry run python -m src.cli validator 5 \
--json-file test/data/state.json \
--historical-state-file test/data/state-8.json
# Option 2: Start the API server
poetry run python -m src.cli serve
# Option 3: Use the API
curl -X POST http://localhost:8000/proofs/validator \
-H "Content-Type: application/json" \
-d '{"identifier": "5", "slot": "head"}'Response Example:
{
"proof": ["0x86ed...", "0x129a...", "0x4aae...", ...],
"root": "0x12c3b9e21f6636e8f81bf4a501c00e5bdd789b561ae7e1455807dca558117992",
"metadata": {
"validator_index": 5,
"balance": "547445850000000",
"effective_balance": "540000000000000",
"proof_type": "balance_proof"
}
}- π Cross-chain Bridges: Verify validator states on other blockchains
- π‘ Light Clients: Prove validator participation without downloading full state
- π¦ Staking Protocols: Cryptographically verify validator balances and status
- π Analytics & Auditing: Generate tamper-proof proofs for validator data
- π Zero-Knowledge Applications: Use as inputs for ZK circuits requiring validator data
βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β REST API ββββββΆβ Proof ββββββΆβ SSZ Library β
βββββββββββββββ β Service β ββββββββββββββββ
βββββββββββββββ β
βββββββββββββββ β βΌ
β CLI ββββββββββββββ ββββββββββββββββ
βββββββββββββββ β Merkle Trees β
β ββββββββββββββββ
βΌ
βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β JSON Files β β Beacon API β β Test Data β
βββββββββββββββ βββββββββββββββ ββββββββββββββββ
git clone <repository-url>
cd bera-proofs
poetry installThe CLI works with local JSON files and provides reliable, offline proof generation.
# Get help
poetry run python -m bera_proofs.cli --help
poetry run python -m bera_proofs.cli validator --help
poetry run python -m bera_proofs.cli balance --help
# Generate validator proof
poetry run python -m bera_proofs.cli validator 5 \
--json-file current_state.json \
--historical-state-file historical_state.json
# Generate balance proof
poetry run python -m bera_proofs.cli balance 5 \
--json-file current_state.json \
--historical-state-file historical_state.json# Quick test with included test data
poetry run python -m bera_proofs.cli validator 5 \
--json-file test/data/state.json \
--historical-state-file test/data/state-8.json
poetry run python -m bera_proofs.cli balance 5 \
--json-file test/data/state.json \
--historical-state-file test/data/state-8.jsonThe REST API provides proof generation via HTTP endpoints with automatic beacon chain data fetching.
# Start API on testnet (default configuration)
poetry run python -m bera_proofs.cli serve
# The API will use:
# - Network: testnet
# - Beacon RPC: https://testnet.beacon-0.bera.gra.lgns.net
# - Server: http://0.0.0.0:8000π§ͺ Testnet Configuration
# Method 1: Default testnet (recommended for testing)
poetry run python -m bera_proofs.cli serve --host 0.0.0.0 --port 8000
# Method 2: Explicit testnet configuration
BEACON_NETWORK=testnet poetry run python -m bera_proofs.cli serve
# Method 3: Custom testnet endpoint
BEACON_RPC_URL_TESTNET=https://your-testnet-beacon.com poetry run python -m bera_proofs.cli serveπ Mainnet Configuration
# Method 1: Set mainnet in environment
BEACON_NETWORK=mainnet poetry run python -m bera_proofs.cli serve
# Method 2: Custom mainnet endpoint
BEACON_NETWORK=mainnet BEACON_RPC_URL_MAINNET=https://your-mainnet-beacon.com poetry run python -m bera_proofs.cli serve
# Method 3: Permanent configuration (edit .env file)
# Set BEACON_NETWORK=mainnet in .env, then:
poetry run python -m bera_proofs.cli serveπ§ Advanced Options
# Custom port and host
poetry run python -m bera_proofs.cli serve --port 8080 --host 127.0.0.1
# Enable development mode with auto-reload
poetry run python -m bera_proofs.cli serve --dev
# Background deployment (using tmux/screen)
tmux new-session -d -s bera-api 'poetry run python -m bera_proofs.cli serve'# Create or attach to tmux session
tmux new-session -d -s bera-proofs-api
# Start testnet API
tmux send-keys -t bera-proofs-api "cd /path/to/bera-proofs" Enter
tmux send-keys -t bera-proofs-api "poetry run python -m bera_proofs.cli serve" Enter
# Start mainnet API
tmux send-keys -t bera-proofs-api "cd /path/to/bera-proofs" Enter
tmux send-keys -t bera-proofs-api "BEACON_NETWORK=mainnet poetry run python -m bera_proofs.cli serve" Enter
# View session
tmux attach-session -t bera-proofs-api# Check which network the API is using
curl -s http://localhost:8000/health
# View initialization logs to confirm beacon endpoint
# Look for: "Initialized BeaconAPIClient with base_url: https://..."Configure the API via environment variables. Copy .env.example to .env and update:
# Copy the example environment file
cp .env.example .env
# Edit .env to set your configuration
# Key settings:
# - BEACON_NETWORK: Choose 'testnet' or 'mainnet'
# - BEACON_RPC_URL_TESTNET: Set testnet beacon URL
# - BEACON_RPC_URL_MAINNET: Set mainnet beacon URL
# - API_HOST: Server host (default: 0.0.0.0)
# - API_PORT: Server port (default: 8000)Example .env for Testnet:
BEACON_NETWORK=testnet
BEACON_RPC_URL_TESTNET=https://testnet.beacon-0.bera.gra.lgns.net
API_HOST=0.0.0.0
API_PORT=8000Example .env for Mainnet:
BEACON_NETWORK=mainnet
BEACON_RPC_URL_MAINNET=https://mainnet.beacon-1.bera.de.lgns.net
API_HOST=0.0.0.0
API_PORT=8000# Using validator index
curl -X POST http://localhost:8000/proofs/validator \
-H "Content-Type: application/json" \
-d '{"identifier": "5", "slot": "head"}'
# Using validator pubkey
curl -X POST http://localhost:8000/proofs/validator \
-H "Content-Type: application/json" \
-d '{"identifier": "0x957004733f0c4d7e51b4f1ac3f1c08247f9c5455d302b669c723eb80d8c286515b5623757a9053a5a7b8c17ee3feed4b"}'# GET request (convenient for simple integrations)
curl http://localhost:8000/proofs/balance/5?slot=head
# POST request with full options
curl -X POST http://localhost:8000/proofs/balance \
-H "Content-Type: application/json" \
-d '{
"identifier": "5",
"slot": "head",
"prev_state_root": "0x01ef6767...",
"prev_block_root": "0x28925c02..."
}'- π Validator Identification: Support for both index and pubkey
- π Auto-fetch: Automatically retrieves beacon chain data
- π OpenAPI Docs: Interactive documentation at
/docs - π CORS Enabled: Ready for cross-origin requests
- π Health Checks: Monitor API and beacon node status
Visit http://localhost:8000/docs for interactive OpenAPI documentation.
Berachain requires historical state data from 8 slots ago for proof generation. The CLI handles this through:
Use two state files - current and historical:
poetry run python -m bera_proofs.cli validator 0 \
--json-file current_state.json \
--historical-state-file historical_state.jsonProvide specific historical roots if you don't have historical state files:
poetry run python -m bera_proofs.cli validator 0 \
--json-file current_state.json \
--prev-state-root 0x01ef6767e8908883d1e84e91095bbb3f7d98e33773d13b6cc949355909365ff8 \
--prev-block-root 0x28925c02852c6462577e73cc0fdb0f49bbf910b559c8c0d1b8f69cac38fa3f74When using test data, the CLI automatically uses appropriate test defaults:
# CLI uses test defaults automatically
poetry run python -m bera_proofs.cli validator 0 --json-file test/data/state.json# Run all tests
poetry run python tests/run_tests.py
# Test specific components
poetry run python -m pytest tests/test_integration.py- ποΈ BeaconState Fields: ~15 ETH2 fields removed, 2 new fields added
- π¦ List Merkleization: All lists treated as fixed vectors with appended length
- π State Modifications: Historical data injection before proof generation
- 45-step Merkle witness navigating through validator lists and BeaconState fields
- Fixed capacity proofs using ETH2 registry limits
- Compatible roots that match Berachain's beacon-kit implementation
Explore proof structure with built-in visualization:
# Interactive proof visualization
python src/visualize_merkle.py
# Features:
# - Tree structure diagrams
# - Step-by-step proof paths
# - ETH2 vs Berachain comparisons
# - Performance metrics- Current State: BeaconState JSON from current slot
- Historical State: BeaconState JSON from 8 slots ago (preferred)
- OR Historical Roots: Manual
prev_state_rootandprev_block_rootvalues
All proofs return:
- proof: Array of 32-byte hex strings (merkle siblings)
- root: Final state root for verification
- metadata: Rich information including validator details, balances, and proof statistics
bera-proofs/
βββ src/
β βββ main.py # Core proof generation
β βββ cli.py # Command-line interface
β βββ visualize_merkle.py # Visualization tools
β βββ api/ # REST API implementation
β β βββ rest_api.py # FastAPI endpoints
β β βββ proof_service.py # Proof generation service
β β βββ beacon_client.py # Beacon chain integration
β βββ models/ # Data models
β β βββ api_models.py # Request/response models
β βββ ssz/ # Modular SSZ library
βββ test/data/ # Test state files
β βββ state.json # Current state example
β βββ state-8.json # Historical state example
βββ tests/ # Test suite
βββ @ai_docs/ # API documentation
βββ README.md
- β CLI: Fully functional and tested
- β Proof Generation: Working with Berachain SSZ
- β Test Suite: Comprehensive coverage
- β Visualization: Interactive proof exploration
- β REST API: Production-ready with validator identification by index or pubkey
- β Beacon Integration: Supports both testnet and mainnet
MIT