@domino-sdk/relay 1.0.0-next.7 → 1.0.0-next.8
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/dist/authoring.d.ts +11 -11
- package/dist/authoring.js +2 -2
- package/dist/avatar.d.ts +2 -2
- package/dist/browser.d.ts +217 -2285
- package/dist/browser.js +6 -6
- package/dist/{chunk-AWLLGCKU.js → chunk-6A6K5RUD.js} +22 -8
- package/dist/{chunk-SKETUPST.js → chunk-77H7APVD.js} +1 -1
- package/dist/{chunk-UFXBQ6FN.js → chunk-MRIURJE3.js} +2 -2
- package/dist/{chunk-ADSP377G.js → chunk-QBOHLT7M.js} +26 -5
- package/dist/{chunk-X6FJIPXR.js → chunk-V5R2DMGY.js} +553 -435
- package/dist/{chunk-DJZB5RY5.js → chunk-V7EZUZ3Z.js} +345 -243
- package/dist/{chunk-UW6R2QGT.js → chunk-VARGF4JS.js} +619 -610
- package/dist/{chunk-7HSTFBMO.js → chunk-ZWY3R6B3.js} +5 -3
- package/dist/{client-BufGakEt.d.ts → client-CK4nwt7V.d.ts} +307 -2253
- package/dist/{images-e6FW9QSx.d.ts → images--vZ9U0kr.d.ts} +2 -2
- package/dist/index.d.ts +6 -6
- package/dist/index.js +19 -7
- package/dist/internal.d.ts +16 -5
- package/dist/internal.js +12 -5
- package/dist/{catalog-C09gnPYT.d.ts → pages-BzqJuI69.d.ts} +79 -21
- package/dist/portal-proxy.js +6 -6
- package/dist/{profiles-BtOXMGcC.d.ts → profiles-DDMFBRKe.d.ts} +1 -1
- package/dist/react/index.d.ts +156 -2224
- package/dist/react/index.js +12 -10
- package/dist/{schema-DCapSPHz.d.ts → schema-pnuWqvGn.d.ts} +8 -8
- package/dist/schema.d.ts +64 -64
- package/dist/schema.js +15 -5
- package/dist/{submission-input-Bter6XiI.d.ts → submission-input-C9qm9ixd.d.ts} +8 -8
- package/dist/{wallet-Bu6sqJvQ.d.ts → wallet-BGOfFkG9.d.ts} +1 -1
- package/package.json +1 -1
|
@@ -3,10 +3,13 @@ import {
|
|
|
3
3
|
pointLedgerReferenceSchema,
|
|
4
4
|
questExperienceSchema,
|
|
5
5
|
rewardDeliveriesSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-MRIURJE3.js";
|
|
7
7
|
import {
|
|
8
8
|
AVATAR_UPLOAD_LIMIT,
|
|
9
|
+
RelayError,
|
|
10
|
+
RelayErrorCode,
|
|
9
11
|
avatarUploadTypes,
|
|
12
|
+
clientError,
|
|
10
13
|
engagementBoundaryPageSchema,
|
|
11
14
|
engagementPageQuerySchema,
|
|
12
15
|
engagementPageSchema,
|
|
@@ -16,6 +19,7 @@ import {
|
|
|
16
19
|
leaderboardQuerySchema,
|
|
17
20
|
linkedWalletSchema,
|
|
18
21
|
ownProfileSchema,
|
|
22
|
+
parseInput,
|
|
19
23
|
profileCompletionPageSchema,
|
|
20
24
|
profileCompletionQuerySchema,
|
|
21
25
|
profileReferralSchema,
|
|
@@ -27,20 +31,18 @@ import {
|
|
|
27
31
|
referralSummarySchema,
|
|
28
32
|
walletAddressInput,
|
|
29
33
|
walletAddressInputSchema,
|
|
30
|
-
walletChallengeInputSchema,
|
|
31
|
-
walletChallengeSchema,
|
|
32
|
-
walletConnectionSchema,
|
|
33
34
|
walletMessageChallengeSchema,
|
|
34
|
-
walletProofSchema,
|
|
35
35
|
walletSignInNetworksSchema,
|
|
36
36
|
walletSignatureSchema,
|
|
37
37
|
walletUnlinkInputSchema
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-V7EZUZ3Z.js";
|
|
39
39
|
import {
|
|
40
40
|
exchangeResultSchema,
|
|
41
|
+
exchangeSchema,
|
|
41
42
|
memberSummarySchema,
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
participantSessionSchema,
|
|
44
|
+
sessionMember
|
|
45
|
+
} from "./chunk-QBOHLT7M.js";
|
|
44
46
|
import {
|
|
45
47
|
accountConnectionSchema,
|
|
46
48
|
attemptSchema,
|
|
@@ -55,33 +57,17 @@ import {
|
|
|
55
57
|
contentQualificationPageSchema,
|
|
56
58
|
contentQualificationQuerySchema,
|
|
57
59
|
contentReleaseInputSchema,
|
|
58
|
-
entitlementSchema,
|
|
59
|
-
errorSchema,
|
|
60
60
|
evidenceSchema,
|
|
61
61
|
identifier,
|
|
62
62
|
memberProgressSchema,
|
|
63
|
-
|
|
63
|
+
pageQuerySchema,
|
|
64
64
|
quizEvidenceSchema,
|
|
65
|
-
snapshotSchema,
|
|
66
65
|
submissionEvidenceSchema,
|
|
67
|
-
|
|
66
|
+
submitSchema,
|
|
68
67
|
tieredRewardReferenceSchema,
|
|
69
68
|
validateSubmissionValue,
|
|
70
69
|
valueEvidenceSchema
|
|
71
|
-
} from "./chunk-
|
|
72
|
-
|
|
73
|
-
// src/errors.ts
|
|
74
|
-
var RelayError = class extends Error {
|
|
75
|
-
constructor(message, status, missing = [], code) {
|
|
76
|
-
super(message);
|
|
77
|
-
this.status = status;
|
|
78
|
-
this.missing = missing;
|
|
79
|
-
this.code = code;
|
|
80
|
-
}
|
|
81
|
-
status;
|
|
82
|
-
missing;
|
|
83
|
-
code;
|
|
84
|
-
};
|
|
70
|
+
} from "./chunk-VARGF4JS.js";
|
|
85
71
|
|
|
86
72
|
// src/submissions.ts
|
|
87
73
|
import { z } from "zod";
|
|
@@ -130,15 +116,20 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
130
116
|
input: "photo"
|
|
131
117
|
}) {
|
|
132
118
|
if (!configuredStore) {
|
|
133
|
-
throw
|
|
134
|
-
"Submissions require durable storage. Use createBrowserRelayClient or provide a SubmissionStore."
|
|
119
|
+
throw clientError(
|
|
120
|
+
"Submissions require durable storage. Use createBrowserRelayClient or provide a SubmissionStore.",
|
|
121
|
+
RelayErrorCode.SubmissionStorage
|
|
135
122
|
);
|
|
136
123
|
}
|
|
137
124
|
const store = configuredStore;
|
|
138
|
-
identifier
|
|
125
|
+
parseInput(identifier, quest);
|
|
139
126
|
const session = await transport.session();
|
|
140
|
-
|
|
141
|
-
|
|
127
|
+
const member = sessionMember(session);
|
|
128
|
+
if (!session || !member) {
|
|
129
|
+
throw clientError(
|
|
130
|
+
"Sign in to submit an activity",
|
|
131
|
+
RelayErrorCode.NotSignedIn
|
|
132
|
+
);
|
|
142
133
|
}
|
|
143
134
|
const sessionId = session.id;
|
|
144
135
|
const key = JSON.stringify([
|
|
@@ -147,14 +138,15 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
147
138
|
session.organization,
|
|
148
139
|
session.environment,
|
|
149
140
|
session.project,
|
|
150
|
-
|
|
141
|
+
member,
|
|
151
142
|
quest
|
|
152
143
|
]);
|
|
153
144
|
async function currentSession() {
|
|
154
145
|
const current = await transport.session();
|
|
155
146
|
if (current?.id !== sessionId) {
|
|
156
|
-
throw
|
|
157
|
-
"Your session changed. Reopen the submission before continuing."
|
|
147
|
+
throw clientError(
|
|
148
|
+
"Your session changed. Reopen the submission before continuing.",
|
|
149
|
+
RelayErrorCode.StaleSession
|
|
158
150
|
);
|
|
159
151
|
}
|
|
160
152
|
}
|
|
@@ -165,15 +157,17 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
165
157
|
}
|
|
166
158
|
const parsed = recordSchema.safeParse(saved);
|
|
167
159
|
if (!parsed.success || parsed.data.quest !== quest) {
|
|
168
|
-
throw
|
|
169
|
-
"Saved submission could not be read. Do not create another claim until it is recovered."
|
|
160
|
+
throw clientError(
|
|
161
|
+
"Saved submission could not be read. Do not create another claim until it is recovered.",
|
|
162
|
+
RelayErrorCode.SubmissionStorage
|
|
170
163
|
);
|
|
171
164
|
}
|
|
172
165
|
const record = parsed.data;
|
|
173
166
|
const input = record.stage === "review" ? record.draft?.kind : "input" in record ? record.input.kind : "photo";
|
|
174
167
|
if (!options.recoverPrevious && input !== options.input) {
|
|
175
|
-
throw
|
|
176
|
-
"Saved submission uses a different input type. Reopen it with its original type to recover it."
|
|
168
|
+
throw clientError(
|
|
169
|
+
"Saved submission uses a different input type. Reopen it with its original type to recover it.",
|
|
170
|
+
RelayErrorCode.SubmissionConflict
|
|
177
171
|
);
|
|
178
172
|
}
|
|
179
173
|
return record;
|
|
@@ -222,11 +216,12 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
222
216
|
await store.write(key, null);
|
|
223
217
|
throw error;
|
|
224
218
|
}
|
|
225
|
-
|
|
219
|
+
const changed = !(error instanceof RelayError) || error.status !== 409 ? null : error.code === "quest-updated" ? "quest-updated" : error.code === "stale-quiz" ? "stale-quiz" : null;
|
|
220
|
+
if (changed && error instanceof RelayError && record.stage === "claim") {
|
|
226
221
|
const draft = "input" in record ? record.input : "file" in record && record.file ? { kind: "photo", file: record.file } : null;
|
|
227
222
|
await store.write(
|
|
228
223
|
key,
|
|
229
|
-
|
|
224
|
+
changed === "quest-updated" ? {
|
|
230
225
|
id: record.id,
|
|
231
226
|
quest,
|
|
232
227
|
release: record.release,
|
|
@@ -234,7 +229,7 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
234
229
|
draft
|
|
235
230
|
} : null
|
|
236
231
|
);
|
|
237
|
-
throw new QuestUpdatedError(error.message,
|
|
232
|
+
throw new QuestUpdatedError(error.message, changed, draft, error);
|
|
238
233
|
}
|
|
239
234
|
throw error;
|
|
240
235
|
}
|
|
@@ -260,8 +255,9 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
260
255
|
);
|
|
261
256
|
}
|
|
262
257
|
if (existing && existing.stage !== "submitted" && existing.stage !== "review") {
|
|
263
|
-
throw
|
|
264
|
-
"A submission is unfinished. Resume it before choosing new input."
|
|
258
|
+
throw clientError(
|
|
259
|
+
"A submission is unfinished. Resume it before choosing new input.",
|
|
260
|
+
RelayErrorCode.SubmissionConflict
|
|
265
261
|
);
|
|
266
262
|
}
|
|
267
263
|
if (existing?.stage === "submitted") {
|
|
@@ -286,14 +282,16 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
286
282
|
return;
|
|
287
283
|
}
|
|
288
284
|
if (record.stage !== "submitted") {
|
|
289
|
-
throw
|
|
290
|
-
"Resume the unfinished submission before starting over."
|
|
285
|
+
throw clientError(
|
|
286
|
+
"Resume the unfinished submission before starting over.",
|
|
287
|
+
RelayErrorCode.SubmissionConflict
|
|
291
288
|
);
|
|
292
289
|
}
|
|
293
290
|
const attempt = await claim(record);
|
|
294
291
|
if (attempt.status !== "failed" && attempt.status !== "rejected" && !(options.repeatable && attempt.status === "accepted")) {
|
|
295
|
-
throw
|
|
296
|
-
"Only a failed or rejected submission can be discarded."
|
|
292
|
+
throw clientError(
|
|
293
|
+
"Only a failed or rejected submission can be discarded.",
|
|
294
|
+
RelayErrorCode.SubmissionConflict
|
|
297
295
|
);
|
|
298
296
|
}
|
|
299
297
|
await store.write(key, null);
|
|
@@ -315,7 +313,10 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
315
313
|
await currentSession();
|
|
316
314
|
const record = await read();
|
|
317
315
|
if (!record) {
|
|
318
|
-
throw
|
|
316
|
+
throw clientError(
|
|
317
|
+
"There is no saved submission to resume",
|
|
318
|
+
RelayErrorCode.SubmissionConflict
|
|
319
|
+
);
|
|
319
320
|
}
|
|
320
321
|
return resumeRecord(record);
|
|
321
322
|
});
|
|
@@ -326,7 +327,7 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
326
327
|
return {
|
|
327
328
|
...handle,
|
|
328
329
|
submit(value) {
|
|
329
|
-
const input = valueEvidenceSchema
|
|
330
|
+
const input = parseInput(valueEvidenceSchema, { kind, value });
|
|
330
331
|
return submit({
|
|
331
332
|
id: crypto.randomUUID(),
|
|
332
333
|
quest,
|
|
@@ -341,7 +342,7 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
341
342
|
return {
|
|
342
343
|
...handle,
|
|
343
344
|
submit(answers, version) {
|
|
344
|
-
const input = quizEvidenceSchema
|
|
345
|
+
const input = parseInput(quizEvidenceSchema, {
|
|
345
346
|
kind: "quiz",
|
|
346
347
|
answers,
|
|
347
348
|
...version || options.release ? { release: version?.release ?? options.release } : {}
|
|
@@ -374,12 +375,18 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
374
375
|
...handle,
|
|
375
376
|
async submit(file) {
|
|
376
377
|
if (!["image/jpeg", "image/png"].includes(file.type) || file.size === 0 || file.size > 5 * 1024 * 1024) {
|
|
377
|
-
throw
|
|
378
|
+
throw clientError(
|
|
379
|
+
"Choose a JPG or PNG photo under 5 MB",
|
|
380
|
+
RelayErrorCode.InvalidInput
|
|
381
|
+
);
|
|
378
382
|
}
|
|
379
383
|
const bytes = new Uint8Array(await file.slice(0, 4).arrayBuffer());
|
|
380
384
|
const signature = file.type === "image/png" ? [137, 80, 78, 71] : [255, 216, 255];
|
|
381
385
|
if (!signature.every((byte, index) => bytes[index] === byte)) {
|
|
382
|
-
throw
|
|
386
|
+
throw clientError(
|
|
387
|
+
"Image content does not match its file type",
|
|
388
|
+
RelayErrorCode.InvalidInput
|
|
389
|
+
);
|
|
383
390
|
}
|
|
384
391
|
return submit({
|
|
385
392
|
id: crypto.randomUUID(),
|
|
@@ -394,11 +401,18 @@ function submissions(transport, configuredStore, namespace) {
|
|
|
394
401
|
return open;
|
|
395
402
|
}
|
|
396
403
|
var QuestUpdatedError = class extends RelayError {
|
|
397
|
-
constructor(message, code, draft) {
|
|
398
|
-
super(message,
|
|
404
|
+
constructor(message, code, draft, source) {
|
|
405
|
+
super(message, {
|
|
406
|
+
kind: source?.kind ?? "client",
|
|
407
|
+
status: source?.status,
|
|
408
|
+
code,
|
|
409
|
+
operationId: source?.operationId,
|
|
410
|
+
cause: source
|
|
411
|
+
});
|
|
399
412
|
this.draft = draft;
|
|
400
413
|
}
|
|
401
414
|
draft;
|
|
415
|
+
name = "QuestUpdatedError";
|
|
402
416
|
};
|
|
403
417
|
|
|
404
418
|
// src/client.ts
|
|
@@ -410,8 +424,9 @@ function observeProgress(transport, listener, options = {}, onDispose = () => {
|
|
|
410
424
|
const interval = options.intervalMs ?? 1500;
|
|
411
425
|
const maximum = options.maxBackoffMs ?? 3e4;
|
|
412
426
|
if (!Number.isFinite(interval) || interval <= 0 || !Number.isFinite(maximum) || maximum < interval) {
|
|
413
|
-
throw
|
|
414
|
-
"Progress polling requires a positive interval and a maximum at least as large"
|
|
427
|
+
throw clientError(
|
|
428
|
+
"Progress polling requires a positive interval and a maximum at least as large",
|
|
429
|
+
RelayErrorCode.InvalidInput
|
|
415
430
|
);
|
|
416
431
|
}
|
|
417
432
|
let disposed = false;
|
|
@@ -449,7 +464,8 @@ function observeProgress(transport, listener, options = {}, onDispose = () => {
|
|
|
449
464
|
sessionId = session?.id ?? null;
|
|
450
465
|
listener({ kind: "session", session });
|
|
451
466
|
}
|
|
452
|
-
|
|
467
|
+
const member = sessionMember(session);
|
|
468
|
+
if (session && member) {
|
|
453
469
|
const progress = await transport.progress(session.id, request.signal);
|
|
454
470
|
if (!current()) {
|
|
455
471
|
return;
|
|
@@ -458,7 +474,7 @@ function observeProgress(transport, listener, options = {}, onDispose = () => {
|
|
|
458
474
|
if (!current()) {
|
|
459
475
|
return;
|
|
460
476
|
}
|
|
461
|
-
if (confirmed?.id !== session.id || progress.member !==
|
|
477
|
+
if (confirmed?.id !== session.id || progress.member !== member) {
|
|
462
478
|
sessionId = void 0;
|
|
463
479
|
listener({ kind: "loading" });
|
|
464
480
|
return;
|
|
@@ -581,14 +597,17 @@ function questActions(submission, latest) {
|
|
|
581
597
|
resume: () => run(handle.resume),
|
|
582
598
|
submit: (value) => run(() => {
|
|
583
599
|
if (view.trigger.kind !== "manual" || view.trigger.input !== "text" && view.trigger.input !== "url") {
|
|
584
|
-
throw
|
|
600
|
+
throw clientError(
|
|
601
|
+
"Quest input changed",
|
|
602
|
+
RelayErrorCode.QuestUpdated
|
|
603
|
+
);
|
|
585
604
|
}
|
|
586
605
|
const problem = validateSubmissionValue(
|
|
587
606
|
{ kind, value },
|
|
588
607
|
view.trigger
|
|
589
608
|
);
|
|
590
609
|
if (problem) {
|
|
591
|
-
throw
|
|
610
|
+
throw clientError(problem, RelayErrorCode.InvalidInput);
|
|
592
611
|
}
|
|
593
612
|
return handle.submit(value);
|
|
594
613
|
})
|
|
@@ -647,9 +666,76 @@ function questActions(submission, latest) {
|
|
|
647
666
|
}
|
|
648
667
|
|
|
649
668
|
// src/client.ts
|
|
669
|
+
var TIMEOUT_MS = 15e3;
|
|
670
|
+
var missingEntrySchema = z2.object({ quest: identifier, title: z2.string() });
|
|
671
|
+
function errorBody(value) {
|
|
672
|
+
const body = value !== null && typeof value === "object" ? value : {};
|
|
673
|
+
return {
|
|
674
|
+
message: typeof body.error === "string" && body.error.trim() ? body.error : void 0,
|
|
675
|
+
code: typeof body.code === "string" && body.code.trim() ? body.code : void 0,
|
|
676
|
+
missing: Array.isArray(body.missing) ? body.missing.flatMap((entry) => {
|
|
677
|
+
const parsed = missingEntrySchema.safeParse(entry);
|
|
678
|
+
return parsed.success ? [parsed.data] : [];
|
|
679
|
+
}) : []
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
async function fromSigner(step) {
|
|
683
|
+
try {
|
|
684
|
+
return await step();
|
|
685
|
+
} catch (error) {
|
|
686
|
+
if (error instanceof RelayError) {
|
|
687
|
+
throw error;
|
|
688
|
+
}
|
|
689
|
+
throw clientError(
|
|
690
|
+
error instanceof Error && error.message ? error.message : "The wallet did not complete the request",
|
|
691
|
+
RelayErrorCode.WalletSigner,
|
|
692
|
+
{ cause: error }
|
|
693
|
+
);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
var uncertainStatuses = /* @__PURE__ */ new Set([500, 502, 504]);
|
|
697
|
+
var methodOf = (call) => call.method ?? (call.json === void 0 ? "GET" : "POST");
|
|
698
|
+
function withQuery(path, values) {
|
|
699
|
+
const params = new URLSearchParams();
|
|
700
|
+
for (const [key, value] of Object.entries(values)) {
|
|
701
|
+
if (value !== void 0) {
|
|
702
|
+
params.set(key, String(value));
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
const search = params.toString();
|
|
706
|
+
return search ? path + "?" + search : path;
|
|
707
|
+
}
|
|
708
|
+
function interrupted(call, error, stage) {
|
|
709
|
+
const details = {
|
|
710
|
+
status: stage.status,
|
|
711
|
+
operationId: call.operationId,
|
|
712
|
+
uncertain: stage.sent && methodOf(call) !== "GET",
|
|
713
|
+
cause: error
|
|
714
|
+
};
|
|
715
|
+
if (call.options?.signal?.aborted) {
|
|
716
|
+
return new RelayError("The request was cancelled", {
|
|
717
|
+
...details,
|
|
718
|
+
kind: "aborted",
|
|
719
|
+
code: RelayErrorCode.Aborted
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
if (call.deadline?.aborted) {
|
|
723
|
+
return new RelayError("Relay did not respond in time", {
|
|
724
|
+
...details,
|
|
725
|
+
kind: "timeout",
|
|
726
|
+
code: RelayErrorCode.Timeout
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
return new RelayError(
|
|
730
|
+
stage.status === void 0 ? "Could not reach Relay" : "Relay's response was cut off",
|
|
731
|
+
{ ...details, kind: "network", code: RelayErrorCode.Network }
|
|
732
|
+
);
|
|
733
|
+
}
|
|
650
734
|
function createRelayClient(options) {
|
|
651
|
-
async function send(path,
|
|
652
|
-
const
|
|
735
|
+
async function send(path, call = {}) {
|
|
736
|
+
const method = methodOf(call);
|
|
737
|
+
const headers = new Headers(call.headers);
|
|
738
|
+
let body2 = call.body;
|
|
653
739
|
if (options.token) {
|
|
654
740
|
headers.set("Authorization", `Bearer ${options.token}`);
|
|
655
741
|
}
|
|
@@ -662,38 +748,97 @@ function createRelayClient(options) {
|
|
|
662
748
|
if (options.environment) {
|
|
663
749
|
headers.set("X-Relay-Environment", options.environment);
|
|
664
750
|
}
|
|
665
|
-
if (
|
|
751
|
+
if (call.options?.session) {
|
|
752
|
+
headers.set("X-Relay-Session", call.options.session);
|
|
753
|
+
}
|
|
754
|
+
if (call.json !== void 0) {
|
|
755
|
+
headers.set("Content-Type", "application/json");
|
|
756
|
+
body2 = JSON.stringify(call.json);
|
|
757
|
+
}
|
|
758
|
+
if (method !== "GET") {
|
|
666
759
|
headers.set("X-Relay-CSRF", "1");
|
|
667
760
|
}
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
761
|
+
const caller = call.options?.signal;
|
|
762
|
+
const deadline = AbortSignal.timeout(TIMEOUT_MS);
|
|
763
|
+
call.deadline = deadline;
|
|
764
|
+
if (caller?.aborted) {
|
|
765
|
+
throw interrupted(call, caller.reason, { sent: false });
|
|
766
|
+
}
|
|
767
|
+
let response;
|
|
768
|
+
try {
|
|
769
|
+
response = await fetch(options.baseUrl + path, {
|
|
770
|
+
method,
|
|
771
|
+
headers,
|
|
772
|
+
body: body2,
|
|
773
|
+
signal: caller ? AbortSignal.any([caller, deadline]) : deadline
|
|
774
|
+
});
|
|
775
|
+
} catch (error) {
|
|
776
|
+
throw interrupted(call, error, { sent: true });
|
|
777
|
+
}
|
|
673
778
|
if (!response.ok) {
|
|
674
|
-
const
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
)
|
|
779
|
+
const text = await response.text().catch(() => "");
|
|
780
|
+
let value = null;
|
|
781
|
+
try {
|
|
782
|
+
value = JSON.parse(text);
|
|
783
|
+
} catch {
|
|
784
|
+
}
|
|
785
|
+
const { message, code, missing } = errorBody(value);
|
|
786
|
+
throw new RelayError(message ?? `Request failed (${response.status})`, {
|
|
787
|
+
kind: "http",
|
|
788
|
+
status: response.status,
|
|
789
|
+
code,
|
|
790
|
+
missing,
|
|
791
|
+
operationId: call.operationId,
|
|
792
|
+
uncertain: methodOf(call) !== "GET" && uncertainStatuses.has(response.status)
|
|
793
|
+
});
|
|
682
794
|
}
|
|
683
795
|
return response;
|
|
684
796
|
}
|
|
685
|
-
async function
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
797
|
+
async function body(response, call, reader) {
|
|
798
|
+
try {
|
|
799
|
+
return await reader(response);
|
|
800
|
+
} catch (error) {
|
|
801
|
+
throw interrupted(call, error, { sent: true, status: response.status });
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
function invalidResponse(status, call, cause) {
|
|
805
|
+
return new RelayError(
|
|
806
|
+
"Relay sent a response this SDK version cannot read. Update @domino-sdk/relay.",
|
|
807
|
+
{
|
|
808
|
+
kind: "invalid-response",
|
|
809
|
+
code: RelayErrorCode.InvalidResponse,
|
|
810
|
+
status,
|
|
811
|
+
operationId: call.operationId,
|
|
812
|
+
// Relay accepted the write, but this client cannot tell what it did.
|
|
813
|
+
uncertain: methodOf(call) !== "GET",
|
|
814
|
+
cause
|
|
815
|
+
}
|
|
816
|
+
);
|
|
689
817
|
}
|
|
690
|
-
async function
|
|
818
|
+
async function read(response, schema, call) {
|
|
819
|
+
const text = await body(response, call, (value2) => value2.text());
|
|
820
|
+
let value;
|
|
821
|
+
try {
|
|
822
|
+
value = JSON.parse(text);
|
|
823
|
+
} catch (error) {
|
|
824
|
+
throw invalidResponse(response.status, call, error);
|
|
825
|
+
}
|
|
826
|
+
const parsed = schema.safeParse(value);
|
|
827
|
+
if (!parsed.success) {
|
|
828
|
+
throw invalidResponse(response.status, call, parsed.error);
|
|
829
|
+
}
|
|
830
|
+
return parsed.data;
|
|
831
|
+
}
|
|
832
|
+
async function request(path, schema, call = {}) {
|
|
833
|
+
return read(await send(path, call), schema, call);
|
|
834
|
+
}
|
|
835
|
+
async function walletRequest(path, schema, call = {}) {
|
|
691
836
|
for (let attempt = 0; ; attempt++) {
|
|
692
837
|
let response;
|
|
693
838
|
try {
|
|
694
|
-
response = await send(path,
|
|
839
|
+
response = await send(path, call);
|
|
695
840
|
} catch (error) {
|
|
696
|
-
const transient = error instanceof RelayError &&
|
|
841
|
+
const transient = error instanceof RelayError && (error.kind === "network" || error.kind === "timeout" || error.kind === "http" && [500, 502, 503, 504].includes(error.status ?? 0));
|
|
697
842
|
if (!transient || attempt === 2) {
|
|
698
843
|
throw error;
|
|
699
844
|
}
|
|
@@ -702,54 +847,40 @@ function createRelayClient(options) {
|
|
|
702
847
|
);
|
|
703
848
|
continue;
|
|
704
849
|
}
|
|
705
|
-
|
|
706
|
-
return schema.parse(value);
|
|
850
|
+
return read(response, schema, call);
|
|
707
851
|
}
|
|
708
852
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
853
|
+
const readSession = (requestOptions) => request("/v1/auth/session", participantSessionSchema.nullable(), {
|
|
854
|
+
options: { signal: requestOptions?.signal }
|
|
855
|
+
});
|
|
856
|
+
async function bound(requestOptions = {}) {
|
|
857
|
+
if (requestOptions.session) {
|
|
858
|
+
return requestOptions;
|
|
715
859
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
headers: { "Content-Type": "application/json" },
|
|
722
|
-
body: JSON.stringify(body)
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
function sessionHeaders(session) {
|
|
726
|
-
return { "Content-Type": "application/json", "X-Relay-Session": session };
|
|
860
|
+
const session = await readSession(requestOptions);
|
|
861
|
+
if (session?.principal.kind !== "member") {
|
|
862
|
+
throw clientError("Sign in to continue", RelayErrorCode.NotSignedIn);
|
|
863
|
+
}
|
|
864
|
+
return { ...requestOptions, session: session.id };
|
|
727
865
|
}
|
|
728
866
|
const submission = submissions(
|
|
729
867
|
{
|
|
730
|
-
session: () =>
|
|
868
|
+
session: () => readSession(),
|
|
731
869
|
upload: (file, action, session) => request("/v1/me/evidence", evidenceSchema, {
|
|
732
870
|
method: "POST",
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
},
|
|
738
|
-
body: file
|
|
871
|
+
body: file,
|
|
872
|
+
headers: { "Content-Type": file.type, "X-Relay-Upload-ID": action },
|
|
873
|
+
options: { session },
|
|
874
|
+
operationId: action
|
|
739
875
|
}),
|
|
740
|
-
claim: (
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
"X-Relay-Session": session
|
|
745
|
-
}
|
|
876
|
+
claim: async (claim, session) => request("/v1/me/attempts", attemptSchema, {
|
|
877
|
+
json: claim,
|
|
878
|
+
options: { session },
|
|
879
|
+
operationId: claim.actionId
|
|
746
880
|
}),
|
|
747
881
|
retry: (attempt, session) => request(`/v1/attempts/${attempt}/retry`, attemptSchema, {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
"Content-Type": "application/json",
|
|
751
|
-
"X-Relay-Session": session
|
|
752
|
-
}
|
|
882
|
+
json: {},
|
|
883
|
+
options: { session }
|
|
753
884
|
})
|
|
754
885
|
},
|
|
755
886
|
options.submissionStore,
|
|
@@ -768,180 +899,205 @@ function createRelayClient(options) {
|
|
|
768
899
|
}
|
|
769
900
|
}
|
|
770
901
|
}
|
|
771
|
-
const experience = () => request("/v1/me/experience", questExperienceSchema
|
|
772
|
-
|
|
773
|
-
|
|
902
|
+
const experience = (requestOptions) => request("/v1/me/experience", questExperienceSchema, {
|
|
903
|
+
options: requestOptions
|
|
904
|
+
});
|
|
905
|
+
async function getQuest(id, requestOptions) {
|
|
906
|
+
const quest = (await experience(requestOptions)).quests.find(
|
|
774
907
|
(q) => q.quest === id || q.key === id
|
|
775
908
|
);
|
|
776
909
|
if (!quest) {
|
|
777
|
-
throw
|
|
910
|
+
throw clientError("Quest not found", RelayErrorCode.NotFound);
|
|
778
911
|
}
|
|
779
912
|
return quest;
|
|
780
913
|
}
|
|
914
|
+
const ok = z2.object({ ok: z2.literal(true) });
|
|
915
|
+
const acknowledged = z2.object({ ok: z2.boolean() });
|
|
781
916
|
return {
|
|
782
917
|
referrals: {
|
|
783
|
-
list: () => request("/v1/referrals", z2.array(referralDefinitionSchema)
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
918
|
+
list: (requestOptions) => request("/v1/referrals", z2.array(referralDefinitionSchema), {
|
|
919
|
+
options: requestOptions
|
|
920
|
+
}),
|
|
921
|
+
summary: (requestOptions) => request("/v1/referrals/me", referralSummarySchema, {
|
|
922
|
+
options: requestOptions
|
|
923
|
+
}),
|
|
924
|
+
/** The member's referral point history, newest first. */
|
|
925
|
+
history: async (query = {}, requestOptions) => request(
|
|
926
|
+
withQuery("/v1/referrals/history", parseInput(pageQuerySchema, query)),
|
|
927
|
+
referralHistorySchema,
|
|
928
|
+
{ options: requestOptions }
|
|
788
929
|
),
|
|
789
|
-
accept:
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
930
|
+
accept: async (value, requestOptions) => {
|
|
931
|
+
const body2 = parseInput(referralAcceptSchema, value);
|
|
932
|
+
return request("/v1/referrals/accept", ok, {
|
|
933
|
+
json: body2,
|
|
934
|
+
options: requestOptions,
|
|
935
|
+
operationId: body2.actionId
|
|
936
|
+
});
|
|
937
|
+
}
|
|
793
938
|
},
|
|
794
939
|
tieredRewards: {
|
|
795
940
|
/**
|
|
796
941
|
* The project's tiered rewards with their keys. Entitlements and reward
|
|
797
942
|
* definitions name them by ID: use this to find the ID for a key.
|
|
798
943
|
*/
|
|
799
|
-
list: () => request("/v1/tiered-rewards", z2.array(tieredRewardReferenceSchema)
|
|
944
|
+
list: (requestOptions) => request("/v1/tiered-rewards", z2.array(tieredRewardReferenceSchema), {
|
|
945
|
+
options: requestOptions
|
|
946
|
+
})
|
|
800
947
|
},
|
|
801
948
|
pointLedgers: {
|
|
802
949
|
/**
|
|
803
950
|
* The project's point ledgers with their keys and names. Reads return
|
|
804
951
|
* ledger IDs: use this to find the ID for a key, or a ledger's name.
|
|
805
952
|
*/
|
|
806
|
-
list: () => request("/v1/point-ledgers", z2.array(pointLedgerReferenceSchema)
|
|
953
|
+
list: (requestOptions) => request("/v1/point-ledgers", z2.array(pointLedgerReferenceSchema), {
|
|
954
|
+
options: requestOptions
|
|
955
|
+
})
|
|
807
956
|
},
|
|
808
957
|
leaderboards: {
|
|
809
|
-
list: () => request("/v1/leaderboards", z2.array(leaderboardDefinitionSchema)
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
958
|
+
list: (requestOptions) => request("/v1/leaderboards", z2.array(leaderboardDefinitionSchema), {
|
|
959
|
+
options: requestOptions
|
|
960
|
+
}),
|
|
961
|
+
standings: async (board, query = {}, requestOptions) => request(
|
|
962
|
+
withQuery(
|
|
963
|
+
`/v1/leaderboards/${parseInput(identifier, board)}`,
|
|
964
|
+
parseInput(leaderboardQuerySchema, query)
|
|
965
|
+
),
|
|
966
|
+
leaderboardPageSchema,
|
|
967
|
+
{ options: requestOptions }
|
|
968
|
+
),
|
|
817
969
|
/**
|
|
818
970
|
* A profile's current rank and score on `board` (`profile.id` from a leaderboard row or
|
|
819
971
|
* `profiles.mine()`). Needs the board's access, like `standings`; a profile this viewer
|
|
820
972
|
* cannot see is a 404, as in `profiles.get`.
|
|
821
973
|
*/
|
|
822
|
-
placement: (board, profile) => request(
|
|
823
|
-
`/v1/leaderboards/${identifier
|
|
824
|
-
leaderboardPlacementSchema
|
|
974
|
+
placement: async (board, profile, requestOptions) => request(
|
|
975
|
+
`/v1/leaderboards/${parseInput(identifier, board)}/profiles/${parseInput(identifier, profile)}`,
|
|
976
|
+
leaderboardPlacementSchema,
|
|
977
|
+
{ options: requestOptions }
|
|
825
978
|
)
|
|
826
979
|
},
|
|
827
980
|
/**
|
|
828
981
|
* Participant profiles: the display name and avatar other participants see where the project
|
|
829
|
-
* enables profiles in Console. Render an avatar with `avatarSrc(profile.avatar)
|
|
982
|
+
* enables profiles in Console. Render an avatar with `avatarSrc(profile.avatar)` from
|
|
983
|
+
* `@domino-sdk/relay/avatar`.
|
|
830
984
|
*/
|
|
831
985
|
profiles: {
|
|
832
986
|
/** The signed-in member's own profile, whatever the project shows to others. */
|
|
833
|
-
mine: () => request("/v1/me/profile", ownProfileSchema
|
|
987
|
+
mine: (requestOptions) => request("/v1/me/profile", ownProfileSchema, {
|
|
988
|
+
options: requestOptions
|
|
989
|
+
}),
|
|
834
990
|
/**
|
|
835
991
|
* Changes the member's own name, avatar choice or visibility; omitted fields stay, and null
|
|
836
|
-
* returns to the default.
|
|
992
|
+
* returns to the default.
|
|
837
993
|
*/
|
|
838
|
-
update: async (
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
"Content-Type": "application/json",
|
|
842
|
-
...options2.session ? { "X-Relay-Session": options2.session } : {}
|
|
843
|
-
},
|
|
844
|
-
body: JSON.stringify(profileUpdateSchema.parse(input))
|
|
994
|
+
update: async (value, requestOptions) => request("/v1/me/profile", ownProfileSchema, {
|
|
995
|
+
json: parseInput(profileUpdateSchema, value),
|
|
996
|
+
options: requestOptions
|
|
845
997
|
}),
|
|
846
998
|
/**
|
|
847
999
|
* Uploads a JPEG, PNG or WebP of at most 5 MB as the member's avatar. The server crops it to
|
|
848
1000
|
* a 512×512 WebP without metadata. Retrying with the same `uploadId` is idempotent.
|
|
849
1001
|
*/
|
|
850
|
-
uploadAvatar: async (file,
|
|
1002
|
+
uploadAvatar: async (file, requestOptions = {}) => {
|
|
851
1003
|
if (!avatarUploadTypes.includes(file.type)) {
|
|
852
|
-
throw
|
|
1004
|
+
throw clientError(
|
|
1005
|
+
"Use a JPEG, PNG or WebP image",
|
|
1006
|
+
RelayErrorCode.InvalidInput
|
|
1007
|
+
);
|
|
853
1008
|
}
|
|
854
1009
|
if (file.size > AVATAR_UPLOAD_LIMIT) {
|
|
855
|
-
throw
|
|
1010
|
+
throw clientError(
|
|
1011
|
+
"Use an image smaller than 5 MB",
|
|
1012
|
+
RelayErrorCode.InvalidInput
|
|
1013
|
+
);
|
|
856
1014
|
}
|
|
1015
|
+
const { uploadId, ...rest } = requestOptions;
|
|
1016
|
+
const operationId = parseInput(identifier, uploadId ?? crypto.randomUUID());
|
|
857
1017
|
return request("/v1/me/profile/avatar", ownProfileSchema, {
|
|
858
1018
|
method: "POST",
|
|
1019
|
+
body: file,
|
|
859
1020
|
headers: {
|
|
860
1021
|
"Content-Type": file.type,
|
|
861
|
-
"X-Relay-Upload-ID":
|
|
862
|
-
options2.uploadId ?? crypto.randomUUID()
|
|
863
|
-
),
|
|
864
|
-
...options2.session ? { "X-Relay-Session": options2.session } : {}
|
|
1022
|
+
"X-Relay-Upload-ID": operationId
|
|
865
1023
|
},
|
|
866
|
-
|
|
1024
|
+
options: rest,
|
|
1025
|
+
operationId
|
|
867
1026
|
});
|
|
868
1027
|
},
|
|
869
1028
|
/**
|
|
870
1029
|
* A profile's name and avatar by its public ID (`profile.id` from a leaderboard row or
|
|
871
1030
|
* `mine()`). A profile that is missing, hidden or not visible to this viewer is a 404.
|
|
872
1031
|
*/
|
|
873
|
-
get: (profile) => request(
|
|
874
|
-
`/v1/profiles/${identifier
|
|
875
|
-
profileSummarySchema
|
|
1032
|
+
get: async (profile, requestOptions) => request(
|
|
1033
|
+
`/v1/profiles/${parseInput(identifier, profile)}`,
|
|
1034
|
+
profileSummarySchema,
|
|
1035
|
+
{ options: requestOptions }
|
|
876
1036
|
),
|
|
877
1037
|
/**
|
|
878
1038
|
* A page of the profile's completions of quests that show on profiles, most recently
|
|
879
|
-
* completed first.
|
|
1039
|
+
* completed first.
|
|
880
1040
|
*/
|
|
881
|
-
completions: (profile,
|
|
882
|
-
|
|
883
|
-
`/v1/profiles/${identifier
|
|
884
|
-
profileCompletionQuerySchema
|
|
1041
|
+
completions: async (profile, query = {}, requestOptions) => request(
|
|
1042
|
+
withQuery(
|
|
1043
|
+
`/v1/profiles/${parseInput(identifier, profile)}/completions`,
|
|
1044
|
+
parseInput(profileCompletionQuerySchema, query)
|
|
885
1045
|
),
|
|
886
|
-
profileCompletionPageSchema
|
|
1046
|
+
profileCompletionPageSchema,
|
|
1047
|
+
{ options: requestOptions }
|
|
887
1048
|
),
|
|
888
1049
|
/**
|
|
889
1050
|
* The profile's invited and qualified counts and milestones in one referral program. Needs
|
|
890
1051
|
* a signed-in participant, as referral programs do.
|
|
891
1052
|
*/
|
|
892
|
-
referral: (profile, program) => request(
|
|
893
|
-
`/v1/profiles/${identifier
|
|
894
|
-
profileReferralSchema
|
|
1053
|
+
referral: async (profile, program, requestOptions) => request(
|
|
1054
|
+
`/v1/profiles/${parseInput(identifier, profile)}/referrals/${parseInput(identifier, program)}`,
|
|
1055
|
+
profileReferralSchema,
|
|
1056
|
+
{ options: requestOptions }
|
|
895
1057
|
)
|
|
896
1058
|
},
|
|
897
1059
|
quests: {
|
|
898
1060
|
get: getQuest,
|
|
899
|
-
|
|
1061
|
+
/** Retries verification of the quest's failed attempt. */
|
|
1062
|
+
retry: async (view, requestOptions) => {
|
|
900
1063
|
if (view.trigger.kind === "automatic") {
|
|
901
|
-
throw
|
|
902
|
-
"Automatic quests recover without participant retries."
|
|
1064
|
+
throw clientError(
|
|
1065
|
+
"Automatic quests recover without participant retries.",
|
|
1066
|
+
RelayErrorCode.RetryUnavailable
|
|
903
1067
|
);
|
|
904
1068
|
}
|
|
905
1069
|
if (!view.attempt || view.attempt.status !== "failed") {
|
|
906
|
-
throw
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
sessionSchema.nullable()
|
|
911
|
-
);
|
|
912
|
-
if (session?.principal.kind !== "member") {
|
|
913
|
-
throw new Error("Sign in to retry verification.");
|
|
1070
|
+
throw clientError(
|
|
1071
|
+
"There is no failed attempt to retry.",
|
|
1072
|
+
RelayErrorCode.RetryUnavailable
|
|
1073
|
+
);
|
|
914
1074
|
}
|
|
915
1075
|
return request(`/v1/attempts/${view.attempt.id}/retry`, attemptSchema, {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
"Content-Type": "application/json",
|
|
919
|
-
"X-Relay-Session": session.id
|
|
920
|
-
}
|
|
1076
|
+
json: {},
|
|
1077
|
+
options: await bound(requestOptions)
|
|
921
1078
|
});
|
|
922
1079
|
},
|
|
923
1080
|
experience,
|
|
924
|
-
collection: async (id) => {
|
|
925
|
-
const collection = (await experience()).collections.find(
|
|
1081
|
+
collection: async (id, requestOptions) => {
|
|
1082
|
+
const collection = (await experience(requestOptions)).collections.find(
|
|
926
1083
|
(c) => c.id === id || c.key === id
|
|
927
1084
|
);
|
|
928
1085
|
if (!collection) {
|
|
929
|
-
throw
|
|
1086
|
+
throw clientError("Collection not found", RelayErrorCode.NotFound);
|
|
930
1087
|
}
|
|
931
1088
|
return collection;
|
|
932
1089
|
},
|
|
933
|
-
open: questActions(submission, getQuest),
|
|
934
|
-
observe: (listener,
|
|
1090
|
+
open: questActions(submission, (id) => getQuest(id)),
|
|
1091
|
+
observe: (listener, observeOptions) => {
|
|
935
1092
|
const observer = observeProgress(
|
|
936
1093
|
{
|
|
937
|
-
session: (signal) =>
|
|
1094
|
+
session: (signal) => readSession({ signal }),
|
|
938
1095
|
progress: (session, signal) => request("/v1/me/experience", questExperienceSchema, {
|
|
939
|
-
signal
|
|
940
|
-
headers: { "X-Relay-Session": session }
|
|
1096
|
+
options: { session, signal }
|
|
941
1097
|
})
|
|
942
1098
|
},
|
|
943
1099
|
listener,
|
|
944
|
-
|
|
1100
|
+
observeOptions,
|
|
945
1101
|
() => observers.delete(observer)
|
|
946
1102
|
);
|
|
947
1103
|
observers.add(observer);
|
|
@@ -952,75 +1108,59 @@ function createRelayClient(options) {
|
|
|
952
1108
|
},
|
|
953
1109
|
/** The signed-in member's linked Solana, EVM and Cosmos wallets for this project. */
|
|
954
1110
|
wallets: {
|
|
955
|
-
list: () => walletRequest(
|
|
1111
|
+
list: (requestOptions) => walletRequest(
|
|
956
1112
|
"/v1/me/wallets",
|
|
957
|
-
z2.object({ wallets: z2.array(linkedWalletSchema) })
|
|
1113
|
+
z2.object({ wallets: z2.array(linkedWalletSchema) }),
|
|
1114
|
+
{ options: requestOptions }
|
|
958
1115
|
).then((result) => result.wallets),
|
|
959
|
-
challenge: (
|
|
1116
|
+
challenge: async (value, requestOptions) => walletRequest(
|
|
960
1117
|
"/v1/me/wallets/challenge",
|
|
961
1118
|
walletMessageChallengeSchema,
|
|
962
1119
|
{
|
|
963
|
-
|
|
964
|
-
|
|
1120
|
+
json: parseInput(walletAddressInputSchema, value),
|
|
1121
|
+
options: await bound(requestOptions)
|
|
965
1122
|
}
|
|
966
1123
|
),
|
|
967
|
-
verify: (
|
|
968
|
-
|
|
969
|
-
|
|
1124
|
+
verify: async (value, requestOptions) => walletRequest("/v1/me/wallets/verify", linkedWalletSchema, {
|
|
1125
|
+
json: parseInput(walletSignatureSchema, value),
|
|
1126
|
+
options: await bound(requestOptions)
|
|
970
1127
|
}),
|
|
971
1128
|
/** The address stays bound to this member: another member still cannot link it. */
|
|
972
|
-
unlink: (wallet) => request(
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
})
|
|
980
|
-
)
|
|
981
|
-
),
|
|
1129
|
+
unlink: async (wallet, requestOptions) => request("/v1/me/wallets/unlink", ok, {
|
|
1130
|
+
json: parseInput(walletUnlinkInputSchema, {
|
|
1131
|
+
chain: wallet.chain,
|
|
1132
|
+
address: wallet.address
|
|
1133
|
+
}),
|
|
1134
|
+
options: requestOptions
|
|
1135
|
+
}),
|
|
982
1136
|
/** Asks the signer for its address, signs the returned challenge, and links the wallet. */
|
|
983
|
-
link: async (signer) => {
|
|
984
|
-
const session = await
|
|
985
|
-
"/v1/auth/session",
|
|
986
|
-
sessionSchema.nullable()
|
|
987
|
-
);
|
|
988
|
-
if (!session) {
|
|
989
|
-
throw new RelayError("Sign in to continue", 401);
|
|
990
|
-
}
|
|
1137
|
+
link: async (signer, requestOptions) => {
|
|
1138
|
+
const session = await bound(requestOptions);
|
|
991
1139
|
const challenge = await walletRequest(
|
|
992
1140
|
"/v1/me/wallets/challenge",
|
|
993
1141
|
walletMessageChallengeSchema,
|
|
994
1142
|
{
|
|
995
|
-
|
|
996
|
-
walletAddressInputSchema
|
|
1143
|
+
json: parseInput(
|
|
1144
|
+
walletAddressInputSchema,
|
|
1145
|
+
await fromSigner(() => walletAddressInput(signer))
|
|
997
1146
|
),
|
|
998
|
-
|
|
1147
|
+
options: session
|
|
999
1148
|
}
|
|
1000
1149
|
);
|
|
1001
|
-
const proof = await
|
|
1150
|
+
const proof = await fromSigner(
|
|
1151
|
+
() => signer.sign(challenge.message, challenge.address)
|
|
1152
|
+
);
|
|
1002
1153
|
return walletRequest("/v1/me/wallets/verify", linkedWalletSchema, {
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1154
|
+
json: parseInput(walletSignatureSchema, {
|
|
1155
|
+
challenge: challenge.id,
|
|
1156
|
+
...proof
|
|
1157
|
+
}),
|
|
1158
|
+
options: session
|
|
1007
1159
|
});
|
|
1008
1160
|
}
|
|
1009
1161
|
},
|
|
1010
|
-
/** @deprecated Use `wallets` (multi-chain). This reads and replaces the newest Solana wallet. */
|
|
1011
|
-
wallet: {
|
|
1012
|
-
connection: () => walletRequest("/v1/me/wallet", walletConnectionSchema.nullable()),
|
|
1013
|
-
challenge: (input, session) => walletRequest("/v1/me/wallet/challenge", walletChallengeSchema, {
|
|
1014
|
-
...json(walletChallengeInputSchema.parse(input)),
|
|
1015
|
-
headers: sessionHeaders(session)
|
|
1016
|
-
}),
|
|
1017
|
-
verify: (input, session) => walletRequest("/v1/me/wallet/verify", walletConnectionSchema, {
|
|
1018
|
-
...json(walletProofSchema.parse(input)),
|
|
1019
|
-
headers: sessionHeaders(session)
|
|
1020
|
-
})
|
|
1021
|
-
},
|
|
1022
1162
|
auth: {
|
|
1023
|
-
providers: () => request(
|
|
1163
|
+
providers: (requestOptions) => request(
|
|
1024
1164
|
"/v1/auth/providers",
|
|
1025
1165
|
z2.object({
|
|
1026
1166
|
providers: z2.array(
|
|
@@ -1033,108 +1173,116 @@ function createRelayClient(options) {
|
|
|
1033
1173
|
/** The wallet sign-in this project enabled; older servers omit it. */
|
|
1034
1174
|
wallets: walletSignInNetworksSchema.default([]),
|
|
1035
1175
|
demo: z2.boolean()
|
|
1036
|
-
})
|
|
1037
|
-
|
|
1038
|
-
start: (provider, mode) => request(
|
|
1039
|
-
"/v1/auth/start",
|
|
1040
|
-
z2.object({ url: z2.string() }),
|
|
1041
|
-
json({ provider, mode })
|
|
1042
|
-
),
|
|
1043
|
-
emailStart: (email) => request(
|
|
1044
|
-
"/v1/auth/email/start",
|
|
1045
|
-
z2.object({ challenge: z2.string() }),
|
|
1046
|
-
json({ email })
|
|
1047
|
-
),
|
|
1048
|
-
emailVerify: (challenge, code) => changeSession(
|
|
1049
|
-
() => request(
|
|
1050
|
-
"/v1/auth/email/verify",
|
|
1051
|
-
sessionSchema,
|
|
1052
|
-
json({ challenge, code })
|
|
1053
|
-
)
|
|
1176
|
+
}),
|
|
1177
|
+
{ options: requestOptions }
|
|
1054
1178
|
),
|
|
1179
|
+
start: async (provider, mode, requestOptions) => request("/v1/auth/start", z2.object({ url: z2.string() }), {
|
|
1180
|
+
json: {
|
|
1181
|
+
provider: parseInput(authProviderSchema, provider),
|
|
1182
|
+
mode: parseInput(z2.enum(["sign-in", "connect"]), mode)
|
|
1183
|
+
},
|
|
1184
|
+
options: requestOptions
|
|
1185
|
+
}),
|
|
1186
|
+
emailStart: async (email, requestOptions) => request("/v1/auth/email/start", z2.object({ challenge: z2.string() }), {
|
|
1187
|
+
json: { email: parseInput(z2.email().max(254), email.trim()) },
|
|
1188
|
+
options: requestOptions
|
|
1189
|
+
}),
|
|
1190
|
+
emailVerify: async (challenge, code, requestOptions) => {
|
|
1191
|
+
const body2 = {
|
|
1192
|
+
challenge: parseInput(z2.string().min(1).max(200), challenge),
|
|
1193
|
+
code: parseInput(
|
|
1194
|
+
z2.string().regex(/^\d{6}$/, "Enter the 6-digit code"),
|
|
1195
|
+
code.trim()
|
|
1196
|
+
)
|
|
1197
|
+
};
|
|
1198
|
+
return changeSession(
|
|
1199
|
+
() => request("/v1/auth/email/verify", participantSessionSchema, {
|
|
1200
|
+
json: body2,
|
|
1201
|
+
options: requestOptions
|
|
1202
|
+
})
|
|
1203
|
+
);
|
|
1204
|
+
},
|
|
1055
1205
|
/**
|
|
1056
1206
|
* Sign in, or sign up, with a Solana, EVM or Cosmos wallet where the project enabled it
|
|
1057
1207
|
* (`providers().wallets`). A wallet the member linked while signed in cannot sign in.
|
|
1058
1208
|
*/
|
|
1059
1209
|
wallet: {
|
|
1060
1210
|
/** A sign-in challenge for the wallet's address; binds the flow to this browser. */
|
|
1061
|
-
start: (
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
),
|
|
1211
|
+
start: async (value, requestOptions) => request("/v1/auth/wallet/start", walletMessageChallengeSchema, {
|
|
1212
|
+
json: parseInput(walletAddressInputSchema, value),
|
|
1213
|
+
options: requestOptions
|
|
1214
|
+
}),
|
|
1066
1215
|
/** Verifies the signed challenge and starts the session. Not retried: start again instead. */
|
|
1067
|
-
verify: (proof) => changeSession(
|
|
1068
|
-
() => request(
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
)
|
|
1216
|
+
verify: (proof, requestOptions) => changeSession(
|
|
1217
|
+
() => request("/v1/auth/wallet/verify", participantSessionSchema, {
|
|
1218
|
+
json: parseInput(walletSignatureSchema, proof),
|
|
1219
|
+
options: requestOptions
|
|
1220
|
+
})
|
|
1073
1221
|
),
|
|
1074
1222
|
/**
|
|
1075
|
-
* Asks the signer for its address, signs the challenge and starts the session.
|
|
1076
|
-
* `RelayError`
|
|
1223
|
+
* Asks the signer for its address, signs the challenge and starts the session. Rejects with
|
|
1224
|
+
* an `http` `RelayError` (status 403) when the project has not enabled this wallet family.
|
|
1077
1225
|
*/
|
|
1078
|
-
signIn: async (signer) => {
|
|
1226
|
+
signIn: async (signer, requestOptions) => {
|
|
1079
1227
|
const challenge = await request(
|
|
1080
1228
|
"/v1/auth/wallet/start",
|
|
1081
1229
|
walletMessageChallengeSchema,
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1230
|
+
{
|
|
1231
|
+
json: parseInput(
|
|
1232
|
+
walletAddressInputSchema,
|
|
1233
|
+
await fromSigner(() => walletAddressInput(signer))
|
|
1234
|
+
),
|
|
1235
|
+
options: requestOptions
|
|
1236
|
+
}
|
|
1237
|
+
);
|
|
1238
|
+
const proof = await fromSigner(
|
|
1239
|
+
() => signer.sign(challenge.message, challenge.address)
|
|
1085
1240
|
);
|
|
1086
|
-
const proof = await signer.sign(challenge.message, challenge.address);
|
|
1087
1241
|
return changeSession(
|
|
1088
|
-
() => request(
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
})
|
|
1096
|
-
)
|
|
1097
|
-
)
|
|
1242
|
+
() => request("/v1/auth/wallet/verify", participantSessionSchema, {
|
|
1243
|
+
json: parseInput(walletSignatureSchema, {
|
|
1244
|
+
challenge: challenge.id,
|
|
1245
|
+
...proof
|
|
1246
|
+
}),
|
|
1247
|
+
options: requestOptions
|
|
1248
|
+
})
|
|
1098
1249
|
);
|
|
1099
1250
|
}
|
|
1100
1251
|
},
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
)
|
|
1116
|
-
),
|
|
1117
|
-
session: () => request("/v1/auth/session", sessionSchema.nullable()),
|
|
1118
|
-
signOut: () => changeSession(
|
|
1119
|
-
() => request("/v1/auth/logout", z2.object({ ok: z2.boolean() }), json({}))
|
|
1252
|
+
/** The member's connected sign-in accounts, one per provider. */
|
|
1253
|
+
accounts: (requestOptions) => request("/v1/auth/accounts", z2.array(accountConnectionSchema), {
|
|
1254
|
+
options: requestOptions
|
|
1255
|
+
}),
|
|
1256
|
+
disconnect: async (provider, requestOptions) => request("/v1/auth/accounts/disconnect", acknowledged, {
|
|
1257
|
+
json: { provider: parseInput(authProviderSchema, provider) },
|
|
1258
|
+
options: requestOptions
|
|
1259
|
+
}),
|
|
1260
|
+
session: (requestOptions) => readSession(requestOptions),
|
|
1261
|
+
signOut: (requestOptions) => changeSession(
|
|
1262
|
+
() => request("/v1/auth/logout", acknowledged, {
|
|
1263
|
+
json: {},
|
|
1264
|
+
options: requestOptions
|
|
1265
|
+
})
|
|
1120
1266
|
),
|
|
1121
1267
|
/** Local development only. Existing hosted apps use createParticipantBackend from /portal-proxy. */
|
|
1122
|
-
exchange: (
|
|
1268
|
+
exchange: async (value, requestOptions) => request("/v1/auth/exchange", exchangeResultSchema, {
|
|
1269
|
+
json: parseInput(exchangeSchema, value),
|
|
1270
|
+
options: requestOptions
|
|
1271
|
+
})
|
|
1123
1272
|
},
|
|
1124
1273
|
me: {
|
|
1125
1274
|
/** The signed-in member, and the seed of their generated avatar: `defaultAvatar(avatarSeed)`. */
|
|
1126
|
-
get: () => request("/v1/me", memberSummarySchema),
|
|
1127
|
-
observeProgress: (listener,
|
|
1275
|
+
get: async (requestOptions) => request("/v1/me", memberSummarySchema, { options: requestOptions }),
|
|
1276
|
+
observeProgress: (listener, observeOptions) => {
|
|
1128
1277
|
const observer = observeProgress(
|
|
1129
1278
|
{
|
|
1130
|
-
session: (signal) =>
|
|
1279
|
+
session: (signal) => readSession({ signal }),
|
|
1131
1280
|
progress: (session, signal) => request("/v1/me/progress", memberProgressSchema, {
|
|
1132
|
-
signal
|
|
1133
|
-
headers: { "X-Relay-Session": session }
|
|
1281
|
+
options: { session, signal }
|
|
1134
1282
|
})
|
|
1135
1283
|
},
|
|
1136
1284
|
listener,
|
|
1137
|
-
|
|
1285
|
+
observeOptions,
|
|
1138
1286
|
() => observers.delete(observer)
|
|
1139
1287
|
);
|
|
1140
1288
|
observers.add(observer);
|
|
@@ -1143,147 +1291,117 @@ function createRelayClient(options) {
|
|
|
1143
1291
|
return { refresh: observer.refresh, dispose: observer.dispose };
|
|
1144
1292
|
},
|
|
1145
1293
|
submission,
|
|
1146
|
-
collectionPass: (entitlement,
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
"Content-Type": "application/json",
|
|
1150
|
-
"X-Relay-Session": session
|
|
1151
|
-
}
|
|
1294
|
+
collectionPass: async (entitlement, requestOptions) => request("/v1/me/collection-pass", collectionPassSchema, {
|
|
1295
|
+
json: { entitlement: parseInput(identifier, entitlement) },
|
|
1296
|
+
options: await bound(requestOptions)
|
|
1152
1297
|
}),
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
progress: () => request("/v1/me/progress", memberProgressSchema),
|
|
1156
|
-
rewardDeliveries: () => request("/v1/reward-deliveries", rewardDeliveriesSchema),
|
|
1157
|
-
claim: (input, options2) => request("/v1/me/attempts", attemptSchema, {
|
|
1158
|
-
...json(input),
|
|
1159
|
-
headers: {
|
|
1160
|
-
"Content-Type": "application/json",
|
|
1161
|
-
...options2 ? { "X-Relay-Session": options2.session } : {}
|
|
1162
|
-
}
|
|
1298
|
+
progress: (requestOptions) => request("/v1/me/progress", memberProgressSchema, {
|
|
1299
|
+
options: requestOptions
|
|
1163
1300
|
}),
|
|
1164
|
-
|
|
1301
|
+
rewardDeliveries: (requestOptions) => request("/v1/reward-deliveries", rewardDeliveriesSchema, {
|
|
1302
|
+
options: requestOptions
|
|
1303
|
+
}),
|
|
1304
|
+
/** Claims a quest for the signed-in member. Quest controllers (`quests.open`) call this. */
|
|
1305
|
+
claim: async (value, requestOptions) => {
|
|
1306
|
+
const claim = parseInput(submitSchema.omit({ member: true }), value);
|
|
1307
|
+
return request("/v1/me/attempts", attemptSchema, {
|
|
1308
|
+
json: claim,
|
|
1309
|
+
options: requestOptions,
|
|
1310
|
+
operationId: claim.actionId
|
|
1311
|
+
});
|
|
1312
|
+
},
|
|
1313
|
+
/** Uploads a photo as the signed-in member's evidence. */
|
|
1314
|
+
upload: (file, requestOptions) => request("/v1/me/evidence", evidenceSchema, {
|
|
1165
1315
|
method: "POST",
|
|
1316
|
+
body: file,
|
|
1166
1317
|
headers: { "Content-Type": file.type },
|
|
1167
|
-
|
|
1318
|
+
options: requestOptions
|
|
1168
1319
|
})
|
|
1169
1320
|
},
|
|
1170
1321
|
evidence: {
|
|
1171
1322
|
async download(id, requestOptions) {
|
|
1323
|
+
const call = { options: requestOptions };
|
|
1172
1324
|
const response = await send(
|
|
1173
|
-
`/v1/evidence/${identifier
|
|
1174
|
-
|
|
1325
|
+
`/v1/evidence/${parseInput(identifier, id)}`,
|
|
1326
|
+
call
|
|
1175
1327
|
);
|
|
1176
1328
|
const type = response.headers.get("Content-Type");
|
|
1177
1329
|
if (type !== "image/jpeg" && type !== "image/png") {
|
|
1178
|
-
throw
|
|
1330
|
+
throw invalidResponse(
|
|
1331
|
+
response.status,
|
|
1332
|
+
call,
|
|
1333
|
+
new Error("Unexpected evidence content type")
|
|
1334
|
+
);
|
|
1179
1335
|
}
|
|
1180
|
-
return response.blob();
|
|
1336
|
+
return body(response, call, (value) => value.blob());
|
|
1181
1337
|
}
|
|
1182
1338
|
},
|
|
1183
|
-
/** @deprecated The participant API accepts only member sessions and rejects this staff call. Use the management API with a management key instead. */
|
|
1184
|
-
lookupMember: (issuer, subject) => request(
|
|
1185
|
-
"/v1/members/lookup",
|
|
1186
|
-
z2.object({ member: z2.string() }),
|
|
1187
|
-
json({ issuer, subject })
|
|
1188
|
-
),
|
|
1189
|
-
/** @deprecated Removed from the participant API. Build quests with `domino` and `@domino-sdk/relay/build`. */
|
|
1190
|
-
journeyTemplate: () => request("/v1/journey-template", z2.array(templateSchema)),
|
|
1191
|
-
/** @deprecated Removed from the participant API. Build quests with `domino` and `@domino-sdk/relay/build`. */
|
|
1192
|
-
template: () => request("/v1/template", templateSchema),
|
|
1193
|
-
/** @deprecated The participant API accepts only member sessions and rejects this staff call. Use the management API with a management key instead. */
|
|
1194
|
-
snapshot: () => request("/v1/snapshot", snapshotSchema),
|
|
1195
|
-
/** @deprecated The participant API rejects publication. Publish with `domino deploy` or the management API. */
|
|
1196
|
-
publish: (release) => request("/v1/releases", publishedReleaseSchema, json(release)),
|
|
1197
|
-
/** @deprecated The participant API rejects publication. Publish with `domino deploy` or the management API. */
|
|
1198
|
-
publishBatch: (releases) => request(
|
|
1199
|
-
"/v1/releases/batch",
|
|
1200
|
-
z2.array(publishedReleaseSchema),
|
|
1201
|
-
json({ releases })
|
|
1202
|
-
),
|
|
1203
|
-
progress: (member) => request(
|
|
1204
|
-
`/v1/members/${encodeURIComponent(member)}/progress`,
|
|
1205
|
-
memberProgressSchema
|
|
1206
|
-
),
|
|
1207
|
-
/** @deprecated The participant API accepts only member sessions and rejects this staff call. Use the management API with a management key instead. */
|
|
1208
|
-
beginHandover: (id, input) => request(`/v1/entitlements/${id}/begin`, entitlementSchema, json(input)),
|
|
1209
|
-
/** @deprecated The participant API accepts only member sessions and rejects this staff call. Use the management API with a management key instead. */
|
|
1210
|
-
confirmHandover: (id, input) => request(`/v1/entitlements/${id}/confirm`, entitlementSchema, json(input)),
|
|
1211
|
-
upload: (member, file) => request(
|
|
1212
|
-
`/v1/evidence?member=${encodeURIComponent(member)}`,
|
|
1213
|
-
evidenceSchema,
|
|
1214
|
-
{
|
|
1215
|
-
method: "POST",
|
|
1216
|
-
headers: { "Content-Type": file.type },
|
|
1217
|
-
body: file
|
|
1218
|
-
}
|
|
1219
|
-
),
|
|
1220
1339
|
engagement: {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
)
|
|
1226
|
-
)
|
|
1227
|
-
|
|
1340
|
+
/** The member's engagement settlements for one post under one rule, newest first. */
|
|
1341
|
+
page: async (query, requestOptions) => request(
|
|
1342
|
+
withQuery(
|
|
1343
|
+
"/v1/engagement/history",
|
|
1344
|
+
parseInput(engagementPageQuerySchema, query)
|
|
1345
|
+
),
|
|
1346
|
+
engagementPageSchema,
|
|
1347
|
+
{ options: requestOptions }
|
|
1228
1348
|
),
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
)
|
|
1234
|
-
)
|
|
1235
|
-
|
|
1349
|
+
/** The formula boundaries the member's settlements for one post crossed, newest first. */
|
|
1350
|
+
boundaries: async (query, requestOptions) => request(
|
|
1351
|
+
withQuery(
|
|
1352
|
+
"/v1/engagement/boundaries",
|
|
1353
|
+
parseInput(engagementPageQuerySchema, query)
|
|
1354
|
+
),
|
|
1355
|
+
engagementBoundaryPageSchema,
|
|
1356
|
+
{ options: requestOptions }
|
|
1236
1357
|
)
|
|
1237
1358
|
},
|
|
1238
1359
|
content: {
|
|
1239
|
-
performance: (
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
).toString(),
|
|
1247
|
-
contentPerformancePageSchema
|
|
1248
|
-
),
|
|
1249
|
-
qualifications: (input) => request(
|
|
1250
|
-
"/v1/content/qualifications?" + new URLSearchParams(
|
|
1251
|
-
Object.entries(
|
|
1252
|
-
contentQualificationQuerySchema.parse(input)
|
|
1253
|
-
).flatMap(
|
|
1254
|
-
([key, value]) => value === void 0 ? [] : [[key, String(value)]]
|
|
1255
|
-
)
|
|
1256
|
-
).toString(),
|
|
1257
|
-
contentQualificationPageSchema
|
|
1360
|
+
performance: async (query, requestOptions) => request(
|
|
1361
|
+
withQuery(
|
|
1362
|
+
"/v1/content/performance",
|
|
1363
|
+
parseInput(contentPerformanceQuerySchema, query)
|
|
1364
|
+
),
|
|
1365
|
+
contentPerformancePageSchema,
|
|
1366
|
+
{ options: requestOptions }
|
|
1258
1367
|
),
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1368
|
+
qualifications: async (query, requestOptions) => request(
|
|
1369
|
+
withQuery(
|
|
1370
|
+
"/v1/content/qualifications",
|
|
1371
|
+
parseInput(contentQualificationQuerySchema, query)
|
|
1372
|
+
),
|
|
1373
|
+
contentQualificationPageSchema,
|
|
1374
|
+
{ options: requestOptions }
|
|
1266
1375
|
),
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1376
|
+
admissions: async (query, requestOptions) => request(
|
|
1377
|
+
withQuery(
|
|
1378
|
+
"/v1/content/admissions",
|
|
1379
|
+
parseInput(contentAdmissionQuerySchema, query)
|
|
1380
|
+
),
|
|
1381
|
+
contentAdmissionPageSchema,
|
|
1382
|
+
{ options: requestOptions }
|
|
1271
1383
|
),
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1384
|
+
enroll: async (value, requestOptions) => {
|
|
1385
|
+
const body2 = parseInput(contentEnrollmentInputSchema, value);
|
|
1386
|
+
return request("/v1/content/enrollments", contentEnrollmentSchema, {
|
|
1387
|
+
json: body2,
|
|
1388
|
+
options: requestOptions,
|
|
1389
|
+
operationId: body2.actionId
|
|
1390
|
+
});
|
|
1391
|
+
},
|
|
1392
|
+
claim: async (value, requestOptions) => {
|
|
1393
|
+
const body2 = parseInput(contentReleaseInputSchema, value);
|
|
1394
|
+
return request("/v1/content/claims", contentAdmissionSchema, {
|
|
1395
|
+
json: body2,
|
|
1396
|
+
options: requestOptions,
|
|
1397
|
+
operationId: body2.actionId
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1282
1401
|
};
|
|
1283
1402
|
}
|
|
1284
1403
|
|
|
1285
1404
|
export {
|
|
1286
|
-
RelayError,
|
|
1287
1405
|
QuestUpdatedError,
|
|
1288
1406
|
createRelayClient
|
|
1289
1407
|
};
|