Provably fair (client side)

The hub server comes with a built-in generic makeOutcomeBet GraphQL method that can be used to build a wide variety of games. It also is provably fair.

While the hub operator might want to create their own bet methods, we’ll demonstrate how provably fair works for a simple makeOutcomeBet example.

  1. Generate a client seed
  2. Create a hash chain
  3. Submit the bet

Generate a client seed

To ensure the server can’t select a biased hash chain, every time you submit a bet to the server, you will provide a clientSeed that will be hashed with the server hash to generate a random outcome.

You should generate the clientSeed on the player’s behalf when your game loads.

let clientSeed = window.crypto.randomUUID();

Every time you create a new hash chain, you should also regenerate the clientSeed so that the server can’t bias the next chain by assuming you’re reusing clientSeed between chains.

Create a hash chain

Whenever you submit a bet to the hub server, you need a valid hashChainId.

Here’s how you create a hash chain:

This is an authenticated GraphQL method, so there must be a current user logged in so that you can send the Authorization: "session:{sessionKey}" header. Read more about authentication.

mutation CreateHashChain {
  hubCreateHashChain {
    hashChain {
      id
    }
  }
}

Submit the bet

Now let’s put it all together into one example:

async function makeCoinFlipBet(
  currency: string,
  wager: number,
  clientSeed: string,
  hashChainId: string
) {
  const houseEdge = 0.01;

  const win: HubOutcomeInput = { weight: 1, profit: 1 - houseEdge * 2 };
  const lose: HubOutcomeInput = { weight: 1, profit: -1 };

  const input: HubMakeOutcomeBetInput = {
    kind: "COINFLIP",
    outcomes: [win, lose],
    currency,
    hashChainId,
    wager,
    clientSeed,
  };

  const result = await client.mutate({
    mutation: MAKE_COINFLIP_BET,
    variables: { input },
  });
}