SSPilot is free · +50% VIP on Stake
← Back to blog

Stake Provably Fair: How to Verify Your Own Bets

By Guide

Every Stake Original result is computed from three values you can see or reveal: a server seed, your client seed and a counter called the nonce. That is what "provably fair" means, and its scope is precise and limited: it proves a result was not changed after you placed the bet. It does not touch the house edge. This page shows the mechanism, gives a short script that recomputes Dice, Limbo and Mines results from your own seeds, and explains how to use it.

The four inputs

  • Server seed. 64 random hex characters generated by Stake. Before you bet, you only see its SHA-256 hash. That hash is Stake's commitment: the seed cannot be swapped later without the hash changing.
  • Client seed. A string you control and can change at any time. Because it enters every calculation, Stake cannot compute your results in advance.
  • Nonce. Starts at 0 and goes up by one with every bet on the current seed pair, so each bet gets a fresh result.
  • Cursor. Games that need more than 8 random numbers per bet read further bytes. Mines needs up to 24, Plinko up to 16.

From seeds to a random number

Stake computes HMAC-SHA256 with the server seed as the key and clientSeed:nonce:round as the message, where round starts at 0 and only increases when a game needs more than 32 bytes. The 32-byte output is read 4 bytes at a time, and each group becomes one number f between 0 and 1:

f = b0/256 + b1/256² + b2/256³ + b3/256⁴

Each game then maps f to a result with its own formula:

Game

Formula

Random numbers per bet

Dice

roll = (f × 10,001) / 100, a result from 0.00 to 100.00

1

Limbo

result = max(floor(0.99 / f × 100) / 100, 1.00)

1

Mines

each mine takes the tile at floor(f × tiles still free) among the free tiles, numbered 0 to 24 left to right, top to bottom

1 per mine

Plinko

the ball goes left or right on each row with floor(f × 2)

1 per row (8 to 16)

These formulas come from Stake's own documentation, in the Implementation and Game Events pages of its Fairness section. The house edge sits in plain sight: the 0.99 in Limbo, and in Dice the payout of 99 divided by the win chance.

Verify a bet yourself

The script below recomputes a Dice roll, a Limbo result and a Mines board from a revealed seed pair. It needs Node.js 18 or later and nothing else. We checked its Mines output against two independently published test vectors.

// verify.mjs: node verify.mjs <serverSeed> <clientSeed> <nonce> [mines]
import { createHash, createHmac } from "node:crypto";

// HMAC-SHA256 keyed with the server seed, message "clientSeed:nonce:round".
function* bytes(serverSeed, clientSeed, nonce) {
  for (let round = 0; ; round++) {
    const hmac = createHmac("sha256", serverSeed);
    hmac.update(`${clientSeed}:${nonce}:${round}`);
    yield* hmac.digest();
  }
}

// Four bytes per number: b0/256 + b1/256^2 + b2/256^3 + b3/256^4.
function floats(serverSeed, clientSeed, nonce, count) {
  const stream = bytes(serverSeed, clientSeed, nonce);
  return Array.from({ length: count }, () => {
    let value = 0;
    for (let i = 1; i <= 4; i++) value += stream.next().value / 256 ** i;
    return value;
  });
}

const [serverSeed, clientSeed, nonceArg, minesArg = "3"] = process.argv.slice(2);
const nonce = Number(nonceArg);
const [f] = floats(serverSeed, clientSeed, nonce, 1);

// Dice: 10,001 outcomes from 0.00 to 100.00.
const dice = Math.floor(f * 10001) / 100;

// Limbo: 1% edge, rounded down to 2 decimals, never below 1.00x.
const limbo = Math.max(Math.floor((0.99 / f) * 100) / 100, 1);

// Mines: one number per mine, each picks among the tiles still free.
const pool = Array.from({ length: 25 }, (_, i) => i);
const mines = floats(serverSeed, clientSeed, nonce, Number(minesArg)).map(
  (value) => pool.splice(Math.floor(value * pool.length), 1)[0],
);

console.log("server seed hash:", createHash("sha256").update(serverSeed).digest("hex"));
console.log("dice roll:       ", dice.toFixed(2));
console.log("limbo result:    ", `${limbo.toFixed(2)}x`);
console.log(`mines (${minesArg}):       `, mines.join(", "));

Save it as verify.mjs and run node verify.mjs <server seed> <client seed> <nonce> <mines>. The first line of output is the SHA-256 of the server seed: it must equal the hashed server seed Stake showed you before those bets. The other lines must match your bet history for that nonce. Mines tiles are numbered 0 to 24 here; add one if you count from 1.

Where to find the values on Stake

  1. Open your profile menu, then Settings, then Fairness. Note the active client seed and the hashed server seed.
  2. Rotate the seed pair. The previous server seed is now revealed in clear, and a new pair takes over.
  3. Open the bet you want to check. Its details show the nonce and the seeds it used.
  4. Run the script with those values and compare.

You cannot verify a bet on the seed pair you are still using: the server seed is only revealed once the pair is retired. That is by design, and it is also why nobody can predict your next result.

What verification proves, and what it doesn't

It proves that the result you got is the one Stake committed to before your bet. Nobody changed a roll after seeing your stake, your bet size or your strategy.

It does not prove the game is worth playing. A perfectly verified session still returns 99% of the amount wagered on average. The odds for every setting, derived from these same formulas, are in the guides to Dice, Limbo and Mines.

Why predictors cannot work

To predict your next result, a tool would need the server seed that has not been revealed. All it can see is the hash, and SHA-256 cannot be reversed. After you rotate, the old seed is revealed but also retired: no future bet ever uses it. Any "predictor" for Mines, Limbo or Dice either guesses at random or is built to take something from you, usually your login or API token.

Seeds and automation

Changing your client seed does not change your odds; it only starts a new sequence of results. If you automate with SSPilot, the seed can be changed from the app, which is also the step that reveals the previous server seed, so a whole automated session can be checked with the script above.

GET SSPILOT

Put this guide to work — download SSPilot

Automate Stake Dice, Limbo, Mines, Plinko, Slots and bonus claiming with a single free tool. Built-in strategies, live stats and stop conditions.

Download Free
  • Free to download
  • Instant setup
  • Windows & Mac