# D20DAO integration guide for agents

D20DAO provides general-purpose verifiable randomness for consumer applications. Dice, selections and shuffles are deterministic mappings of a random word; they are examples, not the scope of the service.

## Integration resources

- [Protocol, interfaces and public replay](https://github.com/d20dao/keeper)
- [SDK](https://www.npmjs.com/package/@d20dao/vrf-sdk): install with `npm install @d20dao/vrf-sdk`. [Source](https://github.com/d20dao/d20-sdk).
- [Agent integration skills](https://github.com/d20dao/skills)

The website's `/docs` guides cover integration, architecture, sources, verification, service rules and security. An Arc Testnet pilot is deployed on chain 5042002. The public deployment manifest is at https://github.com/d20dao/keeper/blob/main/deployments/arc-testnet.json and records proxy addresses, code hashes and upgrade receipts. Consumer allowlisting is required for the pilot. SDK installation does not establish mainnet approval, an external cryptographic audit or a public SLA.

## Getting started with an application

Start at `/docs/getting-started`, then `/docs/deployments` and `/docs/integration`. `/llms.txt` indexes the guides; `/llms-full.txt` contains their full text, SDK setup and deployment snapshot. Each guide has a Copy prompt action and a matching `/prompts/<guide-slug>.txt` file. `/AGENTS.md` is an alias for `/agents.md`.

Use `npm install @d20dao/vrf-sdk`, Node 22.13 or newer and Solidity 0.8.28. Read the installed AGENTS.md, declarations and PROTOCOL-PROVENANCE.json. The reviewed protocol source is `d7e785dda57499220bd37d73bc6fad9226872dcc`. If a source repository cannot be accessed, use packaged interfaces or obtain the reviewed files instead of inventing APIs.

The current Arc Testnet manifest includes the refund-notification upgrade at block 62310349. Recheck active code and consumer allowlisting before sending a live request. Read `requestFee()` at runtime; native test USDC uses 18 decimals. The deployed pilot consumer is restricted test tooling, not an application contract for users to call.

Associate each request ID with an application operation. Test exact fees, callback authentication, duplicate handling, accepted-proof callback failure and same-word retry, expiry/refund and any `_onRefund` hook. Report changed files, checks and missing onboarding steps. Integration needs no keeper, VRF, deployer or bot secrets; follow the user's authorization for deployment and funded actions.

## Request and receive randomness

A consumer can extend `D20VRFConsumer`, which authenticates callbacks from its configured coordinator. `ID20VRF` exposes `requestFee()`, `requestRandomness(clientSeed, callbackGasLimit, refundAddress)`, `requestMappedRandomness(...)` and `getMappedResult(requestId)`.

Read the exact fee from the intended coordinator, choose a fixed refund recipient and submit the request with that exact value. Keep the returned request ID and correlate it with delivery. The client seed is a fixed input, not a guarantee of secrecy. Store the authenticated result in a small callback and perform other application actions separately.

A request checkpoints its epoch's canonical source anchor and escrows the fee even if its API packet has not yet been published. Consumer, client seed, mapping, request block, epoch ID and refund recipient are fixed. The epoch hash resolves at publication. Until publication, the target and complete VRF input are unresolved.

## Epoch publication and proof

Epochs span 200 blocks. The first starts 200 blocks after registry initialization. The source-selection anchor is the block immediately before the epoch starts. The keeper prepares the current epoch locally and preserves its first valid snapshot. Idle epochs need no publication transaction. Live, allowlisted paid demand triggers publication of the packet, which cannot be overwritten.

The randomness target is `max(requestBlock, epochCommitBlock + 1)`, strictly after publication. The target hash is unknown when the packet is committed. The fixed input binds chain, coordinator, key hash, request ID, consumer, client seed, mapping hash, request block, target block and target hash, epoch ID and epoch hash. A genuine fixed secp256k1 VRF key supplies the proof. `fulfillRandomness(requestId, proof)` carries 452 calldata bytes and 416 proof-evidence bytes.

There is no per-request API fetch, fallback or resampling. An unused local packet retires after 50 epochs. Used epoch packets remain available through public chain events.

## Exact source records

Catalog hash, epoch ID and the start-minus-one anchor hash select modulo four:

| Slot | Provider | Fixed recipe |
| --- | --- | --- |
| 0 | Hyperliquid | BTC symbol and dayNtlVlm from metaAndAssetCtxs |
| 1 | ANU | randomNumbers, hex8, length 4, size 8 |
| 2 | TickerLayer | crypto BTCUSD lastTrade |
| 3 | TickerLayer | crypto ETHUSD lastTrade |

Four slots use three providers; both TickerLayer slots pin the same signer. Raw values may repeat. Distinct epoch parameters bind distinct commitments without creating entropy by hashing.

Canonical low-s EIP-191 signatures bind query hash, attestation timestamp and exact UTF-8 data. Raw signed records are at most 128 bytes. At publication the attestation cannot be future-dated or more than 120 seconds old. TickerLayer retains the complete symbol, price, size and timestamp record with exact order and numeric bytes. Malformed, oversized or stale data is rejected rather than cropped or silently replaced.

## Acceptance, delivery and refunds

A proof must be accepted onchain at or before the request timestamp plus 60 seconds. Publication and waiting for the target block consume the same window. Crossing an epoch boundary does not shorten the request's deadline. A pending transaction is not acceptance, and the timestamp rule is not a guaranteed block SLA.

Accepted proof earns the configured keeper and treasury shares even when the consumer callback fails. The keeper share goes to the configured committer, not the proof submitter. Failed transfers become backed credits. The pilot currently allocates 20% to the keeper (0.01 from a 0.05 test USDC fee); read the live configuration rather than treating this as permanent pricing.

A failed callback can be retried with the same stored word and no second service fee. After expiry without accepted proof, the escrowed RNG fee is refundable by transaction to its fixed recipient; gas and application fees are excluded. Refunds are not automatic. Publication alone does not earn the escrowed fee. Inspect request, callback, refund and credit state separately when determining an application's next action.

## Independent verification and trust

`EpochCommitted` emits the complete accepted API packet once when the epoch is used. Accepted requests expose proof evidence. `replayEpochCommitment` validates epoch selection and the signed record; `replayCoordinator` checks request binding, future target, key/configuration, seed, VRF, mapping, transcript and acceptance timing. Replay needs independently trusted canonical blocks, receipts, timestamps and historical implementation context, without a private keeper database or keeper connection.

The coordinator and registry use UUPS implementations behind ERC1967 proxies. Ownership transfer is two-step; owner, fee recipient and keeper/committer roles can rotate. This implementation has no VRF-key setter, but trusted upgrade authority can change behavior. Rotating the transaction wallet does not rotate the VRF key. A stable proxy address or its runtime hash alone does not prove unchanged behavior; identify the implementation and configuration active at each historical receipt.

Proofs do not force operator availability or establish source truthfulness, independence or lack of bias. The operator can withhold preparation, publication or fulfillment. A source signature alone does not prove chain inclusion or a complete VRF result. The website lab is illustrative; its historical Hyperliquid candle inspector authenticates only that historical response, not a current epoch recipe or accepted onchain request.

## Public explorer

The website's `/explorer` lists only canonical indexed requests and onchain epoch publications. Filter by chain, coordinator or registry, numeric ID and request state. Request details preserve the original mapping and evidence; optional what-if mapping is explicitly simulated.

Public replay verifies the signed epoch packet, fixed request/target context, VRF, mapping and transcript. A separate chain check compares canonical receipts, event bytes, source/target hashes and historical configuration through an independently configured RPC. Mathematical validity does not establish chain inclusion. Historical UUPS proxy and implementation runtime hashes must also match the independently configured trust allowlist; otherwise implementation trust remains unknown. The index database alone is not proof.

An unconfigured or empty index shows a waiting state, never substituted sample activity. Test fixtures are local CI evidence and are not a production explorer fallback.

Historical code checks compare block boundaries and inspect Upgraded events across the entire relevant block. If upgrades occur or the implementation slot changes, code attribution remains unknown without transaction-ordered execution evidence; a block-end allowlisted address alone cannot prove which code executed a call.

The bundled consumer source includes optional authenticated `_onRefund(requestId)` support. Fee payment or backed credit is settled before the bounded notification; failed notification can retry without repaying. Verify the live implementation supports it before integration: published source is not evidence that the deployed proxy was upgraded.
