@moneypot/hub 1.9.0 → 1.10.0-dev.2
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/dist/cli/add-casino.js +24 -17
- package/dist/src/context.d.ts +12 -0
- package/dist/src/context.js +31 -0
- package/dist/src/db/index.d.ts +3 -6
- package/dist/src/db/index.js +5 -13
- package/dist/src/hash-chain/plugins/hub-create-hash-chain.js +3 -2
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.js +10 -8
- package/dist/src/plugins/hub-add-casino.js +4 -2
- package/dist/src/plugins/hub-authenticate.js +3 -2
- package/dist/src/plugins/hub-claim-faucet.js +5 -3
- package/dist/src/plugins/hub-make-outcome-bet.js +6 -4
- package/dist/src/plugins/hub-withdraw.js +3 -2
- package/dist/src/process-transfers/index.d.ts +5 -2
- package/dist/src/process-transfers/index.js +15 -11
- package/dist/src/process-transfers/polling-processor.d.ts +3 -1
- package/dist/src/process-transfers/polling-processor.js +17 -13
- package/dist/src/process-transfers/process-transfer.d.ts +3 -1
- package/dist/src/process-transfers/process-transfer.js +7 -8
- package/dist/src/process-transfers/websocket-processor.d.ts +3 -1
- package/dist/src/process-transfers/websocket-processor.js +3 -3
- package/dist/src/process-withdrawal-request.d.ts +3 -1
- package/dist/src/process-withdrawal-request.js +6 -5
- package/dist/src/server/graphile.config.d.ts +3 -1
- package/dist/src/server/graphile.config.js +5 -4
- package/dist/src/server/index.d.ts +3 -1
- package/dist/src/server/index.js +6 -5
- package/dist/src/server/middleware/authentication.d.ts +2 -1
- package/dist/src/server/middleware/authentication.js +5 -5
- package/dist/src/take-request/process-take-request.d.ts +2 -1
- package/dist/src/take-request/process-take-request.js +11 -10
- package/package.json +1 -1
package/dist/cli/add-casino.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { dbInsertCasino } from "../src/db/internal.js";
|
|
4
|
-
import {
|
|
4
|
+
import { upsertCurrencies } from "../src/db/index.js";
|
|
5
5
|
import { createGraphqlClient } from "../src/graphql-client.js";
|
|
6
6
|
import { GET_CURRENCIES } from "../src/graphql-queries.js";
|
|
7
7
|
import { gql } from "../src/__generated__/gql.js";
|
|
8
|
+
import { createServerContext, closeServerContext } from "../src/context.js";
|
|
8
9
|
const GET_CURRENT_CONTROLLER = gql(`
|
|
9
10
|
query AddCasino_GetCurrentController {
|
|
10
11
|
currentController {
|
|
@@ -66,24 +67,30 @@ function parseArgs(args) {
|
|
|
66
67
|
return parsedArgs;
|
|
67
68
|
}
|
|
68
69
|
async function addCasino(input) {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const context = createServerContext();
|
|
71
|
+
try {
|
|
72
|
+
const graphqlClient = createGraphqlClient({
|
|
73
|
+
graphqlUrl: input.graphql_url,
|
|
74
|
+
apiKey: input.api_key,
|
|
75
|
+
});
|
|
76
|
+
console.log(`Verifying controller creds with ${input.graphql_url}...`);
|
|
77
|
+
const result1 = await graphqlClient.request(GET_CURRENT_CONTROLLER);
|
|
78
|
+
if (!result1.currentController) {
|
|
79
|
+
throw new Error("Bad controller ID or API key");
|
|
80
|
+
}
|
|
81
|
+
const result2 = await graphqlClient.request(GET_CURRENCIES);
|
|
82
|
+
const currencies = result2.allCurrencies?.nodes.flatMap((x) => (x ? [x] : [])) || [];
|
|
83
|
+
console.log(`Found ${currencies.length} currencies:`, currencies.map((x) => x.id).join(", "));
|
|
84
|
+
const fields = { ...input, controller_id: result1.currentController.id };
|
|
85
|
+
const casino = await dbInsertCasino(context.superuserPool, fields);
|
|
86
|
+
if (currencies.length > 0) {
|
|
87
|
+
await upsertCurrencies(context.superuserPool, { casinoId: casino.id, currencies });
|
|
88
|
+
}
|
|
89
|
+
return casino;
|
|
77
90
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
console.log(`Found ${currencies.length} currencies:`, currencies.map((x) => x.id).join(", "));
|
|
81
|
-
const fields = { ...input, controller_id: result1.currentController.id };
|
|
82
|
-
const casino = await dbInsertCasino(superuserPool, fields);
|
|
83
|
-
if (currencies.length > 0) {
|
|
84
|
-
await upsertCurrencies(superuserPool, { casinoId: casino.id, currencies });
|
|
91
|
+
finally {
|
|
92
|
+
await closeServerContext(context);
|
|
85
93
|
}
|
|
86
|
-
return casino;
|
|
87
94
|
}
|
|
88
95
|
function printUsageExample() {
|
|
89
96
|
console.error("\nUsage example:");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
import { DatabaseNotifier } from "./db/index.js";
|
|
3
|
+
export interface ServerContext {
|
|
4
|
+
postgraphilePool: pg.Pool;
|
|
5
|
+
superuserPool: pg.Pool;
|
|
6
|
+
notifier: DatabaseNotifier;
|
|
7
|
+
}
|
|
8
|
+
export declare function createServerContext(overrides?: {
|
|
9
|
+
superuserDatabaseUrl?: string;
|
|
10
|
+
postgraphileDatabaseUrl?: string;
|
|
11
|
+
}): ServerContext;
|
|
12
|
+
export declare function closeServerContext(context: ServerContext): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
import * as config from "./config.js";
|
|
3
|
+
import { logger } from "./logger.js";
|
|
4
|
+
import { DatabaseNotifier } from "./db/index.js";
|
|
5
|
+
export function createServerContext(overrides) {
|
|
6
|
+
const postgraphileDatabaseUrl = overrides?.postgraphileDatabaseUrl ?? config.DATABASE_URL;
|
|
7
|
+
const superuserDatabaseUrl = overrides?.superuserDatabaseUrl ?? config.SUPERUSER_DATABASE_URL;
|
|
8
|
+
const context = {
|
|
9
|
+
postgraphilePool: new pg.Pool({
|
|
10
|
+
connectionString: postgraphileDatabaseUrl,
|
|
11
|
+
}),
|
|
12
|
+
superuserPool: new pg.Pool({
|
|
13
|
+
connectionString: superuserDatabaseUrl,
|
|
14
|
+
}),
|
|
15
|
+
notifier: new DatabaseNotifier(postgraphileDatabaseUrl),
|
|
16
|
+
};
|
|
17
|
+
return context;
|
|
18
|
+
}
|
|
19
|
+
export async function closeServerContext(context) {
|
|
20
|
+
try {
|
|
21
|
+
await Promise.all([
|
|
22
|
+
context.notifier.close(),
|
|
23
|
+
context.postgraphilePool.end(),
|
|
24
|
+
context.superuserPool.end(),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
logger.warn(err, "Error closing server context resources");
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/dist/src/db/index.d.ts
CHANGED
|
@@ -7,8 +7,6 @@ export * from "./types.js";
|
|
|
7
7
|
export * from "./public.js";
|
|
8
8
|
export * from "./util.js";
|
|
9
9
|
export declare function getPgClient(connectionString: string): InstanceType<typeof pg.Client>;
|
|
10
|
-
export declare const postgraphilePool: pg.Pool;
|
|
11
|
-
export declare const superuserPool: pg.Pool;
|
|
12
10
|
export interface QueryExecutor {
|
|
13
11
|
query<T extends pg.QueryResultRow = any>(queryText: string, values?: any[]): Promise<pg.QueryResult<T>>;
|
|
14
12
|
}
|
|
@@ -23,13 +21,12 @@ export declare function userFromActiveSessionKey(pgClient: QueryExecutor, sessio
|
|
|
23
21
|
user: DbUser;
|
|
24
22
|
sessionId: DbSession["id"];
|
|
25
23
|
} | null>;
|
|
26
|
-
declare class DatabaseNotifier extends stream.EventEmitter {
|
|
24
|
+
export declare class DatabaseNotifier extends stream.EventEmitter {
|
|
27
25
|
private pgClient;
|
|
28
26
|
constructor(connectionString: string);
|
|
29
27
|
close(): Promise<void>;
|
|
30
28
|
listen(): Promise<void>;
|
|
31
29
|
}
|
|
32
|
-
export declare const notifier: DatabaseNotifier;
|
|
33
30
|
export declare function getTransferCursor(pgClient: QueryExecutor, { casinoId, }: {
|
|
34
31
|
casinoId: string;
|
|
35
32
|
}): Promise<string | undefined>;
|
|
@@ -47,7 +44,7 @@ export declare function upsertExperience(pgClient: QueryExecutor, { casinoId, mp
|
|
|
47
44
|
mpExperienceId: string;
|
|
48
45
|
name: string;
|
|
49
46
|
}): Promise<DbExperience>;
|
|
50
|
-
export declare function insertDeposit(o: {
|
|
47
|
+
export declare function insertDeposit(pool: pg.Pool, o: {
|
|
51
48
|
casinoId: string;
|
|
52
49
|
mpTransferId: string;
|
|
53
50
|
userId: string;
|
|
@@ -78,7 +75,7 @@ export declare function getPendingWithdrawals(pgClient: QueryExecutor, { casinoI
|
|
|
78
75
|
mp_experience_id: string;
|
|
79
76
|
mp_user_id: string;
|
|
80
77
|
})[]>;
|
|
81
|
-
export declare function settleWithdrawal({ withdrawalId, newStatus, }: {
|
|
78
|
+
export declare function settleWithdrawal(pool: pg.Pool, { withdrawalId, newStatus, }: {
|
|
82
79
|
withdrawalId: string;
|
|
83
80
|
newStatus: Extract<DbTransferStatusKind, "COMPLETED" | "CANCELED">;
|
|
84
81
|
}): Promise<void>;
|
package/dist/src/db/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as pg from "pg";
|
|
2
|
-
import * as config from "../config.js";
|
|
3
2
|
import stream from "node:stream";
|
|
4
3
|
import { exactlyOneRow, maybeOneRow } from "./util.js";
|
|
5
4
|
import { logger } from "../logger.js";
|
|
@@ -13,12 +12,6 @@ export function getPgClient(connectionString) {
|
|
|
13
12
|
const client = new pg.Client({ connectionString });
|
|
14
13
|
return client;
|
|
15
14
|
}
|
|
16
|
-
export const postgraphilePool = new pg.Pool({
|
|
17
|
-
connectionString: config.DATABASE_URL,
|
|
18
|
-
});
|
|
19
|
-
export const superuserPool = new pg.Pool({
|
|
20
|
-
connectionString: config.SUPERUSER_DATABASE_URL,
|
|
21
|
-
});
|
|
22
15
|
export class UserFriendlyError extends Error {
|
|
23
16
|
constructor(userFriendlyMessage) {
|
|
24
17
|
super(userFriendlyMessage);
|
|
@@ -93,7 +86,7 @@ export async function userFromActiveSessionKey(pgClient, sessionKey) {
|
|
|
93
86
|
sessionId: session_id,
|
|
94
87
|
};
|
|
95
88
|
}
|
|
96
|
-
class DatabaseNotifier extends stream.EventEmitter {
|
|
89
|
+
export class DatabaseNotifier extends stream.EventEmitter {
|
|
97
90
|
pgClient;
|
|
98
91
|
constructor(connectionString) {
|
|
99
92
|
super();
|
|
@@ -124,7 +117,6 @@ class DatabaseNotifier extends stream.EventEmitter {
|
|
|
124
117
|
});
|
|
125
118
|
}
|
|
126
119
|
}
|
|
127
|
-
export const notifier = new DatabaseNotifier(config.DATABASE_URL);
|
|
128
120
|
export async function getTransferCursor(pgClient, { casinoId, }) {
|
|
129
121
|
const row = await pgClient
|
|
130
122
|
.query("select cursor from hub_hidden.transfer_cursor where casino_id = $1", [casinoId])
|
|
@@ -175,11 +167,11 @@ export async function upsertExperience(pgClient, { casinoId, mpExperienceId, nam
|
|
|
175
167
|
`, [casinoId, mpExperienceId, name])
|
|
176
168
|
.then(exactlyOneRow);
|
|
177
169
|
}
|
|
178
|
-
export async function insertDeposit(o) {
|
|
170
|
+
export async function insertDeposit(pool, o) {
|
|
179
171
|
if (o.amount <= 0) {
|
|
180
172
|
throw new UserFriendlyError("amount must be positive");
|
|
181
173
|
}
|
|
182
|
-
return withPgPoolTransaction(
|
|
174
|
+
return withPgPoolTransaction(pool, async (client) => {
|
|
183
175
|
const result = await client.query(`
|
|
184
176
|
INSERT INTO hub.deposit(casino_id, mp_transfer_id, user_id, experience_id, amount, currency_key)
|
|
185
177
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
@@ -268,8 +260,8 @@ export async function getPendingWithdrawals(pgClient, { casinoId, limit, }) {
|
|
|
268
260
|
`, [casinoId, limit]);
|
|
269
261
|
return result.rows;
|
|
270
262
|
}
|
|
271
|
-
export async function settleWithdrawal({ withdrawalId, newStatus, }) {
|
|
272
|
-
return withPgPoolTransaction(
|
|
263
|
+
export async function settleWithdrawal(pool, { withdrawalId, newStatus, }) {
|
|
264
|
+
return withPgPoolTransaction(pool, async (pgClient) => {
|
|
273
265
|
const dbWithdrawal = await pgClient
|
|
274
266
|
.query(`
|
|
275
267
|
select *
|
|
@@ -2,7 +2,7 @@ import { context, object, sideEffect } from "@moneypot/hub/grafast";
|
|
|
2
2
|
import { gql, makeExtendSchemaPlugin } from "@moneypot/hub/graphile";
|
|
3
3
|
import { GraphQLError } from "graphql";
|
|
4
4
|
import { PgAdvisoryLock } from "../../pg-advisory-lock.js";
|
|
5
|
-
import { exactlyOneRow,
|
|
5
|
+
import { exactlyOneRow, withPgPoolTransaction } from "@moneypot/hub/db";
|
|
6
6
|
import * as HashCommon from "../get-hash.js";
|
|
7
7
|
import { DbHashKind } from "../../db/types.js";
|
|
8
8
|
import * as config from "../../config.js";
|
|
@@ -23,7 +23,8 @@ export const HubCreateHashChainPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
23
23
|
plans: {
|
|
24
24
|
hubCreateHashChain: () => {
|
|
25
25
|
const $identity = context().get("identity");
|
|
26
|
-
const $
|
|
26
|
+
const $superuserPool = context().get("superuserPool");
|
|
27
|
+
const $hashChainId = sideEffect([$identity, $superuserPool], ([identity, superuserPool]) => {
|
|
27
28
|
if (identity?.kind !== "user") {
|
|
28
29
|
throw new GraphQLError("Unauthorized");
|
|
29
30
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Express } from "express";
|
|
2
2
|
import { type PluginIdentity } from "./server/graphile.config.js";
|
|
3
|
+
import { ServerContext } from "./context.js";
|
|
3
4
|
declare global {
|
|
4
5
|
namespace Grafast {
|
|
5
6
|
interface Context {
|
|
6
7
|
identity?: PluginIdentity;
|
|
7
8
|
abortSignal: AbortSignal;
|
|
9
|
+
superuserPool: ServerContext["superuserPool"];
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
}
|
|
@@ -19,8 +21,12 @@ export { MakeOutcomeBetPlugin, type OutcomeBetConfigMap, type OutcomeBetConfig,
|
|
|
19
21
|
export { validateRisk, type RiskPolicy, type RiskPolicyArgs, type RiskLimits, } from "./risk-policy.js";
|
|
20
22
|
export type PluginContext = Grafast.Context;
|
|
21
23
|
export { defaultPlugins, type PluginIdentity, type UserSessionContext, } from "./server/graphile.config.js";
|
|
24
|
+
export type ConfigureAppArgs = {
|
|
25
|
+
app: Express;
|
|
26
|
+
context: ServerContext;
|
|
27
|
+
};
|
|
22
28
|
export type ServerOptions = {
|
|
23
|
-
configureApp?: (
|
|
29
|
+
configureApp?: (args: ConfigureAppArgs) => void;
|
|
24
30
|
plugins?: readonly GraphileConfig.Plugin[];
|
|
25
31
|
extraPgSchemas?: string[];
|
|
26
32
|
exportSchemaSDLPath?: string;
|
package/dist/src/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { createHubServer } from "./server/index.js";
|
|
|
5
5
|
import { initializeTransferProcessors } from "./process-transfers/index.js";
|
|
6
6
|
import { join } from "path";
|
|
7
7
|
import { logger } from "./logger.js";
|
|
8
|
+
import { createServerContext, closeServerContext, } from "./context.js";
|
|
8
9
|
export { MakeOutcomeBetPlugin, } from "./plugins/hub-make-outcome-bet.js";
|
|
9
10
|
export { validateRisk, } from "./risk-policy.js";
|
|
10
11
|
export { defaultPlugins, } from "./server/graphile.config.js";
|
|
@@ -49,6 +50,7 @@ async function initialize(options) {
|
|
|
49
50
|
if (process.env.NODE_ENV !== "test") {
|
|
50
51
|
initializeTransferProcessors({
|
|
51
52
|
signal: options.signal,
|
|
53
|
+
pool: options.context.superuserPool,
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
}
|
|
@@ -66,9 +68,11 @@ export async function startAndListen(options) {
|
|
|
66
68
|
}
|
|
67
69
|
const abortController = new AbortController();
|
|
68
70
|
let isShuttingDown = false;
|
|
71
|
+
const context = createServerContext();
|
|
69
72
|
await initialize({
|
|
70
73
|
userDatabaseMigrationsPath: options.userDatabaseMigrationsPath,
|
|
71
74
|
signal: abortController.signal,
|
|
75
|
+
context,
|
|
72
76
|
});
|
|
73
77
|
const hubServer = createHubServer({
|
|
74
78
|
configureApp: options.configureApp,
|
|
@@ -76,6 +80,7 @@ export async function startAndListen(options) {
|
|
|
76
80
|
exportSchemaSDLPath: options.exportSchemaSDLPath,
|
|
77
81
|
extraPgSchemas: options.extraPgSchemas,
|
|
78
82
|
abortSignal: abortController.signal,
|
|
83
|
+
context,
|
|
79
84
|
});
|
|
80
85
|
const gracefulShutdown = async ({ exit = true } = {}) => {
|
|
81
86
|
if (isShuttingDown) {
|
|
@@ -89,13 +94,8 @@ export async function startAndListen(options) {
|
|
|
89
94
|
logger.info("Closing resources...");
|
|
90
95
|
hubServer.shutdown();
|
|
91
96
|
try {
|
|
92
|
-
const closeTasks = [db.notifier.close()];
|
|
93
|
-
if (process.env.NODE_ENV !== "test") {
|
|
94
|
-
closeTasks.push(db.postgraphilePool.end());
|
|
95
|
-
closeTasks.push(db.superuserPool.end());
|
|
96
|
-
}
|
|
97
97
|
await Promise.race([
|
|
98
|
-
|
|
98
|
+
closeServerContext(context),
|
|
99
99
|
new Promise((_, reject) => setTimeout(() => reject(new Error("Database cleanup timeout")), 3000)),
|
|
100
100
|
]);
|
|
101
101
|
logger.info("Cleanup complete.");
|
|
@@ -107,8 +107,10 @@ export async function startAndListen(options) {
|
|
|
107
107
|
process.exit(0);
|
|
108
108
|
}
|
|
109
109
|
};
|
|
110
|
-
process.
|
|
111
|
-
|
|
110
|
+
if (process.env.NODE_ENV !== "test") {
|
|
111
|
+
process.on("SIGINT", gracefulShutdown);
|
|
112
|
+
process.on("SIGTERM", gracefulShutdown);
|
|
113
|
+
}
|
|
112
114
|
return hubServer.listen().then(() => {
|
|
113
115
|
return {
|
|
114
116
|
port: config.PORT,
|
|
@@ -4,7 +4,7 @@ import { exactlyOneRow } from "../db/util.js";
|
|
|
4
4
|
import { gql as generatedGql } from "../__generated__/gql.js";
|
|
5
5
|
import { GraphQLClient } from "graphql-request";
|
|
6
6
|
import { GraphQLError } from "graphql";
|
|
7
|
-
import {
|
|
7
|
+
import { upsertCurrencies, withPgPoolTransaction, } from "../db/index.js";
|
|
8
8
|
import { logger } from "../logger.js";
|
|
9
9
|
import { assert, is } from "tsafe";
|
|
10
10
|
import * as jwtService from "../services/jwt-service.js";
|
|
@@ -48,8 +48,9 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
48
48
|
plans: {
|
|
49
49
|
hubAddCasino(_, { $input }) {
|
|
50
50
|
const $identity = context().get("identity");
|
|
51
|
+
const $superuserPool = context().get("superuserPool");
|
|
51
52
|
const $abortSignal = context().get("abortSignal");
|
|
52
|
-
const $casinoId = sideEffect([$input, $identity, $abortSignal], ([input, identity, abortSignal]) => {
|
|
53
|
+
const $casinoId = sideEffect([$input, $identity, $superuserPool, $abortSignal], ([input, identity, superuserPool, abortSignal]) => {
|
|
53
54
|
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
54
55
|
if (identity?.kind !== "operator") {
|
|
55
56
|
throw new GraphQLError("Unauthorized");
|
|
@@ -141,6 +142,7 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
141
142
|
startCasinoTransferProcessor({
|
|
142
143
|
casinoId: casino.id,
|
|
143
144
|
signal: abortSignal,
|
|
145
|
+
pool: superuserPool,
|
|
144
146
|
});
|
|
145
147
|
return casino.id;
|
|
146
148
|
});
|
|
@@ -5,7 +5,7 @@ import { GET_USER_FROM_USER_TOKEN } from "../graphql-queries.js";
|
|
|
5
5
|
import { exactlyOneRow, maybeOneRow } from "../db/util.js";
|
|
6
6
|
import { createGraphqlClient } from "../graphql-client.js";
|
|
7
7
|
import { constant, context, error, object, sideEffect, } from "postgraphile/grafast";
|
|
8
|
-
import {
|
|
8
|
+
import { withPgPoolTransaction, } from "../db/index.js";
|
|
9
9
|
import { logger } from "../logger.js";
|
|
10
10
|
import * as jwtService from "../services/jwt-service.js";
|
|
11
11
|
import { extractGraphQLErrorInfo, isGraphQLError } from "../GraphQLError.js";
|
|
@@ -51,7 +51,8 @@ export const HubAuthenticatePlugin = makeExtendSchemaPlugin(() => {
|
|
|
51
51
|
hubAuthenticate(_, { $input }) {
|
|
52
52
|
try {
|
|
53
53
|
const $context = context();
|
|
54
|
-
const $
|
|
54
|
+
const $superuserPool = $context.get("superuserPool");
|
|
55
|
+
const $success = sideEffect([$input, $superuserPool, $context], ([rawInput, superuserPool, context]) => {
|
|
55
56
|
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
56
57
|
let input;
|
|
57
58
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { object } from "grafast";
|
|
2
2
|
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import {
|
|
3
|
+
import { withPgPoolTransaction, } from "../db/index.js";
|
|
4
4
|
import { constant, context, sideEffect } from "postgraphile/grafast";
|
|
5
5
|
import { assert } from "tsafe";
|
|
6
6
|
const CLAIM_AMOUNT = 1000;
|
|
@@ -20,8 +20,10 @@ export const HubClaimFaucetPlugin = makeExtendSchemaPlugin(() => {
|
|
|
20
20
|
Mutation: {
|
|
21
21
|
plans: {
|
|
22
22
|
hubClaimFaucet() {
|
|
23
|
-
const $
|
|
24
|
-
const $
|
|
23
|
+
const $context = context();
|
|
24
|
+
const $identity = $context.get("identity");
|
|
25
|
+
const $superuserPool = $context.get("superuserPool");
|
|
26
|
+
const $result = sideEffect([$identity, $superuserPool], ([identity, superuserPool]) => {
|
|
25
27
|
if (identity?.kind !== "user") {
|
|
26
28
|
throw new Error("Must be logged in as user");
|
|
27
29
|
}
|
|
@@ -2,7 +2,7 @@ import { access, context, object, ObjectStep, sideEffect, } from "postgraphile/g
|
|
|
2
2
|
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import { GraphQLError } from "graphql";
|
|
5
|
-
import { DbHashKind, dbLockPlayerBalanceAndHouseBankroll, exactlyOneRow, maybeOneRow,
|
|
5
|
+
import { DbHashKind, dbLockPlayerBalanceAndHouseBankroll, exactlyOneRow, maybeOneRow, withPgPoolTransaction, } from "../db/index.js";
|
|
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";
|
|
@@ -106,7 +106,8 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
106
106
|
plans: {
|
|
107
107
|
hubMakeOutcomeBet: (_, { $input }) => {
|
|
108
108
|
const $identity = context().get("identity");
|
|
109
|
-
const $
|
|
109
|
+
const $superuserPool = context().get("superuserPool");
|
|
110
|
+
const $result = sideEffect([$identity, $superuserPool, $input], async ([identity, superuserPool, rawInput]) => {
|
|
110
111
|
if (identity?.kind !== "user") {
|
|
111
112
|
throw new GraphQLError("Unauthorized");
|
|
112
113
|
}
|
|
@@ -217,6 +218,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
217
218
|
if (dbHashChain.current_iteration === 1) {
|
|
218
219
|
finishHashChainInBackground({
|
|
219
220
|
hashChainId: input.hashChainId,
|
|
221
|
+
pool: superuserPool,
|
|
220
222
|
}).catch((e) => {
|
|
221
223
|
logger.error({ hashChainId: input.hashChainId, error: e }, "Error finishing hash chain in background");
|
|
222
224
|
});
|
|
@@ -403,7 +405,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
403
405
|
};
|
|
404
406
|
}, "HubMakeOutcomeBetPlugin");
|
|
405
407
|
}
|
|
406
|
-
async function finishHashChainInBackground({ hashChainId, }) {
|
|
408
|
+
async function finishHashChainInBackground({ hashChainId, pool, }) {
|
|
407
409
|
logger.debug({ hashChainId }, "Finishing hash chain in background");
|
|
408
410
|
const preimageHashResult = await getPreimageHash({
|
|
409
411
|
hashChainId,
|
|
@@ -416,7 +418,7 @@ async function finishHashChainInBackground({ hashChainId, }) {
|
|
|
416
418
|
digest: preimageHashResult.hash,
|
|
417
419
|
iteration: 0,
|
|
418
420
|
}, "Inserting preimage hash");
|
|
419
|
-
await withPgPoolTransaction(
|
|
421
|
+
await withPgPoolTransaction(pool, async (pgClient) => {
|
|
420
422
|
await dbInsertHubHash(pgClient, {
|
|
421
423
|
hashChainId,
|
|
422
424
|
kind: DbHashKind.PREIMAGE,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { constant, context, object, sideEffect } from "postgraphile/grafast";
|
|
2
2
|
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import {
|
|
3
|
+
import { withPgPoolTransaction } from "../db/index.js";
|
|
4
4
|
import { exactlyOneRow, maybeOneRow } from "../db/util.js";
|
|
5
5
|
import { GraphQLError } from "graphql";
|
|
6
6
|
export const HubWithdrawPlugin = makeExtendSchemaPlugin((build) => {
|
|
@@ -26,7 +26,8 @@ export const HubWithdrawPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
26
26
|
plans: {
|
|
27
27
|
hubWithdraw(_, { $input }) {
|
|
28
28
|
const $identity = context().get("identity");
|
|
29
|
-
const $
|
|
29
|
+
const $superuserPool = context().get("superuserPool");
|
|
30
|
+
const $withdrawalRequestId = sideEffect([$input, $identity, $superuserPool], ([input, identity, superuserPool]) => {
|
|
30
31
|
if (identity?.kind !== "user") {
|
|
31
32
|
throw new GraphQLError("You must be logged in");
|
|
32
33
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { DbCasino, DbCasinoSecret } from "../db/index.js";
|
|
2
|
+
import * as pg from "pg";
|
|
2
3
|
export type CasinoWithSecret = DbCasino & DbCasinoSecret;
|
|
3
|
-
export declare function startCasinoTransferProcessor({ casinoId, signal, }: {
|
|
4
|
+
export declare function startCasinoTransferProcessor({ casinoId, signal, pool, }: {
|
|
4
5
|
casinoId: string;
|
|
5
6
|
signal: AbortSignal;
|
|
7
|
+
pool: pg.Pool;
|
|
6
8
|
}): Promise<void>;
|
|
7
|
-
export declare function initializeTransferProcessors({ signal, }: {
|
|
9
|
+
export declare function initializeTransferProcessors({ signal, pool, }: {
|
|
8
10
|
signal: AbortSignal;
|
|
11
|
+
pool: pg.Pool;
|
|
9
12
|
}): void;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { startPollingProcessor } from "./polling-processor.js";
|
|
2
2
|
import { startWebsocketProcessor } from "./websocket-processor.js";
|
|
3
|
-
import { superuserPool } from "../db/index.js";
|
|
4
3
|
import { dbGetCasinoById, dbGetCasinoSecretById } from "../db/internal.js";
|
|
5
4
|
import assert from "assert";
|
|
6
5
|
import { logger } from "../logger.js";
|
|
@@ -9,28 +8,29 @@ import * as db from "../db/index.js";
|
|
|
9
8
|
import * as pg from "pg";
|
|
10
9
|
import { z } from "zod";
|
|
11
10
|
const activeCasinos = new Set();
|
|
12
|
-
export async function startCasinoTransferProcessor({ casinoId, signal, }) {
|
|
11
|
+
export async function startCasinoTransferProcessor({ casinoId, signal, pool, }) {
|
|
13
12
|
if (activeCasinos.has(casinoId)) {
|
|
14
13
|
throw new Error(`processor already running for casino ${casinoId}`);
|
|
15
14
|
}
|
|
16
|
-
const casino = await dbGetCasinoById(
|
|
17
|
-
const secret = await dbGetCasinoSecretById(
|
|
15
|
+
const casino = await dbGetCasinoById(pool, casinoId);
|
|
16
|
+
const secret = await dbGetCasinoSecretById(pool, casinoId);
|
|
18
17
|
assert(casino, `Casino not found for casino id ${casinoId}`);
|
|
19
18
|
assert(secret, `Secret not found for casino id ${casinoId}`);
|
|
20
19
|
activeCasinos.add(casinoId);
|
|
21
|
-
startPollingProcessor({ casinoId, signal });
|
|
20
|
+
startPollingProcessor({ casinoId, signal, pool });
|
|
22
21
|
startWebsocketProcessor({
|
|
23
22
|
casinoId,
|
|
24
23
|
graphqlUrl: casino.graphql_url,
|
|
25
24
|
signal,
|
|
26
25
|
controllerId: secret.controller_id,
|
|
27
26
|
apiKey: secret.api_key,
|
|
27
|
+
pool,
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
-
export function initializeTransferProcessors({ signal, }) {
|
|
30
|
+
export function initializeTransferProcessors({ signal, pool, }) {
|
|
31
31
|
(async () => {
|
|
32
32
|
try {
|
|
33
|
-
const casinos = await db.listCasinos(
|
|
33
|
+
const casinos = await db.listCasinos(pool);
|
|
34
34
|
for (const casino of casinos) {
|
|
35
35
|
if (!URL.canParse(casino.graphql_url)) {
|
|
36
36
|
logger.warn(`Skipping casino ${casino.id} due to invalid graphql_url: "${casino.graphql_url}"`);
|
|
@@ -41,16 +41,16 @@ export function initializeTransferProcessors({ signal, }) {
|
|
|
41
41
|
logger.warn(`${casino.id} has localhost endpoint "${casino.graphql_url}" while NODE_ENV=production.`);
|
|
42
42
|
}
|
|
43
43
|
logger.info(`Starting casino processor for "${casino.name}" at "${casino.graphql_url}"`);
|
|
44
|
-
startCasinoTransferProcessor({ casinoId: casino.id, signal });
|
|
44
|
+
startCasinoTransferProcessor({ casinoId: casino.id, signal, pool });
|
|
45
45
|
}
|
|
46
|
-
await listenForNewCasinos({ signal });
|
|
46
|
+
await listenForNewCasinos({ signal, pool });
|
|
47
47
|
}
|
|
48
48
|
catch (e) {
|
|
49
49
|
logger.error(e, `Error initializing transfer processors`);
|
|
50
50
|
}
|
|
51
51
|
})();
|
|
52
52
|
}
|
|
53
|
-
async function listenForNewCasinos({ signal }) {
|
|
53
|
+
async function listenForNewCasinos({ signal, pool, }) {
|
|
54
54
|
const pgClient = new pg.Client(config.SUPERUSER_DATABASE_URL);
|
|
55
55
|
await pgClient.connect();
|
|
56
56
|
const NewCasinoPayload = z.object({
|
|
@@ -76,7 +76,11 @@ async function listenForNewCasinos({ signal }) {
|
|
|
76
76
|
logger.error(result.error, "Error parsing new casino notification");
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
startCasinoTransferProcessor({
|
|
79
|
+
startCasinoTransferProcessor({
|
|
80
|
+
casinoId: result.data.id,
|
|
81
|
+
signal,
|
|
82
|
+
pool,
|
|
83
|
+
});
|
|
80
84
|
break;
|
|
81
85
|
}
|
|
82
86
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as db from "../db/index.js";
|
|
2
|
+
import * as pg from "pg";
|
|
2
3
|
export declare const PAGINATE_TRANSFERS: import("@graphql-typed-document-node/core").TypedDocumentNode<import("../__generated__/graphql.js").PaginateTransfersQuery, import("../__generated__/graphql.js").Exact<{
|
|
3
4
|
controllerId: import("../__generated__/graphql.js").Scalars["UUID"]["input"];
|
|
4
5
|
after?: import("../__generated__/graphql.js").InputMaybe<import("../__generated__/graphql.js").Scalars["Cursor"]["input"]>;
|
|
5
6
|
limit?: import("../__generated__/graphql.js").InputMaybe<import("../__generated__/graphql.js").Scalars["Int"]["input"]>;
|
|
6
7
|
}>>;
|
|
7
|
-
export declare function startPollingProcessor({ casinoId, signal, }: {
|
|
8
|
+
export declare function startPollingProcessor({ casinoId, signal, pool, }: {
|
|
8
9
|
casinoId: db.DbCasino["id"];
|
|
9
10
|
signal: AbortSignal;
|
|
11
|
+
pool: pg.Pool;
|
|
10
12
|
}): void;
|
|
@@ -8,7 +8,6 @@ import { processWithdrawalRequests } from "../process-withdrawal-request.js";
|
|
|
8
8
|
import { processTakeRequests } from "../take-request/process-take-request.js";
|
|
9
9
|
import * as jwtService from "../services/jwt-service.js";
|
|
10
10
|
import { dbGetCasinoById, dbGetCasinoSecretById } from "../db/internal.js";
|
|
11
|
-
import { superuserPool } from "../db/index.js";
|
|
12
11
|
import { TransferStatusKind } from "../__generated__/graphql.js";
|
|
13
12
|
import { MP_COMPLETE_TRANSFER, processTransfer } from "./process-transfer.js";
|
|
14
13
|
import { gql } from "../__generated__/gql.js";
|
|
@@ -44,7 +43,7 @@ export const PAGINATE_TRANSFERS = gql(`
|
|
|
44
43
|
`);
|
|
45
44
|
const MIN_BACKOFF_TIME = 5000;
|
|
46
45
|
const MAX_BACKOFF_TIME = 30 * 1000;
|
|
47
|
-
export function startPollingProcessor({ casinoId, signal, }) {
|
|
46
|
+
export function startPollingProcessor({ casinoId, signal, pool, }) {
|
|
48
47
|
if (signal.aborted) {
|
|
49
48
|
logger.info(`[startTransferProcessor] AbortSignal aborted. Not starting processor for casino ${casinoId}`);
|
|
50
49
|
return;
|
|
@@ -55,7 +54,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
55
54
|
lastAttempt: 0,
|
|
56
55
|
};
|
|
57
56
|
(async () => {
|
|
58
|
-
let cursor = await db.getTransferCursor(
|
|
57
|
+
let cursor = await db.getTransferCursor(pool, {
|
|
59
58
|
casinoId,
|
|
60
59
|
});
|
|
61
60
|
if (cursor && !isUuid(cursor)) {
|
|
@@ -80,13 +79,13 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
80
79
|
await new Promise((resolve) => setTimeout(resolve, timeToWait));
|
|
81
80
|
}
|
|
82
81
|
processorState.lastAttempt = Date.now();
|
|
83
|
-
const casino = await dbGetCasinoById(
|
|
82
|
+
const casino = await dbGetCasinoById(pool, casinoId);
|
|
84
83
|
if (!casino) {
|
|
85
84
|
logger.warn(`casino ${casinoId} not found. Stopping processor...`);
|
|
86
85
|
shouldStop = true;
|
|
87
86
|
break;
|
|
88
87
|
}
|
|
89
|
-
const casinoSecret = await dbGetCasinoSecretById(
|
|
88
|
+
const casinoSecret = await dbGetCasinoSecretById(pool, casino.id);
|
|
90
89
|
if (!casinoSecret) {
|
|
91
90
|
logger.warn(`Casino secret hasn't been set for casino ${casinoId}. Skipping...`);
|
|
92
91
|
continue;
|
|
@@ -99,7 +98,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
99
98
|
logger.info(`[startTransferProcessor] Aborted by graceful shutdown. (1)`);
|
|
100
99
|
break;
|
|
101
100
|
}
|
|
102
|
-
await jwtService.refreshCasinoJwksTask(
|
|
101
|
+
await jwtService.refreshCasinoJwksTask(pool, {
|
|
103
102
|
casinoId: casino.id,
|
|
104
103
|
graphqlClient,
|
|
105
104
|
});
|
|
@@ -114,7 +113,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
114
113
|
return (res.allCurrencies?.nodes || []).flatMap((x) => x ? [x] : []);
|
|
115
114
|
});
|
|
116
115
|
if (currencies.length > 0) {
|
|
117
|
-
await db.upsertCurrencies(
|
|
116
|
+
await db.upsertCurrencies(pool, {
|
|
118
117
|
casinoId: casino.id,
|
|
119
118
|
currencies,
|
|
120
119
|
});
|
|
@@ -130,6 +129,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
130
129
|
graphqlClient,
|
|
131
130
|
casinoInfo: { ...casino, ...casinoSecret },
|
|
132
131
|
signal,
|
|
132
|
+
pool,
|
|
133
133
|
});
|
|
134
134
|
if (signal.aborted) {
|
|
135
135
|
logger.info(`[startTransferProcessor] Aborted by graceful shutdown. (4)`);
|
|
@@ -139,6 +139,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
139
139
|
abortSignal: signal,
|
|
140
140
|
casinoId: casino.id,
|
|
141
141
|
graphqlClient,
|
|
142
|
+
pool,
|
|
142
143
|
});
|
|
143
144
|
if (signal.aborted) {
|
|
144
145
|
logger.info(`[startTransferProcessor] Aborted by graceful shutdown. (5)`);
|
|
@@ -149,6 +150,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
149
150
|
controllerId: casinoSecret.controller_id,
|
|
150
151
|
casinoId: casino.id,
|
|
151
152
|
graphqlClient,
|
|
153
|
+
pool,
|
|
152
154
|
});
|
|
153
155
|
processorState.backoffTime = MIN_BACKOFF_TIME;
|
|
154
156
|
}
|
|
@@ -161,11 +163,11 @@ export function startPollingProcessor({ casinoId, signal, }) {
|
|
|
161
163
|
logger.info(`processor stopped for casino ${casinoId}`);
|
|
162
164
|
})();
|
|
163
165
|
}
|
|
164
|
-
async function processWithdrawals({ abortSignal, casinoId, graphqlClient, }) {
|
|
166
|
+
async function processWithdrawals({ abortSignal, casinoId, graphqlClient, pool, }) {
|
|
165
167
|
if (abortSignal.aborted) {
|
|
166
168
|
return;
|
|
167
169
|
}
|
|
168
|
-
const withdrawals = await db.getPendingWithdrawals(
|
|
170
|
+
const withdrawals = await db.getPendingWithdrawals(pool, {
|
|
169
171
|
casinoId,
|
|
170
172
|
limit: 10,
|
|
171
173
|
});
|
|
@@ -185,7 +187,7 @@ async function processWithdrawals({ abortSignal, casinoId, graphqlClient, }) {
|
|
|
185
187
|
case undefined:
|
|
186
188
|
break;
|
|
187
189
|
case "CompleteTransferSuccess": {
|
|
188
|
-
await db.settleWithdrawal({
|
|
190
|
+
await db.settleWithdrawal(pool, {
|
|
189
191
|
withdrawalId: withdrawal.id,
|
|
190
192
|
newStatus: "COMPLETED",
|
|
191
193
|
});
|
|
@@ -198,7 +200,7 @@ async function processWithdrawals({ abortSignal, casinoId, graphqlClient, }) {
|
|
|
198
200
|
switch (currentState) {
|
|
199
201
|
case TransferStatusKind.Canceled:
|
|
200
202
|
case TransferStatusKind.Completed:
|
|
201
|
-
await db.settleWithdrawal({
|
|
203
|
+
await db.settleWithdrawal(pool, {
|
|
202
204
|
withdrawalId: withdrawal.id,
|
|
203
205
|
newStatus: currentState,
|
|
204
206
|
});
|
|
@@ -224,13 +226,14 @@ async function processWithdrawals({ abortSignal, casinoId, graphqlClient, }) {
|
|
|
224
226
|
}
|
|
225
227
|
}
|
|
226
228
|
}
|
|
227
|
-
async function processTransfersUntilEmpty({ afterCursor, graphqlClient, casinoInfo, signal, }) {
|
|
229
|
+
async function processTransfersUntilEmpty({ afterCursor, graphqlClient, casinoInfo, signal, pool, }) {
|
|
228
230
|
let hasNextPage = true;
|
|
229
231
|
const timeout = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
230
232
|
while (hasNextPage && !signal.aborted) {
|
|
231
233
|
await processWithdrawalRequests({
|
|
232
234
|
casinoId: casinoInfo.id,
|
|
233
235
|
graphqlClient,
|
|
236
|
+
pool,
|
|
234
237
|
});
|
|
235
238
|
if (signal.aborted) {
|
|
236
239
|
logger.info(`[processTransfersUntilEmpty] Aborted by graceful shutdown.`);
|
|
@@ -266,8 +269,9 @@ async function processTransfersUntilEmpty({ afterCursor, graphqlClient, casinoIn
|
|
|
266
269
|
controllerId: casinoInfo.controller_id,
|
|
267
270
|
transfer,
|
|
268
271
|
graphqlClient,
|
|
272
|
+
pool,
|
|
269
273
|
});
|
|
270
|
-
await db.setTransferCursor(
|
|
274
|
+
await db.setTransferCursor(pool, {
|
|
271
275
|
cursor,
|
|
272
276
|
casinoId: casinoInfo.id,
|
|
273
277
|
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { TransferFieldsFragment } from "../__generated__/graphql.js";
|
|
2
2
|
import { GraphQLClient } from "graphql-request";
|
|
3
|
+
import * as pg from "pg";
|
|
3
4
|
export declare const MP_COMPLETE_TRANSFER: import("@graphql-typed-document-node/core").TypedDocumentNode<import("../__generated__/graphql.js").CompleteTransferMutation, import("../__generated__/graphql.js").Exact<{
|
|
4
5
|
mpTransferId: import("../__generated__/graphql.js").Scalars["UUID"]["input"];
|
|
5
6
|
}>>;
|
|
6
|
-
export declare function processTransfer({ casinoId, controllerId, transfer, graphqlClient, }: {
|
|
7
|
+
export declare function processTransfer({ casinoId, controllerId, transfer, graphqlClient, pool, }: {
|
|
7
8
|
casinoId: string;
|
|
8
9
|
controllerId: string;
|
|
9
10
|
transfer: Extract<TransferFieldsFragment, {
|
|
10
11
|
__typename: "ExperienceTransfer";
|
|
11
12
|
}>;
|
|
12
13
|
graphqlClient: GraphQLClient;
|
|
14
|
+
pool: pg.Pool;
|
|
13
15
|
}): Promise<void>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as db from "../db/index.js";
|
|
2
2
|
import { TransferStatusKind, } from "../__generated__/graphql.js";
|
|
3
|
-
import { superuserPool } from "../db/index.js";
|
|
4
3
|
import { gql } from "../__generated__/gql.js";
|
|
5
4
|
import { logger } from "../logger.js";
|
|
6
5
|
import { assert } from "tsafe";
|
|
@@ -50,7 +49,7 @@ const MP_CLAIM_TRANSFER = gql(`
|
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
`);
|
|
53
|
-
export async function processTransfer({ casinoId, controllerId, transfer, graphqlClient, }) {
|
|
52
|
+
export async function processTransfer({ casinoId, controllerId, transfer, graphqlClient, pool, }) {
|
|
54
53
|
assert(transfer, "Expected transfer");
|
|
55
54
|
assert(transfer.__typename === "ExperienceTransfer", `Expected ExperienceTransfer but got ${transfer.__typename}`);
|
|
56
55
|
logger.debug(`processing transfer ${transfer.id} for casino ${casinoId}...`);
|
|
@@ -62,17 +61,17 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
|
|
|
62
61
|
: transfer.holderByToHolderId;
|
|
63
62
|
assert(user?.__typename === "User", "Expected user transfer participant");
|
|
64
63
|
const currency = transfer.currencyByCurrency;
|
|
65
|
-
const dbSender = await db.upsertUser(
|
|
64
|
+
const dbSender = await db.upsertUser(pool, {
|
|
66
65
|
casinoId,
|
|
67
66
|
mpUserId: user.id,
|
|
68
67
|
uname: user.uname,
|
|
69
68
|
});
|
|
70
|
-
const dbExperience = await db.upsertExperience(
|
|
69
|
+
const dbExperience = await db.upsertExperience(pool, {
|
|
71
70
|
casinoId,
|
|
72
71
|
mpExperienceId: transfer.experienceByExperienceId.id,
|
|
73
72
|
name: transfer.experienceByExperienceId.name,
|
|
74
73
|
});
|
|
75
|
-
await db.upsertCurrencies(
|
|
74
|
+
await db.upsertCurrencies(pool, {
|
|
76
75
|
casinoId,
|
|
77
76
|
currencies: [currency],
|
|
78
77
|
});
|
|
@@ -85,7 +84,7 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
|
|
|
85
84
|
case TransferStatusKind.Expired:
|
|
86
85
|
return;
|
|
87
86
|
case TransferStatusKind.Completed: {
|
|
88
|
-
await db.insertDeposit({
|
|
87
|
+
await db.insertDeposit(pool, {
|
|
89
88
|
casinoId,
|
|
90
89
|
mpTransferId: transfer.id,
|
|
91
90
|
userId: dbSender.id,
|
|
@@ -110,7 +109,7 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
|
|
|
110
109
|
if (data.claimTransfer?.result.__typename !== "ClaimTransferSuccess") {
|
|
111
110
|
throw new Error(`Failed to claim transfer: ${JSON.stringify(data.claimTransfer)}`);
|
|
112
111
|
}
|
|
113
|
-
await db.insertDeposit({
|
|
112
|
+
await db.insertDeposit(pool, {
|
|
114
113
|
casinoId,
|
|
115
114
|
mpTransferId: transfer.id,
|
|
116
115
|
userId: dbSender.id,
|
|
@@ -130,7 +129,7 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
|
|
|
130
129
|
logger.debug(`I sent ${user.uname} ${transfer.amount} base units of ${currency.id}`);
|
|
131
130
|
switch (transfer.status) {
|
|
132
131
|
case TransferStatusKind.Canceled:
|
|
133
|
-
await db.settleWithdrawal({
|
|
132
|
+
await db.settleWithdrawal(pool, {
|
|
134
133
|
withdrawalId: transfer.id,
|
|
135
134
|
newStatus: "CANCELED",
|
|
136
135
|
});
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
export declare function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controllerId, apiKey, pool, }: {
|
|
2
3
|
casinoId: string;
|
|
3
4
|
graphqlUrl: string;
|
|
4
5
|
signal: AbortSignal;
|
|
5
6
|
controllerId: string;
|
|
6
7
|
apiKey: string;
|
|
8
|
+
pool: pg.Pool;
|
|
7
9
|
}): void;
|
|
@@ -7,7 +7,6 @@ import { TRANSFER_FIELDS } from "./graphql.js";
|
|
|
7
7
|
import { logger } from "../logger.js";
|
|
8
8
|
import { processTransfer } from "./process-transfer.js";
|
|
9
9
|
import assert from "assert";
|
|
10
|
-
import { superuserPool } from "../db/index.js";
|
|
11
10
|
import { mpGetTakeRequest, processSingleTakeRequest, } from "../take-request/process-take-request.js";
|
|
12
11
|
function httpToWs(url) {
|
|
13
12
|
if (url.protocol === "http:") {
|
|
@@ -50,7 +49,7 @@ async function mpGetExperienceTransfer(graphqlClient, id) {
|
|
|
50
49
|
const mpTransfer = useFragment(TRANSFER_FIELDS, x);
|
|
51
50
|
return mpTransfer;
|
|
52
51
|
}
|
|
53
|
-
export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controllerId, apiKey, }) {
|
|
52
|
+
export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controllerId, apiKey, pool, }) {
|
|
54
53
|
logger.info(`Starting websocket processor for ${graphqlUrl} using apiKey ${apiKey}`);
|
|
55
54
|
const client = createWebsocketClient({
|
|
56
55
|
url: httpToWs(new URL(graphqlUrl)).toString(),
|
|
@@ -90,6 +89,7 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
|
|
|
90
89
|
controllerId,
|
|
91
90
|
transfer: mpTransfer,
|
|
92
91
|
graphqlClient,
|
|
92
|
+
pool,
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
95
|
const dispose2 = createSubscription(client, MP_NEW_TAKE_REQUEST, async (result) => {
|
|
@@ -108,7 +108,7 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
|
|
|
108
108
|
mpTakeRequest,
|
|
109
109
|
casinoId,
|
|
110
110
|
graphqlClient,
|
|
111
|
-
pool
|
|
111
|
+
pool,
|
|
112
112
|
});
|
|
113
113
|
});
|
|
114
114
|
signal.addEventListener("abort", () => {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
1
2
|
import { GraphQLClient } from "graphql-request";
|
|
2
|
-
export declare function processWithdrawalRequests({ casinoId, graphqlClient, }: {
|
|
3
|
+
export declare function processWithdrawalRequests({ casinoId, graphqlClient, pool, }: {
|
|
3
4
|
casinoId: string;
|
|
4
5
|
graphqlClient: GraphQLClient;
|
|
6
|
+
pool: pg.Pool;
|
|
5
7
|
}): Promise<void>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { assert } from "tsafe";
|
|
2
2
|
import { TransferStatusKind } from "./__generated__/graphql.js";
|
|
3
|
-
import { withPgPoolTransaction
|
|
3
|
+
import { withPgPoolTransaction } from "./db/index.js";
|
|
4
4
|
import { maybeOneRow, exactlyOneRow } from "./db/util.js";
|
|
5
5
|
import { START_PENDING_EXPERIENCE_TRANSFER } from "./graphql-queries.js";
|
|
6
6
|
import { logger } from "./logger.js";
|
|
7
|
-
async function processWithdrawalRequest({ requestId, graphqlClient, }) {
|
|
8
|
-
return withPgPoolTransaction(
|
|
7
|
+
async function processWithdrawalRequest({ requestId, graphqlClient, pool, }) {
|
|
8
|
+
return withPgPoolTransaction(pool, async (pgClient) => {
|
|
9
9
|
const dbWithdrawalRequest = await pgClient
|
|
10
10
|
.query({
|
|
11
11
|
text: `
|
|
@@ -120,8 +120,8 @@ async function processWithdrawalRequest({ requestId, graphqlClient, }) {
|
|
|
120
120
|
});
|
|
121
121
|
});
|
|
122
122
|
}
|
|
123
|
-
export async function processWithdrawalRequests({ casinoId, graphqlClient, }) {
|
|
124
|
-
const pendingRequests = await
|
|
123
|
+
export async function processWithdrawalRequests({ casinoId, graphqlClient, pool, }) {
|
|
124
|
+
const pendingRequests = await pool.query({
|
|
125
125
|
text: `
|
|
126
126
|
SELECT wr.*
|
|
127
127
|
FROM hub.withdrawal_request wr
|
|
@@ -136,6 +136,7 @@ export async function processWithdrawalRequests({ casinoId, graphqlClient, }) {
|
|
|
136
136
|
await processWithdrawalRequest({
|
|
137
137
|
requestId: request.id,
|
|
138
138
|
graphqlClient,
|
|
139
|
+
pool,
|
|
139
140
|
});
|
|
140
141
|
}
|
|
141
142
|
catch (error) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "graphile-config";
|
|
2
2
|
import "postgraphile";
|
|
3
|
+
import { ServerContext } from "../context.js";
|
|
3
4
|
export type UserSessionContext = {
|
|
4
5
|
user_id: string;
|
|
5
6
|
mp_user_id: string;
|
|
@@ -15,9 +16,10 @@ export type PluginIdentity = {
|
|
|
15
16
|
};
|
|
16
17
|
export declare const requiredPlugins: readonly GraphileConfig.Plugin[];
|
|
17
18
|
export declare const defaultPlugins: readonly GraphileConfig.Plugin[];
|
|
18
|
-
export declare function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, }: {
|
|
19
|
+
export declare function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, context, }: {
|
|
19
20
|
plugins: readonly GraphileConfig.Plugin[];
|
|
20
21
|
exportSchemaSDLPath?: string;
|
|
21
22
|
extraPgSchemas: string[];
|
|
22
23
|
abortSignal: AbortSignal;
|
|
24
|
+
context: ServerContext;
|
|
23
25
|
}): GraphileConfig.Preset;
|
|
@@ -48,7 +48,7 @@ export const defaultPlugins = [
|
|
|
48
48
|
HubClaimFaucetPlugin,
|
|
49
49
|
customPgOmitArchivedPlugin("deleted"),
|
|
50
50
|
];
|
|
51
|
-
export function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, }) {
|
|
51
|
+
export function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, context, }) {
|
|
52
52
|
if (exportSchemaSDLPath) {
|
|
53
53
|
if (!exportSchemaSDLPath.startsWith("/")) {
|
|
54
54
|
throw new Error("exportSchemaSDLPath must be an absolute path");
|
|
@@ -96,7 +96,7 @@ export function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abo
|
|
|
96
96
|
grafast: {
|
|
97
97
|
context(ctx, _args) {
|
|
98
98
|
if (ctx.ws) {
|
|
99
|
-
return handleWebsocketContext(ctx.ws);
|
|
99
|
+
return handleWebsocketContext(context, ctx.ws);
|
|
100
100
|
}
|
|
101
101
|
const expressReq = ctx.expressv4.req;
|
|
102
102
|
const reqIdentity = expressReq.identity;
|
|
@@ -132,6 +132,7 @@ export function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abo
|
|
|
132
132
|
pgSettings,
|
|
133
133
|
identity: pluginIdentity,
|
|
134
134
|
abortSignal,
|
|
135
|
+
superuserPool: context.superuserPool,
|
|
135
136
|
};
|
|
136
137
|
},
|
|
137
138
|
},
|
|
@@ -147,12 +148,12 @@ function getSessionIdFromWebsocketCtx(ws) {
|
|
|
147
148
|
const uuid = value.slice("session:".length);
|
|
148
149
|
return isUuid(uuid) ? uuid : "";
|
|
149
150
|
}
|
|
150
|
-
async function handleWebsocketContext(ws) {
|
|
151
|
+
async function handleWebsocketContext(context, ws) {
|
|
151
152
|
const sessionId = getSessionIdFromWebsocketCtx(ws);
|
|
152
153
|
if (!sessionId) {
|
|
153
154
|
throw new Error("Unauthorized");
|
|
154
155
|
}
|
|
155
|
-
const result = await db.userFromActiveSessionKey(
|
|
156
|
+
const result = await db.userFromActiveSessionKey(context.superuserPool, sessionId);
|
|
156
157
|
if (!result) {
|
|
157
158
|
throw new Error("Unauthorized");
|
|
158
159
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ServerOptions } from "../index.js";
|
|
2
|
+
import { ServerContext } from "../context.js";
|
|
2
3
|
export type HubServer = {
|
|
3
4
|
listen: () => Promise<void>;
|
|
4
5
|
shutdown: () => Promise<void>;
|
|
5
6
|
};
|
|
6
|
-
export declare function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, }: Pick<ServerOptions, "plugins" | "exportSchemaSDLPath" | "extraPgSchemas" | "configureApp"> & {
|
|
7
|
+
export declare function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, context, }: Pick<ServerOptions, "plugins" | "exportSchemaSDLPath" | "extraPgSchemas" | "configureApp"> & {
|
|
7
8
|
abortSignal: AbortSignal;
|
|
9
|
+
context: ServerContext;
|
|
8
10
|
}): HubServer;
|
package/dist/src/server/index.js
CHANGED
|
@@ -31,11 +31,11 @@ const dashboardDir = path.join(distDir, "dashboard");
|
|
|
31
31
|
if (!fs.existsSync(dashboardDir)) {
|
|
32
32
|
throw new Error(`Could not find dashboard directory. Expected it to be at "${dashboardDir}"`);
|
|
33
33
|
}
|
|
34
|
-
function createExpressServer() {
|
|
34
|
+
function createExpressServer(context) {
|
|
35
35
|
const app = express();
|
|
36
36
|
app.disable("x-powered-by");
|
|
37
37
|
app.use(cors());
|
|
38
|
-
app.use(authentication());
|
|
38
|
+
app.use(authentication(context));
|
|
39
39
|
app.use("/dashboard", express.static(dashboardDir));
|
|
40
40
|
app.use("/dashboard/*splat", (_, res) => {
|
|
41
41
|
res.sendFile(path.join(dashboardDir, "index.html"));
|
|
@@ -45,18 +45,19 @@ function createExpressServer() {
|
|
|
45
45
|
});
|
|
46
46
|
return app;
|
|
47
47
|
}
|
|
48
|
-
export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, }) {
|
|
49
|
-
const expressServer = createExpressServer();
|
|
48
|
+
export function createHubServer({ configureApp, plugins, exportSchemaSDLPath, extraPgSchemas, abortSignal, context, }) {
|
|
49
|
+
const expressServer = createExpressServer(context);
|
|
50
50
|
const preset = createPreset({
|
|
51
51
|
plugins: plugins ?? defaultPlugins,
|
|
52
52
|
exportSchemaSDLPath,
|
|
53
53
|
extraPgSchemas: extraPgSchemas ?? [],
|
|
54
54
|
abortSignal,
|
|
55
|
+
context,
|
|
55
56
|
});
|
|
56
57
|
const pgl = postgraphile.default(preset);
|
|
57
58
|
const serv = pgl.createServ(grafserv);
|
|
58
59
|
if (configureApp) {
|
|
59
|
-
configureApp(expressServer);
|
|
60
|
+
configureApp({ app: expressServer, context });
|
|
60
61
|
}
|
|
61
62
|
const nodeServer = createNodeServer(expressServer);
|
|
62
63
|
nodeServer.on("error", (e) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Response, NextFunction } from "express";
|
|
2
2
|
import { HubRequest } from "../../express.js";
|
|
3
|
-
|
|
3
|
+
import { ServerContext } from "../../context.js";
|
|
4
|
+
declare const authentication: (context: ServerContext) => (req: HubRequest, _: Response, next: NextFunction) => Promise<void>;
|
|
4
5
|
export default authentication;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isUuid } from "../../util.js";
|
|
2
2
|
import * as db from "../../db/index.js";
|
|
3
|
-
async function checkAndUpdateApiKey(key) {
|
|
4
|
-
const row = await
|
|
3
|
+
async function checkAndUpdateApiKey(key, pool) {
|
|
4
|
+
const row = await pool
|
|
5
5
|
.query(`
|
|
6
6
|
UPDATE hub.api_key
|
|
7
7
|
SET last_used_at = now()
|
|
@@ -11,7 +11,7 @@ async function checkAndUpdateApiKey(key) {
|
|
|
11
11
|
.then(db.maybeOneRow);
|
|
12
12
|
return !!row;
|
|
13
13
|
}
|
|
14
|
-
const authentication = () => {
|
|
14
|
+
const authentication = (context) => {
|
|
15
15
|
return async (req, _, next) => {
|
|
16
16
|
const header = req.get("authorization");
|
|
17
17
|
if (!header) {
|
|
@@ -28,7 +28,7 @@ const authentication = () => {
|
|
|
28
28
|
}
|
|
29
29
|
if (tokenType === "session") {
|
|
30
30
|
const sessionKey = token;
|
|
31
|
-
const result = await db.userFromActiveSessionKey(
|
|
31
|
+
const result = await db.userFromActiveSessionKey(context.superuserPool, sessionKey);
|
|
32
32
|
if (result) {
|
|
33
33
|
req.identity = {
|
|
34
34
|
kind: "user",
|
|
@@ -40,7 +40,7 @@ const authentication = () => {
|
|
|
40
40
|
}
|
|
41
41
|
else if (tokenType === "apikey") {
|
|
42
42
|
const apiKey = token;
|
|
43
|
-
const isValid = await checkAndUpdateApiKey(apiKey);
|
|
43
|
+
const isValid = await checkAndUpdateApiKey(apiKey, context.superuserPool);
|
|
44
44
|
if (isValid) {
|
|
45
45
|
req.identity = {
|
|
46
46
|
kind: "operator",
|
|
@@ -3,11 +3,12 @@ import { MpTakeRequestFieldsFragment } from "../__generated__/graphql.js";
|
|
|
3
3
|
import * as pg from "pg";
|
|
4
4
|
export declare const MP_TAKE_REQUEST_FIELDS: import("@graphql-typed-document-node/core").TypedDocumentNode<MpTakeRequestFieldsFragment, unknown>;
|
|
5
5
|
export declare function mpGetTakeRequest(graphqlClient: GraphQLClient, id: string): Promise<MpTakeRequestFieldsFragment | null>;
|
|
6
|
-
export declare function processTakeRequests({ abortSignal, controllerId, casinoId, graphqlClient, }: {
|
|
6
|
+
export declare function processTakeRequests({ abortSignal, controllerId, casinoId, graphqlClient, pool, }: {
|
|
7
7
|
abortSignal: AbortSignal;
|
|
8
8
|
controllerId: string;
|
|
9
9
|
casinoId: string;
|
|
10
10
|
graphqlClient: GraphQLClient;
|
|
11
|
+
pool: pg.Pool;
|
|
11
12
|
}): Promise<void>;
|
|
12
13
|
export declare function processSingleTakeRequest({ mpTakeRequestId, mpTakeRequest, casinoId, graphqlClient, pool, }: {
|
|
13
14
|
mpTakeRequestId: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { gql } from "../__generated__/gql.js";
|
|
2
2
|
import { TakeRequestStatus as MpTakeRequestStatus, TransferStatusKind as MpTransferStatus, } from "../__generated__/graphql.js";
|
|
3
|
-
import { exactlyOneRow, maybeOneRow,
|
|
3
|
+
import { exactlyOneRow, maybeOneRow, withPgPoolTransaction, } from "../db/index.js";
|
|
4
4
|
import { assert } from "tsafe";
|
|
5
5
|
import { PgAdvisoryLock } from "../pg-advisory-lock.js";
|
|
6
6
|
import { useFragment } from "../__generated__/fragment-masking.js";
|
|
@@ -168,7 +168,7 @@ var LocalTakeRequestStatus;
|
|
|
168
168
|
LocalTakeRequestStatus["FAILED"] = "FAILED";
|
|
169
169
|
LocalTakeRequestStatus["REJECTED"] = "REJECTED";
|
|
170
170
|
})(LocalTakeRequestStatus || (LocalTakeRequestStatus = {}));
|
|
171
|
-
export async function processTakeRequests({ abortSignal, controllerId, casinoId, graphqlClient, }) {
|
|
171
|
+
export async function processTakeRequests({ abortSignal, controllerId, casinoId, graphqlClient, pool, }) {
|
|
172
172
|
if (abortSignal.aborted) {
|
|
173
173
|
return;
|
|
174
174
|
}
|
|
@@ -182,15 +182,16 @@ export async function processTakeRequests({ abortSignal, controllerId, casinoId,
|
|
|
182
182
|
mpTakeRequest: takeRequest,
|
|
183
183
|
casinoId,
|
|
184
184
|
graphqlClient,
|
|
185
|
-
pool
|
|
185
|
+
pool,
|
|
186
186
|
});
|
|
187
187
|
}
|
|
188
188
|
await processPendingTransferCompletions({
|
|
189
189
|
casinoId,
|
|
190
190
|
graphqlClient,
|
|
191
191
|
abortSignal,
|
|
192
|
+
pool,
|
|
192
193
|
});
|
|
193
|
-
await processStuckRequests({ casinoId, graphqlClient, abortSignal });
|
|
194
|
+
await processStuckRequests({ casinoId, graphqlClient, abortSignal, pool });
|
|
194
195
|
}
|
|
195
196
|
async function fetchPendingTakeRequests(graphqlClient, controllerId) {
|
|
196
197
|
const result = await graphqlClient.request(MP_PAGINATE_PENDING_TAKE_REQUESTS, {
|
|
@@ -434,11 +435,11 @@ async function attemptTransfer({ pgClient, takeRequestId, mpTakeRequestId, mpExp
|
|
|
434
435
|
return null;
|
|
435
436
|
}
|
|
436
437
|
}
|
|
437
|
-
async function processPendingTransferCompletions({ casinoId, graphqlClient, abortSignal, }) {
|
|
438
|
+
async function processPendingTransferCompletions({ casinoId, graphqlClient, abortSignal, pool, }) {
|
|
438
439
|
if (abortSignal.aborted) {
|
|
439
440
|
return;
|
|
440
441
|
}
|
|
441
|
-
const pendingCompletions = await
|
|
442
|
+
const pendingCompletions = await pool
|
|
442
443
|
.query({
|
|
443
444
|
text: `
|
|
444
445
|
SELECT id, mp_take_request_id, mp_transfer_id, transfer_completion_attempted_at
|
|
@@ -476,7 +477,7 @@ async function processPendingTransferCompletions({ casinoId, graphqlClient, abor
|
|
|
476
477
|
mpTransferId: request.mp_transfer_id,
|
|
477
478
|
graphqlClient,
|
|
478
479
|
casinoId,
|
|
479
|
-
pool
|
|
480
|
+
pool,
|
|
480
481
|
});
|
|
481
482
|
}
|
|
482
483
|
}
|
|
@@ -681,11 +682,11 @@ export async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTrans
|
|
|
681
682
|
}
|
|
682
683
|
});
|
|
683
684
|
}
|
|
684
|
-
async function processStuckRequests({ casinoId, graphqlClient, abortSignal, }) {
|
|
685
|
+
async function processStuckRequests({ casinoId, graphqlClient, abortSignal, pool, }) {
|
|
685
686
|
if (abortSignal.aborted) {
|
|
686
687
|
return;
|
|
687
688
|
}
|
|
688
|
-
const stuckRequests = await
|
|
689
|
+
const stuckRequests = await pool
|
|
689
690
|
.query({
|
|
690
691
|
text: `
|
|
691
692
|
SELECT id, mp_take_request_id
|
|
@@ -710,7 +711,7 @@ async function processStuckRequests({ casinoId, graphqlClient, abortSignal, }) {
|
|
|
710
711
|
mpTakeRequestId: request.mp_take_request_id,
|
|
711
712
|
casinoId,
|
|
712
713
|
graphqlClient,
|
|
713
|
-
pool
|
|
714
|
+
pool,
|
|
714
715
|
});
|
|
715
716
|
}
|
|
716
717
|
}
|