BUILD / GUIDE
Getting started
Install the SDK, connect your application and verify your first result.
Read the repository referenceWork with your agents
Copy a task-specific prompt with the protocol references and integration rules.
View prompt
Integrate D20DAO verifiable randomness into my existing application. Inspect its stack and request lifecycle, then implement the smallest working consumer and validation flow. Read these public references first; do not guess signatures, addresses or limits: - This guide: https://d20dao.org/docs/getting-started (full text of every guide: https://d20dao.org/llms-full.txt, agent guide: https://d20dao.org/agents.md) - SDK README and AGENTS.md: https://github.com/d20dao/d20-sdk (also inside the installed package). It lists the randomness options, callback gas bounds, how to wait for results, compiler setup and gas needs for refunds and retries. - Protocol source (contracts and replay library): https://github.com/d20dao/d20-sdk/tree/main/protocol, pinned to commit 98e537fb249dd0d3365b8d78e6040a9323a65a88 by PROTOCOL-PROVENANCE.json - Deployment manifests: https://d20dao.org/deployments/arc-mainnet.json, https://d20dao.org/deployments/arc-testnet.json, https://d20dao.org/deployments/robinhood-mainnet.json, https://d20dao.org/deployments/robinhood-testnet.json - Integration skills and templates: https://github.com/d20dao/skills (d20-consumer: methods.md, RandomnessConsumer.sol, mappings.mjs) - Explorer for checking requests: https://d20dao.org/explorer (arc.d20dao.org for Arc Mainnet, arc-testnet.d20dao.org for Arc Testnet; Robinhood requests are read from the chain) - Agent API, for agents and services without a contract: https://d20dao.org/docs/agents (0.05 USDC per call over x402) If a link is unavailable, use the installed package's README, AGENTS.md, ABIs and protocol sources. Networks: Arc Mainnet chain 5042 (live, USDC; RPC https://rpc.mainnet.arc.io; explorer https://explorer.arc.io); Arc Testnet chain 5042002 (build and test here first, USDC; RPC https://rpc.testnet.arc.io; explorer https://testnet.arcscan.app); Robinhood Chain chain 4663 (live, ETH; RPC https://rpc.mainnet.chain.robinhood.com; explorer https://robinhoodchain.blockscout.com); Robinhood Chain Testnet chain 46630 (build and test here first, ETH; RPC https://rpc.testnet.chain.robinhood.com; explorer https://explorer.testnet.chain.robinhood.com). Native USDC on Arc and ETH on Robinhood Chain have 18 decimals. The consumer interface is the same on both; Arc serves requests through epochs, Robinhood Chain binds each request to a future drand round. Compile with Solidity 0.8.28 and EVM version cancun, importing contracts from the installed @d20dao/vrf-sdk package. Take the coordinator proxy address from the manifest of the network you target and check that its implementation matches the manifest. Any consumer contract can request; there is no allowlist, and EOAs cannot request. Requests and fees: use the D20VRFRequests helpers from the SDK for every randomness option (raw word, dice, custom dice, coin flip, ranges, choose one or many, shuffle). Never hardcode the fee. In a contract, quote with quoteFee(callbackGasLimit) inside the requesting transaction. Off chain, quote with quoteFeeAt(callbackGasLimit, latest block baseFeePerGas) plus a buffer, or the SDK's quoteRequestFee with an ethers v6 provider, because eth_call reports a base fee of 0. Choose one payment pattern deliberately: collect a buffered quote from the user, pay the exact fee from the contract and return the change; or forward msg.value and accept that the excess becomes refund credit of the refund address. Results: store the delivered word or mapped result in your consumer when the authenticated callback arrives, keyed by request ID, and have the application read that state. Off chain, wait for the coordinator's fulfillment events or poll getRequest (getRoundRequest on Robinhood Chain); the SDK documents the fields and mapped-result readers. A browser app must bundle the ESM package. Delivery usually takes a few seconds; measured Arc Testnet completion times, including under burst load, are at https://d20dao.org/benchmarks (observations of the testnet keepers, not an SLA). On Robinhood Chain a typical delivery takes 5–8 seconds. An unserved request can be refunded strictly after its 60-second deadline at the refund ratio fixed when it was requested. Give refund and callback-retry transactions explicit gas limits as documented. Keep callbacks small and authenticated through D20VRFConsumer, and never request randomness from inside a callback. An accepted proof with a failed callback is paid service: retry the same stored result, never reroll. Optional _onRefund(requestId) means the refund recipient was paid or credited, not that the consumer received funds, and notification retries must not pay twice. Keep application assets and settlement separate from RNG fees. For verification, keep the original epoch packet, request and target context and accepted proof evidence. Mathematical replay alone does not prove chain inclusion; check receipts and the implementation history too. Implement only the requested changes. Do not ask for keeper, VRF, deployer or bot secrets, and do not send funded or mainnet transactions without my explicit authorization. Compile, run lifecycle tests on a local chain or a testnet, then report changed files, results, anything unverified, and any documentation that was unclear or missing.
Randomness on Arc and Robinhood Chain
Neither chain offers randomness in block data. On Arc, block.prevrandao always returns 0: Arc's bridge integration guide says so and recommends an external oracle in its place. On Robinhood Chain, an Arbitrum chain, it returns 1. D20DAO is a VRF oracle for both: a consumer contract pays for a request in the chain's native token, USDC on Arc and ETH on Robinhood Chain, and the result is delivered with a VRF proof that anyone can replay from public chain data. Measured request timing on Arc Testnet is published at /benchmarks with its method and limits. Agents and services without a contract can buy results over HTTP with x402, on Arc; see For agents.
Choose the deployment
D20DAO VRF is live on Arc Mainnet (chain ID 5042) and Robinhood Chain (chain ID 4663); develop and test on Arc Testnet (5042002) or Robinhood Chain Testnet (46630). Networks explains how each serves a request. Open Deployed contracts and use the coordinator proxy of the network you deploy to, not an implementation address. Check the active implementation and code hashes against the manifest. No consumer registration or allowlisting is needed. The fee follows the live pricing() parameters and the current base fee; pay quoteFee from your consumer or quote quoteFeeAt with the latest base fee plus a buffer. Native USDC on Arc and ETH on Robinhood Chain both use 18 decimals, and transaction gas is separate.
View deployed contractsInstall the SDK
Install @d20dao/vrf-sdk in your application; 0.6.2 or newer replays every Arc epoch. The consumer contracts and request calls are the same on Robinhood Chain. @d20dao/vrf-sdk 0.6.2 or newer replays Robinhood requests, and so does the Explorer. Use Node 22.13 or newer, Solidity 0.8.28 and your project's npm import resolver. The package includes consumer contracts, coordinator and registry ABIs, replay helpers and an AGENTS.md integration guide. Its PROTOCOL-PROVENANCE.json records the reviewed contract source.
npm install @d20dao/vrf-sdkAdd an authenticated consumer
Extend D20VRFConsumer and configure the coordinator proxy. Pay quoteFee(callbackGasLimit) from the consumer in the same transaction, fix a refund recipient that can receive the native token or withdraw refund credit and persist the returned request ID with your application's operation. Override _fulfillRandomness to authenticate through the base, validate the expected ID and store the raw bytes32 result with minimal work. Choose raw randomness or a built-in mapping such as a range, selection or shuffle. See Integration for the Solidity example.
Open the consumer exampleExamples
Three commented consumers ship with the SDK: DiceConsumer rolls a d20 per player, RaffleConsumer draws a winner from a closed entrant list and LootDropConsumer picks a weighted item. The randomizer demo requests every randomness option on Arc Mainnet.
Handle delivery and expiry
Track proof acceptance, callback delivery and refunds separately. Accepted proofs earn the fee even if the consumer callback fails; retryCallback redelivers the same word. Unfulfilled requests become refundable strictly after their 60-second deadline. Measured completion times for isolated requests and under burst and sustained load are published at https://d20dao.org/benchmarks; they are Arc Testnet observations of the keeper fleet at one point in time, so base application timeouts on the deadline rather than on them. On Robinhood Chain a typical delivery takes 5–8 seconds. The coordinator supports optional _onRefund(requestId) after payment or backed credit; keep it within the initial 100,000-gas budget. Failed notifications retry without another payment. Application payments and assets need their own settlement rules.
Test and verify the result
Test underpayment rejection (IncorrectFee), overpayment refund credit, authenticated and duplicate callbacks, callback failure with same-word retry, expiry/refund and any application refund hook. Pay the same-transaction quote from your consumer contract for a testnet request. In the Explorer, verify an Arc request's epoch round and signature, fixed request context, VRF, mapping and transcript, or open a Robinhood request and replay its round, VRF, mapping and transcript; then confirm canonical receipts and code separately. No keeper credentials or direct keeper API are needed.