RandProofRandProof
Node Operators

Complete .env Configuration Reference

Copy the template and fill in all required values:

Copy the template and fill in all required values:

cp .env.example .env
nano .env # or: vim .env

Full .env reference (all variables):

# ═══════════════════════════════════════════════════════
# RANDPROOF KEEPER NODE — COMPLETE .env REFERENCE v1.0
# ═══════════════════════════════════════════════════════
# ── IDENTITY ─────────────────────────────────────────
KEEPER_PRIVATE_KEY=0x<your_evm_wallet_private_key>
KEEPER_ADDRESS=0x<your_evm_wallet_address>
BLS_KEYSTORE_PATH=./keys/bls-keystore.json
BLS_KEYSTORE_PASSWORD=<your_bls_keystore_password>
NODE_NAME=randproof-keeper-01 # human-readable label
NODE_REGION=us-east-1 # geographic region (for decentralization tracking)
# ── CHAIN SELECTION ──────────────────────────────────
# Comma-separated list. Start with 1-2 chains, add more after testing.
CHAINS=base,optimism,arbitrum
# Full list: base,optimism,arbitrum,linea,ethereum,polygon,worldchain,
# bnb,avalanche,moonbeam,solana,ton,cardano,sui,polkadot,bittensor,hyperevm
# ── EVM RPC ENDPOINTS (WebSocket required for event listening) ──
BASE_RPC=wss://base-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
BASE_RPC_HTTP=https://base-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
OPTIMISM_RPC=wss://opt-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
OPTIMISM_RPC_HTTP=https://opt-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
ARBITRUM_RPC=wss://arb-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
ARBITRUM_RPC_HTTP=https://arb-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
LINEA_RPC=wss://linea-mainnet.infura.io/ws/v3/<YOUR_INFURA_KEY>
LINEA_RPC_HTTP=https://linea-mainnet.infura.io/v3/<YOUR_INFURA_KEY>
ETHEREUM_RPC=wss://eth-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
ETHEREUM_RPC_HTTP=https://eth-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
POLYGON_RPC=wss://polygon-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
BNB_RPC=wss://bsc-ws-node.nariox.org:443
AVALANCHE_RPC=wss://api.avax.network/ext/bc/C/ws
MOONBEAM_RPC=wss://wss.api.moonbeam.network
HYPEREVM_RPC=wss://rpc.hyperliquid.xyz/evm
WORLDCHAIN_RPC=wss://worldchain-mainnet.g.alchemy.com/v2/<YOUR_ALCHEMY_KEY>
# ── NON-EVM RPC ENDPOINTS ───────────────────────────
SOLANA_RPC=wss://api.mainnet-beta.solana.com
SOLANA_RPC_HTTP=https://mainnet.helius-rpc.com/?api-key=<YOUR_HELIUS_KEY>
SOLANA_KEEPER_KEYPAIR=./keys/solana-keypair.json
TON_RPC=https://toncenter.com/api/v2/
TON_API_KEY=<your_toncenter_api_key>
TON_KEEPER_MNEMONIC=word1 word2 word3 ... word24
CARDANO_NODE_HOST=cardano-mainnet.blockfrost.io
CARDANO_BLOCKFROST_KEY=<your_blockfrost_key>
CARDANO_PAYMENT_SIGNING_KEY=./keys/cardano.skey
SUI_RPC=https://fullnode.mainnet.sui.io:443
SUI_KEEPER_KEYPAIR=./keys/sui-keypair.json
POLKADOT_RPC=wss://rpc.polkadot.io
POLKADOT_KEEPER_MNEMONIC=<polkadot_sr25519_mnemonic>
BITTENSOR_RPC=wss://entrypoint-finney.opentensor.ai:443
# ── ENTROPY SOURCE API KEYS ─────────────────────────
# DRAND (no key required - public)
DRAND_HTTP_ENDPOINT=https://api.drand.sh
DRAND_CHAIN_HASH=8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce
DRAND_QUICKNET_CHAIN_HASH=52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971
# NIST Randomness Beacon (no key required - public)
NIST_BEACON_ENDPOINT=https://beacon.nist.gov/beacon/2.0/pulse/last
NIST_MAX_STALENESS_SECONDS=65
# ANU QRNG (sole quantum entropy source)
ANU_QRNG_ENDPOINT=https://qrng.anu.edu.au/API/jsonI.php
ANU_MAX_STALENESS_SECONDS=30
# AV-54 / v0.57: ANU QRNG has no acceptable fallback provider. If ANU QRNG is stale or unavailable, its weight is redistributed automatically. Do not configure a substitute source.
# (HotBits variables removed in v0.57 -- the retired HotBits service is not an acceptable entropy source; see Section 3.3, Source 9.)
# Tor Consensus (no key required - public)
TOR_CONSENSUS_ENDPOINT=https://torproject.org/tor/status-all.json
TOR_MAX_STALENESS_SECONDS=3900
# Bitcoin Merkle Root (via public RPC or block explorer API)
BITCOIN_RPC_ENDPOINT=https://blockstream.info/api
BITCOIN_CONFIRMATIONS_REQUIRED=2
# Multi-Chain Block Hashes (list of non-EVM chains to include)
MULTICHAIN_HASH_SOURCES=solana,cardano,polkadot
# ── STAKING CONFIGURATION ───────────────────────────
MIN_STAKE_ETH=0.005 # Base/OP/ARB/Linea/Polygon/WorldChain
MIN_STAKE_SOL=0.5 # Solana
MIN_STAKE_SUI=5 # Sui
MIN_STAKE_TON=10 # TON
MIN_STAKE_ADA=50 # Cardano
MIN_STAKE_BNB=0.1 # BNB Chain
MIN_STAKE_AVAX=1 # Avalanche
MIN_STAKE_GLMR=0.5 # Moonbeam
MIN_STAKE_DOT=5 # Polkadot (5 DOT minimum)
MIN_STAKE_ETH_MAINNET=0.01 # Ethereum mainnet
# ── KEEPER BEHAVIOR ────────────────────────────────
MIN_UPTIME_PERCENT=80 # below this = slashing risk
MAX_FULFILLMENT_LATENCY_MS=5000 # flag events taking longer than 5s
GOSSIP_PEERS=11 # genesis: n-1 (full mesh); Phase 2+: 5+ (deterministic from registry)
BLS_THRESHOLD=3 # minimum signatures to aggregate (t)
BLS_COMMITTEE_SIZE=12 # total keepers in signing committee (n)
FULFILL_RETRY_ATTEMPTS=3 # retry failed fulfillments
FULFILL_RETRY_DELAY_MS=2000 # wait between retries
# ── FEE ASSET PREFERENCE ───────────────────────────
FEE_ASSET=usdc # options: usdc | native
# If usdc: fees received in USDC via CCTP V2 (EVM chains) or native USDC
# If native: fees received in chain native asset
# ── MONITORING & ALERTING ──────────────────────────
METRICS_PORT=9090 # Prometheus scrape port
HEALTH_PORT=3000 # HTTP health check port
LOG_LEVEL=info # debug | info | warn | error
LOG_FORMAT=json # json | pretty
ALERT_EMAIL=you@yourdomain.com # email for critical alerts
ALERT_WEBHOOK=https://hooks.slack.com/... # Slack/Discord webhook
PAGERDUTY_INTEGRATION_KEY=<key> # optional: PagerDuty for 24/7 on-call
# ── DATABASE (for local event history) ─────────────
DB_TYPE=sqlite # sqlite | postgres
DB_PATH=./data/keeper.db # sqlite path
# DB_HOST=localhost # postgres only
# DB_PORT=5432 # postgres only
# DB_NAME=randproof # postgres only
# DB_USER=keeper # postgres only
# DB_PASSWORD=<password> # postgres only