@moneypot/hub 1.3.0-dev.13 → 1.3.0-dev.15

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.
@@ -6,6 +6,7 @@ import { DbHashKind, exactlyOneRow, maybeOneRow, superuserPool, withPgPoolTransa
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
10
  const FLOAT_EPSILON = 1e-10;
10
11
  function sum(ns) {
11
12
  return ns.reduce((a, b) => a + b, 0);
@@ -118,9 +119,6 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
118
119
  if (!betConfig) {
119
120
  throw new GraphQLError(`Invalid bet kind`);
120
121
  }
121
- if (!betKinds.includes(rawInput.kind)) {
122
- throw new GraphQLError(`Invalid bet kind`);
123
- }
124
122
  let initializedMetadata;
125
123
  if (betConfig.initializeMetadataFromUntrustedUserInput) {
126
124
  const result = betConfig.initializeMetadataFromUntrustedUserInput(input);
@@ -239,7 +237,18 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
239
237
  if (result.rowCount !== 1) {
240
238
  throw new GraphQLError("Failed to update hash chain iteration");
241
239
  }
242
- const { outcome, outcomeIdx } = pickRandomOutcome(input.outcomes, betHashResult.hash);
240
+ const finalHash = (() => {
241
+ const serverHash = betHashResult.hash;
242
+ const clientSeed = dbHashChain.client_seed;
243
+ const finalHash = createHmac("sha256", serverHash)
244
+ .update(clientSeed)
245
+ .digest();
246
+ return finalHash;
247
+ })();
248
+ const { outcome, outcomeIdx } = pickRandomOutcome({
249
+ outcomes: input.outcomes,
250
+ hash: finalHash,
251
+ });
243
252
  const netPlayerAmount = input.wager * outcome.profit;
244
253
  await pgClient.query({
245
254
  text: `
@@ -377,7 +386,7 @@ function normalizeHash(hash) {
377
386
  const uint32Value = view.getUint32(0, false);
378
387
  return uint32Value / Math.pow(2, 32);
379
388
  }
380
- function pickRandomOutcome(outcomes, hash) {
389
+ function pickRandomOutcome({ outcomes, hash, }) {
381
390
  assert(outcomes.length >= 2, "Outcome count must be >= 2");
382
391
  const totalWeight = sum(outcomes.map((o) => o.weight));
383
392
  const outcomesWithProbability = outcomes.map((o) => ({
@@ -1,55 +1,30 @@
1
- import { access, context, loadOne, object, } from "postgraphile/grafast";
1
+ import { access, constant, context } from "postgraphile/grafast";
2
2
  import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
- import { superuserPool } from "../db/index.js";
4
- import { pgSelectSingleFromRecord, } from "postgraphile/@dataplan/pg";
3
+ import { TYPES } from "postgraphile/@dataplan/pg";
4
+ import { sql } from "postgraphile/pg-sql2";
5
5
  export const HubUserBalanceByCurrencyPlugin = makeExtendSchemaPlugin((build) => {
6
- const balances = build.input.pgRegistry.pgResources.hub_balance;
6
+ const balanceTable = build.input.pgRegistry.pgResources.hub_balance;
7
7
  return {
8
8
  typeDefs: gql `
9
9
  extend type HubUser {
10
- balanceByCurrency(currency: String!): HubBalance
10
+ hubBalanceByCurrency(currency: String!): HubBalance
11
11
  }
12
12
  `,
13
13
  plans: {
14
14
  HubUser: {
15
- balanceByCurrency: ($record, { $currency }) => {
15
+ hubBalanceByCurrency: ($record, { $currency }) => {
16
16
  const $identity = context().get("identity");
17
- const $params = object({
18
- currency: $currency,
19
- targetUserId: $record.get("id"),
20
- casino_id: access($identity, ["session", "casino_id"]),
21
- experience_id: access($identity, ["session", "experience_id"]),
22
- });
23
- const $balance = loadOne($params, batchGetUserBalanceByCurrency);
24
- return pgSelectSingleFromRecord(balances, $balance);
17
+ const $balances = balanceTable.find();
18
+ $balances.where(sql `
19
+ ${$balances}.currency_key = ${$balances.placeholder($currency, TYPES.text)}
20
+ AND ${$balances}.user_id = ${$balances.placeholder($record.get("id"), TYPES.uuid)}
21
+ AND ${$balances}.casino_id = ${$balances.placeholder(access($identity, ["session", "casino_id"]), TYPES.uuid)}
22
+ AND ${$balances}.experience_id = ${$balances.placeholder(access($identity, ["session", "experience_id"]), TYPES.uuid)}
23
+ `);
24
+ $balances.setFirst(constant(1));
25
+ return $balances.single();
25
26
  },
26
27
  },
27
28
  },
28
29
  };
29
30
  });
30
- async function batchGetUserBalanceByCurrency(paramsArray) {
31
- const values = [];
32
- const valuePlaceholders = [];
33
- paramsArray.forEach((p, index) => {
34
- const baseIndex = index * 4 + 1;
35
- valuePlaceholders.push(`($${baseIndex}, $${baseIndex + 1}::uuid, $${baseIndex + 2}::uuid, $${baseIndex + 3}::uuid)`);
36
- values.push(p.currency, p.targetUserId, p.casino_id, p.experience_id);
37
- });
38
- const sql = `
39
- SELECT b.*
40
- FROM hub.balance b
41
- JOIN (
42
- VALUES
43
- ${valuePlaceholders.join(",\n ")}
44
- ) AS vals(currency_key, user_id, casino_id, experience_id)
45
- ON b.currency_key = vals.currency_key
46
- AND b.user_id = vals.user_id
47
- AND b.casino_id = vals.casino_id
48
- AND b.experience_id = vals.experience_id
49
- `;
50
- const { rows } = await superuserPool.query(sql, values);
51
- return paramsArray.map((p) => rows.find((row) => row.currency_key === p.currency &&
52
- row.user_id === p.targetUserId &&
53
- row.casino_id === p.casino_id &&
54
- row.experience_id === p.experience_id));
55
- }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.3.0-dev.13",
3
+ "version": "1.3.0-dev.15",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [