@moneypot/hub 1.4.8 → 1.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,10 +76,4 @@ insert into hub.api_key default values returning key;
76
76
 
77
77
  ## Changelog
78
78
 
79
- ### 1.4.4
80
-
81
- - Added `allowLossBeyondWager` option to `MakeOutcomeBetPlugin`. Must be set to `true` to allow outcome profits to be less than -1.
82
-
83
- ### 1.4.1
84
-
85
- - Added `hubPutAlert` subscription
79
+ (Waiting for launch to begin publishing to changelog)
@@ -0,0 +1,4 @@
1
+ export { dbLockHubHashChain, dbInsertHubHash } from "./db-hash-chain.js";
2
+ export type { HashResult } from "./get-hash.js";
3
+ export { getTerminalHash, getIntermediateHash, getPreimageHash, } from "./get-hash.js";
4
+ export { makeFinalHash, getRollFromFinalHash, pickRandomOutcome, } from "./util.js";
@@ -0,0 +1,3 @@
1
+ export { dbLockHubHashChain, dbInsertHubHash } from "./db-hash-chain.js";
2
+ export { getTerminalHash, getIntermediateHash, getPreimageHash, } from "./get-hash.js";
3
+ export { makeFinalHash, getRollFromFinalHash, pickRandomOutcome, } from "./util.js";
@@ -0,0 +1,15 @@
1
+ import { DbOutcome } from "../db/types.js";
2
+ export declare function makeFinalHash({ serverHash, clientSeed, }: {
3
+ serverHash: Uint8Array;
4
+ clientSeed: string;
5
+ }): Buffer<ArrayBufferLike>;
6
+ declare function normalizeHash(hash: Uint8Array): number;
7
+ export declare const getRollFromFinalHash: typeof normalizeHash;
8
+ export declare function pickRandomOutcome({ outcomes, finalHash, }: {
9
+ outcomes: readonly DbOutcome[];
10
+ finalHash: Uint8Array;
11
+ }, floatEpsilon?: number): {
12
+ outcomeIdx: number;
13
+ roll: number;
14
+ };
15
+ export {};
@@ -0,0 +1,38 @@
1
+ import { createHmac } from "crypto";
2
+ import { assert } from "tsafe";
3
+ export function makeFinalHash({ serverHash, clientSeed, }) {
4
+ const finalHash = createHmac("sha256", serverHash)
5
+ .update(clientSeed)
6
+ .digest();
7
+ return finalHash;
8
+ }
9
+ function normalizeHash(hash) {
10
+ assert(hash.length >= 4, "Hash must be at least 4 bytes");
11
+ const view = new DataView(hash.buffer, hash.byteOffset, Math.min(hash.byteLength, 4));
12
+ const uint32Value = view.getUint32(0, false);
13
+ return uint32Value / Math.pow(2, 32);
14
+ }
15
+ export const getRollFromFinalHash = normalizeHash;
16
+ export function pickRandomOutcome({ outcomes, finalHash, }, floatEpsilon = 1e-10) {
17
+ assert(outcomes.length >= 2, "Outcome count must be >= 2");
18
+ const totalWeight = outcomes.reduce((sum, o) => sum + o.weight, 0);
19
+ const outcomesWithProbability = outcomes.map((o) => ({
20
+ ...o,
21
+ probability: o.weight / totalWeight,
22
+ }));
23
+ const totalProb = outcomesWithProbability.reduce((sum, outcome) => sum + outcome.probability, 0);
24
+ assert(Math.abs(totalProb - 1.0) < floatEpsilon, "Probabilities must sum to ~1");
25
+ const roll = getRollFromFinalHash(finalHash);
26
+ let cumulativeProb = 0;
27
+ for (let i = 0; i < outcomesWithProbability.length; i++) {
28
+ const outcome = outcomesWithProbability[i];
29
+ cumulativeProb += outcome.probability;
30
+ if (roll <= cumulativeProb) {
31
+ return { outcomeIdx: i, roll };
32
+ }
33
+ }
34
+ return {
35
+ outcomeIdx: outcomes.length - 1,
36
+ roll,
37
+ };
38
+ }
@@ -59,5 +59,4 @@ create policy select_outcome_bet on hub.outcome_bet for select using (
59
59
  user_id = hub_hidden.current_user_id() and
60
60
  experience_id = hub_hidden.current_experience_id() and
61
61
  casino_id = hub_hidden.current_casino_id()
62
- )
63
- );
62
+ );
@@ -35,22 +35,22 @@ declare const InputSchema: z.ZodObject<{
35
35
  hashChainId: string;
36
36
  kind: string;
37
37
  clientSeed: string;
38
- wager: number;
39
38
  outcomes: {
40
39
  profit: number;
41
40
  weight: number;
42
41
  }[];
42
+ wager: number;
43
43
  metadata?: Record<string, unknown> | undefined;
44
44
  }, {
45
45
  currency: string;
46
46
  hashChainId: string;
47
47
  kind: string;
48
48
  clientSeed: string;
49
- wager: number;
50
49
  outcomes: {
51
50
  profit: number;
52
51
  weight: number;
53
52
  }[];
53
+ wager: number;
54
54
  metadata?: Record<string, unknown> | undefined;
55
55
  }>;
56
56
  type Input = z.infer<typeof InputSchema>;
@@ -6,7 +6,7 @@ import { DbHashKind, dbLockPlayerBalanceAndHouseBankroll, exactlyOneRow, maybeOn
6
6
  import { assert } from "tsafe";
7
7
  import { dbInsertHubHash, dbLockHubHashChain, } from "../hash-chain/db-hash-chain.js";
8
8
  import { getIntermediateHash, getPreimageHash, } from "../hash-chain/get-hash.js";
9
- import { createHmac } from "node:crypto";
9
+ import { makeFinalHash, pickRandomOutcome } from "../hash-chain/util.js";
10
10
  const FLOAT_EPSILON = 1e-10;
11
11
  function sum(ns) {
12
12
  return ns.reduce((a, b) => a + b, 0);
@@ -247,18 +247,15 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
247
247
  if (result.rowCount !== 1) {
248
248
  throw new GraphQLError("Failed to update hash chain iteration");
249
249
  }
250
- const finalHash = (() => {
251
- const serverHash = betHashResult.hash;
252
- const clientSeed = input.clientSeed;
253
- const finalHash = createHmac("sha256", serverHash)
254
- .update(clientSeed)
255
- .digest();
256
- return finalHash;
257
- })();
258
- const { outcome, outcomeIdx, roll } = pickRandomOutcome({
259
- outcomes: input.outcomes,
260
- hash: finalHash,
250
+ const finalHash = makeFinalHash({
251
+ serverHash: betHashResult.hash,
252
+ clientSeed: input.clientSeed,
261
253
  });
254
+ const { outcomeIdx, roll } = pickRandomOutcome({
255
+ outcomes: input.outcomes,
256
+ finalHash: finalHash,
257
+ }, FLOAT_EPSILON);
258
+ const outcome = input.outcomes[outcomeIdx];
262
259
  const netPlayerAmount = input.wager * outcome.profit;
263
260
  await pgClient.query({
264
261
  text: `
@@ -391,36 +388,6 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
391
388
  };
392
389
  }, "HubMakeOutcomeBetPlugin");
393
390
  }
394
- function normalizeHash(hash) {
395
- assert(hash.length >= 4, "Hash must be at least 4 bytes");
396
- const view = new DataView(hash.buffer, hash.byteOffset, Math.min(hash.byteLength, 4));
397
- const uint32Value = view.getUint32(0, false);
398
- return uint32Value / Math.pow(2, 32);
399
- }
400
- function pickRandomOutcome({ outcomes, hash, }) {
401
- assert(outcomes.length >= 2, "Outcome count must be >= 2");
402
- const totalWeight = sum(outcomes.map((o) => o.weight));
403
- const outcomesWithProbability = outcomes.map((o) => ({
404
- ...o,
405
- probability: o.weight / totalWeight,
406
- }));
407
- const totalProb = outcomesWithProbability.reduce((sum, outcome) => sum + outcome.probability, 0);
408
- assert(Math.abs(totalProb - 1.0) < FLOAT_EPSILON, "Probabilities must sum to ~1");
409
- const roll = normalizeHash(hash);
410
- let cumulativeProb = 0;
411
- for (let i = 0; i < outcomesWithProbability.length; i++) {
412
- const outcome = outcomesWithProbability[i];
413
- cumulativeProb += outcome.probability;
414
- if (roll <= cumulativeProb) {
415
- return { outcome, outcomeIdx: i, roll };
416
- }
417
- }
418
- return {
419
- outcome: outcomes[outcomes.length - 1],
420
- outcomeIdx: outcomes.length - 1,
421
- roll,
422
- };
423
- }
424
391
  async function finishHashChainInBackground({ hashChainId, }) {
425
392
  console.log("Finishing hash chain in background", { hashChainId });
426
393
  const preimageHashResult = await getPreimageHash({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [
@@ -20,7 +20,8 @@
20
20
  "./graphql": "./dist/src/graphql.js",
21
21
  "./grafast": "./dist/src/grafast.js",
22
22
  "./express": "./dist/src/express.js",
23
- "./dataplan/pg": "./dist/src/dataplan/pg.js"
23
+ "./dataplan/pg": "./dist/src/dataplan/pg.js",
24
+ "./hash-chain": "./dist/src/hash-chain/index.js"
24
25
  },
25
26
  "files": [
26
27
  "/dist"