…
Since coordinator deploy
… SOMI
Pays every request out of pocket
…
Chain id 5031
Flip a coin. The chain reveals it.
One tx from your wallet, sixteen blocks, heads or tails resolved on-chain by the coordinator. Switch chains in the header to see the same demo on testnet or mainnet.
CoinFlip · a 42-line VRF consumer
Click flip, sign one tx from your wallet, wait 16 blocks, and read heads or tails back on-chain. The coordinator handles the schedule, the reveal, and the callback. No fulfiller sits behind it.
Four moves. Nothing off-chain in between.
A commit-reveal flow that borrows the Reactivity precompile as the delivery mechanism, so the network itself pays for the callback out of the coordinator's balance.
Consumer requests words
Any contract that extends VRFConsumerBaseV2Plus calls requestRandomWords({callbackGasLimit, commitDelayBlocks, numWords, useVerifiableEntropy}). The coordinator records the request under revealBlock = block.number + commitDelayBlocks.
Coordinator schedules Reactivity tick
The coordinator schedules a subscription against Somnia's Reactivity precompile for revealBlock. Multiple requests at the same reveal block share one subscription (coalescence).
Reveal block fires
At revealBlock, the Reactivity precompile calls coordinator.onEvent(...). Fast mode derives the seed from blockhash(revealBlock-1) directly. Verifiable mode fires a Somnia Agents JSON API Request against api.drand.sh.
Callback delivered
Once entropy is resolved (immediately in Fast mode, ~5s later in Verifiable mode), consumer.rawFulfillRandomWords(requestId, words) is called under a try/catch. A reverting consumer surfaces callbackSuccess=false in the event.
The mainnet coordinator was deployed with FAST_MODE_ENABLED = false. Blockhash-only requests revert at request time. Every mainnet request goes through the drand-mixed Verifiable path.
Drop-in shape.
coordinator = 0x50AAEE5ECE41627F2bc4b64Ad29a4659a5C018cb
import {VRFConsumerBaseV2Plus} from "somnia-vrf/VRFConsumerBaseV2Plus.sol";
import {ISomniaVRFCoordinator} from "somnia-vrf/ISomniaVRFCoordinator.sol";
contract CoinFlip is VRFConsumerBaseV2Plus {
enum Result { Pending, Heads, Tails }
mapping(uint256 => Result) public flips;
constructor(address coordinator) VRFConsumerBaseV2Plus(coordinator) {}
function flipVerifiable() external returns (uint256 requestId) {
return COORDINATOR.requestRandomWords(
ISomniaVRFCoordinator.RandomWordsRequest({
callbackGasLimit: 100_000,
commitDelayBlocks: 16,
numWords: 1,
useVerifiableEntropy: true
})
);
}
function fulfillRandomWords(uint256 requestId, uint256[] memory words)
internal override
{
flips[requestId] = words[0] & 1 == 0 ? Result.Heads : Result.Tails;
}
}Live coordinators on both chains.
Somnia Mainnet
Chain 5031 · SOMIVerifiable-onlySomnia Testnet
Chain 50312 · STTEvery reveal on the active chain.
Landed events from CoinFlip
scanning last ~300k blocks…