@domino-sdk/relay 1.66.1 → 1.68.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/CHANGELOG.md +68 -0
- package/dist/{accounts-_lNsiR2k.d.ts → accounts-DnpKoJCo.d.ts} +210 -3
- package/dist/{attempt-captures-BqPggxTU.d.ts → attempt-captures-DMNFMYFb.d.ts} +9 -1
- package/dist/authoring.d.ts +352 -40
- package/dist/authoring.js +131 -22
- package/dist/{automatic-outcomes-BzAvfcpd.d.ts → automatic-outcomes-CQ3vpiQl.d.ts} +2 -2
- package/dist/avatar.d.ts +1 -1
- package/dist/browser.d.ts +10 -9
- package/dist/browser.js +12 -12
- package/dist/{catalog-ByZMRS7I.d.ts → catalog-BLGie8Lh.d.ts} +60 -2
- package/dist/chunk-4JSPMFO2.js +427 -0
- package/dist/{chunk-5LD5DKOM.js → chunk-55WJVFWC.js} +2 -2
- package/dist/{chunk-CJDB6W6I.js → chunk-5AKD4ZF3.js} +75 -36
- package/dist/{chunk-7MQCQYEE.js → chunk-6UBFSMCM.js} +1 -1
- package/dist/{chunk-XCEGNKGH.js → chunk-6YTSRWRB.js} +1254 -700
- package/dist/{chunk-OWDIR7ZU.js → chunk-75KF633N.js} +9 -1
- package/dist/{chunk-4TC4HK5Y.js → chunk-7YSVZA7A.js} +1 -1
- package/dist/{chunk-7HTRIEM7.js → chunk-CZ7NQ7W7.js} +11 -68
- package/dist/{chunk-ANVAUOJP.js → chunk-DDJN2T5A.js} +1 -1
- package/dist/{chunk-M66Y5OMJ.js → chunk-DNPDR4Z7.js} +16 -9
- package/dist/{chunk-FU3W4IQN.js → chunk-EXZVWQOQ.js} +2 -2
- package/dist/{chunk-5DYS2OIP.js → chunk-HXTKI34N.js} +14 -2
- package/dist/{chunk-FGXLXENM.js → chunk-IW46TW3A.js} +21 -1
- package/dist/{chunk-2Y4EZKET.js → chunk-KKHENO57.js} +2 -2
- package/dist/{chunk-U66GUVSG.js → chunk-LZXDYSUH.js} +2 -0
- package/dist/{chunk-QYHEHMCG.js → chunk-MEUAJIVO.js} +2 -2
- package/dist/{chunk-BQXRCJ3N.js → chunk-P4TPW4SY.js} +1 -1
- package/dist/{chunk-CGUL4MRE.js → chunk-R3MNZKNJ.js} +1 -1
- package/dist/{chunk-R2LHIWAM.js → chunk-SD74HD75.js} +45 -9
- package/dist/{chunk-FUFMYKSQ.js → chunk-TYZFVL73.js} +136 -5
- package/dist/chunk-VAGGGB6B.js +87 -0
- package/dist/{chunk-2HHZV7U3.js → chunk-VRZZB7CQ.js} +1 -1
- package/dist/{client-Cze4lfwA.d.ts → client-BMif22WQ.d.ts} +136 -7
- package/dist/{dashboards-pVfclkyh.d.ts → dashboards-DMk-vL1q.d.ts} +4 -4
- package/dist/{deployments-Cr1tfqrr.d.ts → deployments-BCr418BX.d.ts} +582 -173
- package/dist/{identity-integration-Ci2vGKtX.d.ts → identity-integration-r76xaAax.d.ts} +10 -2
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/dist/internal.d.ts +155 -14
- package/dist/internal.js +255 -25
- package/dist/{limits-pE04y9O2.d.ts → limits-ByVRQePO.d.ts} +6 -1
- package/dist/{offers-Hw2P6tcK.d.ts → offers-xcPbYaEv.d.ts} +2 -2
- package/dist/portal-proxy.d.ts +5 -5
- package/dist/portal-proxy.js +13 -15
- package/dist/react/index.d.ts +38 -15
- package/dist/react/index.js +12 -12
- package/dist/{reward-deliveries-BCV8hznc.d.ts → reward-deliveries-0VvT6LMj.d.ts} +1 -1
- package/dist/runtime/authoring.js +1 -1
- package/dist/runtime/chunks/2UDZ6TPL.js +1 -0
- package/dist/runtime/manifest.json +3 -3
- package/dist/runtime/schema.js +1 -1
- package/dist/schema.d.ts +401 -104
- package/dist/schema.js +66 -8
- package/dist/server/index.d.ts +12 -12
- package/dist/server/index.js +2288 -873
- package/dist/{sign-in-providers-BAkGjSXo.d.ts → sign-in-providers-C5_753DZ.d.ts} +2 -2
- package/dist/solana.d.ts +171 -0
- package/dist/solana.js +364 -0
- package/dist/{submission-input-ChL1aYNH.d.ts → submission-input-CaL8drIh.d.ts} +2 -2
- package/dist/{telegram-browser-BFs4u7lC.d.ts → telegram-browser-DLtHPRBI.d.ts} +6 -108
- package/dist/telegram.d.ts +8 -8
- package/dist/telegram.js +2 -2
- package/dist/testing.d.ts +87 -14
- package/dist/testing.js +108 -11
- package/dist/{tracker-data-Bl-qPIvZ.d.ts → tracker-data-CAK942sx.d.ts} +300 -3
- package/dist/{transport-WE49Ta3A.d.ts → transport-CkidqTOk.d.ts} +5866 -1244
- package/dist/{wallet-B7e06v4m.d.ts → wallet-DQtJelQQ.d.ts} +418 -33
- package/dist/wallet-browser-dpmr22Xv.d.ts +106 -0
- package/package.json +18 -1
- package/dist/chunk-UYVJZR33.js +0 -34
- package/dist/chunk-UZ765UGH.js +0 -18
- package/dist/runtime/chunks/C5V267I7.js +0 -1
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import {
|
|
2
|
+
activityTypeSchema
|
|
3
|
+
} from "./chunk-DNPDR4Z7.js";
|
|
4
|
+
import {
|
|
5
|
+
completionRecordSchema,
|
|
6
|
+
completionSourceSchema,
|
|
7
|
+
identifier,
|
|
8
|
+
isSolanaNetwork,
|
|
9
|
+
pageCursorSchema,
|
|
10
|
+
pageLimit,
|
|
11
|
+
solanaAddressSchema,
|
|
12
|
+
solanaSignatureSchema
|
|
13
|
+
} from "./chunk-6YTSRWRB.js";
|
|
14
|
+
|
|
15
|
+
// src/server/webhooks.ts
|
|
16
|
+
import * as z from "zod";
|
|
17
|
+
var PayoutSourceKind = {
|
|
18
|
+
Quest: "quest",
|
|
19
|
+
Leaderboard: "leaderboard",
|
|
20
|
+
Engagement: "engagement",
|
|
21
|
+
Manual: "manual"
|
|
22
|
+
};
|
|
23
|
+
var webhookEventSchema = /* @__PURE__ */ (() => z.object({
|
|
24
|
+
id: z.string().uuid(),
|
|
25
|
+
version: z.literal(1),
|
|
26
|
+
type: activityTypeSchema,
|
|
27
|
+
createdAt: z.number().int().nonnegative(),
|
|
28
|
+
organization: z.string(),
|
|
29
|
+
project: z.string(),
|
|
30
|
+
environment: z.enum(["test", "live"]),
|
|
31
|
+
data: z.record(z.string(), z.json())
|
|
32
|
+
}))();
|
|
33
|
+
var walletLinkedEventDataSchema = /* @__PURE__ */ (() => z.object({
|
|
34
|
+
member: z.string(),
|
|
35
|
+
chain: z.string(),
|
|
36
|
+
network: z.string().nullable(),
|
|
37
|
+
address: z.string()
|
|
38
|
+
}))();
|
|
39
|
+
var webhookControlInputSchema = /* @__PURE__ */ (() => z.object({ actionId: z.string().uuid().optional() }).strict())();
|
|
40
|
+
var webhookInputSchema = /* @__PURE__ */ (() => z.object({
|
|
41
|
+
url: z.url().max(2048).refine((value) => {
|
|
42
|
+
const url2 = new URL(value);
|
|
43
|
+
return url2.protocol === "https:" && !url2.username && !url2.password && !url2.hash;
|
|
44
|
+
}, "Use an HTTPS URL without credentials or a fragment"),
|
|
45
|
+
types: z.array(activityTypeSchema).min(1).max(100).refine((v) => new Set(v).size === v.length)
|
|
46
|
+
}).strict())();
|
|
47
|
+
var webhookCreateInputSchema = /* @__PURE__ */ (() => webhookInputSchema.extend({ actionId: z.string().uuid().optional() }).strict())();
|
|
48
|
+
var webhookRotateInputSchema = /* @__PURE__ */ (() => z.object({ actionId: z.string().uuid().optional() }).strict())();
|
|
49
|
+
var webhookUpdateSchema = /* @__PURE__ */ (() => webhookInputSchema.partial().extend({ enabled: z.boolean().optional() }).strict())();
|
|
50
|
+
var webhookEndpointSchema = /* @__PURE__ */ (() => z.object({
|
|
51
|
+
...webhookInputSchema.shape,
|
|
52
|
+
id: z.string().uuid(),
|
|
53
|
+
enabled: z.boolean(),
|
|
54
|
+
disabledReason: z.string().nullable(),
|
|
55
|
+
consecutiveFailures: z.number().int().nonnegative(),
|
|
56
|
+
createdAt: z.number(),
|
|
57
|
+
updatedAt: z.number()
|
|
58
|
+
}))();
|
|
59
|
+
var webhookEndpointStateSchema = /* @__PURE__ */ (() => webhookEndpointSchema.extend({
|
|
60
|
+
revision: z.number().int().nonnegative(),
|
|
61
|
+
deletedAt: z.number().int().safe().nonnegative().nullable()
|
|
62
|
+
}))();
|
|
63
|
+
var webhookDeleteInputSchema = /* @__PURE__ */ (() => z.strictObject({
|
|
64
|
+
actionId: z.string().uuid().default(() => crypto.randomUUID()),
|
|
65
|
+
expectedRevision: z.number().int().nonnegative(),
|
|
66
|
+
reason: z.string().trim().min(1).max(500)
|
|
67
|
+
}))();
|
|
68
|
+
var webhookStateQuerySchema = /* @__PURE__ */ (() => z.strictObject({
|
|
69
|
+
cursor: pageCursorSchema.optional(),
|
|
70
|
+
limit: z.coerce.number().int().min(1).max(100).default(50)
|
|
71
|
+
}))();
|
|
72
|
+
var webhookStatePageSchema = /* @__PURE__ */ (() => z.object({
|
|
73
|
+
items: z.array(webhookEndpointStateSchema),
|
|
74
|
+
nextCursor: pageCursorSchema.nullable()
|
|
75
|
+
}))();
|
|
76
|
+
var webhookSecretSchema = /* @__PURE__ */ (() => z.object({
|
|
77
|
+
endpoint: webhookEndpointSchema,
|
|
78
|
+
secret: z.string(),
|
|
79
|
+
previousValidUntil: z.number().nullable()
|
|
80
|
+
}))();
|
|
81
|
+
var webhookDeliverySchema = /* @__PURE__ */ (() => z.object({
|
|
82
|
+
id: z.string().uuid(),
|
|
83
|
+
endpoint: z.string().uuid(),
|
|
84
|
+
event: webhookEventSchema,
|
|
85
|
+
status: z.enum(["pending", "delivered", "failed", "skipped"]),
|
|
86
|
+
attempts: z.number().int().nonnegative(),
|
|
87
|
+
responseStatus: z.number().nullable(),
|
|
88
|
+
lastError: z.string().nullable(),
|
|
89
|
+
createdAt: z.number(),
|
|
90
|
+
deliveredAt: z.number().nullable(),
|
|
91
|
+
replayOf: z.string().uuid().nullable()
|
|
92
|
+
}))();
|
|
93
|
+
var webhookQuerySchema = /* @__PURE__ */ (() => z.object({
|
|
94
|
+
/** A page's `nextCursor`: the deliveries after it, newest first. */
|
|
95
|
+
cursor: pageCursorSchema.optional(),
|
|
96
|
+
/** @deprecated Use `cursor`. Removed in 2.0.0. */
|
|
97
|
+
before: z.string().uuid().optional(),
|
|
98
|
+
limit: z.coerce.number().int().min(1).max(100).default(50)
|
|
99
|
+
}).strict())();
|
|
100
|
+
var webhookDeliveryPageSchema = /* @__PURE__ */ (() => z.object({
|
|
101
|
+
items: z.array(webhookDeliverySchema),
|
|
102
|
+
nextCursor: pageCursorSchema.nullable().default(null),
|
|
103
|
+
/** @deprecated Use `nextCursor`, passed back as `cursor`. Removed in 2.0.0. */
|
|
104
|
+
next: z.string().uuid().nullable()
|
|
105
|
+
}))();
|
|
106
|
+
var WEBHOOK_MAX_BYTES = 64 * 1024;
|
|
107
|
+
async function verifyWebhook(input) {
|
|
108
|
+
const bytes = new TextEncoder().encode(input.body);
|
|
109
|
+
const tolerance = input.toleranceSeconds ?? 300;
|
|
110
|
+
const now = input.now ?? Date.now();
|
|
111
|
+
if (bytes.length > WEBHOOK_MAX_BYTES || !Number.isFinite(now) || !Number.isFinite(tolerance) || tolerance < 0 || tolerance > 300) {
|
|
112
|
+
throw new Error("Invalid webhook verification input");
|
|
113
|
+
}
|
|
114
|
+
const parts = input.signature.split(",");
|
|
115
|
+
const timestamps = parts.filter((part) => part.startsWith("t="));
|
|
116
|
+
const timestamp = timestamps[0]?.slice(2) ?? "";
|
|
117
|
+
const signatures = parts.filter((part) => /^v1=[a-f0-9]{64}$/.test(part)).map((part) => part.slice(3));
|
|
118
|
+
if (timestamps.length !== 1 || !/^\d{1,12}$/.test(timestamp) || Math.abs(now / 1e3 - Number(timestamp)) > tolerance || signatures.length < 1 || signatures.length > 2) {
|
|
119
|
+
throw new Error("Invalid or expired webhook signature");
|
|
120
|
+
}
|
|
121
|
+
const secrets = typeof input.secret === "string" ? [input.secret] : input.secret;
|
|
122
|
+
const message = new TextEncoder().encode(`${timestamp}.${input.body}`);
|
|
123
|
+
for (const secret of secrets) {
|
|
124
|
+
if (!secret) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const key = await crypto.subtle.importKey(
|
|
128
|
+
"raw",
|
|
129
|
+
new TextEncoder().encode(secret),
|
|
130
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
131
|
+
false,
|
|
132
|
+
["verify"]
|
|
133
|
+
);
|
|
134
|
+
for (const signature of signatures) {
|
|
135
|
+
const digest = Uint8Array.from(
|
|
136
|
+
signature.match(/../g) ?? [],
|
|
137
|
+
(byte) => Number.parseInt(byte, 16)
|
|
138
|
+
);
|
|
139
|
+
if (await crypto.subtle.verify("HMAC", key, digest, message)) {
|
|
140
|
+
return webhookEventSchema.parse(JSON.parse(input.body));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
throw new Error("Invalid webhook signature");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/server/completions.ts
|
|
148
|
+
import * as z2 from "zod";
|
|
149
|
+
var completionRevokeSchema = /* @__PURE__ */ (() => z2.object({
|
|
150
|
+
actionId: identifier,
|
|
151
|
+
reason: z2.string().trim().min(1).max(500),
|
|
152
|
+
freeOccurrence: z2.boolean().default(false)
|
|
153
|
+
}).strict())();
|
|
154
|
+
var RevokedEntitlementOutcome = {
|
|
155
|
+
/** No other completion grants the reward: it is void, after cancelling a handover in progress. */
|
|
156
|
+
Voided: "voided",
|
|
157
|
+
/** Lowered to the best tier another completion grants, after cancelling a handover in progress. */
|
|
158
|
+
Downgraded: "downgraded",
|
|
159
|
+
/** Another completion grants the same tier, or it was already void. */
|
|
160
|
+
Kept: "kept",
|
|
161
|
+
/** Already collected: its earned tier follows the other completions, and the item stays handed over. */
|
|
162
|
+
Flagged: "flagged"
|
|
163
|
+
};
|
|
164
|
+
var RevokedDeliveryOutcome = {
|
|
165
|
+
/** The role was delivered and stays: remove it in Discord if appropriate. */
|
|
166
|
+
Flagged: "flagged",
|
|
167
|
+
/** The grant was stopped before any call to Discord. */
|
|
168
|
+
Cancelled: "cancelled",
|
|
169
|
+
/** The grant was stopped, but a call to Discord may already have been sent and can still land. */
|
|
170
|
+
InFlight: "in-flight",
|
|
171
|
+
/** The grant had failed, so Discord never received the role. */
|
|
172
|
+
NotDelivered: "not-delivered"
|
|
173
|
+
};
|
|
174
|
+
var RevokedReferralOutcome = {
|
|
175
|
+
/** The inviter's rewards for this member are reversed. */
|
|
176
|
+
Unqualified: "unqualified",
|
|
177
|
+
/** Qualified on another accepted completion of the program's quest instead. */
|
|
178
|
+
Requalified: "requalified"
|
|
179
|
+
};
|
|
180
|
+
var entitlementOutcomeSchema = /* @__PURE__ */ (() => z2.string().min(1).max(64))();
|
|
181
|
+
var deliveryOutcomeSchema = /* @__PURE__ */ (() => z2.string().min(1).max(64))();
|
|
182
|
+
var referralOutcomeSchema = /* @__PURE__ */ (() => z2.string().min(1).max(64))();
|
|
183
|
+
var completionRevocationSchema = /* @__PURE__ */ (() => z2.object({
|
|
184
|
+
completion: identifier,
|
|
185
|
+
/** The quest ID, or the board ID when `source.kind` is `leaderboard`. */
|
|
186
|
+
quest: identifier,
|
|
187
|
+
member: identifier,
|
|
188
|
+
/** What paid the revoked completion. `source.id` repeats `quest`. */
|
|
189
|
+
source: completionSourceSchema.optional(),
|
|
190
|
+
revokedAt: z2.number(),
|
|
191
|
+
occurrenceFreed: z2.boolean(),
|
|
192
|
+
badges: z2.array(z2.object({ badge: identifier, stillAwarded: z2.boolean() })).optional(),
|
|
193
|
+
groups: z2.array(z2.object({ group: identifier, stillMember: z2.boolean() })).optional(),
|
|
194
|
+
points: z2.array(
|
|
195
|
+
z2.object({
|
|
196
|
+
entry: identifier,
|
|
197
|
+
balance: identifier,
|
|
198
|
+
reversal: identifier.nullable(),
|
|
199
|
+
reversed: z2.number().int(),
|
|
200
|
+
unreversed: z2.number().int()
|
|
201
|
+
})
|
|
202
|
+
),
|
|
203
|
+
entitlements: z2.array(
|
|
204
|
+
z2.object({
|
|
205
|
+
entitlement: identifier,
|
|
206
|
+
reward: identifier,
|
|
207
|
+
outcome: entitlementOutcomeSchema,
|
|
208
|
+
status: z2.string()
|
|
209
|
+
})
|
|
210
|
+
),
|
|
211
|
+
deliveries: z2.array(
|
|
212
|
+
z2.object({
|
|
213
|
+
delivery: z2.string(),
|
|
214
|
+
roleId: z2.string(),
|
|
215
|
+
outcome: deliveryOutcomeSchema,
|
|
216
|
+
/**
|
|
217
|
+
* By Relay's records, another accepted, unrevoked completion of the member also granted this
|
|
218
|
+
* role to the same Discord account and server. Relay does not read Discord's membership.
|
|
219
|
+
*/
|
|
220
|
+
stillGranted: z2.boolean()
|
|
221
|
+
})
|
|
222
|
+
),
|
|
223
|
+
referrals: z2.array(
|
|
224
|
+
z2.object({
|
|
225
|
+
program: identifier,
|
|
226
|
+
outcome: referralOutcomeSchema
|
|
227
|
+
})
|
|
228
|
+
),
|
|
229
|
+
streakMilestone: z2.boolean(),
|
|
230
|
+
budgets: z2.array(
|
|
231
|
+
z2.object({ budget: identifier, released: z2.number().int().nonnegative() })
|
|
232
|
+
).optional()
|
|
233
|
+
}))();
|
|
234
|
+
var completionRestoreSchema = /* @__PURE__ */ (() => z2.object({
|
|
235
|
+
actionId: identifier,
|
|
236
|
+
reason: z2.string().trim().min(1).max(500)
|
|
237
|
+
}).strict())();
|
|
238
|
+
var RestoredEntitlementOutcome = {
|
|
239
|
+
/** The revocation voided it, and it is available again. */
|
|
240
|
+
Restored: "restored",
|
|
241
|
+
/** The revocation lowered or flagged it: its earned tier is the completion's again. */
|
|
242
|
+
Raised: "raised",
|
|
243
|
+
/** It changed since the revocation (an operator restored, voided or corrected it), so it stays. */
|
|
244
|
+
Kept: "kept"
|
|
245
|
+
};
|
|
246
|
+
var RestoredDeliveryOutcome = {
|
|
247
|
+
/** The grant had not reached Discord, and it is queued again. */
|
|
248
|
+
Requeued: "requeued",
|
|
249
|
+
/** The grant counts again for reconciliation, and its delivery status stays. */
|
|
250
|
+
Kept: "kept"
|
|
251
|
+
};
|
|
252
|
+
var RestoredReferralOutcome = {
|
|
253
|
+
/** The member qualifies on this completion again. */
|
|
254
|
+
Qualified: "qualified",
|
|
255
|
+
/** The program is disabled or gone, or the referral is suspended, so nothing changed. */
|
|
256
|
+
Kept: "kept"
|
|
257
|
+
};
|
|
258
|
+
var openOutcome = /* @__PURE__ */ (() => z2.string().min(1).max(64))();
|
|
259
|
+
var completionRestorationSchema = /* @__PURE__ */ (() => z2.object({
|
|
260
|
+
completion: identifier,
|
|
261
|
+
/** The quest ID, or the board ID when `source.kind` is `leaderboard`. */
|
|
262
|
+
quest: identifier,
|
|
263
|
+
member: identifier,
|
|
264
|
+
source: completionSourceSchema.optional(),
|
|
265
|
+
restoredAt: z2.number(),
|
|
266
|
+
points: z2.array(
|
|
267
|
+
z2.object({
|
|
268
|
+
entry: identifier,
|
|
269
|
+
balance: identifier,
|
|
270
|
+
reversal: identifier,
|
|
271
|
+
amount: z2.number().int()
|
|
272
|
+
})
|
|
273
|
+
),
|
|
274
|
+
badges: z2.array(z2.object({ badge: identifier })),
|
|
275
|
+
groups: z2.array(z2.object({ group: identifier, added: z2.boolean() })),
|
|
276
|
+
entitlements: z2.array(
|
|
277
|
+
z2.object({
|
|
278
|
+
entitlement: identifier,
|
|
279
|
+
reward: identifier,
|
|
280
|
+
outcome: openOutcome,
|
|
281
|
+
status: z2.string()
|
|
282
|
+
})
|
|
283
|
+
),
|
|
284
|
+
deliveries: z2.array(
|
|
285
|
+
z2.object({
|
|
286
|
+
delivery: z2.string(),
|
|
287
|
+
roleId: z2.string(),
|
|
288
|
+
outcome: openOutcome
|
|
289
|
+
})
|
|
290
|
+
),
|
|
291
|
+
referrals: z2.array(
|
|
292
|
+
z2.object({
|
|
293
|
+
program: identifier,
|
|
294
|
+
outcome: openOutcome
|
|
295
|
+
})
|
|
296
|
+
),
|
|
297
|
+
streakMilestone: z2.boolean(),
|
|
298
|
+
budgets: z2.array(
|
|
299
|
+
z2.object({ budget: identifier, charged: z2.number().int().nonnegative() })
|
|
300
|
+
).optional()
|
|
301
|
+
}))();
|
|
302
|
+
var completionRevocationShortfallSchema = /* @__PURE__ */ (() => z2.object({
|
|
303
|
+
completion: identifier,
|
|
304
|
+
quest: identifier,
|
|
305
|
+
revokedAt: z2.number().int().nonnegative().safe(),
|
|
306
|
+
unreversedPoints: z2.record(identifier, z2.number().int().positive().safe())
|
|
307
|
+
}))();
|
|
308
|
+
var revokedCompletionSchema = /* @__PURE__ */ (() => z2.object({
|
|
309
|
+
completion: identifier,
|
|
310
|
+
quest: identifier,
|
|
311
|
+
/** The completion key: its occurrence, such as `once` or a day. */
|
|
312
|
+
key: z2.string(),
|
|
313
|
+
revokedAt: z2.number().int().nonnegative().safe(),
|
|
314
|
+
/** Why it was revoked, and what the revoke did, which a restore re-applies. */
|
|
315
|
+
reason: z2.string().optional(),
|
|
316
|
+
revocation: completionRevocationSchema.optional()
|
|
317
|
+
}))();
|
|
318
|
+
var maxCompletionReceipts = 20;
|
|
319
|
+
var receiptNetworkPattern = /^[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}$/;
|
|
320
|
+
var receiptValue = /* @__PURE__ */ (() => z2.string().min(1).max(256).regex(/^[\x21-\x7e]+$/, "Use printable characters without spaces"))();
|
|
321
|
+
var completionReceiptInputSchema = /* @__PURE__ */ (() => z2.object({
|
|
322
|
+
actionId: identifier,
|
|
323
|
+
key: z2.string().regex(
|
|
324
|
+
/^[a-z0-9][a-z0-9._-]{0,63}$/,
|
|
325
|
+
"Use 1 to 64 lowercase letters, digits, dots, hyphens or underscores"
|
|
326
|
+
),
|
|
327
|
+
network: z2.string().regex(
|
|
328
|
+
receiptNetworkPattern,
|
|
329
|
+
"Use a CAIP-2 chain ID such as solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
|
|
330
|
+
),
|
|
331
|
+
signature: receiptValue,
|
|
332
|
+
asset: receiptValue.optional(),
|
|
333
|
+
recipient: receiptValue.optional(),
|
|
334
|
+
label: z2.string().trim().min(1).max(120).optional()
|
|
335
|
+
}).strict().superRefine((receipt, context) => {
|
|
336
|
+
if (!isSolanaNetwork(receipt.network)) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (!solanaSignatureSchema.safeParse(receipt.signature).success) {
|
|
340
|
+
context.addIssue({
|
|
341
|
+
code: "custom",
|
|
342
|
+
path: ["signature"],
|
|
343
|
+
message: "Use a Solana transaction signature: base58, 64 bytes"
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
for (const field of ["asset", "recipient"]) {
|
|
347
|
+
const value = receipt[field];
|
|
348
|
+
if (value !== void 0 && !solanaAddressSchema.safeParse(value).success) {
|
|
349
|
+
context.addIssue({
|
|
350
|
+
code: "custom",
|
|
351
|
+
path: [field],
|
|
352
|
+
message: "Use a base58 Solana address"
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}))();
|
|
357
|
+
var completionReceiptSchema = /* @__PURE__ */ (() => z2.object({
|
|
358
|
+
completion: identifier,
|
|
359
|
+
/** The quest ID, or the board ID for a leaderboard prize's completion. */
|
|
360
|
+
quest: identifier,
|
|
361
|
+
member: identifier,
|
|
362
|
+
key: z2.string(),
|
|
363
|
+
network: z2.string(),
|
|
364
|
+
signature: z2.string(),
|
|
365
|
+
asset: z2.string().nullable(),
|
|
366
|
+
recipient: z2.string().nullable(),
|
|
367
|
+
label: z2.string().nullable(),
|
|
368
|
+
recordedAt: z2.number().int().nonnegative().safe(),
|
|
369
|
+
/** The operator or key that recorded it. */
|
|
370
|
+
recordedBy: z2.string().nullable(),
|
|
371
|
+
completionRevokedAt: z2.number().int().nonnegative().safe().nullable()
|
|
372
|
+
}))();
|
|
373
|
+
var completionReceiptListSchema = /* @__PURE__ */ (() => z2.array(completionReceiptSchema))();
|
|
374
|
+
var memberCompletionQuerySchema = /* @__PURE__ */ (() => z2.strictObject({
|
|
375
|
+
member: identifier,
|
|
376
|
+
quest: identifier.optional(),
|
|
377
|
+
cursor: pageCursorSchema.optional(),
|
|
378
|
+
limit: pageLimit
|
|
379
|
+
}))();
|
|
380
|
+
var memberCompletionSchema = /* @__PURE__ */ (() => completionRecordSchema.extend({
|
|
381
|
+
completedAt: z2.number().int().nonnegative().safe().nullable()
|
|
382
|
+
}))();
|
|
383
|
+
var memberCompletionPageSchema = /* @__PURE__ */ (() => z2.object({
|
|
384
|
+
items: z2.array(memberCompletionSchema),
|
|
385
|
+
nextCursor: pageCursorSchema.nullable()
|
|
386
|
+
}))();
|
|
387
|
+
|
|
388
|
+
export {
|
|
389
|
+
PayoutSourceKind,
|
|
390
|
+
webhookEventSchema,
|
|
391
|
+
walletLinkedEventDataSchema,
|
|
392
|
+
webhookControlInputSchema,
|
|
393
|
+
webhookInputSchema,
|
|
394
|
+
webhookCreateInputSchema,
|
|
395
|
+
webhookRotateInputSchema,
|
|
396
|
+
webhookUpdateSchema,
|
|
397
|
+
webhookEndpointSchema,
|
|
398
|
+
webhookEndpointStateSchema,
|
|
399
|
+
webhookDeleteInputSchema,
|
|
400
|
+
webhookStateQuerySchema,
|
|
401
|
+
webhookStatePageSchema,
|
|
402
|
+
webhookSecretSchema,
|
|
403
|
+
webhookDeliverySchema,
|
|
404
|
+
webhookQuerySchema,
|
|
405
|
+
webhookDeliveryPageSchema,
|
|
406
|
+
WEBHOOK_MAX_BYTES,
|
|
407
|
+
verifyWebhook,
|
|
408
|
+
completionRevokeSchema,
|
|
409
|
+
RevokedEntitlementOutcome,
|
|
410
|
+
RevokedDeliveryOutcome,
|
|
411
|
+
RevokedReferralOutcome,
|
|
412
|
+
completionRevocationSchema,
|
|
413
|
+
completionRestoreSchema,
|
|
414
|
+
RestoredEntitlementOutcome,
|
|
415
|
+
RestoredDeliveryOutcome,
|
|
416
|
+
RestoredReferralOutcome,
|
|
417
|
+
completionRestorationSchema,
|
|
418
|
+
completionRevocationShortfallSchema,
|
|
419
|
+
revokedCompletionSchema,
|
|
420
|
+
maxCompletionReceipts,
|
|
421
|
+
completionReceiptInputSchema,
|
|
422
|
+
completionReceiptSchema,
|
|
423
|
+
completionReceiptListSchema,
|
|
424
|
+
memberCompletionQuerySchema,
|
|
425
|
+
memberCompletionSchema,
|
|
426
|
+
memberCompletionPageSchema
|
|
427
|
+
};
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
resourceHandle,
|
|
13
13
|
responseShape,
|
|
14
14
|
tierRewardSchema
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-6YTSRWRB.js";
|
|
16
16
|
import {
|
|
17
17
|
parseDefinition
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-IW46TW3A.js";
|
|
19
19
|
|
|
20
20
|
// src/engagement.ts
|
|
21
21
|
import * as z from "zod";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
imageAssetArtifactSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DDJN2T5A.js";
|
|
4
4
|
import {
|
|
5
5
|
authScopeSchema,
|
|
6
6
|
exchangeResultSchema
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-6UBFSMCM.js";
|
|
8
8
|
import {
|
|
9
9
|
appIdentityKindSchema,
|
|
10
10
|
cosmosAddressSchema,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
openIdentityKindSchema,
|
|
18
18
|
pageCursorSchema,
|
|
19
19
|
solanaAddressSchema
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-6YTSRWRB.js";
|
|
21
21
|
|
|
22
22
|
// src/credential-secrets.ts
|
|
23
23
|
import * as z from "zod";
|
|
@@ -418,6 +418,34 @@ var memberImportListQuerySchema = /* @__PURE__ */ (() => z2.object({
|
|
|
418
418
|
// src/server/schedules.ts
|
|
419
419
|
import * as z3 from "zod";
|
|
420
420
|
import { Cron } from "croner";
|
|
421
|
+
|
|
422
|
+
// src/server/request-body.ts
|
|
423
|
+
async function boundedBodyText(body, limit) {
|
|
424
|
+
const reader = body.getReader();
|
|
425
|
+
let text = "";
|
|
426
|
+
let size = 0;
|
|
427
|
+
const decoder = new TextDecoder();
|
|
428
|
+
try {
|
|
429
|
+
for (; ; ) {
|
|
430
|
+
const chunk = await reader.read();
|
|
431
|
+
if (chunk.done) {
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
size += chunk.value.byteLength;
|
|
435
|
+
if (size > limit) {
|
|
436
|
+
void reader.cancel().catch(() => {
|
|
437
|
+
});
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
text += decoder.decode(chunk.value, { stream: true });
|
|
441
|
+
}
|
|
442
|
+
return text + decoder.decode();
|
|
443
|
+
} catch {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// src/server/schedules.ts
|
|
421
449
|
var APP_SCHEDULE_LIMIT = 10;
|
|
422
450
|
var APP_SCHEDULE_MIN_INTERVAL = 3e5;
|
|
423
451
|
var APP_SCHEDULE_TIMEOUT = 3e4;
|
|
@@ -564,29 +592,12 @@ async function verifyScheduledRequest(request, key) {
|
|
|
564
592
|
if (request.method !== "POST" || url.search !== "" || url.hash !== "" || !key || !signature || !/^[a-f0-9]{64}$/.test(signature)) {
|
|
565
593
|
return null;
|
|
566
594
|
}
|
|
567
|
-
const
|
|
568
|
-
if (!
|
|
595
|
+
const stream = request.clone().body;
|
|
596
|
+
if (!stream) {
|
|
569
597
|
return null;
|
|
570
598
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
const decoder = new TextDecoder();
|
|
574
|
-
try {
|
|
575
|
-
for (; ; ) {
|
|
576
|
-
const chunk = await reader.read();
|
|
577
|
-
if (chunk.done) {
|
|
578
|
-
break;
|
|
579
|
-
}
|
|
580
|
-
size += chunk.value.byteLength;
|
|
581
|
-
if (size > 4096) {
|
|
582
|
-
void reader.cancel().catch(() => {
|
|
583
|
-
});
|
|
584
|
-
return null;
|
|
585
|
-
}
|
|
586
|
-
body += decoder.decode(chunk.value, { stream: true });
|
|
587
|
-
}
|
|
588
|
-
body += decoder.decode();
|
|
589
|
-
} catch {
|
|
599
|
+
const body = await boundedBodyText(stream, 4096);
|
|
600
|
+
if (body === null) {
|
|
590
601
|
return null;
|
|
591
602
|
}
|
|
592
603
|
const secret = await crypto.subtle.importKey(
|
|
@@ -626,7 +637,7 @@ var starters = [
|
|
|
626
637
|
{
|
|
627
638
|
id: "campaign",
|
|
628
639
|
title: "Campaign tour",
|
|
629
|
-
summary: "A
|
|
640
|
+
summary: "A quest app with a guided tour of every quest kind, in a clean default look to rebrand. The blank canvas for anything."
|
|
630
641
|
},
|
|
631
642
|
{
|
|
632
643
|
id: "classic",
|
|
@@ -1241,21 +1252,43 @@ var buildArtifactsSchema = /* @__PURE__ */ (() => z5.discriminatedUnion("format"
|
|
|
1241
1252
|
}
|
|
1242
1253
|
}))();
|
|
1243
1254
|
|
|
1255
|
+
// src/origins.ts
|
|
1256
|
+
var loopbackHosts = [
|
|
1257
|
+
"localhost",
|
|
1258
|
+
"127.0.0.1",
|
|
1259
|
+
"[::1]"
|
|
1260
|
+
];
|
|
1261
|
+
function secureOrLoopbackOrigin(url, options = {}) {
|
|
1262
|
+
return url.protocol === "https:" || url.protocol === "http:" && (loopbackHosts.includes(url.hostname) || (options.localHosts ?? []).includes(url.hostname));
|
|
1263
|
+
}
|
|
1264
|
+
function bareOrigin(url) {
|
|
1265
|
+
return !url.username && !url.password && !url.search && !url.hash && url.pathname === "/";
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1244
1268
|
// src/identity-integration.ts
|
|
1245
1269
|
import * as z6 from "zod";
|
|
1270
|
+
var exactOrigin = (allowed, message) => z6.string().url().superRefine((value, context) => {
|
|
1271
|
+
const url = new URL(value);
|
|
1272
|
+
if (!allowed(url)) {
|
|
1273
|
+
context.addIssue({ code: "custom", message });
|
|
1274
|
+
} else if (url.origin !== value) {
|
|
1275
|
+
context.addIssue({
|
|
1276
|
+
code: "custom",
|
|
1277
|
+
message: `Use the exact origin ${url.origin}, without a path, query or trailing slash.`
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
1281
|
+
var httpsOriginSchema = /* @__PURE__ */ (() => exactOrigin(
|
|
1282
|
+
(url) => url.protocol === "https:",
|
|
1283
|
+
"Use an HTTPS origin."
|
|
1284
|
+
))();
|
|
1285
|
+
var appLoginOriginSchema = /* @__PURE__ */ (() => exactOrigin(
|
|
1286
|
+
(url) => secureOrLoopbackOrigin(url),
|
|
1287
|
+
"Use an HTTPS origin, or a loopback origin such as http://localhost:3000 for a Test key."
|
|
1288
|
+
))();
|
|
1246
1289
|
var identityIntegrationInputSchema = /* @__PURE__ */ (() => z6.object({
|
|
1247
1290
|
name: z6.string().trim().min(1).max(80),
|
|
1248
|
-
origin:
|
|
1249
|
-
const url = new URL(value);
|
|
1250
|
-
if (url.protocol !== "https:") {
|
|
1251
|
-
context.addIssue({ code: "custom", message: "Use an HTTPS origin." });
|
|
1252
|
-
} else if (url.origin !== value) {
|
|
1253
|
-
context.addIssue({
|
|
1254
|
-
code: "custom",
|
|
1255
|
-
message: `Use the exact origin ${url.origin}, without a path, query or trailing slash.`
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
}),
|
|
1291
|
+
origin: appLoginOriginSchema,
|
|
1259
1292
|
/**
|
|
1260
1293
|
* The identity kind this integration owns in the project and environment, such as
|
|
1261
1294
|
* `app:game`. Each member it signs in gets the exchanged subject as an identity of this
|
|
@@ -1408,6 +1441,7 @@ export {
|
|
|
1408
1441
|
memberImportSchema,
|
|
1409
1442
|
memberImportPageSchema,
|
|
1410
1443
|
memberImportListQuerySchema,
|
|
1444
|
+
boundedBodyText,
|
|
1411
1445
|
APP_SCHEDULE_LIMIT,
|
|
1412
1446
|
APP_SCHEDULE_MIN_INTERVAL,
|
|
1413
1447
|
APP_SCHEDULE_TIMEOUT,
|
|
@@ -1495,6 +1529,11 @@ export {
|
|
|
1495
1529
|
stagedDeploymentContentSchema,
|
|
1496
1530
|
stagedDeploymentKey,
|
|
1497
1531
|
buildArtifactsSchema,
|
|
1532
|
+
loopbackHosts,
|
|
1533
|
+
secureOrLoopbackOrigin,
|
|
1534
|
+
bareOrigin,
|
|
1535
|
+
httpsOriginSchema,
|
|
1536
|
+
appLoginOriginSchema,
|
|
1498
1537
|
identityIntegrationInputSchema,
|
|
1499
1538
|
identityIntegrationSchema,
|
|
1500
1539
|
identityIntegrationSecretSchema,
|