@moneypot/hub 1.3.0-dev.4 → 1.3.0-dev.6
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,4 +1,15 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { Result } from "../util.js";
|
|
3
|
+
declare const OutcomeSchema: z.ZodObject<{
|
|
4
|
+
weight: z.ZodNumber;
|
|
5
|
+
profit: z.ZodNumber;
|
|
6
|
+
}, "strict", z.ZodTypeAny, {
|
|
7
|
+
weight: number;
|
|
8
|
+
profit: number;
|
|
9
|
+
}, {
|
|
10
|
+
weight: number;
|
|
11
|
+
profit: number;
|
|
12
|
+
}>;
|
|
2
13
|
declare const InputSchema: z.ZodObject<{
|
|
3
14
|
kind: z.ZodString;
|
|
4
15
|
wager: z.ZodNumber;
|
|
@@ -26,6 +37,7 @@ declare const InputSchema: z.ZodObject<{
|
|
|
26
37
|
profit: number;
|
|
27
38
|
}[]>;
|
|
28
39
|
hashChainId: z.ZodString;
|
|
40
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
29
41
|
}, "strict", z.ZodTypeAny, {
|
|
30
42
|
currency: string;
|
|
31
43
|
kind: string;
|
|
@@ -35,6 +47,7 @@ declare const InputSchema: z.ZodObject<{
|
|
|
35
47
|
weight: number;
|
|
36
48
|
profit: number;
|
|
37
49
|
}[];
|
|
50
|
+
metadata?: Record<string, any> | undefined;
|
|
38
51
|
}, {
|
|
39
52
|
currency: string;
|
|
40
53
|
kind: string;
|
|
@@ -44,12 +57,21 @@ declare const InputSchema: z.ZodObject<{
|
|
|
44
57
|
weight: number;
|
|
45
58
|
profit: number;
|
|
46
59
|
}[];
|
|
60
|
+
metadata?: Record<string, any> | undefined;
|
|
47
61
|
}>;
|
|
48
62
|
type Input = z.infer<typeof InputSchema>;
|
|
63
|
+
type Outcome = z.infer<typeof OutcomeSchema>;
|
|
64
|
+
type FinalizeMetadataData = {
|
|
65
|
+
clientSeed: string;
|
|
66
|
+
hash: Uint8Array;
|
|
67
|
+
outcomes: Outcome[];
|
|
68
|
+
outcomeIdx: number;
|
|
69
|
+
};
|
|
49
70
|
export type OutcomeBetConfig = {
|
|
50
71
|
houseEdge: number;
|
|
51
72
|
saveOutcomes: boolean;
|
|
52
|
-
|
|
73
|
+
initializeMetadata?: (input: Input) => Result<Record<string, any>, string>;
|
|
74
|
+
finalizeMetadata?: (input: Input, metadata: Record<string, any>, data: FinalizeMetadataData) => Record<string, any>;
|
|
53
75
|
};
|
|
54
76
|
export type OutcomeBetConfigMap<BetKind extends string> = {
|
|
55
77
|
[betKind in BetKind]: OutcomeBetConfig;
|
|
@@ -38,6 +38,7 @@ const InputSchema = z
|
|
|
38
38
|
.refine((data) => data.some((o) => o.profit < 0), "At least one outcome should have profit < 0")
|
|
39
39
|
.refine((data) => data.some((o) => o.profit > 0), "At least one outcome should have profit > 0"),
|
|
40
40
|
hashChainId: z.string().uuid("Invalid hash chain ID"),
|
|
41
|
+
metadata: z.record(z.string(), z.any()).optional(),
|
|
41
42
|
})
|
|
42
43
|
.strict();
|
|
43
44
|
const BetKindSchema = z
|
|
@@ -51,10 +52,11 @@ const BetConfigsSchema = z.record(BetKindSchema, z.object({
|
|
|
51
52
|
.gte(0, "House edge must be >= 0")
|
|
52
53
|
.lte(1, "House edge must be <= 1"),
|
|
53
54
|
saveOutcomes: z.boolean(),
|
|
54
|
-
|
|
55
|
+
initializeMetadata: z
|
|
56
|
+
.function()
|
|
57
|
+
.optional(),
|
|
58
|
+
finalizeMetadata: z
|
|
55
59
|
.function()
|
|
56
|
-
.args(InputSchema)
|
|
57
|
-
.returns(z.record(z.string(), z.any()))
|
|
58
60
|
.optional(),
|
|
59
61
|
}));
|
|
60
62
|
export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
@@ -73,6 +75,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
73
75
|
currency: String!
|
|
74
76
|
outcomes: [HubOutcomeInput!]!
|
|
75
77
|
hashChainId: UUID!
|
|
78
|
+
metadata: JSON
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
type HubMakeOutcomeBetOk {
|
|
@@ -118,6 +121,16 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
118
121
|
if (!betKinds.includes(rawInput.kind)) {
|
|
119
122
|
throw new GraphQLError(`Invalid bet kind`);
|
|
120
123
|
}
|
|
124
|
+
let validatedMetadata;
|
|
125
|
+
if (betConfig.initializeMetadata) {
|
|
126
|
+
const result = betConfig.initializeMetadata(input);
|
|
127
|
+
if (result.ok) {
|
|
128
|
+
validatedMetadata = result.value;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
throw new GraphQLError(`Invalid metadata: ${result.error}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
121
134
|
const houseEV = calculateHouseEV(input.outcomes);
|
|
122
135
|
const minHouseEV = Math.max(0, betConfig.houseEdge - FLOAT_EPSILON);
|
|
123
136
|
if (houseEV < minHouseEV) {
|
|
@@ -261,6 +274,15 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
261
274
|
input.wager,
|
|
262
275
|
],
|
|
263
276
|
});
|
|
277
|
+
const immutableData = structuredClone({
|
|
278
|
+
clientSeed: dbHashChain.client_seed,
|
|
279
|
+
hash: betHashResult.hash,
|
|
280
|
+
outcomes: input.outcomes,
|
|
281
|
+
outcomeIdx,
|
|
282
|
+
});
|
|
283
|
+
const finalizedMetadata = betConfig.finalizeMetadata
|
|
284
|
+
? betConfig.finalizeMetadata(input, validatedMetadata, immutableData)
|
|
285
|
+
: validatedMetadata;
|
|
264
286
|
const newBet = {
|
|
265
287
|
kind: rawInput.kind,
|
|
266
288
|
wager: input.wager,
|
|
@@ -270,9 +292,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
|
|
|
270
292
|
user_id: session.user_id,
|
|
271
293
|
casino_id: session.casino_id,
|
|
272
294
|
experience_id: session.experience_id,
|
|
273
|
-
metadata:
|
|
274
|
-
? await betConfig.getMetadata(input)
|
|
275
|
-
: {},
|
|
295
|
+
metadata: finalizedMetadata,
|
|
276
296
|
...(betConfig.saveOutcomes
|
|
277
297
|
? {
|
|
278
298
|
outcomes: input.outcomes,
|