@moneypot/hub 1.7.0 → 1.8.0-dev.1

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.
@@ -1,6 +1,8 @@
1
1
  import "dotenv/config";
2
2
  export declare const NODE_ENV: string;
3
3
  export declare const PORT: number;
4
+ export declare const LOG_LEVEL: string;
5
+ export declare const LOG_PRETTY: boolean | undefined;
4
6
  export declare const MP_GRAPHQL_URL: string;
5
7
  export declare const DATABASE_URL: string;
6
8
  export declare const SUPERUSER_DATABASE_URL: string;
@@ -1,13 +1,12 @@
1
1
  import "dotenv/config";
2
2
  import pgConnectionString from "pg-connection-string";
3
- import { logger } from "./logger.js";
4
3
  import { assert } from "tsafe";
5
4
  function getEnvVariable(key, transform = (value) => value) {
6
5
  return transform(process.env[key] || "");
7
6
  }
8
7
  export const NODE_ENV = getEnvVariable("NODE_ENV", (value) => {
9
8
  if (!value) {
10
- logger.warn("Missing NODE_ENV env var. Defaulting to 'development'");
9
+ console.warn("Missing NODE_ENV env var. Defaulting to 'development'");
11
10
  return "development";
12
11
  }
13
12
  return value;
@@ -16,22 +15,57 @@ export const PORT = getEnvVariable("PORT", (value) => {
16
15
  const parsed = Number.parseInt(value, 10);
17
16
  if (!parsed || parsed <= 0 || !Number.isSafeInteger(parsed)) {
18
17
  const DEFAULT_PORT = 4000;
19
- logger.warn(`Warning: PORT missing or invalid, defaulting to ${DEFAULT_PORT}`);
18
+ console.warn(`Warning: PORT missing or invalid, defaulting to ${DEFAULT_PORT}`);
20
19
  return DEFAULT_PORT;
21
20
  }
22
21
  return parsed;
23
22
  });
23
+ const logLevels = [
24
+ "silent",
25
+ "trace",
26
+ "debug",
27
+ "info",
28
+ "warn",
29
+ "error",
30
+ ];
31
+ export const LOG_LEVEL = getEnvVariable("LOG_LEVEL", (value) => {
32
+ if (logLevels.includes(value)) {
33
+ if (value === "silent") {
34
+ console.log("LOG_LEVEL is set to silent. No logging will be done.");
35
+ }
36
+ return value;
37
+ }
38
+ if (value === "") {
39
+ console.log(`Defaulting LOG_LEVEL to "info". (Options: ${logLevels.join(", ")})`);
40
+ return "info";
41
+ }
42
+ console.warn(`Unknown LOG_LEVEL: "${value}". Defaulting to "info".`);
43
+ return "info";
44
+ });
45
+ export const LOG_PRETTY = getEnvVariable("LOG_PRETTY", (value) => {
46
+ switch (value) {
47
+ case "":
48
+ return undefined;
49
+ case "true":
50
+ return true;
51
+ case "false":
52
+ return false;
53
+ default:
54
+ console.warn(`Unknown LOG_PRETTY: "${value}"`);
55
+ return undefined;
56
+ }
57
+ });
24
58
  export const MP_GRAPHQL_URL = getEnvVariable("MP_GRAPHQL_URL", (value) => {
25
59
  if (!value) {
26
- logger.warn("Missing MP_GRAPHQL_URL env var. Defaulting to http://localhost:3000/graphql");
60
+ console.warn("Missing MP_GRAPHQL_URL env var. Defaulting to http://localhost:3000/graphql");
27
61
  return "http://localhost:3000/graphql";
28
62
  }
29
63
  if (!URL.parse(value)) {
30
- logger.warn("MP_GRAPHQL_URL is not a valid URL. Defaulting to http://localhost:3000/graphql");
64
+ console.warn("MP_GRAPHQL_URL is not a valid URL. Defaulting to http://localhost:3000/graphql");
31
65
  }
32
66
  const url = new URL(value);
33
67
  if (url.pathname !== "/graphql") {
34
- logger.warn("MP_GRAPHQL_URL pathname is not '/graphql'. Are you sure it points to a graphql endpoint?");
68
+ console.warn("MP_GRAPHQL_URL pathname is not '/graphql'. Are you sure it points to a graphql endpoint?");
35
69
  }
36
70
  return value;
37
71
  });
@@ -40,11 +74,11 @@ export const DATABASE_URL = getEnvVariable("DATABASE_URL", (value) => {
40
74
  throw new Error(`Missing DATABASE_URL env var.`);
41
75
  }
42
76
  if (!URL.parse(value)) {
43
- logger.warn("DATABASE_URL is not a valid URL.");
77
+ console.warn("DATABASE_URL is not a valid URL.");
44
78
  }
45
79
  const databaseUrlUsername = pgConnectionString.parse(value).user;
46
80
  if (databaseUrlUsername !== "app_postgraphile") {
47
- logger.warn(`DATABASE_URL username is ${databaseUrlUsername}, expected app_postgraphile`);
81
+ console.warn(`DATABASE_URL username is ${databaseUrlUsername}, expected app_postgraphile`);
48
82
  }
49
83
  return value;
50
84
  });
@@ -53,21 +87,21 @@ export const SUPERUSER_DATABASE_URL = getEnvVariable("SUPERUSER_DATABASE_URL", (
53
87
  throw new Error("SUPERUSER_DATABASE_URL env var is required");
54
88
  }
55
89
  if (!URL.parse(value)) {
56
- logger.warn("SUPERUSER_DATABASE_URL is not a valid URL.");
90
+ console.warn("SUPERUSER_DATABASE_URL is not a valid URL.");
57
91
  }
58
92
  return value;
59
93
  });
60
94
  export const HASHCHAINSERVER_URL = getEnvVariable("HASHCHAINSERVER_URL", (value) => {
61
95
  value = value || "mock-server";
62
96
  if (value === "mock-server") {
63
- logger.warn("Using mock-server for HASHCHAINSERVER_URL. This is only allowed in development.");
97
+ console.warn("Using mock-server for HASHCHAINSERVER_URL. This is only allowed in development.");
64
98
  }
65
99
  else if (!URL.parse(value)) {
66
- logger.warn("HASHCHAINSERVER_URL is not a valid URL. It can either be empty, 'mock-server', or URL but it was: " +
100
+ console.warn("HASHCHAINSERVER_URL is not a valid URL. It can either be empty, 'mock-server', or URL but it was: " +
67
101
  value);
68
102
  }
69
103
  if (NODE_ENV !== "development" && value === "mock-server") {
70
- logger.warn("Using mock-server for HASHCHAINSERVER_URL. This is only allowed in development.");
104
+ console.warn("Using mock-server for HASHCHAINSERVER_URL. This is only allowed in development.");
71
105
  }
72
106
  return value;
73
107
  });
@@ -78,7 +112,7 @@ export const HASHCHAINSERVER_MAX_ITERATIONS = getEnvVariable("HASHCHAINSERVER_MA
78
112
  });
79
113
  export const HASHCHAINSERVER_APPLICATION_SECRET = getEnvVariable("HASHCHAINSERVER_APPLICATION_SECRET", (value) => {
80
114
  if (!value && NODE_ENV !== "development") {
81
- logger.warn("Missing HASHCHAINSERVER_APPLICATION_SECRET and NODE_ENV != 'development': To use the hashchain server you must pick a random (but stable) HASHCHAINSERVER_APPLICATION_SECRET for secure communciation with it. (If you aren't using the hashchain server, you can ignore this.)");
115
+ console.warn("Missing HASHCHAINSERVER_APPLICATION_SECRET and NODE_ENV != 'development': To use the hashchain server you must pick a random (but stable) HASHCHAINSERVER_APPLICATION_SECRET for secure communciation with it. (If you aren't using the hashchain server, you can ignore this.)");
82
116
  }
83
117
  return value || "";
84
118
  });
@@ -50,8 +50,8 @@ export async function withPgPoolTransaction(pool, callback, retryCount = 0, maxR
50
50
  await pgClient.query("rollback");
51
51
  }
52
52
  catch (rollbackError) {
53
- logger.error("Original error:", error);
54
- logger.error("Rollback failed:", rollbackError);
53
+ logger.error(error, "Original error");
54
+ logger.error(rollbackError, "Rollback failed");
55
55
  pgClient.release(true);
56
56
  pgClient = null;
57
57
  throw error;
@@ -132,7 +132,7 @@ export async function getTransferCursor(pgClient, { casinoId, }) {
132
132
  return row?.cursor;
133
133
  }
134
134
  export async function setTransferCursor(pgClient, { cursor, casinoId, }) {
135
- console.log(`[setTransferCursor] SETTING CURSOR..... ${cursor}`);
135
+ logger.debug(cursor, `[setTransferCursor] Setting cursor`);
136
136
  await pgClient.query(`
137
137
  insert into hub_hidden.transfer_cursor (casino_id, cursor)
138
138
  values ($1, $2)
@@ -1,5 +1,4 @@
1
1
  import { Express } from "express";
2
- import { Logger } from "./logger.js";
3
2
  import { type PluginIdentity } from "./server/graphile.config.js";
4
3
  declare global {
5
4
  namespace Grafast {
@@ -25,7 +24,6 @@ export type ServerOptions = {
25
24
  extraPgSchemas?: string[];
26
25
  exportSchemaSDLPath?: string;
27
26
  userDatabaseMigrationsPath?: string;
28
- logger?: Logger;
29
27
  };
30
28
  type ListenInfo = {
31
29
  port: number;
package/dist/src/index.js CHANGED
@@ -4,13 +4,10 @@ import * as config from "./config.js";
4
4
  import { createHubServer } from "./server/index.js";
5
5
  import { initializeTransferProcessors } from "./process-transfers/index.js";
6
6
  import { join } from "path";
7
- import { logger, setLogger } from "./logger.js";
7
+ import { logger } from "./logger.js";
8
8
  export { MakeOutcomeBetPlugin, } from "./plugins/hub-make-outcome-bet.js";
9
9
  export { defaultPlugins, } from "./server/graphile.config.js";
10
10
  async function initialize(options) {
11
- if (options.logger) {
12
- setLogger(options.logger);
13
- }
14
11
  if (options.signal.aborted) {
15
12
  logger.info("Initialization aborted by graceful shutdown");
16
13
  return;
@@ -27,9 +24,7 @@ async function initialize(options) {
27
24
  catch (e) {
28
25
  logger.error("Error upgrading core schema", e);
29
26
  if (e instanceof DatabaseAheadError) {
30
- logger.error("⚠️".repeat(80));
31
- logger.error("@moneypot/hub database was reset to prepare for a production release and you must reset your database to continue. Please see <https://www.npmjs.com/package/@moneypot/hub#change-log> for more info.");
32
- logger.error("⚠️".repeat(80));
27
+ logger.error(`${"⚠️".repeat(10)}\n@moneypot/hub database was reset to prepare for a production release and you must reset your database to continue. Please see <https://www.npmjs.com/package/@moneypot/hub#change-log> for more info.`);
33
28
  process.exit(1);
34
29
  }
35
30
  throw e;
@@ -70,7 +65,6 @@ export async function startAndListen(options) {
70
65
  let isShuttingDown = false;
71
66
  await initialize({
72
67
  userDatabaseMigrationsPath: options.userDatabaseMigrationsPath,
73
- logger: options.logger,
74
68
  signal: abortController.signal,
75
69
  });
76
70
  const hubServer = createHubServer({
@@ -82,14 +76,14 @@ export async function startAndListen(options) {
82
76
  });
83
77
  const gracefulShutdown = async () => {
84
78
  if (isShuttingDown) {
85
- console.warn("Already shutting down.");
79
+ logger.warn("Already shutting down.");
86
80
  return;
87
81
  }
88
82
  isShuttingDown = true;
89
- console.log("Shutting down gracefully...");
83
+ logger.info("Shutting down gracefully...");
90
84
  abortController.abort();
91
85
  await new Promise((resolve) => setTimeout(resolve, 500));
92
- console.log("Closing resources...");
86
+ logger.info("Closing resources...");
93
87
  hubServer.shutdown();
94
88
  try {
95
89
  await Promise.race([
@@ -100,10 +94,10 @@ export async function startAndListen(options) {
100
94
  ]),
101
95
  new Promise((_, reject) => setTimeout(() => reject(new Error("Database cleanup timeout")), 3000)),
102
96
  ]);
103
- console.log("Cleanup complete.");
97
+ logger.info("Cleanup complete.");
104
98
  }
105
99
  catch (err) {
106
- console.log("Cleanup error (proceeding anyway):", err instanceof Error ? err.message : err);
100
+ logger.warn(err, "Cleanup error (proceeding anyway)");
107
101
  }
108
102
  process.exit(0);
109
103
  };
@@ -1,9 +1,3 @@
1
- export declare class Logger {
2
- debug(...args: any[]): void;
3
- error(...args: any[]): void;
4
- info(...args: any[]): void;
5
- trace(...args: any[]): void;
6
- warn(...args: any[]): void;
7
- }
8
- export declare let logger: Logger;
9
- export declare function setLogger(instance: Logger): void;
1
+ import { type Logger } from "pino";
2
+ export { type Logger };
3
+ export declare const logger: Logger;
@@ -1,21 +1,22 @@
1
- export class Logger {
2
- debug(...args) {
3
- logger.debug(...args);
1
+ import { pino } from "pino";
2
+ import { LOG_LEVEL, LOG_PRETTY, NODE_ENV } from "./config.js";
3
+ function createLogger(options) {
4
+ const prettify = LOG_PRETTY === undefined ? NODE_ENV === "development" : LOG_PRETTY;
5
+ if (prettify) {
6
+ return pino({
7
+ level: options.level,
8
+ transport: {
9
+ target: "pino-pretty",
10
+ options: {
11
+ colorize: true,
12
+ },
13
+ },
14
+ });
4
15
  }
5
- error(...args) {
6
- logger.error(...args);
16
+ else {
17
+ return pino({
18
+ level: options.level,
19
+ });
7
20
  }
8
- info(...args) {
9
- logger.info(...args);
10
- }
11
- trace(...args) {
12
- logger.trace(...args);
13
- }
14
- warn(...args) {
15
- logger.warn(...args);
16
- }
17
- }
18
- export let logger = console;
19
- export function setLogger(instance) {
20
- logger = instance;
21
21
  }
22
+ export const logger = createLogger({ level: LOG_LEVEL });
@@ -7,7 +7,10 @@ export const DebugPlugin = {
7
7
  hooks: {
8
8
  processGraphQLRequestBody(info, event) {
9
9
  const { body } = event;
10
- logger.debug("GraphQL request:", body.operationName, body.variableValues);
10
+ logger.debug({
11
+ operationName: body.operationName,
12
+ variableValues: body.variableValues,
13
+ }, "GraphQL request");
11
14
  },
12
15
  },
13
16
  },
@@ -61,7 +61,7 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
61
61
  Authorization: `apikey:${apiKey}`,
62
62
  },
63
63
  });
64
- console.log(`[hubAddCasino] Making request to ${graphqlUrl}`);
64
+ logger.info(`[hubAddCasino] Making request to ${graphqlUrl}`);
65
65
  const result = await graphqlClient
66
66
  .request(GET_CURRENT_CONTROLLER)
67
67
  .catch((e) => {
@@ -84,10 +84,6 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
84
84
  returning id
85
85
  `,
86
86
  values: [name, baseUrl, graphqlUrl],
87
- })
88
- .then((res) => {
89
- console.log("res", res.rows);
90
- return res;
91
87
  })
92
88
  .then(exactlyOneRow);
93
89
  }
@@ -105,7 +101,7 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
105
101
  throw new GraphQLError(`Duplicate constraint violation: ${e.constraint}`);
106
102
  }
107
103
  }
108
- logger.error("Error adding casino", e);
104
+ logger.error(e, "Error adding casino");
109
105
  throw e;
110
106
  }
111
107
  await pgClient.query({
@@ -99,7 +99,7 @@ export const HubAuthenticatePlugin = makeExtendSchemaPlugin(() => {
99
99
  });
100
100
  }
101
101
  catch (e) {
102
- logger.error(`[hubAuthenticate] Error when making GET_USER_FROM_USER_TOKEN to casino:`, e);
102
+ logger.error(e, `[hubAuthenticate] Error when making GET_USER_FROM_USER_TOKEN to casino`);
103
103
  if (isGraphQLError(e)) {
104
104
  const errorInfo = extractGraphQLErrorInfo(e);
105
105
  if (errorInfo.code === "UNAUTHENTICATED") {
@@ -143,7 +143,11 @@ export const HubAuthenticatePlugin = makeExtendSchemaPlugin(() => {
143
143
  SET name = EXCLUDED.name
144
144
  RETURNING id
145
145
  `,
146
- values: [casino.id, mpExperience.id, mpExperience.name],
146
+ values: [
147
+ casino.id,
148
+ mpExperience.id,
149
+ mpExperience.name,
150
+ ],
147
151
  })
148
152
  .then(exactlyOneRow);
149
153
  const dbSession = await pgClient
@@ -153,7 +157,12 @@ export const HubAuthenticatePlugin = makeExtendSchemaPlugin(() => {
153
157
  VALUES($1, $2, $3, $4)
154
158
  RETURNING id, key
155
159
  `,
156
- values: [casino.id, userId, dbExperience.id, userToken],
160
+ values: [
161
+ casino.id,
162
+ userId,
163
+ dbExperience.id,
164
+ userToken,
165
+ ],
157
166
  })
158
167
  .then(exactlyOneRow);
159
168
  const ret = {
@@ -172,12 +172,12 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
172
172
  }
173
173
  const minProfit = Math.min(...input.outcomes.map((o) => o.profit));
174
174
  const maxPlayerLoss = Math.abs(input.wager * minProfit);
175
- logger.debug("Determining if player can afford bet", {
175
+ logger.debug({
176
176
  wager: input.wager,
177
177
  minProfit,
178
178
  maxPlayerLoss,
179
179
  dbPlayerBalance,
180
- });
180
+ }, "Determining if player can afford bet");
181
181
  if (dbPlayerBalance.amount < maxPlayerLoss) {
182
182
  if (minProfit === -1) {
183
183
  throw new GraphQLError(`You cannot afford wager`);
@@ -207,7 +207,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
207
207
  finishHashChainInBackground({
208
208
  hashChainId: input.hashChainId,
209
209
  }).catch((e) => {
210
- logger.error("Error finishing hash chain in background", { hashChainId: input.hashChainId, error: e });
210
+ logger.error({ hashChainId: input.hashChainId, error: e }, "Error finishing hash chain in background");
211
211
  });
212
212
  }
213
213
  return {
@@ -393,18 +393,18 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
393
393
  }, "HubMakeOutcomeBetPlugin");
394
394
  }
395
395
  async function finishHashChainInBackground({ hashChainId, }) {
396
- logger.debug("Finishing hash chain in background", { hashChainId });
396
+ logger.debug({ hashChainId }, "Finishing hash chain in background");
397
397
  const preimageHashResult = await getPreimageHash({
398
398
  hashChainId,
399
399
  });
400
- logger.debug("Preimage hash result", { preimageHashResult });
400
+ logger.debug({ preimageHashResult }, "Preimage hash result");
401
401
  if (preimageHashResult.type === "success") {
402
- logger.debug("Inserting preimage hash", {
402
+ logger.debug({
403
403
  hashChainId,
404
404
  kind: DbHashKind.PREIMAGE,
405
405
  digest: preimageHashResult.hash,
406
406
  iteration: 0,
407
- });
407
+ }, "Inserting preimage hash");
408
408
  await withPgPoolTransaction(superuserPool, async (pgClient) => {
409
409
  await dbInsertHubHash(pgClient, {
410
410
  hashChainId,
@@ -424,9 +424,6 @@ async function finishHashChainInBackground({ hashChainId, }) {
424
424
  });
425
425
  }
426
426
  else {
427
- logger.warn("Failed to insert preimage hash in background", {
428
- hashChainId,
429
- error: preimageHashResult,
430
- });
427
+ logger.warn({ hashChainId, error: preimageHashResult }, "Failed to insert preimage hash in background");
431
428
  }
432
429
  }
@@ -2,6 +2,7 @@ import { context, lambda } from "postgraphile/grafast";
2
2
  import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
3
  import { jsonParse } from "postgraphile/@dataplan/json";
4
4
  import { listenWithFilter } from "./listen-with-filter.js";
5
+ import { logger } from "../logger.js";
5
6
  export const HubPutAlertPlugin = makeExtendSchemaPlugin(() => {
6
7
  return {
7
8
  typeDefs: gql `
@@ -31,7 +32,7 @@ export const HubPutAlertPlugin = makeExtendSchemaPlugin(() => {
31
32
  });
32
33
  return listenWithFilter($pgSubscriber, $channelKey, jsonParse, $identity, (item, identity) => {
33
34
  if (typeof item !== "string") {
34
- console.warn(`hubPutAlert: item is not a string: ${JSON.stringify(item)}`);
35
+ logger.warn(item, `hubPutAlert: item is not a string`);
35
36
  return false;
36
37
  }
37
38
  if (identity?.kind !== "user") {
@@ -57,7 +57,7 @@ async function listenForNewCasinos({ signal }) {
57
57
  id: z.string(),
58
58
  });
59
59
  pgClient.on("notification", async (msg) => {
60
- logger.debug(`[listenForNewCasinos] received notification:`, msg);
60
+ logger.debug(msg, `[listenForNewCasinos] received notification`);
61
61
  switch (msg.channel) {
62
62
  case "hub:new_casino": {
63
63
  if (!msg.payload) {
@@ -69,11 +69,11 @@ async function listenForNewCasinos({ signal }) {
69
69
  json = JSON.parse(msg.payload);
70
70
  }
71
71
  catch (error) {
72
- logger.error("Error parsing new casino notification:", error);
72
+ logger.error(error, "Error parsing new casino notification");
73
73
  }
74
74
  const result = NewCasinoPayload.safeParse(json);
75
75
  if (!result.success) {
76
- logger.error("Error parsing new casino notification:", result.error);
76
+ logger.error(result.error, "Error parsing new casino notification");
77
77
  return;
78
78
  }
79
79
  startCasinoTransferProcessor({ casinoId: result.data.id, signal });
@@ -154,7 +154,7 @@ export function startPollingProcessor({ casinoId, signal, }) {
154
154
  }
155
155
  catch (e) {
156
156
  processorState.backoffTime = Math.min(processorState.backoffTime * 2, MAX_BACKOFF_TIME);
157
- logger.error(`transfer processor failed:`, e);
157
+ logger.error(e, `transfer processor failed`);
158
158
  logger.debug(`Next retry for casino ${casinoId} in ${processorState.backoffTime}ms`);
159
159
  }
160
160
  }
@@ -170,7 +170,7 @@ async function processWithdrawals({ abortSignal, casinoId, graphqlClient, }) {
170
170
  limit: 10,
171
171
  });
172
172
  if (withdrawals.length > 0) {
173
- logger.debug(`[sendWithdrawalLoop] withdrawals:`, withdrawals);
173
+ logger.debug(withdrawals, `[sendWithdrawalLoop] withdrawals`);
174
174
  }
175
175
  for (const withdrawal of withdrawals) {
176
176
  if (abortSignal.aborted) {
@@ -54,7 +54,7 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
54
54
  assert(transfer, "Expected transfer");
55
55
  assert(transfer.__typename === "ExperienceTransfer", `Expected ExperienceTransfer but got ${transfer.__typename}`);
56
56
  logger.debug(`processing transfer ${transfer.id} for casino ${casinoId}...`);
57
- logger.debug("transfer", transfer);
57
+ logger.debug(transfer, "transfer");
58
58
  assert(transfer.experienceByExperienceId, "Expected experienceByExperienceId");
59
59
  const isIncoming = controllerId === transfer.toHolderId;
60
60
  const user = isIncoming
@@ -103,10 +103,10 @@ export async function processTransfer({ casinoId, controllerId, transfer, graphq
103
103
  });
104
104
  }
105
105
  catch (e) {
106
- logger.error(`Error sending claimTransfer(${transfer.id}) to ${casinoId}:`, e);
106
+ logger.error(e, `Error sending claimTransfer(${transfer.id}) to ${casinoId}:`);
107
107
  throw e;
108
108
  }
109
- logger.debug("MP_CLAIM_TRANSFER response:", data);
109
+ logger.debug(data, "MP_CLAIM_TRANSFER response");
110
110
  if (data.claimTransfer?.result.__typename !== "ClaimTransferSuccess") {
111
111
  throw new Error(`Failed to claim transfer: ${JSON.stringify(data.claimTransfer)}`);
112
112
  }
@@ -69,13 +69,13 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
69
69
  logger.info(`[websocketProcessor] Disconnected from websocket ${graphqlUrl}`);
70
70
  });
71
71
  client.on("error", (error) => {
72
- logger.error(`[websocketProcessor] Error on websocket ${graphqlUrl}`, error);
72
+ logger.error(error, `[websocketProcessor] Error on websocket ${graphqlUrl}`);
73
73
  });
74
74
  const graphqlClient = createGraphqlClient({ graphqlUrl, apiKey });
75
75
  const dispose1 = createSubscription(client, MP_NEW_EXPERIENCE_TRANSFER, async (result) => {
76
76
  const transferId = result.data?.newExperienceTransfer?.id;
77
77
  if (!transferId) {
78
- logger.warn(`Weird, no transfer id in websocket result`, result);
78
+ logger.warn(result, `Weird, no transfer id in websocket result`);
79
79
  return;
80
80
  }
81
81
  const mpTransfer = await mpGetExperienceTransfer(graphqlClient, transferId);
@@ -94,7 +94,7 @@ export function startWebsocketProcessor({ casinoId, graphqlUrl, signal, controll
94
94
  const dispose2 = createSubscription(client, MP_NEW_TAKE_REQUEST, async (result) => {
95
95
  const mpTakeRequestId = result.data?.newTakeRequest?.id;
96
96
  if (!mpTakeRequestId) {
97
- logger.warn(`Weird, no take request id in websocket result`, result);
97
+ logger.warn(result, `Weird, no take request id in websocket result`);
98
98
  return;
99
99
  }
100
100
  const mpTakeRequest = await mpGetTakeRequest(graphqlClient, mpTakeRequestId);
@@ -118,11 +118,11 @@ function createSubscription(client, query, handler) {
118
118
  return client.subscribe({ query: print(query) }, {
119
119
  next: (result) => {
120
120
  handler(result).catch((e) => {
121
- logger.error(`Error while handling websocket result`, e);
121
+ logger.error(e, `Error while handling websocket result`);
122
122
  });
123
123
  },
124
124
  error: (err) => {
125
- logger.error(`Error during WebSocket subscription`, err);
125
+ logger.error(err, `Error during WebSocket subscription`);
126
126
  },
127
127
  complete: () => logger.info("Subscription closed"),
128
128
  });
@@ -64,7 +64,7 @@ export function createPreset({ plugins, exportSchemaSDLPath, extraPgSchemas, abo
64
64
  mutablePlugins.unshift(requiredPlugin);
65
65
  }
66
66
  }
67
- logger.info("Will save generated graphql schema to:", exportSchemaSDLPath);
67
+ logger.info(`Will save generated graphql schema to ${exportSchemaSDLPath}`);
68
68
  const preset = {
69
69
  extends: [PostGraphileAmberPreset],
70
70
  disablePlugins: ["NodePlugin"],
@@ -233,7 +233,7 @@ export async function processSingleTakeRequest({ mpTakeRequestId, mpTakeRequest,
233
233
  graphqlClient,
234
234
  });
235
235
  }
236
- console.log(`[processSingleTakeRequest] Take request ${mpTakeRequestId} not found in MP or our DB for casino ${casinoId}`);
236
+ logger.info(`[processSingleTakeRequest] Take request ${mpTakeRequestId} not found in MP or our DB for casino ${casinoId}`);
237
237
  return null;
238
238
  });
239
239
  }
@@ -319,7 +319,7 @@ async function processExistingTakeRequest({ pgClient, takeRequest, casinoId, gra
319
319
  assert(pgClient._inTransaction, "pgClient must be in a transaction");
320
320
  switch (takeRequest.status) {
321
321
  case LocalTakeRequestStatus.PENDING:
322
- console.log(`[processExistingTakeRequest] Take request ${takeRequest.id} in PENDING state`);
322
+ logger.info(`[processExistingTakeRequest] Take request ${takeRequest.id} in PENDING state`);
323
323
  break;
324
324
  case LocalTakeRequestStatus.PROCESSING: {
325
325
  const { dbUser, dbExperience, dbCurrency } = await loadRequiredEntities(pgClient, {
@@ -345,16 +345,16 @@ async function processExistingTakeRequest({ pgClient, takeRequest, casinoId, gra
345
345
  });
346
346
  }
347
347
  case LocalTakeRequestStatus.COMPLETED:
348
- console.log(`[processExistingTakeRequest] Take request ${takeRequest.id} already COMPLETED`);
348
+ logger.info(`[processExistingTakeRequest] Take request ${takeRequest.id} already COMPLETED`);
349
349
  break;
350
350
  case LocalTakeRequestStatus.FAILED:
351
- console.log(`[processExistingTakeRequest] Take request ${takeRequest.id} in FAILED state`);
351
+ logger.info(`[processExistingTakeRequest] Take request ${takeRequest.id} in FAILED state`);
352
352
  break;
353
353
  case LocalTakeRequestStatus.REJECTED:
354
- console.log(`[processExistingTakeRequest] Take request ${takeRequest.id} already REJECTED`);
354
+ logger.info(`[processExistingTakeRequest] Take request ${takeRequest.id} already REJECTED`);
355
355
  break;
356
356
  default:
357
- console.error(`[processExistingTakeRequest] Unknown status: ${takeRequest.status}`);
357
+ logger.error(`[processExistingTakeRequest] Unknown status: ${takeRequest.status}`);
358
358
  break;
359
359
  }
360
360
  return null;
@@ -422,7 +422,7 @@ async function attemptTransfer({ pgClient, takeRequestId, mpTakeRequestId, mpExp
422
422
  return transferId;
423
423
  }
424
424
  catch (error) {
425
- console.error(`[attemptTransfer] Error: ${error}`);
425
+ logger.error(error, `[attemptTransfer] Error`);
426
426
  await pgClient.query({
427
427
  text: `
428
428
  UPDATE hub.take_request
@@ -521,7 +521,7 @@ async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTransferId,
521
521
  MpTakeRequestStatus.Transferred,
522
522
  ],
523
523
  });
524
- console.log(`[completeTransfer] Successfully completed transfer ${mpTransferId}`);
524
+ logger.info(`[completeTransfer] Successfully completed transfer ${mpTransferId}`);
525
525
  break;
526
526
  case "InvalidTransferStatus": {
527
527
  const currentStatus = completionResult.currentStatus;
@@ -543,7 +543,7 @@ async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTransferId,
543
543
  MpTakeRequestStatus.Transferred,
544
544
  ],
545
545
  });
546
- console.log(`[completeTransfer] Transfer ${mpTransferId} was already completed`);
546
+ logger.info(`[completeTransfer] Transfer ${mpTransferId} was already completed`);
547
547
  }
548
548
  else if (currentStatus === "CANCELED" ||
549
549
  currentStatus === "EXPIRED") {
@@ -572,15 +572,15 @@ async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTransferId,
572
572
  `MP transfer was ${currentStatus}`,
573
573
  ],
574
574
  });
575
- console.log(`[completeTransfer] Transfer ${mpTransferId} has status ${currentStatus}`);
575
+ logger.info(`[completeTransfer] Transfer ${mpTransferId} has status ${currentStatus}`);
576
576
  }
577
577
  else {
578
- console.log(`[completeTransfer] Transfer ${mpTransferId} has status ${currentStatus}, will retry later`);
578
+ logger.info(`[completeTransfer] Transfer ${mpTransferId} has status ${currentStatus}, will retry later`);
579
579
  }
580
580
  break;
581
581
  }
582
582
  case "InsufficientBalance": {
583
- console.log(`[completeTransfer] Insufficient balance to complete transfer ${mpTransferId}, will retry later`);
583
+ logger.info(`[completeTransfer] Insufficient balance to complete transfer ${mpTransferId}, will retry later`);
584
584
  await pgClient.query({
585
585
  text: `
586
586
  UPDATE hub.take_request
@@ -592,7 +592,7 @@ async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTransferId,
592
592
  break;
593
593
  }
594
594
  case undefined: {
595
- console.error(`[completeTransfer] Unexpected completion result of undefined for transfer ${mpTransferId}`);
595
+ logger.error(`[completeTransfer] Unexpected completion result of undefined for transfer ${mpTransferId}`);
596
596
  await pgClient.query({
597
597
  text: `
598
598
  UPDATE hub.take_request
@@ -610,7 +610,7 @@ async function completeTransfer({ mpTakeRequestId, takeRequestId, mpTransferId,
610
610
  }
611
611
  }
612
612
  catch (e) {
613
- console.error(`[completeTransfer] Error completing transfer ${mpTransferId}:`, e);
613
+ logger.error(e, `[completeTransfer] Error completing transfer ${mpTransferId}`);
614
614
  if (e instanceof Error) {
615
615
  if (isNetworkError(e)) {
616
616
  await pgClient.query({
@@ -682,7 +682,7 @@ async function loadRequiredEntities(pgClient, params) {
682
682
  })
683
683
  .then(maybeOneRow);
684
684
  if (!dbCurrency) {
685
- console.warn(`[loadRequiredEntities] Currency ${currencyKey} not found`);
685
+ logger.warn(`[loadRequiredEntities] Currency ${currencyKey} not found`);
686
686
  return {
687
687
  dbCurrency: null,
688
688
  dbUser: null,
@@ -716,7 +716,7 @@ async function loadRequiredEntities(pgClient, params) {
716
716
  .then(maybeOneRow);
717
717
  }
718
718
  if (!dbUser) {
719
- console.warn(`[loadRequiredEntities] User not found`);
719
+ logger.warn(`[loadRequiredEntities] User not found`);
720
720
  return { dbCurrency, dbUser: null, dbExperience: null, dbBalance: null };
721
721
  }
722
722
  let dbExperience;
@@ -745,7 +745,7 @@ async function loadRequiredEntities(pgClient, params) {
745
745
  .then(maybeOneRow);
746
746
  }
747
747
  if (!dbExperience) {
748
- console.warn(`[loadRequiredEntities] Experience not found`);
748
+ logger.warn(`[loadRequiredEntities] Experience not found`);
749
749
  return { dbCurrency, dbUser, dbExperience: null, dbBalance: null };
750
750
  }
751
751
  let dbBalance = null;
@@ -771,7 +771,7 @@ async function loadRequiredEntities(pgClient, params) {
771
771
  async function rejectMpTakeRequest(pgClient, graphqlClient, mpTakeRequestId, takeRequestId) {
772
772
  assert(pgClient._inTransaction, "pgClient must be in a transaction");
773
773
  try {
774
- console.log(`[rejectMpTakeRequest] Rejecting take request ${mpTakeRequestId}`);
774
+ logger.info(`[rejectMpTakeRequest] Rejecting take request ${mpTakeRequestId}`);
775
775
  const rejectResult = await graphqlClient.request(MP_REJECT_TAKE_REQUEST, {
776
776
  mpTakeRequestId,
777
777
  });
@@ -841,7 +841,7 @@ async function rejectMpTakeRequest(pgClient, graphqlClient, mpTakeRequestId, tak
841
841
  return success;
842
842
  }
843
843
  catch (error) {
844
- console.error(`[rejectMpTakeRequest] Error: ${error}`);
844
+ logger.error(error, `[rejectMpTakeRequest] Error`);
845
845
  return false;
846
846
  }
847
847
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.7.0",
3
+ "version": "1.8.0-dev.1",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [
@@ -56,6 +56,7 @@
56
56
  "jose": "^6.0.11",
57
57
  "pg": "^8.12.0",
58
58
  "pg-connection-string": "^2.6.4",
59
+ "pino": "^9.7.0",
59
60
  "postgraphile": "^5.0.0-beta.42",
60
61
  "tsafe": "^1.6.6",
61
62
  "yup": "^1.6.1",
@@ -72,6 +73,7 @@
72
73
  "@types/supertest": "^6.0.2",
73
74
  "eslint": "^9.8.0",
74
75
  "globals": "^16.0.0",
76
+ "pino-pretty": "^13.0.0",
75
77
  "supertest": "^7.0.0",
76
78
  "tsx": "^4.20.3",
77
79
  "typescript": "^5.4.5",