> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roll.codes/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create a new roll.codes project from the starter CLI or integrate the hosted coordinator into an existing Solidity contract.

Use this page when you want the fastest path to a working consumer contract on Abstract.

Choose the path that matches your starting point:

* New project: scaffold a Foundry starter that already includes an example consumer contract.
* Existing project: wire the hosted roll.codes coordinator into your current Solidity app.

## New projects

The starter CLI generates a Foundry project with:

* `src/DiceDuelConsumer.sol`
* `test/DiceDuelConsumer.t.sol`
* `script/DeployDiceDuelConsumer.s.sol`
* remappings and Foundry config for Abstract

The generated consumer already requests randomness with `requestRandomNumberWithTraceId(...)` and receives it in `randomNumberCallback(...)`.

<Steps>
  <Step title="Build the starter CLI">
    The CLI source currently lives in this repository.

    ```bash theme={null}
    git clone https://github.com/jarrodwatts/roll.codes.git
    cd roll.codes/packages/create-roll-codes
    npm ci
    npm run build
    ```
  </Step>

  <Step title="Scaffold a starter project">
    Run the generator from the CLI package directory:

    ```bash theme={null}
    node dist/index.js contract my-game
    ```

    This creates `./my-game` with the example consumer already wired to the public `IVRFSystem` interface.
  </Step>

  <Step title="Build and test the generated project">
    ```bash theme={null}
    cd my-game
    forge build --zksync
    forge test --zksync -vvv
    ```
  </Step>

  <Step title="Configure the hosted coordinator and deploy">
    <Tabs>
      <Tab title="Abstract testnet">
        ```bash theme={null}
        cast wallet import deployer --interactive
        export ROLL_OWNER=$(cast wallet address --account deployer)
        export ABSTRACT_RPC_URL=https://api.testnet.abs.xyz
        export ROLL_VRF_SYSTEM=0x5ab0e04147A2A1BCa1D06da3c1cB48ea04294B5E

        forge script script/DeployDiceDuelConsumer.s.sol:DeployDiceDuelConsumer \
          --account deployer \
          --rpc-url "$ABSTRACT_RPC_URL" \
          --zksync \
          --broadcast
        ```
      </Tab>

      <Tab title="Abstract mainnet">
        Mainnet deployment is not live yet.

        ```bash theme={null}
        cast wallet import deployer --interactive
        export ROLL_OWNER=$(cast wallet address --account deployer)
        export ABSTRACT_RPC_URL=<your_abstract_mainnet_rpc_url>
        export ROLL_VRF_SYSTEM=<mainnet_coordinator_address>

        forge script script/DeployDiceDuelConsumer.s.sol:DeployDiceDuelConsumer \
          --account deployer \
          --rpc-url "$ABSTRACT_RPC_URL" \
          --zksync \
          --broadcast
        ```
      </Tab>
    </Tabs>

    See [Deployed addresses](/contracts/deployed-addresses) for the current network-specific coordinator status and addresses.
  </Step>
</Steps>

<Tip>
  If you want the full CLI surface, including `--dir`, `--force`, and `--skip-install`, see [CLI reference](/cli/create-roll-codes).
</Tip>

## Integrating into an existing project

Use this path if you already have a Foundry project and only need to add roll.codes support.

<Steps>
  <Step title="Install the dependency">
    ```bash theme={null}
    forge install roll.codes=jarrodwatts/roll.codes@main --no-git
    forge install forge-std=foundry-rs/forge-std --no-git
    ```
  </Step>

  <Step title="Add remappings">
    Your project should include:

    ```txt theme={null}
    @rollcodes/=lib/roll.codes/src/
    forge-std/=lib/forge-std/src/
    ```
  </Step>

  <Step title="Request a random number">
    Import the public interfaces, store the hosted coordinator address, then request randomness by paying `requestFee()`.

    ```solidity theme={null}
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.24;

    import {IVRFSystem} from "@rollcodes/interfaces/IVRFSystem.sol";
    import {IVRFSystemCallback} from "@rollcodes/interfaces/IVRFSystemCallback.sol";

    contract ExampleConsumer is IVRFSystemCallback {
        IVRFSystem public immutable vrfSystem;

        constructor(address coordinatorAddress) {
            vrfSystem = IVRFSystem(coordinatorAddress);
        }

        function play() external payable returns (uint256 requestId) {
            uint256 fee = vrfSystem.requestFee();
            require(msg.value == fee, "fee mismatch");

            uint256 traceId = 0;
            requestId = vrfSystem.requestRandomNumberWithTraceId{ value: fee }(traceId);
        }

        function randomNumberCallback(uint256 requestId, uint256 randomNumber) external override {}
    }
    ```
  </Step>

  <Step title="Handle the callback safely">
    Every request is delivered asynchronously. Restrict the callback to the hosted coordinator and settle against stored request state.

    ```solidity theme={null}
    function randomNumberCallback(uint256 requestId, uint256 randomNumber) external {
        if (msg.sender != address(vrfSystem)) revert Unauthorized();

        Pending storage request = pendingByRequestId[requestId];
        if (request.player == address(0)) revert RequestNotFound(requestId);
        if (request.settled) revert AlreadySettled(requestId);

        request.settled = true;
        request.randomNumber = randomNumber;

        // settle your game or app logic here
    }
    ```
  </Step>

  <Step title="Deploy only your consumer">
    Set the hosted coordinator address for the same network as your RPC URL:

    <Tabs>
      <Tab title="Abstract testnet">
        ```bash theme={null}
        cast wallet import deployer --interactive
        export ABSTRACT_RPC_URL=https://api.testnet.abs.xyz
        export ROLL_COORDINATOR=0x5ab0e04147A2A1BCa1D06da3c1cB48ea04294B5E
        ```
      </Tab>

      <Tab title="Abstract mainnet">
        Mainnet deployment is not live yet.

        ```bash theme={null}
        cast wallet import deployer --interactive
        export ABSTRACT_RPC_URL=<your_abstract_mainnet_rpc_url>
        export ROLL_COORDINATOR=<mainnet_coordinator_address>
        ```
      </Tab>
    </Tabs>

    Then deploy your own consumer contract with your normal Foundry script flow, using `--account deployer` when you broadcast.
  </Step>
</Steps>

<Note>
  `requestRandomNumberWithTraceId` is payable on roll.codes, so callers must send the exact value returned by `requestFee()`.
</Note>

<Tip>
  Prefer a Foundry keystore account over exporting plaintext private keys. Import once with `cast wallet import` and reuse that account name with `forge script --account ...`.
</Tip>

Requests delivered from the same drand round receive the same base `randomNumber`. If your app needs a unique value per request within that same round, derive one locally from `requestId` and `randomNumber`.

## Verify the result

You should end with:

* a deployed consumer contract
* a configured roll.codes coordinator address in your deployment inputs
* a request path that pays `requestFee()`
* a callback that only accepts the hosted coordinator

## Next steps

<CardGroup cols={2}>
  <Card title="Integration pattern" icon="blocks" href="/contracts/integration-pattern">
    Copy a fuller consumer example with request storage and settlement guards.
  </Card>

  <Card title="Coordinator reference" icon="file-text" href="/contracts/coordinator-reference">
    Keep the request function, fee call, and callback interface beside you while implementing.
  </Card>

  <Card title="Troubleshooting" icon="life-buoy" href="/faq/troubleshooting">
    Fix fee mismatches, unauthorized callbacks, and pending requests.
  </Card>

  <Card title="CLI reference" icon="terminal" href="/cli/create-roll-codes">
    Review the starter generator flags and output files.
  </Card>
</CardGroup>
