Don’t trust us. Recompute it.
There is no operator seed to trust. A draw is two public things: the Merkle root of every holder’s balance, committed on-chain just before a close slot we named in advance, and that slot’s hash, read on-chain from Solana’s SlotHashes. The roll is just keccak256 of the slot hash, so the winner is fixed and public the instant the slot lands. This page re-runs the whole computation in your browser, the same math the program verifies on-chain.
What we cannot do
The roll is keccak256 of the hash of a close slot we committed to before it was produced — that hash didn't exist yet, so it can't be ground.
There is NO operator seed. Nothing is revealed, so there is nothing to withhold or quietly re-roll if the result is unfavorable.
The snapshot's Merkle root is committed on-chain BEFORE the close slot, so it can't be tuned to a roll that doesn't exist yet. The full snapshot is published; anyone recomputes the root.
settle is permissionless and verifies a Merkle proof that the winner's weight interval covers the roll; payout then sends the escrowed card to exactly that address.
Reference implementation
The exact rules. The full implementation is open source (packages/shared/src/roll.ts) — same answer as this page.
// no seed, no secret — everything is public on-chain data
import { keccak_256 } from "@noble/hashes/sha3";
// slotHash = hash of the first produced slot ≥ closeSlot (SlotHashes sysvar),
// captured on-chain by the permissionless reveal
// roll = keccak256(slotHash ‖ u64le(drawId))
// offset = u128le(roll[0..16]) mod totalWeight
// winner = the holder whose [cumBefore, cumBefore + weight) covers offset,
// in the snapshot sorted by raw pubkey bytes; proven on-chain by a
// Merkle proof of keccak256(keccak256(pubkey ‖ u64le(cumBefore) ‖ u64le(weight)))
// full source: packages/shared/src/roll.ts
