@domino-sdk/relay 1.67.0 → 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 +43 -0
- package/dist/{accounts-C2O8mpB8.d.ts → accounts-DnpKoJCo.d.ts} +210 -3
- package/dist/{attempt-captures-ClHAoo_n.d.ts → attempt-captures-DMNFMYFb.d.ts} +9 -1
- package/dist/authoring.d.ts +349 -38
- package/dist/authoring.js +125 -18
- package/dist/{automatic-outcomes-BEnPn4Uh.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 -13
- package/dist/{catalog-CbiftcxQ.d.ts → catalog-BLGie8Lh.d.ts} +60 -2
- package/dist/chunk-4JSPMFO2.js +427 -0
- package/dist/{chunk-5DZNMLDM.js → chunk-55WJVFWC.js} +2 -2
- package/dist/{chunk-Q5QVAF7R.js → chunk-5AKD4ZF3.js} +37 -25
- package/dist/{chunk-DSJ46QLB.js → chunk-6UBFSMCM.js} +1 -1
- package/dist/{chunk-P33ZAJMS.js → chunk-6YTSRWRB.js} +1199 -677
- package/dist/{chunk-RDUSFUXX.js → chunk-75KF633N.js} +9 -1
- package/dist/{chunk-Q6KTTVOI.js → chunk-7YSVZA7A.js} +1 -1
- package/dist/{chunk-BMJHFWVT.js → chunk-CZ7NQ7W7.js} +10 -43
- package/dist/{chunk-X3FMVRMM.js → chunk-DDJN2T5A.js} +1 -1
- package/dist/{chunk-KUNPCDN6.js → chunk-DNPDR4Z7.js} +16 -9
- package/dist/{chunk-RWR2LOPA.js → chunk-EXZVWQOQ.js} +2 -2
- package/dist/{chunk-MVQQDPQX.js → chunk-HXTKI34N.js} +14 -2
- package/dist/{chunk-FGXLXENM.js → chunk-IW46TW3A.js} +21 -1
- package/dist/{chunk-5SBA6X5X.js → chunk-KKHENO57.js} +2 -2
- package/dist/{chunk-U66GUVSG.js → chunk-LZXDYSUH.js} +2 -0
- package/dist/{chunk-QYC3CZVD.js → chunk-MEUAJIVO.js} +2 -2
- package/dist/{chunk-BQXRCJ3N.js → chunk-P4TPW4SY.js} +1 -1
- package/dist/{chunk-NRMQVK2W.js → chunk-R3MNZKNJ.js} +1 -1
- package/dist/{chunk-Z2Z5DBNW.js → chunk-SD74HD75.js} +45 -9
- package/dist/{chunk-JK3XV2CR.js → chunk-TYZFVL73.js} +50 -8
- package/dist/chunk-VAGGGB6B.js +87 -0
- package/dist/{chunk-2HHZV7U3.js → chunk-VRZZB7CQ.js} +1 -1
- package/dist/{client-CZPewB9h.d.ts → client-BMif22WQ.d.ts} +133 -7
- package/dist/{dashboards-jGPM3AxF.d.ts → dashboards-DMk-vL1q.d.ts} +4 -4
- package/dist/{deployments-BVFd7ddA.d.ts → deployments-BCr418BX.d.ts} +582 -173
- package/dist/{identity-integration-W1Vo3Ql9.d.ts → identity-integration-r76xaAax.d.ts} +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/dist/internal.d.ts +137 -14
- package/dist/internal.js +240 -19
- package/dist/{limits-C4RzrOV4.d.ts → limits-ByVRQePO.d.ts} +6 -1
- package/dist/{offers-BpYenB9i.d.ts → offers-xcPbYaEv.d.ts} +2 -2
- package/dist/portal-proxy.d.ts +2 -2
- package/dist/portal-proxy.js +11 -11
- package/dist/react/index.d.ts +37 -15
- package/dist/react/index.js +12 -13
- package/dist/{reward-deliveries-BOWpMytr.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 +398 -104
- package/dist/schema.js +62 -8
- package/dist/server/index.d.ts +12 -12
- package/dist/server/index.js +2046 -886
- package/dist/{sign-in-providers-BRYVOSlG.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-C152xIdn.d.ts → submission-input-CaL8drIh.d.ts} +2 -2
- package/dist/{telegram-browser-657QqiQl.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 +85 -13
- package/dist/testing.js +101 -11
- package/dist/{tracker-data-BqY-9Vu-.d.ts → tracker-data-CAK942sx.d.ts} +298 -1
- package/dist/{transport-CthYgZXK.d.ts → transport-CkidqTOk.d.ts} +5250 -1226
- package/dist/{wallet-Btng186v.d.ts → wallet-DQtJelQQ.d.ts} +367 -13
- package/dist/wallet-browser-dpmr22Xv.d.ts +106 -0
- package/package.json +16 -1
- package/dist/chunk-UWUS4OOV.js +0 -59
- package/dist/chunk-UYVJZR33.js +0 -34
- package/dist/runtime/chunks/C2MGLQXC.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",
|
|
@@ -1430,6 +1441,7 @@ export {
|
|
|
1430
1441
|
memberImportSchema,
|
|
1431
1442
|
memberImportPageSchema,
|
|
1432
1443
|
memberImportListQuerySchema,
|
|
1444
|
+
boundedBodyText,
|
|
1433
1445
|
APP_SCHEDULE_LIMIT,
|
|
1434
1446
|
APP_SCHEDULE_MIN_INTERVAL,
|
|
1435
1447
|
APP_SCHEDULE_TIMEOUT,
|