When you open a session, your browser generates a secret hash chain of 4096 values and commits only its root; the house does the same. A sessionSeed is fixed on-chain at open by a two-party commit-reveal — no external oracle: the house publishes houseSeedCommit = keccak256(abi.encode(houseSeed)) before seeing your seed; your wallet signs over playerSeed and that commitment; the open transaction reveals houseSeed and the contract enforces sessionSeed = keccak256(abi.encode(houseSeed, playerSeed, channelId)). Neither side can predict or bias it — and you can recompute it below. At this point every future card and number is already determined — but neither side can compute any of them alone.
For outcome k, both sides walk one step down their hash chains and exchange reveals. The result is pure math: outcome_k = keccak256(playerReveal, houseReveal, sessionSeed, channelId, k) mod N (N = 52 for cards, 37 for the wheel). A reveal is valid only if it hashes back to the previous link — forgery is impossible.
After each action both parties sign the new game state (EIP-712, via burner session keys that cannot move funds). If anyone disconnects or stalls, the chain enforces the last dual-signed state. If the house stalls, your open round is voided in your favor and you're paid compensation from the house bond.
Your deposit sits in the ChannelManager escrow on Arbitrum One. Cooperative close pays out instantly; forceClose guarantees your exit even if MAY vanishes forever; reclaimStale is the final backstop. Any disputed transition is checked by the on-chain rules verifiers (Blackjack / Roulette via GameMux) — cheating is provable and punished.
Typical provably-fair casinos generate and hold a server seed, hold your deposit, and process withdrawals at their discretion. MAY has no unilateral seed, no custody, no withdrawal queue — just math and contracts you can read.
Recompute an outcome entirely in your browser. Paste the reveal pair, session seed, and channel id from any round (the SDK exposes them; nothing is sent anywhere).
Paste both seed halves (the SDK exposes houseSeed / playerSeed; they're also in the on-chain SessionSeedCommitReveal event of your open tx) and your channel id. Recomputes keccak256(abi.encode(houseSeed, playerSeed, channelId)) — must equal your session seed — and the house commitment keccak256(abi.encode(houseSeed)).
keccak256(abi.encode(reveal)) == previousLink — the same check the on-chain verifier does.