@moneypot/hub 1.4.9 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -1
- package/dist/src/hash-chain/index.d.ts +1 -1
- package/dist/src/hash-chain/index.js +1 -1
- package/dist/src/hash-chain/plugins/hub-bad-hash-chain-error.js +7 -5
- package/dist/src/hash-chain/plugins/hub-create-hash-chain.js +42 -40
- package/dist/src/hash-chain/plugins/hub-user-active-hash-chain.js +19 -17
- package/dist/src/hash-chain/util.d.ts +1 -3
- package/dist/src/hash-chain/util.js +2 -3
- package/dist/src/index.d.ts +1 -1
- package/dist/src/plugins/hub-add-casino.js +89 -87
- package/dist/src/plugins/hub-authenticate.js +120 -118
- package/dist/src/plugins/hub-balance-alert.js +23 -19
- package/dist/src/plugins/hub-claim-faucet.js +43 -39
- package/dist/src/plugins/hub-current-x.js +43 -41
- package/dist/src/plugins/hub-make-outcome-bet.js +230 -227
- package/dist/src/plugins/hub-put-alert.js +38 -34
- package/dist/src/plugins/hub-user-balance-by-currency.js +9 -7
- package/dist/src/plugins/hub-withdraw.js +72 -68
- package/dist/src/server/graphile.config.d.ts +0 -11
- package/dist/src/server/graphile.config.js +5 -5
- package/package.json +4 -4
|
@@ -45,150 +45,152 @@ export const HubAuthenticatePlugin = makeExtendSchemaPlugin(() => {
|
|
|
45
45
|
hubAuthenticate(input: HubAuthenticateInput!): HubAuthenticatePayload
|
|
46
46
|
}
|
|
47
47
|
`,
|
|
48
|
-
|
|
48
|
+
objects: {
|
|
49
49
|
Mutation: {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
catch (e) {
|
|
60
|
-
if (e instanceof z.ZodError) {
|
|
61
|
-
throw new GraphQLError(e.errors[0].message);
|
|
50
|
+
plans: {
|
|
51
|
+
hubAuthenticate(_, { $input }) {
|
|
52
|
+
try {
|
|
53
|
+
const $context = context();
|
|
54
|
+
const $success = sideEffect([$input, $context], ([rawInput, context]) => {
|
|
55
|
+
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
56
|
+
let input;
|
|
57
|
+
try {
|
|
58
|
+
input = InputSchema.parse(rawInput);
|
|
62
59
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
catch (e) {
|
|
61
|
+
if (e instanceof z.ZodError) {
|
|
62
|
+
throw new GraphQLError(e.errors[0].message);
|
|
63
|
+
}
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
const { userToken: jwt, casinoBaseUrl } = input;
|
|
67
|
+
const casino = await pgClient
|
|
68
|
+
.query({
|
|
69
|
+
text: `
|
|
69
70
|
SELECT c.*, s.api_key
|
|
70
71
|
FROM hub.casino c
|
|
71
72
|
LEFT JOIN hub.casino_secret s ON c.id = s.id
|
|
72
73
|
WHERE c.base_url = $1`,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
86
|
-
const verifyResult = await jwtService.verifyJwtFromDbCacheAndEnsureNotAlreadyUsed(pgClient, {
|
|
87
|
-
casinoId: casino.id,
|
|
88
|
-
jwt,
|
|
89
|
-
});
|
|
90
|
-
if (!verifyResult.ok) {
|
|
91
|
-
throw new GraphQLError(`Error verifying userToken: ${verifyResult.error}`);
|
|
92
|
-
}
|
|
93
|
-
const { userToken } = verifyResult.value;
|
|
94
|
-
let res;
|
|
95
|
-
try {
|
|
96
|
-
res = await graphqlClient.request(GET_USER_FROM_USER_TOKEN, {
|
|
97
|
-
token: userToken,
|
|
74
|
+
values: [casinoBaseUrl],
|
|
75
|
+
})
|
|
76
|
+
.then(maybeOneRow);
|
|
77
|
+
if (!casino) {
|
|
78
|
+
throw new GraphQLError(`hub server is unaware of casino with a base url of provided casinoBaseUrl`);
|
|
79
|
+
}
|
|
80
|
+
if (!casino.api_key) {
|
|
81
|
+
throw new GraphQLError("Casino secret not configured");
|
|
82
|
+
}
|
|
83
|
+
const graphqlClient = createGraphqlClient({
|
|
84
|
+
graphqlUrl: casino.graphql_url,
|
|
85
|
+
apiKey: casino.api_key,
|
|
98
86
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
87
|
+
const verifyResult = await jwtService.verifyJwtFromDbCacheAndEnsureNotAlreadyUsed(pgClient, {
|
|
88
|
+
casinoId: casino.id,
|
|
89
|
+
jwt,
|
|
90
|
+
});
|
|
91
|
+
if (!verifyResult.ok) {
|
|
92
|
+
throw new GraphQLError(`Error verifying userToken: ${verifyResult.error}`);
|
|
93
|
+
}
|
|
94
|
+
const { userToken } = verifyResult.value;
|
|
95
|
+
let res;
|
|
96
|
+
try {
|
|
97
|
+
res = await graphqlClient.request(GET_USER_FROM_USER_TOKEN, {
|
|
98
|
+
token: userToken,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
logger.error(`[hubAuthenticate] Error when making GET_USER_FROM_USER_TOKEN to casino:`, e);
|
|
103
|
+
if (isGraphQLError(e)) {
|
|
104
|
+
const errorInfo = extractGraphQLErrorInfo(e);
|
|
105
|
+
if (errorInfo.code === "UNAUTHENTICATED") {
|
|
106
|
+
throw new GraphQLError("Invalid api key");
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw new GraphQLError(errorInfo.message);
|
|
110
|
+
}
|
|
109
111
|
}
|
|
112
|
+
throw error;
|
|
110
113
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
.query({
|
|
123
|
-
text: `
|
|
114
|
+
const result = res.userFromUserToken;
|
|
115
|
+
if (!result || !result.user || !result.experience) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const mpUserId = result.user.id;
|
|
119
|
+
assert(mpUserId);
|
|
120
|
+
const uname = result.user.uname;
|
|
121
|
+
assert(uname);
|
|
122
|
+
const dbUser = await pgClient
|
|
123
|
+
.query({
|
|
124
|
+
text: `
|
|
124
125
|
INSERT INTO hub.user(casino_id, mp_user_id, uname)
|
|
125
126
|
VALUES($1, $2, $3)
|
|
126
127
|
ON CONFLICT (casino_id, mp_user_id) DO UPDATE
|
|
127
128
|
SET uname = EXCLUDED.uname
|
|
128
129
|
RETURNING id, uname
|
|
129
130
|
`,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
131
|
+
values: [casino.id, mpUserId, uname],
|
|
132
|
+
})
|
|
133
|
+
.then(exactlyOneRow);
|
|
134
|
+
const userId = dbUser.id;
|
|
135
|
+
const mpExperience = result.experience;
|
|
136
|
+
assert(mpExperience);
|
|
137
|
+
const dbExperience = await pgClient
|
|
138
|
+
.query({
|
|
139
|
+
text: `
|
|
139
140
|
INSERT INTO hub.experience(casino_id, mp_experience_id, name)
|
|
140
141
|
VALUES($1, $2, $3)
|
|
141
142
|
ON CONFLICT (casino_id, mp_experience_id) DO UPDATE
|
|
142
143
|
SET name = EXCLUDED.name
|
|
143
144
|
RETURNING id
|
|
144
145
|
`,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
values: [casino.id, mpExperience.id, mpExperience.name],
|
|
147
|
+
})
|
|
148
|
+
.then(exactlyOneRow);
|
|
149
|
+
const dbSession = await pgClient
|
|
150
|
+
.query({
|
|
151
|
+
text: `
|
|
151
152
|
INSERT INTO hub.session(casino_id, user_id, experience_id, user_token)
|
|
152
153
|
VALUES($1, $2, $3, $4)
|
|
153
154
|
RETURNING id, key
|
|
154
155
|
`,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
156
|
+
values: [casino.id, userId, dbExperience.id, userToken],
|
|
157
|
+
})
|
|
158
|
+
.then(exactlyOneRow);
|
|
159
|
+
const ret = {
|
|
160
|
+
userId,
|
|
161
|
+
uname: dbUser.uname,
|
|
162
|
+
experienceId: dbExperience.id,
|
|
163
|
+
sessionKey: dbSession.key,
|
|
164
|
+
};
|
|
165
|
+
context.identity = {
|
|
166
|
+
kind: "user",
|
|
167
|
+
session: {
|
|
168
|
+
user_id: userId,
|
|
169
|
+
mp_user_id: mpUserId,
|
|
170
|
+
casino_id: casino.id,
|
|
171
|
+
experience_id: dbExperience.id,
|
|
172
|
+
session_id: dbSession.id,
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
context.pgSettings = {
|
|
176
|
+
"session.user_id": userId,
|
|
177
|
+
"session.casino_id": casino.id,
|
|
178
|
+
"session.experience_id": dbExperience.id,
|
|
179
|
+
"session.session_id": dbSession.id,
|
|
180
|
+
};
|
|
181
|
+
return ret;
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
return object({
|
|
185
|
+
query: constant(true),
|
|
186
|
+
success: $success,
|
|
181
187
|
});
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
logger.error(error);
|
|
190
|
-
throw error;
|
|
191
|
-
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
logger.error(error);
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
},
|
|
192
194
|
},
|
|
193
195
|
},
|
|
194
196
|
},
|
|
@@ -12,30 +12,34 @@ export const HubBalanceAlertPlugin = makeExtendSchemaPlugin(() => {
|
|
|
12
12
|
currencyKey: String
|
|
13
13
|
}
|
|
14
14
|
`,
|
|
15
|
-
|
|
15
|
+
objects: {
|
|
16
16
|
Subscription: {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
plans: {
|
|
18
|
+
hubBalanceAlert: {
|
|
19
|
+
subscribePlan(_$root) {
|
|
20
|
+
const $pgSubscriber = context().get("pgSubscriber");
|
|
21
|
+
const $identity = context().get("identity");
|
|
22
|
+
const $channelKey = lambda($identity, (identity) => {
|
|
23
|
+
if (identity?.kind === "user") {
|
|
24
|
+
return `hub:user:${identity.session.user_id}:balance_alert`;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return listen($pgSubscriber, $channelKey, jsonParse);
|
|
31
|
+
},
|
|
32
|
+
plan($event) {
|
|
33
|
+
return $event;
|
|
34
|
+
},
|
|
33
35
|
},
|
|
34
36
|
},
|
|
35
37
|
},
|
|
36
38
|
HubBalanceAlertPayload: {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
plans: {
|
|
40
|
+
currencyKey($event) {
|
|
41
|
+
return $event.get("currency_key");
|
|
42
|
+
},
|
|
39
43
|
},
|
|
40
44
|
},
|
|
41
45
|
},
|
|
@@ -16,59 +16,63 @@ export const HubClaimFaucetPlugin = makeExtendSchemaPlugin(() => {
|
|
|
16
16
|
hubClaimFaucet: HubClaimFaucetPayload
|
|
17
17
|
}
|
|
18
18
|
`,
|
|
19
|
-
|
|
19
|
+
objects: {
|
|
20
20
|
Mutation: {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
plans: {
|
|
22
|
+
hubClaimFaucet() {
|
|
23
|
+
const $identity = context().get("identity");
|
|
24
|
+
const $result = sideEffect([$identity], ([identity]) => {
|
|
25
|
+
if (identity?.kind !== "user") {
|
|
26
|
+
throw new Error("Must be logged in as user");
|
|
27
|
+
}
|
|
28
|
+
const { session } = identity;
|
|
29
|
+
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
30
|
+
await upsertPlayCurrency(pgClient, session.casino_id);
|
|
31
|
+
await pgClient.query({
|
|
32
|
+
text: `
|
|
32
33
|
insert into hub.faucet_claim (user_id, casino_id, experience_id, currency_key, amount)
|
|
33
34
|
values ($1, $2, $3, $4, $5)
|
|
34
35
|
`,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
values: [
|
|
37
|
+
session.user_id,
|
|
38
|
+
session.casino_id,
|
|
39
|
+
session.experience_id,
|
|
40
|
+
"PLAY",
|
|
41
|
+
CLAIM_AMOUNT,
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
await pgClient.query({
|
|
45
|
+
text: `
|
|
45
46
|
INSERT INTO hub.balance (user_id, experience_id, casino_id, currency_key, amount)
|
|
46
47
|
VALUES ($1, $2, $3, $4, $5)
|
|
47
48
|
ON CONFLICT (user_id, experience_id, casino_id, currency_key) DO UPDATE
|
|
48
49
|
SET amount = balance.amount + EXCLUDED.amount
|
|
49
50
|
`,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
values: [
|
|
52
|
+
session.user_id,
|
|
53
|
+
session.experience_id,
|
|
54
|
+
session.casino_id,
|
|
55
|
+
"PLAY",
|
|
56
|
+
CLAIM_AMOUNT,
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
return true;
|
|
57
60
|
});
|
|
58
|
-
return true;
|
|
59
61
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
62
|
+
return object({
|
|
63
|
+
result: $result,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
64
66
|
},
|
|
65
67
|
},
|
|
66
68
|
HubClaimFaucetPayload: {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
plans: {
|
|
70
|
+
success($data) {
|
|
71
|
+
return $data.get("result");
|
|
72
|
+
},
|
|
73
|
+
query() {
|
|
74
|
+
return constant(true);
|
|
75
|
+
},
|
|
72
76
|
},
|
|
73
77
|
},
|
|
74
78
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { gql, makeExtendSchemaPlugin } from "
|
|
1
|
+
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
2
2
|
import { context, inhibitOnNull, lambda } from "postgraphile/grafast";
|
|
3
3
|
export const HubCurrentXPlugin = makeExtendSchemaPlugin((build) => {
|
|
4
4
|
const userTable = build.input.pgRegistry.pgResources.hub_user;
|
|
@@ -14,47 +14,49 @@ export const HubCurrentXPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
14
14
|
hubCurrentSession: HubSession
|
|
15
15
|
}
|
|
16
16
|
`,
|
|
17
|
-
|
|
17
|
+
objects: {
|
|
18
18
|
Query: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
19
|
+
plans: {
|
|
20
|
+
hubCurrentUser() {
|
|
21
|
+
const $identity = context().get("identity");
|
|
22
|
+
const $userId = lambda($identity, (identity) => {
|
|
23
|
+
if (identity?.kind === "user") {
|
|
24
|
+
return identity.session.user_id;
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
});
|
|
28
|
+
return userTable.get({ id: inhibitOnNull($userId) });
|
|
29
|
+
},
|
|
30
|
+
hubCurrentCasino() {
|
|
31
|
+
const $identity = context().get("identity");
|
|
32
|
+
const $casinoId = lambda($identity, (identity) => {
|
|
33
|
+
if (identity?.kind === "user") {
|
|
34
|
+
return identity.session.casino_id;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
});
|
|
38
|
+
return casinoTable.get({ id: inhibitOnNull($casinoId) });
|
|
39
|
+
},
|
|
40
|
+
hubCurrentExperience() {
|
|
41
|
+
const $identity = context().get("identity");
|
|
42
|
+
const $experienceId = lambda($identity, (identity) => {
|
|
43
|
+
if (identity?.kind === "user") {
|
|
44
|
+
return identity.session.experience_id;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
});
|
|
48
|
+
return experienceTable.get({ id: inhibitOnNull($experienceId) });
|
|
49
|
+
},
|
|
50
|
+
hubCurrentSession() {
|
|
51
|
+
const $identity = context().get("identity");
|
|
52
|
+
const $sessionId = lambda($identity, (identity) => {
|
|
53
|
+
if (identity?.kind === "user") {
|
|
54
|
+
return identity.session.session_id;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
});
|
|
58
|
+
return sessionTable.get({ id: inhibitOnNull($sessionId) });
|
|
59
|
+
},
|
|
58
60
|
},
|
|
59
61
|
},
|
|
60
62
|
},
|