Provably fair
Safety & Fairness
Your trust is our priority. Every outcome on ExA Cup is random, resistant to tampering, and open to verification by anyone. We commit to each result before you play and reveal the proof afterwards, so you never have to take our word for it.
Verify an open
Paste the values from your pack-opening history (dashboard, Wallet tab) and recompute the ticket right here in your browser. The server seed is revealed once you rotate your seed pair.
Verify an open right here
Paste the client seed, server seed and nonce from your opening history (dashboard, Wallet tab) and recompute the ticket in your browser. Add the seed hash and ticket number to check them too. Nothing is sent to our servers
How we ensure fairness
Single pack opens
We combine a secret server seed, your client seed, and a nonce into one string, hash it with SHA-512, and normalize it to a ticket number between 1 and 1,000,000. That ticket falls inside exactly one item's published range, which decides what you win. Pass the same three inputs into our getTicketNumber function and you reproduce the result yourself.
Terms & definitions
Ticket number
An integer between 1 and 1,000,000 produced from the client seed, server seed, and nonce. It looks up the resulting item by that item's ticket range, shown in the pack details.
Client seed
A string known to you before a result is generated. You can rotate it from your wallet fairness panel before future pack opens.
Server seed
A secret string our servers generate. We show you its SHA-512 hash before any purchase and reveal the raw seed after, so you can re-hash it and confirm it matches what you were shown.
Nonce
An auto-incrementing number that gives a unique result when the server and client seeds stay the same, as when opening several packs in one purchase.
Reference implementation
import { createHash } from "crypto";
// 1..1,000,000 ticket from your client seed + our server seed + a nonce
export const sha512 = (v: string) =>
createHash("sha512").update(v).digest("hex");
export const combineSeeds = (
clientSeed: string,
serverSeed: string,
nonce: number,
) => sha512(`${clientSeed}:${serverSeed}:${nonce}`);
export const getTicketNumber = (hash: string) => {
const hashInt = BigInt("0x" + hash);
const maxInt = BigInt(1_000_000);
return Number((hashInt % maxInt) + BigInt(1));
};