provably-fair
Version:
Provably-fair generator for custom bets
110 lines (87 loc) • 4.37 kB
Markdown
# Provably-fair
[](https://travis-ci.org/atmys/provably-fair)
[](https://coveralls.io/github/atmys/provably-fair?branch=master)
[](https://snyk.io/test/github/atmys/provably-fair?targetFile=package.json)
[](https://codebeat.co/projects/github-com-atmys-provably-fair-master)
Dead simple generator for provably fair gambling. Entirely callback, we need performance here.
Uses a new server seed on each bet to provide verification capabilty to the client right after he gets the result.
### Provably-fair logic
The idea is to generate a reproductible result that is defined in advance to prevent the server from cheating.
To achieve this, we must :
- create a server seed and pass the hash of that seed to the client before he gambles;
- receive a client seed generated by the client;
- concat the two seeds to get only one;
- create the bet result from a random generator seeded with our concatenated seed.
- send the result to client, along with the original server seed.
This way, the client will be able to :
- make sure the server seed we used to generate the result is indeed the one we sent him as a hash (he can hash it himself to compare);
- reproduce the same bet result by reproducing the whole process.
## Getting Started
### Install
```
npm i --save provably-fair
```
### API
- `generateServerSeedHash({ userId = 'none', expiresIn = 60 * 60 })` stores server seed with redis & returns the seed hash to pass to client.
- `createAndChallenge({ userId = 'none', expiresIn = 60 * 60, serverSeedHash, clientSeed, guess, customResult, customValidation }, callback)` creates a new bet and compares the result with the client guess, then deletes the server seed redis key to prevent reuse. Returns `(err, valid, bet)`;
- `verify({ serverSeed, clientSeed, customResult }, callback)` returns serverSeedHash of provided serverSeed & reproduces bet result.
#### `require('provably-fair')(client)`
- Initialize provablyFair
- `client` **Required:** Redis client
#### `generateServerSeedHash(options)`
- `options <Object>`
- `userId` **Default:** none - unique client identifier
- `expiresIn` **Default:** 60 * 60
- returns `hash` hash of the securely stored with Redis serverSeed.
#### `createAndChallenge(options, callback)`
- `options <Object>`
- `userId` **Default:** none - unique client identifier
- `expiresIn` **Default:** 60 * 60
- `serverSeedHash` **Required**
- `clientSeed` **Required**
- `guess` **Required**
- `customResult` **Default:** `function(randomNumber) { return randomNumer }`
- `customValidation` **Default:** `function(guess, result) { return guess === result }`
- `callback <Function>` returns `(err, valid, bet)`
- `valid <Boolean>` whether or not captcha is solved
- `bet <Object>`
- `id` bet ID
- `result` bet result
- `serverSeed`
- `clientSeed`
### Example : Gobelet game
The client must guess a number between 1 and 10. Test it on [RunKit](https://runkit.com/atmys/provably-fair).
```js
// Init
const redis = require('redis');
const client = redis.createClient();
const provablyFair = require('provably-fair')(client);
// default return randomNumber
const gobeletResult = function (randomNumber) {
return Math.floor(randomNumber * 10) + 1;
};
// this is default
const gobeletValidation = function (guess, result) {
return guess === result;
};
// Generate & send before client gambles;
const serverSeedHash = provablyFair.generateServerSeedHash();
// Retrieve the serverSeedHash & these values from the client :
const clientSeed = 'clientSeed';
const guess = 5;
// We create & challenge the bet
provablyFair.createAndChallenge({
serverSeedHash,
clientSeed,
expiresIn: 60 * 60,
guess,
customResult: gobeletResult,
customValidation: gobeletValidation
}, (err, valid, bet) => {
// returns true if guess is correct
// bet = { serverSeed, clientSeed, result } can be passed to the client
// for verification (along with your customResult resolver)
});
```
### Todo
Client plugin for verification.