@moneypot/hub 0.0.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.
Files changed (106) hide show
  1. package/README.md +108 -0
  2. package/dist/cli/add-casino.d.ts +2 -0
  3. package/dist/cli/add-casino.js +116 -0
  4. package/dist/dashboard/assets/index-BtrbrisP.js +360 -0
  5. package/dist/dashboard/assets/index-tK7EUtyc.css +5 -0
  6. package/dist/dashboard/index.html +13 -0
  7. package/dist/src/GraphQLError.d.ts +8 -0
  8. package/dist/src/GraphQLError.js +79 -0
  9. package/dist/src/__generated__/fragment-masking.d.ts +19 -0
  10. package/dist/src/__generated__/fragment-masking.js +16 -0
  11. package/dist/src/__generated__/gql.d.ts +26 -0
  12. package/dist/src/__generated__/gql.js +15 -0
  13. package/dist/src/__generated__/graphql.d.ts +3129 -0
  14. package/dist/src/__generated__/graphql.js +454 -0
  15. package/dist/src/__generated__/index.d.ts +2 -0
  16. package/dist/src/__generated__/index.js +2 -0
  17. package/dist/src/config.d.ts +14 -0
  18. package/dist/src/config.js +57 -0
  19. package/dist/src/db/index.d.ts +89 -0
  20. package/dist/src/db/index.js +339 -0
  21. package/dist/src/db/internal.d.ts +7 -0
  22. package/dist/src/db/internal.js +33 -0
  23. package/dist/src/db/public.d.ts +7 -0
  24. package/dist/src/db/public.js +20 -0
  25. package/dist/src/db/types.d.ts +80 -0
  26. package/dist/src/db/types.js +1 -0
  27. package/dist/src/db/util.d.ts +6 -0
  28. package/dist/src/db/util.js +9 -0
  29. package/dist/src/express.d.ts +13 -0
  30. package/dist/src/express.js +1 -0
  31. package/dist/src/grafast.d.ts +1 -0
  32. package/dist/src/grafast.js +1 -0
  33. package/dist/src/graphile.d.ts +1 -0
  34. package/dist/src/graphile.js +1 -0
  35. package/dist/src/graphql-client.d.ts +6 -0
  36. package/dist/src/graphql-client.js +8 -0
  37. package/dist/src/graphql-queries.d.ts +18 -0
  38. package/dist/src/graphql-queries.js +123 -0
  39. package/dist/src/graphql.d.ts +1 -0
  40. package/dist/src/graphql.js +1 -0
  41. package/dist/src/index.d.ts +15 -0
  42. package/dist/src/index.js +65 -0
  43. package/dist/src/logger.d.ts +9 -0
  44. package/dist/src/logger.js +21 -0
  45. package/dist/src/pg-versions/001-schema.sql +456 -0
  46. package/dist/src/plugins/caas-add-casino.d.ts +1 -0
  47. package/dist/src/plugins/caas-add-casino.js +150 -0
  48. package/dist/src/plugins/caas-authenticate.d.ts +1 -0
  49. package/dist/src/plugins/caas-authenticate.js +175 -0
  50. package/dist/src/plugins/caas-balance-alert.d.ts +1 -0
  51. package/dist/src/plugins/caas-balance-alert.js +43 -0
  52. package/dist/src/plugins/caas-claim-faucet.d.ts +1 -0
  53. package/dist/src/plugins/caas-claim-faucet.js +85 -0
  54. package/dist/src/plugins/caas-current-x.d.ts +1 -0
  55. package/dist/src/plugins/caas-current-x.js +62 -0
  56. package/dist/src/plugins/caas-schema-prefix.d.ts +1 -0
  57. package/dist/src/plugins/caas-schema-prefix.js +25 -0
  58. package/dist/src/plugins/caas-user-balance-by-currency.d.ts +1 -0
  59. package/dist/src/plugins/caas-user-balance-by-currency.js +55 -0
  60. package/dist/src/plugins/caas-withdraw.d.ts +1 -0
  61. package/dist/src/plugins/caas-withdraw.js +133 -0
  62. package/dist/src/plugins/debug.d.ts +1 -0
  63. package/dist/src/plugins/debug.js +14 -0
  64. package/dist/src/plugins/hub-add-casino.d.ts +1 -0
  65. package/dist/src/plugins/hub-add-casino.js +150 -0
  66. package/dist/src/plugins/hub-authenticate.d.ts +1 -0
  67. package/dist/src/plugins/hub-authenticate.js +175 -0
  68. package/dist/src/plugins/hub-balance-alert.d.ts +1 -0
  69. package/dist/src/plugins/hub-balance-alert.js +43 -0
  70. package/dist/src/plugins/hub-claim-faucet.d.ts +1 -0
  71. package/dist/src/plugins/hub-claim-faucet.js +85 -0
  72. package/dist/src/plugins/hub-current-x.d.ts +1 -0
  73. package/dist/src/plugins/hub-current-x.js +62 -0
  74. package/dist/src/plugins/hub-schema-prefix.d.ts +1 -0
  75. package/dist/src/plugins/hub-schema-prefix.js +25 -0
  76. package/dist/src/plugins/hub-user-balance-by-currency.d.ts +1 -0
  77. package/dist/src/plugins/hub-user-balance-by-currency.js +55 -0
  78. package/dist/src/plugins/hub-withdraw.d.ts +1 -0
  79. package/dist/src/plugins/hub-withdraw.js +133 -0
  80. package/dist/src/plugins/id-to-node-id.d.ts +1 -0
  81. package/dist/src/plugins/id-to-node-id.js +31 -0
  82. package/dist/src/plugins/validate-fields.d.ts +1 -0
  83. package/dist/src/plugins/validate-fields.js +61 -0
  84. package/dist/src/process-transfers.d.ts +7 -0
  85. package/dist/src/process-transfers.js +413 -0
  86. package/dist/src/process-withdrawal-request.d.ts +5 -0
  87. package/dist/src/process-withdrawal-request.js +129 -0
  88. package/dist/src/server/graphile.config.d.ts +33 -0
  89. package/dist/src/server/graphile.config.js +166 -0
  90. package/dist/src/server/handle-errors.d.ts +10 -0
  91. package/dist/src/server/handle-errors.js +88 -0
  92. package/dist/src/server/index.d.ts +2 -0
  93. package/dist/src/server/index.js +69 -0
  94. package/dist/src/server/middleware/authentication.d.ts +4 -0
  95. package/dist/src/server/middleware/authentication.js +55 -0
  96. package/dist/src/server/middleware/cors.d.ts +3 -0
  97. package/dist/src/server/middleware/cors.js +14 -0
  98. package/dist/src/services/jwt-service.d.ts +13 -0
  99. package/dist/src/services/jwt-service.js +131 -0
  100. package/dist/src/smart-tags.d.ts +1 -0
  101. package/dist/src/smart-tags.js +55 -0
  102. package/dist/src/util.d.ts +12 -0
  103. package/dist/src/util.js +4 -0
  104. package/dist/src/validate.d.ts +9 -0
  105. package/dist/src/validate.js +91 -0
  106. package/package.json +69 -0
@@ -0,0 +1,62 @@
1
+ import { gql, makeExtendSchemaPlugin } from "graphile-utils";
2
+ import { context, inhibitOnNull, lambda } from "postgraphile/grafast";
3
+ export const HubCurrentXPlugin = makeExtendSchemaPlugin((build) => {
4
+ const userTable = build.input.pgRegistry.pgResources.hub_user;
5
+ const casinoTable = build.input.pgRegistry.pgResources.hub_casino;
6
+ const experienceTable = build.input.pgRegistry.pgResources.hub_experience;
7
+ const sessionTable = build.input.pgRegistry.pgResources.hub_session;
8
+ return {
9
+ typeDefs: gql `
10
+ extend type Query {
11
+ hubCurrentUser: HubUser
12
+ hubCurrentCasino: HubCasino
13
+ hubCurrentExperience: HubExperience
14
+ hubCurrentSession: HubSession
15
+ }
16
+ `,
17
+ plans: {
18
+ Query: {
19
+ hubCurrentUser() {
20
+ const $identity = context().get("identity");
21
+ const $userId = lambda($identity, (identity) => {
22
+ if (identity?.kind === "user") {
23
+ return identity.session.user_id;
24
+ }
25
+ return null;
26
+ });
27
+ return userTable.get({ id: inhibitOnNull($userId) });
28
+ },
29
+ hubCurrentCasino() {
30
+ const $identity = context().get("identity");
31
+ const $casinoId = lambda($identity, (identity) => {
32
+ if (identity?.kind === "user") {
33
+ return identity.session.casino_id;
34
+ }
35
+ return null;
36
+ });
37
+ return casinoTable.get({ id: inhibitOnNull($casinoId) });
38
+ },
39
+ hubCurrentExperience() {
40
+ const $identity = context().get("identity");
41
+ const $experienceId = lambda($identity, (identity) => {
42
+ if (identity?.kind === "user") {
43
+ return identity.session.experience_id;
44
+ }
45
+ return null;
46
+ });
47
+ return experienceTable.get({ id: inhibitOnNull($experienceId) });
48
+ },
49
+ hubCurrentSession() {
50
+ const $identity = context().get("identity");
51
+ const $sessionId = lambda($identity, (identity) => {
52
+ if (identity?.kind === "user") {
53
+ return identity.session.session_id;
54
+ }
55
+ return null;
56
+ });
57
+ return sessionTable.get({ id: inhibitOnNull($sessionId) });
58
+ },
59
+ },
60
+ },
61
+ };
62
+ });
@@ -0,0 +1 @@
1
+ export declare const HubPrefixPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,25 @@
1
+ export const HubPrefixPlugin = {
2
+ name: "HubPrefixPlugin",
3
+ version: "1.0.0",
4
+ after: ["PgTablesPlugin"],
5
+ inflection: {
6
+ replace: {
7
+ _schemaPrefix(previous, options, { pgNamespace, serviceName, }) {
8
+ const pgService = options.pgServices?.find((db) => db.name === serviceName);
9
+ const databasePrefix = serviceName === "main" ? "" : `${serviceName}_`;
10
+ let schemaPrefix;
11
+ if (pgNamespace.nspname === "hub" ||
12
+ pgNamespace.nspname.startsWith("hub_")) {
13
+ schemaPrefix = `${pgNamespace.nspname}_`;
14
+ }
15
+ else if (pgNamespace.nspname === pgService?.schemas?.[0]) {
16
+ schemaPrefix = "";
17
+ }
18
+ else {
19
+ schemaPrefix = `${pgNamespace.nspname}_`;
20
+ }
21
+ return `${databasePrefix}${schemaPrefix}`;
22
+ },
23
+ },
24
+ },
25
+ };
@@ -0,0 +1 @@
1
+ export declare const HubUserBalanceByCurrencyPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,55 @@
1
+ import { access, context, loadOne, object, } from "postgraphile/grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { superuserPool } from "../db/index.js";
4
+ import { pgSelectSingleFromRecord, } from "postgraphile/@dataplan/pg";
5
+ export const HubUserBalanceByCurrencyPlugin = makeExtendSchemaPlugin((build) => {
6
+ const balances = build.input.pgRegistry.pgResources.hub_balance;
7
+ return {
8
+ typeDefs: gql `
9
+ extend type HubUser {
10
+ balanceByCurrency(currency: String!): HubBalance
11
+ }
12
+ `,
13
+ plans: {
14
+ HubUser: {
15
+ balanceByCurrency: ($record, { $currency }) => {
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);
25
+ },
26
+ },
27
+ },
28
+ };
29
+ });
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
+ }
@@ -0,0 +1 @@
1
+ export declare const HubWithdrawPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,133 @@
1
+ import { constant, context, object, sideEffect } from "postgraphile/grafast";
2
+ import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
3
+ import { superuserPool, withPgPoolTransaction, } from "../db/index.js";
4
+ import { exactlyOneRow, maybeOneRow } from "../db/util.js";
5
+ import { GraphQLError } from "graphql";
6
+ export const HubWithdrawPlugin = makeExtendSchemaPlugin((build) => {
7
+ const hubWithdrawalRequests = build.input.pgRegistry.pgResources.hub_withdrawal_request;
8
+ return {
9
+ typeDefs: gql `
10
+ input HubWithdrawInput {
11
+ amount: Int!
12
+ currency: String!
13
+ }
14
+
15
+ type HubWithdrawPayload {
16
+ withdrawalRequest: HubWithdrawalRequest!
17
+ query: Query
18
+ }
19
+
20
+ extend type Mutation {
21
+ hubWithdraw(input: HubWithdrawInput!): HubWithdrawPayload
22
+ }
23
+ `,
24
+ plans: {
25
+ Mutation: {
26
+ hubWithdraw(_, { $input }) {
27
+ const $identity = context().get("identity");
28
+ const $withdrawalRequestId = sideEffect([$input, $identity], ([input, identity]) => {
29
+ if (identity?.kind !== "user") {
30
+ throw new GraphQLError("You must be logged in");
31
+ }
32
+ const { session } = identity;
33
+ return withPgPoolTransaction(superuserPool, async (pgClient) => {
34
+ const { amount, currency } = input;
35
+ if (amount <= 0) {
36
+ throw new GraphQLError("Withdraw amount must be greater than zero");
37
+ }
38
+ if (!Number.isInteger(amount)) {
39
+ throw new GraphQLError("Withdraw amount must be an integer");
40
+ }
41
+ const dbCurrency = await pgClient
42
+ .query({
43
+ text: `
44
+ SELECT key
45
+ FROM hub.currency
46
+ WHERE key = $1 AND casino_id = $2
47
+ `,
48
+ values: [currency, session.casino_id],
49
+ })
50
+ .then(maybeOneRow);
51
+ if (!dbCurrency) {
52
+ throw new GraphQLError("Currency not supported");
53
+ }
54
+ const balance = await pgClient
55
+ .query({
56
+ text: `
57
+ select *
58
+ from hub.balance
59
+ where currency_key = $1
60
+ and user_id = $2
61
+ and casino_id = $3
62
+ and experience_id = $4
63
+
64
+ FOR UPDATE
65
+ `,
66
+ values: [
67
+ currency,
68
+ session.user_id,
69
+ session.casino_id,
70
+ session.experience_id,
71
+ ],
72
+ })
73
+ .then(maybeOneRow);
74
+ if (!balance || balance.amount < amount) {
75
+ throw new GraphQLError("Insufficient funds for withdrawal");
76
+ }
77
+ const dbWithdrawalRequest = await pgClient
78
+ .query({
79
+ text: `
80
+ insert into hub.withdrawal_request(
81
+ user_id,
82
+ experience_id,
83
+ casino_id,
84
+ amount,
85
+ currency_key
86
+ )
87
+ values ($1, $2, $3, $4, $5)
88
+ returning id
89
+ `,
90
+ values: [
91
+ session.user_id,
92
+ session.experience_id,
93
+ session.casino_id,
94
+ amount,
95
+ currency,
96
+ ],
97
+ })
98
+ .then(exactlyOneRow);
99
+ await pgClient.query({
100
+ text: `
101
+ update hub.balance
102
+ set amount = amount - $1
103
+ where user_id = $2
104
+ and experience_id = $3
105
+ and currency_key = $4
106
+ and casino_id = $5
107
+ `,
108
+ values: [
109
+ amount,
110
+ session.user_id,
111
+ session.experience_id,
112
+ currency,
113
+ session.casino_id,
114
+ ],
115
+ });
116
+ return dbWithdrawalRequest.id;
117
+ });
118
+ });
119
+ return object({
120
+ withdrawalRequestId: $withdrawalRequestId,
121
+ query: constant(true),
122
+ });
123
+ },
124
+ },
125
+ HubWithdrawPayload: {
126
+ withdrawalRequest($data) {
127
+ const $id = $data.get("withdrawalRequestId");
128
+ return hubWithdrawalRequests.get({ id: $id });
129
+ },
130
+ },
131
+ },
132
+ };
133
+ });
@@ -0,0 +1 @@
1
+ export declare const IdToNodeIdPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,31 @@
1
+ export const IdToNodeIdPlugin = {
2
+ name: "IdToNodeIdPlugin",
3
+ version: "1.0.0",
4
+ inflection: {
5
+ replace: {
6
+ nodeIdFieldName() {
7
+ return "nodeId";
8
+ },
9
+ attribute(previous, options, details) {
10
+ if (!previous) {
11
+ throw new Error("There was no 'attribute' inflector to replace");
12
+ }
13
+ const name = previous(details);
14
+ if (name === "rowId") {
15
+ return "id";
16
+ }
17
+ return name;
18
+ },
19
+ _attributeName(previous, options, details) {
20
+ const { codec, attributeName } = details;
21
+ const attribute = codec.attributes[attributeName];
22
+ const baseName = attribute.extensions?.tags?.name || attributeName;
23
+ const name = previous(details);
24
+ if (baseName === "id" && name === "row_id" && !codec.isAnonymous) {
25
+ return "id";
26
+ }
27
+ return name;
28
+ },
29
+ },
30
+ },
31
+ };
@@ -0,0 +1 @@
1
+ export declare const ValidateCasinoFieldsPlugin: GraphileConfig.Plugin;
@@ -0,0 +1,61 @@
1
+ import { sideEffect } from "postgraphile/grafast";
2
+ import { GraphQLError } from "postgraphile/graphql";
3
+ import { makeWrapPlansPlugin } from "postgraphile/utils";
4
+ import * as v from "../validate.js";
5
+ import * as Yup from "yup";
6
+ function validate(value, schema) {
7
+ try {
8
+ schema.validateSync(value, { strict: true, abortEarly: true });
9
+ }
10
+ catch (e) {
11
+ if (e instanceof Yup.ValidationError) {
12
+ const errorMessage = e.path ? `${e.path}: ${e.errors[0]}` : e.errors[0];
13
+ throw new GraphQLError(errorMessage);
14
+ }
15
+ else {
16
+ throw e;
17
+ }
18
+ }
19
+ }
20
+ const casinoPatchSchema = Yup.object()
21
+ .shape({
22
+ name: Yup.string().trim().min(1),
23
+ graphqlUrl: v.graphqlUrl(),
24
+ baseUrl: v.baseUrl(),
25
+ })
26
+ .strict()
27
+ .noUnknown();
28
+ const addCasinoSchema = Yup.object()
29
+ .shape({
30
+ name: Yup.string().trim().min(1).required(),
31
+ baseUrl: v.baseUrl().required(),
32
+ graphqlUrl: v.graphqlUrl().required(),
33
+ apiKey: v.uuid().required(),
34
+ })
35
+ .strict()
36
+ .noUnknown();
37
+ const updateBankrollSchema = Yup.object()
38
+ .shape({
39
+ amount: Yup.number().integer().min(0).required(),
40
+ })
41
+ .strict()
42
+ .noUnknown();
43
+ export const ValidateCasinoFieldsPlugin = makeWrapPlansPlugin({
44
+ Mutation: {
45
+ updateHubCasinoById: (plan, $source, fieldArgs) => {
46
+ const $patch = fieldArgs.getRaw(["input", "hubCasinoPatch"]);
47
+ sideEffect($patch, (patch) => validate(patch, casinoPatchSchema));
48
+ return plan();
49
+ },
50
+ hubAddCasino: (plan, $source, fieldArgs) => {
51
+ const $input = fieldArgs.getRaw(["input"]);
52
+ sideEffect($input, (input) => validate(input, addCasinoSchema));
53
+ return plan();
54
+ },
55
+ updateHubBankrollById: (plan, $source, fieldArgs) => {
56
+ const $patch = fieldArgs.getRaw(["input", "hubBankrollPatch"]);
57
+ sideEffect($patch, (patch) => validate(patch, updateBankrollSchema));
58
+ return plan();
59
+ },
60
+ },
61
+ });
@@ -0,0 +1,7 @@
1
+ import * as db from "./db/index.js";
2
+ export declare function casinoIdsInProcess(): string[];
3
+ export declare function startTransferProcessor({ casinoId, }: {
4
+ casinoId: db.DbCasino["id"];
5
+ }): void;
6
+ export declare function stopTransferProcessor(casinoId: string): void;
7
+ export declare function initializeTransferProcessors(): void;