@domino-sdk/relay 1.66.1 → 1.67.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/{accounts-_lNsiR2k.d.ts → accounts-C2O8mpB8.d.ts} +2 -2
  3. package/dist/{attempt-captures-BqPggxTU.d.ts → attempt-captures-ClHAoo_n.d.ts} +1 -1
  4. package/dist/authoring.d.ts +24 -23
  5. package/dist/authoring.js +17 -15
  6. package/dist/{automatic-outcomes-BzAvfcpd.d.ts → automatic-outcomes-BEnPn4Uh.d.ts} +2 -2
  7. package/dist/avatar.d.ts +1 -1
  8. package/dist/browser.d.ts +9 -9
  9. package/dist/browser.js +9 -8
  10. package/dist/{catalog-ByZMRS7I.d.ts → catalog-CbiftcxQ.d.ts} +2 -2
  11. package/dist/{chunk-5LD5DKOM.js → chunk-5DZNMLDM.js} +1 -1
  12. package/dist/{chunk-2Y4EZKET.js → chunk-5SBA6X5X.js} +1 -1
  13. package/dist/{chunk-7HTRIEM7.js → chunk-BMJHFWVT.js} +5 -29
  14. package/dist/{chunk-7MQCQYEE.js → chunk-DSJ46QLB.js} +1 -1
  15. package/dist/{chunk-FUFMYKSQ.js → chunk-JK3XV2CR.js} +92 -3
  16. package/dist/{chunk-M66Y5OMJ.js → chunk-KUNPCDN6.js} +6 -6
  17. package/dist/{chunk-5DYS2OIP.js → chunk-MVQQDPQX.js} +1 -1
  18. package/dist/{chunk-CGUL4MRE.js → chunk-NRMQVK2W.js} +1 -1
  19. package/dist/{chunk-XCEGNKGH.js → chunk-P33ZAJMS.js} +56 -24
  20. package/dist/{chunk-CJDB6W6I.js → chunk-Q5QVAF7R.js} +41 -14
  21. package/dist/{chunk-4TC4HK5Y.js → chunk-Q6KTTVOI.js} +1 -1
  22. package/dist/{chunk-QYHEHMCG.js → chunk-QYC3CZVD.js} +1 -1
  23. package/dist/{chunk-OWDIR7ZU.js → chunk-RDUSFUXX.js} +1 -1
  24. package/dist/{chunk-FU3W4IQN.js → chunk-RWR2LOPA.js} +2 -2
  25. package/dist/chunk-UWUS4OOV.js +59 -0
  26. package/dist/{chunk-ANVAUOJP.js → chunk-X3FMVRMM.js} +1 -1
  27. package/dist/{chunk-R2LHIWAM.js → chunk-Z2Z5DBNW.js} +6 -6
  28. package/dist/{client-Cze4lfwA.d.ts → client-CZPewB9h.d.ts} +10 -7
  29. package/dist/{dashboards-pVfclkyh.d.ts → dashboards-jGPM3AxF.d.ts} +3 -3
  30. package/dist/{deployments-Cr1tfqrr.d.ts → deployments-BVFd7ddA.d.ts} +3 -3
  31. package/dist/{identity-integration-Ci2vGKtX.d.ts → identity-integration-W1Vo3Ql9.d.ts} +10 -2
  32. package/dist/index.d.ts +10 -10
  33. package/dist/index.js +7 -7
  34. package/dist/internal.d.ts +32 -14
  35. package/dist/internal.js +29 -20
  36. package/dist/{limits-pE04y9O2.d.ts → limits-C4RzrOV4.d.ts} +1 -1
  37. package/dist/{offers-Hw2P6tcK.d.ts → offers-BpYenB9i.d.ts} +2 -2
  38. package/dist/portal-proxy.d.ts +5 -5
  39. package/dist/portal-proxy.js +11 -13
  40. package/dist/react/index.d.ts +14 -13
  41. package/dist/react/index.js +9 -8
  42. package/dist/{reward-deliveries-BCV8hznc.d.ts → reward-deliveries-BOWpMytr.d.ts} +1 -1
  43. package/dist/runtime/authoring.js +1 -1
  44. package/dist/runtime/chunks/C2MGLQXC.js +1 -0
  45. package/dist/runtime/manifest.json +3 -3
  46. package/dist/runtime/schema.js +1 -1
  47. package/dist/schema.d.ts +20 -17
  48. package/dist/schema.js +11 -7
  49. package/dist/server/index.d.ts +12 -12
  50. package/dist/server/index.js +277 -22
  51. package/dist/{sign-in-providers-BAkGjSXo.d.ts → sign-in-providers-BRYVOSlG.d.ts} +2 -2
  52. package/dist/{submission-input-ChL1aYNH.d.ts → submission-input-C152xIdn.d.ts} +2 -2
  53. package/dist/{telegram-browser-BFs4u7lC.d.ts → telegram-browser-657QqiQl.d.ts} +4 -4
  54. package/dist/telegram.d.ts +8 -8
  55. package/dist/testing.d.ts +12 -11
  56. package/dist/testing.js +14 -7
  57. package/dist/{tracker-data-Bl-qPIvZ.d.ts → tracker-data-BqY-9Vu-.d.ts} +2 -2
  58. package/dist/{transport-WE49Ta3A.d.ts → transport-CthYgZXK.d.ts} +618 -20
  59. package/dist/{wallet-B7e06v4m.d.ts → wallet-Btng186v.d.ts} +57 -26
  60. package/package.json +3 -1
  61. package/dist/chunk-UZ765UGH.js +0 -18
  62. package/dist/runtime/chunks/C5V267I7.js +0 -1
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  attemptCaptureSchema,
3
3
  capturedFactSchema
4
- } from "../chunk-OWDIR7ZU.js";
4
+ } from "../chunk-RDUSFUXX.js";
5
5
  import {
6
6
  DEFAULT_MANAGEMENT_TIMEOUT,
7
7
  ManagementError,
@@ -9,22 +9,25 @@ import {
9
9
  ManagementUploadBody,
10
10
  REFERRAL_INTEGRATION_REWARD_ERROR,
11
11
  actionIdOf,
12
+ canonicalWalletAddress,
12
13
  containsReferralIntegrationReward,
14
+ hex,
13
15
  isManagementError,
14
16
  managementErrorSchema,
15
17
  managementTransport,
16
18
  questConfiguration,
17
- sequenceCursorSchema
18
- } from "../chunk-FUFMYKSQ.js";
19
+ sequenceCursorSchema,
20
+ walletSignatureValid
21
+ } from "../chunk-JK3XV2CR.js";
19
22
  import {
20
23
  parseImageExtraction,
21
24
  parseImageResult
22
- } from "../chunk-FU3W4IQN.js";
25
+ } from "../chunk-RWR2LOPA.js";
23
26
  import {
24
27
  sourceDataSchema,
25
28
  sourceRoles,
26
29
  validateQuestShape
27
- } from "../chunk-5DYS2OIP.js";
30
+ } from "../chunk-MVQQDPQX.js";
28
31
  import {
29
32
  APP_KV_LIMIT,
30
33
  APP_MIGRATION_FILE_BYTES,
@@ -152,7 +155,7 @@ import {
152
155
  starterTemplates,
153
156
  starters,
154
157
  verifyScheduledRequest
155
- } from "../chunk-CJDB6W6I.js";
158
+ } from "../chunk-Q5QVAF7R.js";
156
159
  import {
157
160
  isIntegrationParticipantPath,
158
161
  isParticipantRoute,
@@ -184,12 +187,12 @@ import {
184
187
  publishDeploymentSchema,
185
188
  rejectDeploymentSchema,
186
189
  submitDeploymentSchema
187
- } from "../chunk-M66Y5OMJ.js";
190
+ } from "../chunk-KUNPCDN6.js";
188
191
  import {
189
192
  xUserLookupInputSchema,
190
193
  xUserSchema,
191
194
  xUsernameSchema
192
- } from "../chunk-ANVAUOJP.js";
195
+ } from "../chunk-X3FMVRMM.js";
193
196
  import {
194
197
  analyticsBreakdowns,
195
198
  analyticsCatalog,
@@ -204,15 +207,18 @@ import {
204
207
  analyticsRanges,
205
208
  analyticsReadSchema,
206
209
  dashboardDefinitionSchema
207
- } from "../chunk-QYHEHMCG.js";
210
+ } from "../chunk-QYC3CZVD.js";
208
211
  import "../chunk-MWMCQLCG.js";
209
212
  import {
210
213
  withActionId
211
214
  } from "../chunk-BQXRCJ3N.js";
215
+ import {
216
+ base58
217
+ } from "../chunk-UWUS4OOV.js";
212
218
  import {
213
219
  withQuery
214
- } from "../chunk-4TC4HK5Y.js";
215
- import "../chunk-2Y4EZKET.js";
220
+ } from "../chunk-Q6KTTVOI.js";
221
+ import "../chunk-5SBA6X5X.js";
216
222
  import {
217
223
  collectionBeginSchema,
218
224
  collectionPreviewSchema,
@@ -227,7 +233,7 @@ import {
227
233
  rewardDeliveriesSchema,
228
234
  rewardDeliveryQuerySchema,
229
235
  rewardDeliverySchema
230
- } from "../chunk-CGUL4MRE.js";
236
+ } from "../chunk-NRMQVK2W.js";
231
237
  import {
232
238
  allocateQuestSchema,
233
239
  allocatedQuestSchema,
@@ -238,7 +244,7 @@ import {
238
244
  questDraftSchema,
239
245
  questPublicationPreviewSchema,
240
246
  saveQuestDraftSchema
241
- } from "../chunk-7MQCQYEE.js";
247
+ } from "../chunk-DSJ46QLB.js";
242
248
  import {
243
249
  engagementBoundaryPageSchema,
244
250
  engagementChangePreviewInputSchema,
@@ -264,7 +270,7 @@ import {
264
270
  referralQualificationSchema,
265
271
  referralRewardResolutionSchema,
266
272
  referralSuspensionSchema
267
- } from "../chunk-5LD5DKOM.js";
273
+ } from "../chunk-5DZNMLDM.js";
268
274
  import {
269
275
  CompletionSourceKind,
270
276
  acceptAnywaySchema,
@@ -277,6 +283,7 @@ import {
277
283
  badgePropertiesSchema,
278
284
  baseUnitsSchema,
279
285
  beginHandoverSchema,
286
+ caip10,
280
287
  campaignEnrollmentSchema,
281
288
  completionKeySchema,
282
289
  completionSourceSchema,
@@ -312,6 +319,7 @@ import {
312
319
  groupPageQuerySchema,
313
320
  groupPageSchema,
314
321
  identifier,
322
+ isEvmChainId,
315
323
  leaderboardExclusionGroupBindingSchema,
316
324
  leaderboardExclusionGroupSchema,
317
325
  leaderboardExclusionSchema,
@@ -366,6 +374,7 @@ import {
366
374
  signInProviderSchema,
367
375
  snapshotSchema,
368
376
  solanaAddressSchema,
377
+ solanaDevnet,
369
378
  solanaMainnet,
370
379
  staffDecisionSchema,
371
380
  stockItemSchema,
@@ -400,7 +409,7 @@ import {
400
409
  walletSignInNetworksSchema,
401
410
  walletUnlinkInputSchema,
402
411
  whereSchemaIssue
403
- } from "../chunk-XCEGNKGH.js";
412
+ } from "../chunk-P33ZAJMS.js";
404
413
  import {
405
414
  issueText
406
415
  } from "../chunk-FGXLXENM.js";
@@ -682,13 +691,15 @@ var leaderboardSettlementExportSchema = /* @__PURE__ */ (() => z6.object({
682
691
  share: baseUnitsSchema.nullable(),
683
692
  /** The pool share in whole units: `"600.5"` for 600500000 USDC base units. */
684
693
  amount: z6.string().nullable(),
685
- /** Linked wallets the member proved, on every chain, newest first per chain. */
694
+ /** Linked wallets the member proved, newest first per chain family; a smart wallet names its `provedOn` chain. */
686
695
  wallets: z6.array(
687
696
  z6.object({
688
697
  chain: walletChainSchema,
689
698
  /** The CAIP-2 network, for Cosmos wallets only. */
690
699
  network: z6.string().nullable(),
691
- address: z6.string()
700
+ address: z6.string(),
701
+ /** EVM smart-contract wallets only: the CAIP-2 network that proved it, the one chain to pay it on. */
702
+ provedOn: evmChainIdSchema.optional()
692
703
  })
693
704
  )
694
705
  })
@@ -709,7 +720,9 @@ function settlementPayoutCsv(exported) {
709
720
  row.share,
710
721
  row.amount,
711
722
  row.share === null ? "" : unit,
712
- row.wallets.map((wallet) => `${wallet.network ?? wallet.chain}:${wallet.address}`).join(" ")
723
+ row.wallets.map(
724
+ (wallet) => `${wallet.provedOn ?? wallet.network ?? wallet.chain}:${wallet.address}`
725
+ ).join(" ")
713
726
  ])
714
727
  ].map((fields) => fields.map(csvField).join(",")).join("\n");
715
728
  }
@@ -2401,7 +2414,12 @@ function subscriptionSchema(plan) {
2401
2414
  since: z25.number().int(),
2402
2415
  promotionsRefusedAt: z25.number().int(),
2403
2416
  offlineAt: z25.number().int()
2404
- }).nullable().default(null)
2417
+ }).nullable().default(null),
2418
+ discount: z25.object({
2419
+ amount: z25.number().int(),
2420
+ listAmount: z25.number().int(),
2421
+ until: z25.number().int()
2422
+ }).nullable().optional()
2405
2423
  });
2406
2424
  }
2407
2425
  var billingSubscriptionSchema = /* @__PURE__ */ (() => subscriptionSchema(billingPlanSchema))();
@@ -3653,13 +3671,19 @@ var automationKeyPermissionSchema = /* @__PURE__ */ (() => z37.enum([
3653
3671
  var automationKeyInputSchema = /* @__PURE__ */ (() => z37.object({
3654
3672
  name: z37.string().trim().min(1).max(80),
3655
3673
  permissions: z37.array(automationKeyPermissionSchema).min(1),
3656
- /** The projects it reaches. Omit it for every project of the organization, current and future. */
3657
- projects: z37.array(identifier).min(1).max(100).optional(),
3674
+ /**
3675
+ * The projects it reaches. Omit it for every project of the organization, current and future.
3676
+ * An empty list, allowed only with `createProjects`, reaches only the projects it creates.
3677
+ */
3678
+ projects: z37.array(identifier).max(100).optional(),
3658
3679
  /** Whether it may create projects. A project it creates joins its `projects` list. */
3659
3680
  createProjects: z37.boolean().default(false),
3660
3681
  /** Days until the first secret expires. Omit it for a key that never expires. */
3661
3682
  expiresInDays: z37.number().int().min(1).max(3650).optional()
3662
- }).strict())();
3683
+ }).strict().refine((key) => key.projects?.length !== 0 || key.createProjects, {
3684
+ message: "Choose a project, or let the key create projects",
3685
+ path: ["projects"]
3686
+ }))();
3663
3687
  var automationKeySchema = /* @__PURE__ */ (() => z37.object({
3664
3688
  id: z37.string().uuid(),
3665
3689
  organization: z37.string(),
@@ -4623,6 +4647,7 @@ var walletBalanceChainsSchema = /* @__PURE__ */ (() => z48.object({
4623
4647
  z48.object({
4624
4648
  chain: z48.union([
4625
4649
  z48.literal(solanaMainnet),
4650
+ z48.literal(solanaDevnet),
4626
4651
  cosmosNetworkSchema,
4627
4652
  evmChainIdSchema
4628
4653
  ]),
@@ -5826,6 +5851,15 @@ function quests(http) {
5826
5851
  * included; requires `read` permission.
5827
5852
  */
5828
5853
  list: (call) => get("/quests/list", z55.array(publishedReleaseSchema), call),
5854
+ /**
5855
+ * `list` without each release's evaluator `code`; requires `read` permission. Code is most of
5856
+ * a release's size, up to a megabyte each, so use this to show or match quests.
5857
+ */
5858
+ listWithoutCode: (call) => get(
5859
+ "/quests/list-without-code",
5860
+ z55.array(publishedReleaseSchema.omit({ code: true })),
5861
+ call
5862
+ ),
5829
5863
  /** Pending and exhausted asynchronous balance checks. Requires read. */
5830
5864
  automaticScheduling: (query = {}, call) => get(
5831
5865
  `/quests/automatic-scheduling${queryString(automaticSchedulingQuerySchema.parse(query))}`,
@@ -6195,6 +6229,224 @@ var participantSignInInputSchema = /* @__PURE__ */ (() => z59.object({
6195
6229
  telegram: z59.object({ miniAppBotId: telegramBotIdSchema.nullable() }).strict().optional()
6196
6230
  }).strict())();
6197
6231
 
6232
+ // src/server/wallet-sign-in.ts
6233
+ var walletSignInErrorBrand = /* @__PURE__ */ (() => /* @__PURE__ */ Symbol.for("@domino-sdk/relay.WalletSignInError"))();
6234
+ var WalletSignInError = class extends Error {
6235
+ constructor(message, code) {
6236
+ super(message);
6237
+ this.code = code;
6238
+ }
6239
+ code;
6240
+ name = "WalletSignInError";
6241
+ [walletSignInErrorBrand] = true;
6242
+ };
6243
+ function isWalletSignInError(value) {
6244
+ return value instanceof Error && value[walletSignInErrorBrand] === true;
6245
+ }
6246
+ var solanaChains = {
6247
+ mainnet: solanaMainnet,
6248
+ devnet: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",
6249
+ testnet: "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
6250
+ };
6251
+ var fieldOrder = [
6252
+ "URI",
6253
+ "Version",
6254
+ "Chain ID",
6255
+ "Nonce",
6256
+ "Issued At",
6257
+ "Expiration Time",
6258
+ "Not Before",
6259
+ "Request ID",
6260
+ "Resources"
6261
+ ];
6262
+ var fieldLine = /* @__PURE__ */ (() => new RegExp(`^(${fieldOrder.join("|")}):(?: (.*))?$`))();
6263
+ var dateTime = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
6264
+ var refuse = (code, message) => new WalletSignInError(message, code);
6265
+ var invalid = (message) => refuse("invalid-message", message);
6266
+ function time(value, field) {
6267
+ if (value === void 0) {
6268
+ return null;
6269
+ }
6270
+ const parsed = Date.parse(value);
6271
+ if (!dateTime.test(value) || Number.isNaN(parsed)) {
6272
+ throw invalid(`${field} is not an RFC 3339 date-time`);
6273
+ }
6274
+ return parsed;
6275
+ }
6276
+ function parse(message) {
6277
+ const lines = message.split("\n");
6278
+ const header = /^(?:([a-z][a-z0-9+.-]*):\/\/)?(\S+) wants you to sign in with your (Ethereum|Solana) account:$/.exec(
6279
+ lines[0] ?? ""
6280
+ );
6281
+ if (!header) {
6282
+ throw invalid(
6283
+ "The message does not start with an EIP-4361 or SIWS sign-in line"
6284
+ );
6285
+ }
6286
+ const [, scheme, domain, family] = header;
6287
+ const address = lines[1] ?? "";
6288
+ let index = 2;
6289
+ let statement = null;
6290
+ if (index < lines.length) {
6291
+ if (lines[index] !== "") {
6292
+ throw invalid("The address is not followed by an empty line");
6293
+ }
6294
+ index++;
6295
+ if (lines[index] === "") {
6296
+ index++;
6297
+ } else if (index < lines.length && !fieldLine.test(lines[index])) {
6298
+ statement = lines[index];
6299
+ index++;
6300
+ if (lines[index] !== "") {
6301
+ throw invalid("The statement is not followed by an empty line");
6302
+ }
6303
+ index++;
6304
+ }
6305
+ }
6306
+ const fields = {};
6307
+ const resources2 = [];
6308
+ let position = -1;
6309
+ for (; index < lines.length; index++) {
6310
+ const line = lines[index];
6311
+ const field = fieldLine.exec(line);
6312
+ const name = field?.[1];
6313
+ const at = name ? fieldOrder.indexOf(name) : -1;
6314
+ if (!field || at <= position) {
6315
+ throw invalid(`Unexpected line ${JSON.stringify(line)}`);
6316
+ }
6317
+ position = at;
6318
+ if (name === "Resources") {
6319
+ if (field[2] !== void 0) {
6320
+ throw invalid("Resources are listed one per line");
6321
+ }
6322
+ while (lines[index + 1]?.startsWith("- ")) {
6323
+ resources2.push(lines[++index].slice(2));
6324
+ }
6325
+ } else if (field[2] === void 0 || field[2] === "") {
6326
+ throw invalid(`${name} has no value`);
6327
+ } else {
6328
+ fields[name] = field[2];
6329
+ }
6330
+ }
6331
+ return {
6332
+ scheme: scheme ?? null,
6333
+ domain,
6334
+ family,
6335
+ address,
6336
+ statement,
6337
+ fields,
6338
+ resources: resources2
6339
+ };
6340
+ }
6341
+ async function verifyWalletSignIn(input) {
6342
+ const origin = new URL(input.origin);
6343
+ if (origin.origin !== input.origin) {
6344
+ throw new TypeError(
6345
+ `Pass the app's exact origin, such as ${origin.origin}, as origin`
6346
+ );
6347
+ }
6348
+ const now = input.now ?? Date.now();
6349
+ const maxAge = input.maxAge ?? 6e5;
6350
+ const parsed = parse(input.message);
6351
+ const { fields } = parsed;
6352
+ const evm = parsed.family === "Ethereum";
6353
+ if (parsed.domain.toLowerCase() !== origin.host || parsed.scheme !== null && parsed.scheme + ":" !== origin.protocol) {
6354
+ throw refuse(
6355
+ "wrong-domain",
6356
+ `The message is for ${parsed.domain}, not ${origin.host}`
6357
+ );
6358
+ }
6359
+ if (fields.URI !== void 0) {
6360
+ let uri;
6361
+ try {
6362
+ uri = new URL(fields.URI);
6363
+ } catch {
6364
+ throw invalid("URI is not a URL");
6365
+ }
6366
+ if (uri.origin !== origin.origin) {
6367
+ throw refuse(
6368
+ "wrong-domain",
6369
+ `The message's URI ${fields.URI} is not on ${origin.origin}`
6370
+ );
6371
+ }
6372
+ } else if (evm) {
6373
+ throw invalid("An EIP-4361 message needs a URI");
6374
+ }
6375
+ if ((evm || fields.Version !== void 0) && fields.Version !== "1") {
6376
+ throw invalid("Version must be 1");
6377
+ }
6378
+ let chainId;
6379
+ if (evm) {
6380
+ chainId = "eip155:" + fields["Chain ID"];
6381
+ if (!isEvmChainId(chainId)) {
6382
+ throw invalid("An EIP-4361 message needs a numeric Chain ID");
6383
+ }
6384
+ } else {
6385
+ const cluster = (fields["Chain ID"] ?? "mainnet").replace(/^solana:/, "");
6386
+ const known = Object.hasOwn(solanaChains, cluster) ? solanaChains[cluster] : void 0;
6387
+ if (!known) {
6388
+ throw refuse(
6389
+ "unsupported-chain",
6390
+ `Unknown Solana Chain ID ${fields["Chain ID"]}`
6391
+ );
6392
+ }
6393
+ chainId = known;
6394
+ }
6395
+ const accepted = input.chains.map((chain2) => {
6396
+ const cluster = /^solana:(mainnet|devnet|testnet)$/.exec(chain2);
6397
+ return cluster ? solanaChains[cluster[1]] : chain2;
6398
+ });
6399
+ if (!accepted.includes(chainId)) {
6400
+ throw refuse(
6401
+ "unsupported-chain",
6402
+ `The message signs in on ${chainId}, which is not among ${input.chains.join(", ")}`
6403
+ );
6404
+ }
6405
+ if (fields.Nonce === void 0 || fields.Nonce !== input.nonce) {
6406
+ throw refuse(
6407
+ "wrong-nonce",
6408
+ "The message's nonce is not the one issued for this sign-in"
6409
+ );
6410
+ }
6411
+ const issuedAt = time(fields["Issued At"], "Issued At");
6412
+ const expiresAt = time(fields["Expiration Time"], "Expiration Time");
6413
+ const notBefore = time(fields["Not Before"], "Not Before");
6414
+ if (issuedAt === null) {
6415
+ throw invalid("The message needs an Issued At time");
6416
+ }
6417
+ if (issuedAt > now + 6e4 || notBefore !== null && notBefore > now) {
6418
+ throw refuse("not-yet-valid", "The message is not valid yet");
6419
+ }
6420
+ if (now - issuedAt > maxAge || expiresAt !== null && expiresAt <= now) {
6421
+ throw refuse("expired", "The message has expired");
6422
+ }
6423
+ const chain = evm ? "eip155" : "solana";
6424
+ const address = canonicalWalletAddress(chain, parsed.address);
6425
+ if (!address) {
6426
+ throw invalid(`The address is not ${evm ? "an EVM" : "a Solana"} address`);
6427
+ }
6428
+ const account2 = { kind: "wallet", chain, address };
6429
+ const signature = typeof input.signature === "string" ? input.signature : evm ? "0x" + hex(input.signature) : base58(input.signature);
6430
+ if (!await walletSignatureValid({
6431
+ chain: account2.chain,
6432
+ address: account2.address,
6433
+ message: input.message,
6434
+ signature
6435
+ })) {
6436
+ throw refuse(
6437
+ "invalid-signature",
6438
+ "The signature is not this wallet's signature over this message"
6439
+ );
6440
+ }
6441
+ return {
6442
+ account: account2,
6443
+ accountId: caip10({ ...account2, network: null }, chainId),
6444
+ chainId,
6445
+ issuedAt,
6446
+ expiresAt
6447
+ };
6448
+ }
6449
+
6198
6450
  // src/server/development.ts
6199
6451
  import * as z60 from "zod";
6200
6452
  var developmentPreflightSchema = /* @__PURE__ */ (() => z60.object({
@@ -6834,6 +7086,7 @@ export {
6834
7086
  RevokedReferralOutcome,
6835
7087
  TestMemberDecisionKind,
6836
7088
  WEBHOOK_MAX_BYTES,
7089
+ WalletSignInError,
6837
7090
  accessHistoryQuerySchema,
6838
7091
  accessSchema,
6839
7092
  accountProfileSchema,
@@ -7005,6 +7258,7 @@ export {
7005
7258
  isIntegrationParticipantPath,
7006
7259
  isManagementError,
7007
7260
  isParticipantRoute,
7261
+ isWalletSignInError,
7008
7262
  issuedAutomationKeySchema,
7009
7263
  issuedServiceKeySchema,
7010
7264
  issuedTokenSchema,
@@ -7250,6 +7504,7 @@ export {
7250
7504
  validateQuestShape2 as validateQuestShape,
7251
7505
  verifiedPassSchema,
7252
7506
  verifyScheduledRequest,
7507
+ verifyWalletSignIn,
7253
7508
  verifyWebhook,
7254
7509
  walletBalanceChainsSchema,
7255
7510
  walletIdentitySelectorSchema,
@@ -1,6 +1,6 @@
1
- import { J as SignInProvider } from './accounts-_lNsiR2k.js';
1
+ import { J as SignInProvider } from './accounts-C2O8mpB8.js';
2
2
  import * as z from 'zod';
3
- import { a as TelegramSignInMethods } from './submission-input-ChL1aYNH.js';
3
+ import { a as TelegramSignInMethods } from './submission-input-C152xIdn.js';
4
4
 
5
5
  /**
6
6
  * `GET /v1/auth/providers`, as `relay.auth.providers()` reads it. Exported as a schema only, for the
@@ -1,6 +1,6 @@
1
1
  import * as z from 'zod';
2
- import { L as LedgerReference, Q as QuestHandle } from './tracker-data-Bl-qPIvZ.js';
3
- import { B as ProjectGroupReference } from './accounts-_lNsiR2k.js';
2
+ import { L as LedgerReference, Q as QuestHandle } from './tracker-data-BqY-9Vu-.js';
3
+ import { B as ProjectGroupReference } from './accounts-C2O8mpB8.js';
4
4
 
5
5
  declare const completionPrerequisiteSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
6
6
  kind: z.ZodLiteral<"completion">;
@@ -1,8 +1,8 @@
1
- import { c as AuthProvider, J as SignInProvider } from './accounts-_lNsiR2k.js';
2
- import { p as createRelayClient, k as RelayRequestOptions, g as RelayError } from './client-Cze4lfwA.js';
3
- import { a as TelegramSignInMethods } from './submission-input-ChL1aYNH.js';
1
+ import { c as AuthProvider, J as SignInProvider } from './accounts-C2O8mpB8.js';
2
+ import { p as createRelayClient, k as RelayRequestOptions, g as RelayError } from './client-CZPewB9h.js';
3
+ import { a as TelegramSignInMethods } from './submission-input-C152xIdn.js';
4
4
  import { b as ParticipantSession } from './participant-activity-DXRq4s6K.js';
5
- import { C as CosmosChain, a as CosmosNetwork, m as WalletSigner, k as WalletSignInNetwork } from './wallet-B7e06v4m.js';
5
+ import { C as CosmosChain, a as CosmosNetwork, m as WalletSigner, k as WalletSignInNetwork } from './wallet-Btng186v.js';
6
6
 
7
7
  /** An EIP-1193 provider, such as `window.ethereum` or an EIP-6963 announcement's provider. */
8
8
  type Eip1193Provider = {
@@ -1,15 +1,15 @@
1
- import { k as RelayRequestOptions, R as RelayClient } from './client-Cze4lfwA.js';
1
+ import { k as RelayRequestOptions, R as RelayClient } from './client-CZPewB9h.js';
2
2
  import { b as ParticipantSession } from './participant-activity-DXRq4s6K.js';
3
- import './accounts-_lNsiR2k.js';
3
+ import './accounts-C2O8mpB8.js';
4
4
  import 'zod';
5
- import './tracker-data-Bl-qPIvZ.js';
6
- import './wallet-B7e06v4m.js';
7
- import './submission-input-ChL1aYNH.js';
5
+ import './tracker-data-BqY-9Vu-.js';
6
+ import './wallet-Btng186v.js';
7
+ import './submission-input-C152xIdn.js';
8
8
  import './request-error-D_dUPLwo.js';
9
- import './reward-deliveries-BCV8hznc.js';
10
- import './catalog-ByZMRS7I.js';
9
+ import './reward-deliveries-BOWpMytr.js';
10
+ import './catalog-CbiftcxQ.js';
11
11
  import './action-9Xl0StBg.js';
12
- import './sign-in-providers-BAkGjSXo.js';
12
+ import './sign-in-providers-BRYVOSlG.js';
13
13
 
14
14
  /**
15
15
  * A plugin's own sign-in method, such as Telegram's Mini App sign-in: the app passes the vendor's
package/dist/testing.d.ts CHANGED
@@ -1,19 +1,19 @@
1
- import { d5 as pointBalanceSchema, bD as discordMemberSchema, bG as discordMessageSchema, c$ as photoResultSchema, a8 as TextReviewInput, H as Reward, ac as Decision, P as PointBalance, y as PointLedgerReference, u as PointEntry, o as LeaderboardPage } from './accounts-_lNsiR2k.js';
1
+ import { d5 as pointBalanceSchema, bD as discordMemberSchema, bG as discordMessageSchema, c$ as photoResultSchema, a8 as TextReviewInput, H as Reward, ac as Decision, P as PointBalance, y as PointLedgerReference, u as PointEntry, o as LeaderboardPage } from './accounts-C2O8mpB8.js';
2
2
  import * as z from 'zod';
3
- import { N as NftCollection, aO as profileReferralSchema, aE as linkedWalletSchema, aY as walletBalanceSchema, b2 as walletNftsSchema, M as WalletCallArgument, aZ as walletCallSchema, a$ as walletDelegationsSchema, U as WalletEventCondition, b0 as walletEventsSchema, b7 as walletTransactionsSchema, v as WalletReader } from './wallet-B7e06v4m.js';
3
+ import { N as NftCollection, aR as profileReferralSchema, aH as linkedWalletSchema, b0 as walletBalanceSchema, b6 as walletNftsSchema, Q as WalletCallArgument, b1 as walletCallSchema, b3 as walletDelegationsSchema, V as WalletEventCondition, b4 as walletEventsSchema, bb as walletTransactionsSchema, w as WalletReader } from './wallet-Btng186v.js';
4
4
  import { f as CapabilityFailure, q as memberCompletionSchema } from './capability-error-CuI_F7yM.js';
5
5
  export { C as CapabilityError } from './capability-error-CuI_F7yM.js';
6
- import { C as xConnectionSchema, G as xProfileSchema, F as xPostSchema, g as ImageReference, u as imageInspectionSchema, q as imageComparisonSchema, x as imageSightingsSchema } from './limits-pE04y9O2.js';
7
- export { L as Limits, l as limits } from './limits-pE04y9O2.js';
8
- import { aM as memberIdentitySchema, bf as trackerQuerySchema, ba as trackerPageSchema, bo as trackerSummarySchema, ac as TrackerContentQuery, aX as trackerContentSchema, a8 as TrackerAttribution, o as Tracker, p as TrackerData, H as ContentBody, B as TrackerTriggerContext, U as TrackerPage } from './tracker-data-Bl-qPIvZ.js';
9
- import { C as telegramConnectionSchema, y as telegramChatMemberSchema, e as TelegramReader } from './submission-input-ChL1aYNH.js';
6
+ import { C as xConnectionSchema, G as xProfileSchema, F as xPostSchema, g as ImageReference, u as imageInspectionSchema, q as imageComparisonSchema, x as imageSightingsSchema } from './limits-C4RzrOV4.js';
7
+ export { L as Limits, l as limits } from './limits-C4RzrOV4.js';
8
+ import { aM as memberIdentitySchema, bf as trackerQuerySchema, ba as trackerPageSchema, bo as trackerSummarySchema, ac as TrackerContentQuery, aX as trackerContentSchema, a8 as TrackerAttribution, o as Tracker, p as TrackerData, H as ContentBody, B as TrackerTriggerContext, U as TrackerPage } from './tracker-data-BqY-9Vu-.js';
9
+ import { C as telegramConnectionSchema, y as telegramChatMemberSchema, e as TelegramReader } from './submission-input-C152xIdn.js';
10
10
  import { EvaluationMember } from './authoring.js';
11
- export { A as AttemptCapture, C as CapturedFact } from './attempt-captures-BqPggxTU.js';
11
+ export { A as AttemptCapture, C as CapturedFact } from './attempt-captures-ClHAoo_n.js';
12
12
  import { b as ParticipantSession, R as RelayEvent } from './participant-activity-DXRq4s6K.js';
13
- import { B as Badge } from './offers-Hw2P6tcK.js';
14
- import { b as QuestView, q as questExperienceSchema } from './catalog-ByZMRS7I.js';
13
+ import { B as Badge } from './offers-BpYenB9i.js';
14
+ import { b as QuestView, q as questExperienceSchema } from './catalog-CbiftcxQ.js';
15
15
  import './streaks-0YuipsUQ.js';
16
- import './dashboards-pVfclkyh.js';
16
+ import './dashboards-jGPM3AxF.js';
17
17
  import './units-CwgsPB_r.js';
18
18
 
19
19
  /** One project time-zone change: from `effectiveAt` on, days are counted in `timeZone`. */
@@ -26,7 +26,7 @@ type CalendarSegment = {
26
26
  declare const capabilityRequestSchemas: {
27
27
  "wallet-balance": z.ZodObject<{
28
28
  kind: z.ZodLiteral<"wallet-balance">;
29
- chain: z.ZodUnion<readonly [z.ZodLiteral<"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp">, z.ZodCustom<`eip155:${number}`, `eip155:${number}`>, z.ZodCustom<`cosmos:${string}`, `cosmos:${string}`>]>;
29
+ chain: z.ZodUnion<readonly [z.ZodLiteral<"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp">, z.ZodLiteral<"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1">, z.ZodCustom<`eip155:${number}`, `eip155:${number}`>, z.ZodCustom<`cosmos:${string}`, `cosmos:${string}`>]>;
30
30
  token: z.ZodNullable<z.ZodString>;
31
31
  address: z.ZodNullable<z.ZodString>;
32
32
  }, z.core.$strict>;
@@ -268,6 +268,7 @@ type WalletEventsRequest = z.output<typeof walletEventsRequestSchema>;
268
268
  declare const walletTransactionsRequestSchema: z.ZodObject<{
269
269
  kind: z.ZodLiteral<"wallet-transactions">;
270
270
  program: z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>;
271
+ chain: z.ZodOptional<z.ZodLiteral<"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1">>;
271
272
  since: z.ZodNumber;
272
273
  afterActivation: z.ZodBoolean;
273
274
  mint: z.ZodNullable<z.ZodString>;
package/dist/testing.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  attemptCaptureSchema
3
- } from "./chunk-OWDIR7ZU.js";
3
+ } from "./chunk-RDUSFUXX.js";
4
4
  import {
5
5
  parseImageResult
6
- } from "./chunk-FU3W4IQN.js";
6
+ } from "./chunk-RWR2LOPA.js";
7
7
  import {
8
8
  isParticipantRoute
9
9
  } from "./chunk-U66GUVSG.js";
@@ -13,7 +13,7 @@ import {
13
13
  xPostSchema,
14
14
  xProfileSchema,
15
15
  xRequestSchema
16
- } from "./chunk-ANVAUOJP.js";
16
+ } from "./chunk-X3FMVRMM.js";
17
17
  import {
18
18
  CapabilityError
19
19
  } from "./chunk-MWMCQLCG.js";
@@ -22,7 +22,7 @@ import {
22
22
  participantActivitySchema,
23
23
  participantSessionSchema,
24
24
  questExperienceSchema
25
- } from "./chunk-7MQCQYEE.js";
25
+ } from "./chunk-DSJ46QLB.js";
26
26
  import {
27
27
  badgeCatalogSchema,
28
28
  badgeSchema,
@@ -34,6 +34,7 @@ import {
34
34
  discordMessageInputSchema,
35
35
  discordMessageSchema,
36
36
  evmChainIdSchema,
37
+ evmWalletOn,
37
38
  identifier,
38
39
  isContractCall,
39
40
  isContractEvent,
@@ -54,6 +55,7 @@ import {
54
55
  quizEvidenceSchema,
55
56
  rewardKey,
56
57
  solanaAddressSchema,
58
+ solanaDevnet,
57
59
  solanaMainnet,
58
60
  telegramChatMemberSchema,
59
61
  telegramConnectionInputSchema,
@@ -77,7 +79,7 @@ import {
77
79
  walletEventsSchema,
78
80
  walletNftsSchema,
79
81
  walletTransactionsSchema
80
- } from "./chunk-XCEGNKGH.js";
82
+ } from "./chunk-P33ZAJMS.js";
81
83
  import {
82
84
  RelayErrorCode
83
85
  } from "./chunk-FGXLXENM.js";
@@ -180,6 +182,7 @@ var capabilityRequestSchemas = /* @__PURE__ */ (() => ({
180
182
  kind: z.literal("wallet-balance"),
181
183
  chain: z.union([
182
184
  z.literal(solanaMainnet),
185
+ z.literal(solanaDevnet),
183
186
  evmChainIdSchema,
184
187
  cosmosNetworkSchema
185
188
  ]),
@@ -246,6 +249,8 @@ var walletEventsRequestSchema = /* @__PURE__ */ (() => z.strictObject({
246
249
  var walletTransactionsRequestSchema = /* @__PURE__ */ (() => z.strictObject({
247
250
  kind: z.literal("wallet-transactions"),
248
251
  program: z.string().max(44).refine(isSolanaProgram),
252
+ /** Solana devnet; absent for mainnet, as Relay's request has it. */
253
+ chain: z.literal(solanaDevnet).optional(),
249
254
  since: z.number().int().nonnegative().safe(),
250
255
  afterActivation: z.boolean(),
251
256
  mint: solanaAddressSchema.nullable(),
@@ -539,6 +544,8 @@ var readerFactories = {
539
544
  transactions: (query) => call({
540
545
  kind: "wallet-transactions",
541
546
  program: query.program,
547
+ // Only for another cluster, so a mainnet read sends the request it always did.
548
+ ...query.chain === void 0 || query.chain === "solana" || query.chain === solanaMainnet ? {} : { chain: query.chain },
542
549
  since: query.since,
543
550
  afterActivation: query.afterActivation ?? false,
544
551
  mint: query.mint ?? null,
@@ -903,7 +910,7 @@ function covers(wallet, chain) {
903
910
  return wallet.chain === "solana";
904
911
  }
905
912
  if (chain.startsWith("eip155:")) {
906
- return wallet.chain === "eip155";
913
+ return evmWalletOn(wallet, chain);
907
914
  }
908
915
  return wallet.chain === "cosmos" && wallet.network === chain;
909
916
  }
@@ -1107,7 +1114,7 @@ function factsAnswerer(facts) {
1107
1114
  if ("error" in pinned) {
1108
1115
  return pinned;
1109
1116
  }
1110
- const chain = request.kind === "wallet-events" ? request.event.split(":").slice(0, 2).join(":") : solanaMainnet;
1117
+ const chain = request.kind === "wallet-events" ? request.event.split(":").slice(0, 2).join(":") : request.chain ?? solanaMainnet;
1111
1118
  const wallets = (pinned.value ?? []).filter(
1112
1119
  (wallet) => covers(wallet, chain)
1113
1120
  );