RandProofRandProof

Quickstart

Integrate RandProof into your contracts in four steps: no token purchase, no staking, no minimum commitment.

Integration follows the same four steps regardless of which RandProof product you use.

1. Choose the Product

Match your need to a Layer 1 product:

NeedProduct
Verifiable randomnessRandProofRNG
Triggered execution / upkeepRandProofAutomation or Sentinel
Off-chain computation / AI inferenceRandProofCompute or Forge
External dataRandProof Oracle
Sybil-resistance signalsRandProof Identity
Continuous monitoringRandProof Audit
Reserve attestationRandProof Custody Proof

2. Call the Contract

Integrate the relevant Layer 1 interface directly from your client contract. Where a RandProof product is built as a compatible replacement for an existing dependency, such as RandProofAutomation's Chainlink-compatible interface, integration can be a direct address swap with no logic changes required.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

interface IKeeperCoordinator {
    // Request a PoFR event. Returns eventId.
    // Fee must be >= MIN_FEE. Rate limited: 1 request per 10 blocks per address.
    function requestRandomness(bytes32 userSeed) external payable returns (bytes32 eventId);

    // Check if an event has been fulfilled
    function isFulfilled(bytes32 eventId) external view returns (bool);

    // Get the RandProof artifact for a fulfilled event
    function getRandProof(bytes32 eventId) external view returns (
        bytes32 seed,
        bytes memory aggregatedBLSSig,
        address[] memory signers,
        uint256 fulfillBlock,
        uint256 fulfillTimestamp
    );
}

A minimal consumer requests randomness and receives the fulfilled seed via callback:

contract MyRaffle is IRandProofConsumer {
    IKeeperCoordinator public coordinator;
    mapping(bytes32 => uint256) public pendingDraws; // eventId => totalEntrants

    constructor(address _coordinator) {
        coordinator = IKeeperCoordinator(_coordinator);
    }

    // Step 1: request randomness when the draw is ready
    function requestDraw(uint256 totalEntrants) external payable {
        bytes32 userSeed = keccak256(abi.encode(block.number, msg.sender, totalEntrants));
        bytes32 eventId = coordinator.requestRandomness{value: msg.value}(userSeed);
        pendingDraws[eventId] = totalEntrants;
    }

    // Step 2: receive the fulfilled randomness (called by KeeperCoordinator)
    function fulfillRandomness(bytes32 eventId, bytes32 seed) external override {
        require(msg.sender == address(coordinator), "Only coordinator");
        uint256 totalEntrants = pendingDraws[eventId];
        require(totalEntrants > 0, "Unknown event");
        uint256 winnerIndex = uint256(seed) % totalEntrants;
        // ... settle the draw
    }
}

The full interface, including fulfill, submitEntropy, submitFraudProof, and getEntropyInputs, is documented in Client Contract Integration.

3. Pay Per Use

Fees are paid in USDC at the point of use via the x402 micropayment rail. There is no protocol token required to integrate, no staking requirement on the client side, and no minimum commitment beyond the fee for the specific call being made.

4. Consume the Result

A request returns either an on-chain value directly (randomness, an oracle reading) or a certificate referencing an off-chain result (a PoIF fidelity certificate, a PoRC provenance certificate, an identity attestation). Where ERC-8004 integration applies, you can additionally check a counterparty's or keeper's attestation history in the Validation Registry before relying on a given result.

What Integration Does Not Require

  • No RandProof token purchase or holding requirement to integrate any product as a client.
  • No migration of existing contract logic beyond the specific function calls being replaced, for products offered as compatible drop-in replacements.
  • No relationship with BIT5050 or any other existing production deployment, every Layer 1 product is designed to be integrated independently.

Next Steps

On this page