# Quickstart

Randoo is pay-per-request on Ronin. Inherit `RandooConsumerRonin` (shipped with the sample below), quote the fee on-chain, and send it with the request.

1. Deploy your consumer with the Randoo coordinator `0xC66eB2e7EE91145875000Ad46B55600000000001` (same CREATE3 address on Ronin mainnet and Saigon).
2. Call `estimateRequestRandomFee(callbackGasLimit, gasPrice)`.
3. Call `requestRandomSeed` with `msg.value >= estimate` and a non-zero refund address (not the consumer if it is not payable).
4. The oracle fulfills. Your `rawFulfillRandomSeed` runs with the seed.

## Consumer

`TemplateConsumer` is the canonical consumer sample. Its base `RandooConsumerRonin` ships with the sample and is inlined first; together with `contracts/src/interfaces/IRoninVRFCoordinatorForConsumers.sol` they compile as shown in a fresh Foundry project.

```solidity RandooConsumerRonin.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import {IRoninVRFCoordinatorForConsumers} from "./interfaces/IRoninVRFCoordinatorForConsumers.sol";

/// @notice Ronin VRFConsumer-shaped base. Swap coordinator address to migrate.
abstract contract RandooConsumerRonin {
    error OnlyCoordinatorCanFulfill();

    address public vrfCoordinator;

    constructor(address vrfCoordinator_) {
        vrfCoordinator = vrfCoordinator_;
    }

    function rawFulfillRandomSeed(bytes32 reqHash, uint256 randomSeed) external {
        if (msg.sender != vrfCoordinator) revert OnlyCoordinatorCanFulfill();
        _fulfillRandomSeed(reqHash, randomSeed);
    }

    function _fulfillRandomSeed(bytes32 reqHash, uint256 randomSeed) internal virtual;

    function _requestRandomness(
        uint256 value,
        uint256 callbackGasLimit,
        uint256 gasPriceToFulfill,
        address refundAddr
    ) internal returns (bytes32 reqHash) {
        reqHash = IRoninVRFCoordinatorForConsumers(vrfCoordinator).requestRandomSeed{value: value}(
            callbackGasLimit, gasPriceToFulfill, address(this), refundAddr
        );
    }
}
```

```solidity TemplateConsumer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

// ---------------------------------------------------------------------------
// Randoo consumer template: copy-pasteable as a unit with
// RandooConsumerTemplate.t.sol and MockRandooCoordinator.sol (this folder), plus
// src/RandooConsumerRonin.sol and src/interfaces/IRoninVRFCoordinatorForConsumers.sol.
// Imports resolve in a fresh `forge init` with only forge-std installed.
// ---------------------------------------------------------------------------

import {RandooConsumerRonin} from "../../src/RandooConsumerRonin.sol";

/// @notice The canonical Randoo consumer. Copy it, rename it, put your game
///         logic in `_fulfillRandomSeed`.
///
/// Flow: a caller pays `estimateRequestRandomFee(callbackGasLimit, gasPrice)`
/// into `roll`, which forwards the request to the coordinator and returns the
/// `reqHash`. Later the coordinator calls `rawFulfillRandomSeed` (inherited,
/// coordinator-only) which lands in `_fulfillRandomSeed` with the seed.
contract TemplateConsumer is RandooConsumerRonin {
    /// @notice Last seed delivered by the coordinator.
    uint256 public lastSeed;
    /// @notice Request hash of the most recent `roll`, then of the most recent fulfil.
    bytes32 public lastReqHash;

    constructor(address vrfCoordinator_) RandooConsumerRonin(vrfCoordinator_) {}

    /// @param callbackGasLimit Gas the coordinator will give `_fulfillRandomSeed` (50k..2.5M).
    /// @param gasPrice Gas price the fulfiller may spend; must be >= the coordinator floor.
    /// @param refundAddr Receives unspent fulfilment gas; must be non-zero.
    function roll(uint256 callbackGasLimit, uint256 gasPrice, address refundAddr)
        external
        payable
        returns (bytes32 reqHash)
    {
        reqHash = _requestRandomness(msg.value, callbackGasLimit, gasPrice, refundAddr);
        lastReqHash = reqHash;
    }

    /// @dev Your randomness lands here. Keep it within `callbackGasLimit`.
    function _fulfillRandomSeed(bytes32 reqHash, uint256 randomSeed) internal override {
        lastReqHash = reqHash;
        lastSeed = randomSeed;
    }
}
```

_Last verified 2026-08-25._
