Documentation

Docs

ShinyLuck is a provably-fair casino and poker room on the Somnia testnet. Casino outcomes are drawn by a commit-reveal scheme the CasinoVault contract computes itself; poker cards are dealt by mental poker (zkShuffle v2), so no server ever sees your hand. This page covers how it works, what it costs, and where the contracts live.

Overview

Two products share one site, one wallet and one on-chain profile:

Casino · seven games (Dice, Mines, Plinko, Roulette, Crash, VAULT.7, SUGAR.LAB), all live. One permanent CasinoVault holds the bankroll and derives the randomness; each game is its own module contract registered with it. A settlement bot reveals the pre-committed seeds · it has no power over any result. Crash and Roulette run on demand: the first player to bet opens the round, and the bot only settles it, so nothing spins or burns gas on an empty table.

Poker · full no-limit hold'em, cash tables and tournaments, all chips and actions on-chain in the PokerRoom contract. The deck is shuffled by the players themselves in-browser, and every shuffle carries a zero-knowledge proof (zkShuffle v2).

Wallet & STT

Sign in with email · Privy creates an embedded wallet for you inside ShinyLuck, with no extension to install. Transactions are signed headlessly: no per-bet popups. The address is scoped to this app, so it is not the same address you would get in other Somnia apps.

The currency is STT, Somnia's testnet token · it carries no monetary value. You need STT in your wallet to cover gas on every on-chain action, so keep a small balance there and play straight from it. Somnia's base fee is a fixed 6 gwei, which makes the numbers small and predictable: a poker action costs about 0.001 STT, a slot spin about 0.006 STT, a Dice or Plinko bet about 0.01 STT. Poker uses a separate in-contract bankroll: top it up (and cash out) from the profile drawer.

Casino games

Bets are placed directly from your wallet; wins are credited by the Vault and paid out on claim() (the site claims for you once you stop betting, and the profile drawer has the button). The bet panel shows your live limits, both read from the contract in real time: a single stake may not exceed 1% of the free bankroll, and no bet may be able to win more than 20% of it.

Dice · pick a win chance anywhere from 0.01% to 99.99% and roll over or under; payouts scale up to 9900×, and the house edge is a flat 1.00% at every chance. Mines · open safe tiles, each compounds the multiplier; cash out any time. Edge 1.20%. Plinko · a ball drops through 16 rows of pins and the path replays the on-chain randomness bits exactly; three risk tables, each carrying about 1.0%. Roulette · an American wheel (0 and 00) with shared rounds, so every player is on the same spin. Edge 5.26%. Crash · shared rounds too; cash out before the bust point. Edge 1.00%. VAULT.7 · a 5×3, 20-line slot. SUGAR.LAB · a 7×7 cluster slot with cascades and a Charge Meter that pays out on a hidden, per-cycle threshold.

Every edge above is a constant in that game's module contract (Plinko's lives in its pay tables). The two slots publish their measured return-to-player on their own pages, because a pay table with free spins and a bonus meter has no closed-form edge.

RNG & settlement

For every bet the contract derives randomness as keccak256(serverSeed ‖ clientSeed ‖ blockhash(commitBlock + 1) ‖ nonce):

1 · The house pre-commits batches of keccak256(serverSeed) on-chain before any bet can bind to one. The pool tops itself up automatically, so a game never stalls for want of a seed.
2 · Your browser contributes a fresh 32-byte client seed with each bet, and you can supply your own.
3 · The hash of the block after yours is mixed in. At the moment you bet, the outcome is unknown to everybody, including the house.
4 · The settlement bot reveals the seed; the contract checks it against the commitment, recomputes the outcome and credits the payout.

The blockhash window on the EVM is 256 blocks. If a reveal is ever missed, the stake comes back and anyone (including you) can trigger it: refundExpired(betId) on the Vault for Dice and Plinko or on the slot module for VAULT.7 and SUGAR.LAB, refundRound(roundId) on Crash and Roulette, cancelPick(betId) on Mines.

You can re-derive a Dice or Plinko outcome in the browser on the Provably Fair page. Slots, Mines and the round games settle inside their own module contracts; their receipts are all on the explorer, but re-deriving them in the browser is not wired into that page yet.

Vault & modules

The casino is deliberately split in two. CasinoVault is the permanent part: it holds the entire bankroll, owns the seed pool and the risk limits, keeps the registry of games and pays every claim. Each game is a separate contract registered in that registry, so adding or fixing a game means deploying a module · never migrating the bankroll or changing the address players trust.

What a game can and cannot do. Modules hold no money and cannot move any: they compute results, and the Vault decides what gets paid. Every payout is clamped three times · by the game's own budget (currently 5 STT per game), by the per-bet exposure cap, and by what the pool can actually pay, so a broken or hostile module can never cost the house more than that game's budget. Only the owner can register a module; an unregistered contract asking the Vault for money reverts.

Stop button. Any single game can be switched off instantly, and the whole casino can be paused, at every entry point. Bets already placed are never frozen by it · they still settle or refund.

This is not a diagram: six of the seven modules were replaced on the running chain in July 2026 without touching the Vault, the bankroll or the addresses above.

Poker

Cash tables run 2, 6 and 9 handed no-limit hold'em, with blinds from 0.01/0.02 up to 1/2 STT. Your table buy-in comes from your PokerRoom balance; every action (bet, call, raise, fold) is an on-chain transaction of roughly 0.001 STT in gas, and pots settle in the contract.

Cards you can trust: the deck is ElGamal-encrypted under the table's aggregate key and shuffled by the players themselves (mental poker on BN254). Each shuffle carries a Wikström zero-knowledge proof that every other client verifies before it will hand over a decryption share, and the contract itself verifies each player's key proof, each Chaum–Pedersen decryption share and that those shares decrypt to exactly the card shown. Neither other players, nor the coordinator bot, nor the house can see your hole cards before showdown. The full protocol runs live in the ZK Lab.

Rake · 10% of the pot on the live cash tables, with a per-hand cap set per table; the contract's own ceiling is 10% and the exact figure for each table is shown in the lobby. No flop, no drop, and zero rake on tournament tables.

If a tab dies mid-hand the protocol settles it on-chain rather than stalling: the coordinator files an accusation naming the missing decryption share, the player's own client can answer it within a rescue window (and doing so also delivers the share), and only an accusation nobody answered forfeits that player's committed chips · pro-rata to the other players in the hand, never to the house.

Tournaments

Anyone can host a tournament: up to 45 players, 2 to 9 per table. You set the buy-in, the entry fee, the blind schedule (or a custom level structure) and the payout split, which must add up to 100%. Registration can require host approval if you want a curated field, and a pending entry is escrowed and withdrawable until it is approved.

Host reward · the creator can take a cut of the pool, capped at 10% and only on buy-in events. It is set at creation and visible to everyone before they register; prizes are computed from the pool net of it, so the payout split always describes 100% of what the players compete for.
Sponsored prizes · anyone can add STT to a tournament's pool. 90% seeds the prizes and 10% is the platform fee; if the event never runs, a cancel refunds the sponsorship in full and reverses the fee.

Prizes are paid into PokerRoom balances automatically as players bust, so there is nothing to collect at the end.

Profile

One profile for casino and poker, stored on-chain: your nickname lives in the PlayerProfile contract and your avatar image in AvatarStore (yes, the actual image bytes are on-chain). Set both from the profile drawer · they show up at poker tables and in the lobby's win feeds.

Contracts

Somnia testnet (chain id 50312). Every address below is public and links to the explorer. The Solidity is public too, in the GitHub repository · we have not submitted the sources to Shannon Explorer yet, so the explorer shows bytecode rather than code.

Casino · core
Casino · game modules
Poker

Earlier casino deployments stay on-chain and keep paying out anything they still owe; the profile drawer sweeps them for you. Not audited by a third party yet. Testnet deployment · STT carries no monetary value. 18+ · play responsibly.