Pokerni: chips with no monetary value, cannot be bought, converted or transferred; AI opponents marked with a badge. Since the house provides the opponents, we owe you full transparency on the deal.
Everything is computed in your browser; nothing is sent to the server. This browser keeps the fingerprint received before the hand and the seed received after it; if you are signed in, your hand history is consulted too. You can also paste both values yourself: at the table, the fingerprint appears when you hover the "Verifiable deal" badge.
What this check proves: that the fingerprint published before the first card is indeed the one of the seed revealed after the last card. The deck was therefore fixed before you saw a single card, and nobody could change it during the hand.
What it does not prove: the exact order of the 52 cards derived from the seed. That shuffle uses NumPy's generator, which the browser cannot replay; the Python script in the technical version rebuilds it card by card.
AI opponents always wear the IA badge on their seat, with their level. An AI receives exactly the same information as a human player sitting in its place: its two cards, the community cards and the public actions; never the other players' cards nor the cards to come. The dealing code is verifiable, as explained above. The coach is an automated system: its advice is computed by a program, never given by a person, from your cards and the public actions only.
Before every hand, the server draws a 63-bit seed with the system's cryptographic generator (secrets.randbits(63) in Python, unpredictable, including for us). That seed drives a deterministic permutation of the 52 cards (numpy.random.default_rng(seed).permutation(52)). Each player's two cards, then the 5 community cards, are dealt in deck order, with no burn cards.
The server cannot change the cards during a hand, and proves it:
1. Before the hand, every state message carries a commitment: commit = SHA-256("selfpoker:" + seed). The fingerprint locks the whole deck without revealing anything.
2. After the hand, the end message (hand_end) reveals the seed. Anyone can then check that the fingerprint matches and rebuild the entire deck, including the cards that were not dealt.
import hashlib
import numpy as np
graine = 1234567890123456789 # field "fairplay.seed" of hand_end
commit = "..." # field "commit" of the state messages
assert hashlib.sha256(f"selfpoker:{graine}".encode()).hexdigest() == commit
paquet = list(np.random.default_rng(graine).permutation(52))
# n players: cards 0..2n-1 = hole cards (2 per player), 2n..2n+4 = community cards
# rank = card // 4 (0=2 … 12=ace), suit = card % 4 (♣♦♥♠)
Every hand played is archived with its seed: the whole history can be replayed identically.
Questions? The server code can be inspected on the machine that hosts it: this is a private site, among people who trust each other.
Background music: Jason Shaw, audionautix.com, licensed under Creative Commons BY 4.0 (« Big Swing Band », « Closer To Jazz », « Dirt Road Traveler », « Nice And Easy », « Acoustic Rock », « Feel Good Rock »).