Operator node
The node in node/ runs four services, each in its own loop with its own account, so they never compete for transaction nonces.
| Service | Does |
|---|---|
vrf | Watches for requests on its key, waits for confirmations, submits ECVRF proofs |
beacon | Publishes each due round in order, catching up after downtime |
automation | Simulates every upkeep, performs those due on its turn, and keeps its stake topped up |
oracle | Fetches prices, collects signer signatures, transmits on deviation or heartbeat |
Run it
cp node/.env.example node/.env # then fill it in
npm run operatorOn the local chain (id 31337) every key is optional, because dev keys are used. Anywhere else, the node refuses to start without explicit keys.
Configuration
| Variable | Purpose |
|---|---|
GENESIS_RPC_URL | RPC endpoint |
GENESIS_DEPLOYMENT | Path to deployments/<network>.json |
SERVICES | Comma-separated: vrf,beacon,automation,oracle |
VRF_SECRET_KEY, BEACON_SECRET_KEY | Proving keys. Generate them with npm run keygen -w node |
VRF_OPERATOR_PRIVATE_KEY | Sends VRF fulfillments |
BEACON_PRIVATE_KEY | Sends beacon rounds |
KEEPER_PRIVATE_KEY | Node wallet authorized as the keeper's operator (gas only, never staked) |
ORACLE_TRANSMITTER_PRIVATE_KEY | Sends oracle reports |
ORACLE_SIGNER_PRIVATE_KEYS | Observation signers. In production, run one signer per independent node |
ORACLE_DEVIATION_BPS, ORACLE_HEARTBEAT_SEC | Oracle update policy (default 50 bps, 60 s) |
POLL_MS | Base polling interval (default 2000) |
Keep stake out of the node
Node wallets should hold only gas money:
| Role | Staked identity (secure wallet) | Node wallet does |
|---|---|---|
| VRF operator | Registered as the key's operator: holds the stake and receives fees | Relays proofs (anyone can submit a valid proof) |
| Keeper | Stakes, registerKeeper(), then setKeeperOperator(nodeWallet) | Performs upkeeps; earnings go to the keeper |
| Beacon publisher, oracle transmitter | None needed | Submits rounds and reports |
On Elysium the deploy script does this automatically. The deployer wallet stakes as the VRF operator and as the keeper, then authorizes GENESIS_KEEPER_OPERATOR as its node wallet.
Keys
npm run keygen -w node
# VRF_SECRET_KEY=0x… keep it secret, in .env only
# public key (x,y): …,… goes into GENESIS_VRF_PUBLIC_KEY at deploy timeGenerate keys on a machine you trust, and never paste a secret key into chat, tickets or screenshots.
Elysium specifics
On Elysium, which is an Arbitrum Nitro chain, block.number inside contracts is the parent chain's block number, not the RPC block height. The node reads the contract-visible number for VRF confirmations, so requests are fulfilled correctly.