Deploying Quiver to Robinhood Chain
This is the runbook for deploying the coordinator, registering a provider, and running Fletcher — first on testnet (46630), then mainnet (4663).
Live broadcasts require a funded key and RPC access that only you control. This repo scripts everything up to the broadcast; you supply the signer.
0. Networks
| Testnet | Mainnet | |
|---|---|---|
| Chain ID | 46630 | 4663 |
| RPC (public, rate-limited) | https://rpc.testnet.chain.robinhood.com | https://rpc.mainnet.chain.robinhood.com |
| RPC (recommended) | https://robinhood-testnet.g.alchemy.com/v2/KEY | https://robinhood-mainnet.g.alchemy.com/v2/KEY |
| Explorer | explorer.testnet.chain.robinhood.com | robinhoodchain.blockscout.com |
| Gas token | ETH | ETH |
| Foundry profile name | rh_testnet | rh_mainnet |
Robinhood Chain is an Arbitrum Orbit L2; standard Foundry tooling works unmodified.
1. Prerequisites
forge --version # Foundry
node --version # ≥ 20
pnpm --version
forge install && pnpm install
forge test # green before you deploy anything
Fund your deployer address with a little ETH on the target network (bridge to testnet/mainnet per Robinhood's docs).
2. Configure environment
cp .env.example .env
# edit .env — at minimum set RH_TESTNET_RPC_URL / RH_MAINNET_RPC_URL
Use a keystore, not a raw key, especially for mainnet:
cast wallet import quiver-deployer --interactive # paste your private key once
# deploy with `--account quiver-deployer` (Foundry prompts for the password)
3. Deploy the coordinator
Dry run (no broadcast) first:
forge script script/Deploy.s.sol --rpc-url rh_testnet
Broadcast + verify on Blockscout:
forge script script/Deploy.s.sol \
--rpc-url rh_testnet \
--account quiver-deployer \
--broadcast \
--verify --verifier blockscout \
--verifier-url https://explorer.testnet.chain.robinhood.com/api
This writes deployments/46630.json with the coordinator address. Commit it.
Owner: defaults to the deployer. For production set
QUIVER_OWNERto a multisig (QUIVER_OWNER=0xSAFE forge script ...).
4. Register a provider
Pick a chain length (random values before a rotation) and generate a seed:
pnpm --filter @quiver/fletcher exec tsx src/index.ts genseed # → 0x… , store as FLETCHER_SEED
Set in .env: QUIVER_COORDINATOR_ADDRESS (from step 3), FLETCHER_SEED,
FLETCHER_CHAIN_LENGTH (e.g. 100000), FLETCHER_FEE_WEI, FLETCHER_MAX_NUM_HASHES,
PRIVATE_KEY (the provider key). Then either:
# via Fletcher (recommended — same code path the keeper uses)
FLETCHER_NETWORK=rh_testnet pnpm --filter @quiver/fletcher exec tsx src/index.ts register
# …or via Foundry
forge script script/RegisterProvider.s.sol --rpc-url rh_testnet --account quiver-deployer --broadcast
Both compute commitment = keccak256^chainLength(seed) identically.
5. Run Fletcher
FLETCHER_NETWORK=rh_testnet pnpm --filter @quiver/fletcher exec tsx src/index.ts run
For production, run it as a managed service (systemd/Docker) with restart-on-failure and a dedicated, funded operator key. See fletcher-operations.md.
6. (Optional) Deploy an example consumer
QUIVER_COORDINATOR_ADDRESS=0x… QUIVER_PROVIDER_ADDRESS=0x… \
forge script script/DeployCoinFlip.s.sol --rpc-url rh_testnet --account quiver-deployer --broadcast
7. Smoke test on testnet
# request a flip (as any funded account)
cast send <coinflip> "flip(bytes32)" $(cast keccak $RANDOM) --account quiver-deployer --rpc-url rh_testnet
# watch Fletcher fulfill, then read the result
cast call <coinflip> "flips(uint64)(address,uint8,bool)" 1 --rpc-url rh_testnet
Or run the whole thing locally first: ./demo/local-demo.sh.
8. Promote to mainnet
Repeat steps 3–7 with --rpc-url rh_mainnet and the mainnet verifier URL
(https://robinhoodchain.blockscout.com/api). Before mainnet:
- Owner set to a multisig (ideally + timelock).
-
deployments/4663.jsoncommitted and published to integrators. - Fletcher running as a monitored service with alerting on low ETH and low remaining random values.
- A fresh mainnet seed (never reuse the testnet seed).
- Reviewed security.md; ideally an independent audit for value at scale.
9. Post-deploy checklist
-
getProviderInfo(provider)shows the expected commitment, fee, and chain length. - A test request is fulfilled end-to-end.
- Contract is verified and readable on Blockscout.
- Runbooks exist for: rotating a chain, pausing, transferring ownership, and rotating the Fletcher operator key.
Troubleshooting
| Symptom | Likely cause / fix |
|---|---|
ProviderNotRegistered on request | run step 4; check you targeted the right provider address |
| Fletcher: "provider … not registered" | QUIVER_COORDINATOR_ADDRESS/PRIVATE_KEY mismatch, or wrong network |
Reveal reverts IncorrectProviderRevelation | FLETCHER_SEED/FLETCHER_CHAIN_LENGTH/FLETCHER_ANCHOR don't match what was registered |
TooManyHashes on request | provider is behind on reveals — Fletcher down or out of gas |
| Verification fails on Blockscout | pass --verifier blockscout and the correct --verifier-url …/api |