@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access, context, object, ObjectStep,
|
|
1
|
+
import { access, context, object, ObjectStep, sideEffect, } from "postgraphile/grafast";
|
|
2
2
|
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { GraphQLError } from "graphql";
|
|
@@ -98,167 +98,168 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
98
98
|
`;
|
|
99
99
|
return {
|
|
100
100
|
typeDefs,
|
|
101
|
-
|
|
101
|
+
objects: {
|
|
102
102
|
Mutation: {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
let input;
|
|
110
|
-
let betKind;
|
|
111
|
-
try {
|
|
112
|
-
input = InputSchema.parse(rawInput);
|
|
113
|
-
betKind = BetKindSchema.parse(rawInput.kind);
|
|
114
|
-
}
|
|
115
|
-
catch (e) {
|
|
116
|
-
if (e instanceof z.ZodError) {
|
|
117
|
-
throw new GraphQLError(e.errors[0].message);
|
|
103
|
+
plans: {
|
|
104
|
+
hubMakeOutcomeBet: (_, { $input }) => {
|
|
105
|
+
const $identity = context().get("identity");
|
|
106
|
+
const $result = sideEffect([$identity, $input], async ([identity, rawInput]) => {
|
|
107
|
+
if (identity?.kind !== "user") {
|
|
108
|
+
throw new GraphQLError("Unauthorized");
|
|
118
109
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
if (!betConfig.allowLossBeyondWager) {
|
|
126
|
-
const minProfit = Math.min(...input.outcomes.map((o) => o.profit));
|
|
127
|
-
if (minProfit < -1) {
|
|
128
|
-
throw new GraphQLError(`Loss beyond wager not allowed: outcome profit must be >= -1`);
|
|
110
|
+
let input;
|
|
111
|
+
let betKind;
|
|
112
|
+
try {
|
|
113
|
+
input = InputSchema.parse(rawInput);
|
|
114
|
+
betKind = BetKindSchema.parse(rawInput.kind);
|
|
129
115
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
116
|
+
catch (e) {
|
|
117
|
+
if (e instanceof z.ZodError) {
|
|
118
|
+
throw new GraphQLError(e.errors[0].message);
|
|
119
|
+
}
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
const betConfig = betConfigs[betKind];
|
|
123
|
+
if (!betConfig) {
|
|
124
|
+
throw new GraphQLError(`Invalid bet kind`);
|
|
125
|
+
}
|
|
126
|
+
if (!betConfig.allowLossBeyondWager) {
|
|
127
|
+
const minProfit = Math.min(...input.outcomes.map((o) => o.profit));
|
|
128
|
+
if (minProfit < -1) {
|
|
129
|
+
throw new GraphQLError(`Loss beyond wager not allowed: outcome profit must be >= -1`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
let initializedMetadata;
|
|
133
|
+
if (betConfig.initializeMetadataFromUntrustedUserInput) {
|
|
134
|
+
const result = betConfig.initializeMetadataFromUntrustedUserInput(input);
|
|
135
|
+
if (result.ok) {
|
|
136
|
+
initializedMetadata = result.value;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
throw new GraphQLError(`Invalid input: ${result.error}`);
|
|
140
|
+
}
|
|
136
141
|
}
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
const houseEV = calculateHouseEV(input.outcomes);
|
|
143
|
+
const minHouseEV = Math.max(0, betConfig.houseEdge - FLOAT_EPSILON);
|
|
144
|
+
if (houseEV < minHouseEV) {
|
|
145
|
+
throw new GraphQLError(`No deal. House EV too low: ${houseEV.toFixed(4)}`);
|
|
139
146
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
throw new GraphQLError(`No deal. House EV too low: ${houseEV.toFixed(4)}`);
|
|
145
|
-
}
|
|
146
|
-
const { session } = identity;
|
|
147
|
-
const dbCurrency = await superuserPool
|
|
148
|
-
.query({
|
|
149
|
-
text: `
|
|
147
|
+
const { session } = identity;
|
|
148
|
+
const dbCurrency = await superuserPool
|
|
149
|
+
.query({
|
|
150
|
+
text: `
|
|
150
151
|
SELECT key
|
|
151
152
|
FROM hub.currency
|
|
152
153
|
WHERE key = $1
|
|
153
154
|
AND casino_id = $2
|
|
154
155
|
`,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
162
|
-
const { dbPlayerBalance, dbHouseBankroll, found } = await dbLockPlayerBalanceAndHouseBankroll(pgClient, {
|
|
163
|
-
userId: session.user_id,
|
|
164
|
-
casinoId: session.casino_id,
|
|
165
|
-
experienceId: session.experience_id,
|
|
166
|
-
currencyKey: dbCurrency.key,
|
|
167
|
-
});
|
|
168
|
-
if (!found) {
|
|
169
|
-
throw new GraphQLError("No balance entry found for player or house");
|
|
156
|
+
values: [input.currency, session.casino_id],
|
|
157
|
+
})
|
|
158
|
+
.then(maybeOneRow);
|
|
159
|
+
if (!dbCurrency) {
|
|
160
|
+
throw new GraphQLError("Currency not found");
|
|
170
161
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (minProfit === -1) {
|
|
181
|
-
throw new GraphQLError(`You cannot afford wager`);
|
|
162
|
+
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
163
|
+
const { dbPlayerBalance, dbHouseBankroll, found } = await dbLockPlayerBalanceAndHouseBankroll(pgClient, {
|
|
164
|
+
userId: session.user_id,
|
|
165
|
+
casinoId: session.casino_id,
|
|
166
|
+
experienceId: session.experience_id,
|
|
167
|
+
currencyKey: dbCurrency.key,
|
|
168
|
+
});
|
|
169
|
+
if (!found) {
|
|
170
|
+
throw new GraphQLError("No balance entry found for player or house");
|
|
182
171
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
197
|
-
if (!dbHashChain || !dbHashChain.active) {
|
|
198
|
-
return {
|
|
199
|
-
__typename: "HubBadHashChainError",
|
|
200
|
-
message: "Active hash chain not found",
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
if (dbHashChain.current_iteration <= 1) {
|
|
204
|
-
if (dbHashChain.current_iteration === 1) {
|
|
205
|
-
finishHashChainInBackground({
|
|
206
|
-
hashChainId: input.hashChainId,
|
|
207
|
-
}).catch((e) => {
|
|
208
|
-
console.error("Error finishing hash chain in background", { hashChainId: input.hashChainId, error: e });
|
|
209
|
-
});
|
|
172
|
+
const minProfit = Math.min(...input.outcomes.map((o) => o.profit));
|
|
173
|
+
const maxPlayerLoss = Math.abs(input.wager * minProfit);
|
|
174
|
+
console.log("Determining if player can afford bet", {
|
|
175
|
+
wager: input.wager,
|
|
176
|
+
minProfit,
|
|
177
|
+
maxPlayerLoss,
|
|
178
|
+
dbPlayerBalance,
|
|
179
|
+
});
|
|
180
|
+
if (dbPlayerBalance.amount < maxPlayerLoss) {
|
|
181
|
+
if (minProfit === -1) {
|
|
182
|
+
throw new GraphQLError(`You cannot afford wager`);
|
|
183
|
+
}
|
|
184
|
+
throw new GraphQLError("You cannot afford the worst outcome");
|
|
210
185
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
break;
|
|
225
|
-
case "bad_hash_chain":
|
|
186
|
+
const maxProfitMultiplier = Math.max(...input.outcomes.map((o) => o.profit));
|
|
187
|
+
const maxPotentialPayout = input.wager * maxProfitMultiplier;
|
|
188
|
+
const maxAllowablePayout = dbHouseBankroll.amount * 0.01;
|
|
189
|
+
if (maxPotentialPayout > maxAllowablePayout) {
|
|
190
|
+
throw new GraphQLError(`House risk limit exceeded. Max payout: ${maxPotentialPayout.toFixed(4)}`);
|
|
191
|
+
}
|
|
192
|
+
const dbHashChain = await dbLockHubHashChain(pgClient, {
|
|
193
|
+
userId: session.user_id,
|
|
194
|
+
experienceId: session.experience_id,
|
|
195
|
+
casinoId: session.casino_id,
|
|
196
|
+
hashChainId: input.hashChainId,
|
|
197
|
+
});
|
|
198
|
+
if (!dbHashChain || !dbHashChain.active) {
|
|
226
199
|
return {
|
|
227
200
|
__typename: "HubBadHashChainError",
|
|
228
|
-
message: "
|
|
201
|
+
message: "Active hash chain not found",
|
|
229
202
|
};
|
|
230
|
-
default: {
|
|
231
|
-
const _exhaustiveCheck = betHashResult;
|
|
232
|
-
throw new Error(`Unknown bet hash result: ${_exhaustiveCheck}`);
|
|
233
203
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
204
|
+
if (dbHashChain.current_iteration <= 1) {
|
|
205
|
+
if (dbHashChain.current_iteration === 1) {
|
|
206
|
+
finishHashChainInBackground({
|
|
207
|
+
hashChainId: input.hashChainId,
|
|
208
|
+
}).catch((e) => {
|
|
209
|
+
console.error("Error finishing hash chain in background", { hashChainId: input.hashChainId, error: e });
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
__typename: "HubBadHashChainError",
|
|
214
|
+
message: "Hash chain drained. Create a new one.",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
const betHashIteration = dbHashChain.current_iteration - 1;
|
|
218
|
+
assert(betHashIteration > 0, "Bet hash iteration must be > 0");
|
|
219
|
+
const betHashResult = await getIntermediateHash({
|
|
220
|
+
hashChainId: input.hashChainId,
|
|
221
|
+
iteration: betHashIteration,
|
|
222
|
+
});
|
|
223
|
+
switch (betHashResult.type) {
|
|
224
|
+
case "success":
|
|
225
|
+
break;
|
|
226
|
+
case "bad_hash_chain":
|
|
227
|
+
return {
|
|
228
|
+
__typename: "HubBadHashChainError",
|
|
229
|
+
message: "Hash chain not found",
|
|
230
|
+
};
|
|
231
|
+
default: {
|
|
232
|
+
const _exhaustiveCheck = betHashResult;
|
|
233
|
+
throw new Error(`Unknown bet hash result: ${_exhaustiveCheck}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const dbHash = await dbInsertHubHash(pgClient, {
|
|
237
|
+
hashChainId: dbHashChain.id,
|
|
238
|
+
kind: DbHashKind.INTERMEDIATE,
|
|
239
|
+
digest: betHashResult.hash,
|
|
240
|
+
iteration: betHashIteration,
|
|
241
|
+
clientSeed: input.clientSeed,
|
|
242
|
+
});
|
|
243
|
+
const result = await pgClient.query(`
|
|
243
244
|
UPDATE hub.hash_chain
|
|
244
245
|
SET current_iteration = $2
|
|
245
246
|
WHERE id = $1
|
|
246
247
|
`, [dbHashChain.id, betHashIteration]);
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
248
|
+
if (result.rowCount !== 1) {
|
|
249
|
+
throw new GraphQLError("Failed to update hash chain iteration");
|
|
250
|
+
}
|
|
251
|
+
const finalHash = makeFinalHash({
|
|
252
|
+
serverHash: betHashResult.hash,
|
|
253
|
+
clientSeed: input.clientSeed,
|
|
254
|
+
});
|
|
255
|
+
const { outcomeIdx, roll } = pickRandomOutcome({
|
|
256
|
+
outcomes: input.outcomes,
|
|
257
|
+
finalHash: finalHash,
|
|
258
|
+
}, FLOAT_EPSILON);
|
|
259
|
+
const outcome = input.outcomes[outcomeIdx];
|
|
260
|
+
const netPlayerAmount = input.wager * outcome.profit;
|
|
261
|
+
await pgClient.query({
|
|
262
|
+
text: `
|
|
262
263
|
UPDATE hub.balance
|
|
263
264
|
SET amount = amount + $1
|
|
264
265
|
WHERE user_id = $2
|
|
@@ -266,16 +267,16 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
266
267
|
AND experience_id = $4
|
|
267
268
|
AND currency_key = $5
|
|
268
269
|
`,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
270
|
+
values: [
|
|
271
|
+
netPlayerAmount,
|
|
272
|
+
session.user_id,
|
|
273
|
+
session.casino_id,
|
|
274
|
+
session.experience_id,
|
|
275
|
+
dbCurrency.key,
|
|
276
|
+
],
|
|
277
|
+
});
|
|
278
|
+
await pgClient.query({
|
|
279
|
+
text: `
|
|
279
280
|
UPDATE hub.bankroll
|
|
280
281
|
SET amount = amount - $1,
|
|
281
282
|
bets = bets + 1,
|
|
@@ -283,48 +284,48 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
283
284
|
WHERE currency_key = $2
|
|
284
285
|
AND casino_id = $3
|
|
285
286
|
`,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
287
|
+
values: [
|
|
288
|
+
netPlayerAmount,
|
|
289
|
+
dbCurrency.key,
|
|
290
|
+
session.casino_id,
|
|
291
|
+
input.wager,
|
|
292
|
+
],
|
|
293
|
+
});
|
|
294
|
+
const immutableData = structuredClone({
|
|
295
|
+
wager: input.wager,
|
|
296
|
+
currencyKey: dbCurrency.key,
|
|
297
|
+
clientSeed: input.clientSeed,
|
|
298
|
+
hash: betHashResult.hash,
|
|
299
|
+
outcomes: input.outcomes,
|
|
300
|
+
outcomeIdx,
|
|
301
|
+
roll,
|
|
302
|
+
});
|
|
303
|
+
const finalizedMetadata = betConfig.finalizeMetadata
|
|
304
|
+
? betConfig.finalizeMetadata(initializedMetadata, immutableData)
|
|
305
|
+
: initializedMetadata;
|
|
306
|
+
const newBet = {
|
|
307
|
+
kind: rawInput.kind,
|
|
308
|
+
wager: input.wager,
|
|
309
|
+
profit: outcome.profit,
|
|
310
|
+
currency_key: dbCurrency.key,
|
|
311
|
+
hash_id: dbHash.id,
|
|
312
|
+
user_id: session.user_id,
|
|
313
|
+
casino_id: session.casino_id,
|
|
314
|
+
experience_id: session.experience_id,
|
|
315
|
+
metadata: finalizedMetadata || {},
|
|
316
|
+
...(betConfig.saveOutcomes
|
|
317
|
+
? {
|
|
318
|
+
outcomes: input.outcomes,
|
|
319
|
+
outcome_idx: outcomeIdx,
|
|
320
|
+
}
|
|
321
|
+
: {
|
|
322
|
+
outcomes: [],
|
|
323
|
+
outcome_idx: null,
|
|
324
|
+
}),
|
|
325
|
+
};
|
|
326
|
+
const bet = await pgClient
|
|
327
|
+
.query({
|
|
328
|
+
text: `
|
|
328
329
|
INSERT INTO hub.outcome_bet (
|
|
329
330
|
user_id,
|
|
330
331
|
casino_id,
|
|
@@ -341,47 +342,49 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
341
342
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
342
343
|
RETURNING id
|
|
343
344
|
`,
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
345
|
+
values: [
|
|
346
|
+
newBet.user_id,
|
|
347
|
+
newBet.casino_id,
|
|
348
|
+
newBet.experience_id,
|
|
349
|
+
newBet.hash_id,
|
|
350
|
+
newBet.kind,
|
|
351
|
+
newBet.currency_key,
|
|
352
|
+
newBet.wager,
|
|
353
|
+
newBet.profit,
|
|
354
|
+
newBet.outcomes.map((o) => `(${o.weight},${o.profit})`),
|
|
355
|
+
newBet.outcome_idx,
|
|
356
|
+
newBet.metadata,
|
|
357
|
+
],
|
|
358
|
+
})
|
|
359
|
+
.then(exactlyOneRow);
|
|
360
|
+
return {
|
|
361
|
+
__typename: "HubMakeOutcomeBetSuccess",
|
|
362
|
+
betId: bet.id,
|
|
363
|
+
};
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
return object({
|
|
367
|
+
result: $result,
|
|
363
368
|
});
|
|
364
|
-
}
|
|
365
|
-
return object({
|
|
366
|
-
result: $result,
|
|
367
|
-
});
|
|
369
|
+
},
|
|
368
370
|
},
|
|
369
371
|
},
|
|
370
372
|
HubMakeOutcomeBetSuccess: {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
373
|
+
assertStep: ObjectStep,
|
|
374
|
+
plans: {
|
|
375
|
+
bet($data) {
|
|
376
|
+
const $betId = access($data, "betId");
|
|
377
|
+
return outcomeBetTable.get({ id: $betId });
|
|
378
|
+
},
|
|
375
379
|
},
|
|
376
380
|
},
|
|
377
381
|
HubMakeOutcomeBetPayload: {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
});
|
|
382
|
+
assertStep: ObjectStep,
|
|
383
|
+
plans: {
|
|
384
|
+
result($data) {
|
|
385
|
+
const $result = $data.get("result");
|
|
386
|
+
return $result;
|
|
387
|
+
},
|
|
385
388
|
},
|
|
386
389
|
},
|
|
387
390
|
},
|
|
@@ -14,45 +14,49 @@ export const HubPutAlertPlugin = makeExtendSchemaPlugin(() => {
|
|
|
14
14
|
mpTransferId: UUID!
|
|
15
15
|
}
|
|
16
16
|
`,
|
|
17
|
-
|
|
17
|
+
objects: {
|
|
18
18
|
Subscription: {
|
|
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
|
-
|
|
19
|
+
plans: {
|
|
20
|
+
hubPutAlert: {
|
|
21
|
+
subscribePlan(_$root) {
|
|
22
|
+
const $pgSubscriber = context().get("pgSubscriber");
|
|
23
|
+
const $identity = context().get("identity");
|
|
24
|
+
const $channelKey = lambda($identity, (identity) => {
|
|
25
|
+
if (identity?.kind === "user") {
|
|
26
|
+
return `hub:user:${identity.session.user_id}:put`;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return listenWithFilter($pgSubscriber, $channelKey, jsonParse, $identity, (item, identity) => {
|
|
33
|
+
if (typeof item !== "string") {
|
|
34
|
+
console.warn(`hubPutAlert: item is not a string: ${JSON.stringify(item)}`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (identity?.kind !== "user") {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return (identity.session.experience_id ===
|
|
42
|
+
JSON.parse(item).experience_id);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
plan($event) {
|
|
47
|
+
return $event;
|
|
48
|
+
},
|
|
47
49
|
},
|
|
48
50
|
},
|
|
49
51
|
},
|
|
50
52
|
HubPutAlertPayload: {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
plans: {
|
|
54
|
+
currencyKey($event) {
|
|
55
|
+
return $event.get("currency_key");
|
|
56
|
+
},
|
|
57
|
+
mpTransferId($event) {
|
|
58
|
+
return $event.get("mp_transfer_id");
|
|
59
|
+
},
|
|
56
60
|
},
|
|
57
61
|
},
|
|
58
62
|
},
|