# Workers

One Node process on the operator machine serves both chains: watch logs (WebSocket subscription when `RANDOO_WS` is set, HTTP polling always), produce a Chainlink-format VRF proof with the per-chain proving key, fulfill in turn — in the block after the request on the fast path. The VRF secret and the gas wallet are separate keys and never leave that machine. The playground is a separate Convex simulation and does not drive Saigon or mainnet rows.

```sh node.ts
# One process, both chains. VRF proving keys are per-chain and
# distinct from the gas wallet (enforced at startup).
RANDOO_NETWORKS=saigon,ronin \
RANDOO_COORDINATOR=0xC66eB2e7EE91145875000Ad46B55600000000001 \
RANDOO_ORACLE_PK=0x...            # gas wallet (per-chain nonces) \
RANDOO_VRF_SK_SAIGON=0x...        # from workers/src/keygen.ts saigon \
RANDOO_VRF_SK_RONIN=0x...         # from workers/src/keygen.ts ronin \
RANDOO_WS_SAIGON=wss://...        # optional: next-block fast path (subscriptions + sends; reads stay on HTTP) \
RANDOO_WS_RONIN=wss://...         # \
RANDOO_MAX_FEE_GWEI=100           # optional absolute fee cap, per-network suffix allowed \
npm start
# GET :8788/health → per-network head, wallet balance, keyHash, lastError,
#   feed status, divergence, in-flight, latency percentiles (blocksP50/P95) and the last 20 requests
```

_Last verified 2026-08-25._
