@metamask-previews/kyc-controller 0.0.0-preview-abca9bcea → 0.0.0-preview-8bfa290fb

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 (58) hide show
  1. package/CHANGELOG.md +0 -6
  2. package/dist/KycController-method-action-types.cjs.map +1 -1
  3. package/dist/KycController-method-action-types.d.cts +4 -6
  4. package/dist/KycController-method-action-types.d.cts.map +1 -1
  5. package/dist/KycController-method-action-types.d.mts +4 -6
  6. package/dist/KycController-method-action-types.d.mts.map +1 -1
  7. package/dist/KycController-method-action-types.mjs.map +1 -1
  8. package/dist/KycController.cjs +302 -179
  9. package/dist/KycController.cjs.map +1 -1
  10. package/dist/KycController.d.cts +37 -43
  11. package/dist/KycController.d.cts.map +1 -1
  12. package/dist/KycController.d.mts +37 -43
  13. package/dist/KycController.d.mts.map +1 -1
  14. package/dist/KycController.mjs +301 -176
  15. package/dist/KycController.mjs.map +1 -1
  16. package/dist/KycService-method-action-types.cjs.map +1 -1
  17. package/dist/KycService-method-action-types.d.cts +4 -4
  18. package/dist/KycService-method-action-types.d.mts +4 -4
  19. package/dist/KycService-method-action-types.mjs.map +1 -1
  20. package/dist/KycService.cjs +13 -21
  21. package/dist/KycService.cjs.map +1 -1
  22. package/dist/KycService.d.cts +4 -4
  23. package/dist/KycService.d.cts.map +1 -1
  24. package/dist/KycService.d.mts +4 -4
  25. package/dist/KycService.d.mts.map +1 -1
  26. package/dist/KycService.mjs +13 -21
  27. package/dist/KycService.mjs.map +1 -1
  28. package/dist/index.cjs +1 -3
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +2 -2
  31. package/dist/index.d.cts.map +1 -1
  32. package/dist/index.d.mts +2 -2
  33. package/dist/index.d.mts.map +1 -1
  34. package/dist/index.mjs +1 -1
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/types.cjs.map +1 -1
  37. package/dist/types.d.cts +11 -50
  38. package/dist/types.d.cts.map +1 -1
  39. package/dist/types.d.mts +11 -50
  40. package/dist/types.d.mts.map +1 -1
  41. package/dist/types.mjs.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/vendorDisclaimerAcceptance.cjs +0 -74
  44. package/dist/vendorDisclaimerAcceptance.cjs.map +0 -1
  45. package/dist/vendorDisclaimerAcceptance.d.cts +0 -39
  46. package/dist/vendorDisclaimerAcceptance.d.cts.map +0 -1
  47. package/dist/vendorDisclaimerAcceptance.d.mts +0 -39
  48. package/dist/vendorDisclaimerAcceptance.d.mts.map +0 -1
  49. package/dist/vendorDisclaimerAcceptance.mjs +0 -67
  50. package/dist/vendorDisclaimerAcceptance.mjs.map +0 -1
  51. package/dist/vendors/MoonPayFrameHandler.cjs +0 -235
  52. package/dist/vendors/MoonPayFrameHandler.cjs.map +0 -1
  53. package/dist/vendors/MoonPayFrameHandler.d.cts +0 -74
  54. package/dist/vendors/MoonPayFrameHandler.d.cts.map +0 -1
  55. package/dist/vendors/MoonPayFrameHandler.d.mts +0 -74
  56. package/dist/vendors/MoonPayFrameHandler.d.mts.map +0 -1
  57. package/dist/vendors/MoonPayFrameHandler.mjs +0 -230
  58. package/dist/vendors/MoonPayFrameHandler.mjs.map +0 -1
@@ -9,10 +9,11 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _KycController_instances, _KycController_sumsubLauncher, _KycController_moonPayFrames, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_userStatusPollIntervalMs, _KycController_userStatusPollTimer, _KycController_userStatusPolling, _KycController_userStatusPollToken, _KycController_localUserSecretStore, _KycController_startConsentsSession, _KycController_recordSessionDisclaimers, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_buildUkycSessionVendorFields, _KycController_createUkycSession, _KycController_fetchAndApplyUserStatus, _KycController_applyUserStatus, _KycController_ensureUserStatusPolling, _KycController_stopUserStatusPolling, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_cancelPendingSession, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_assertAttestedServerPublicKey, _KycController_fail;
12
+ var _KycController_instances, _KycController_sumsubLauncher, _KycController_moonpayFrameKeypair, _KycController_authClientToken, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_userStatusPollIntervalMs, _KycController_userStatusPollTimer, _KycController_userStatusPolling, _KycController_userStatusPollToken, _KycController_localUserSecretStore, _KycController_startConsentsSession, _KycController_recordSessionDisclaimers, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_clearMoonPaySession, _KycController_dropTermsUnlessForVendor, _KycController_hasTermsForVendor, _KycController_handleCheckOutcome, _KycController_handleAuthOutcome, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_buildUkycSessionVendorFields, _KycController_createUkycSession, _KycController_fetchAndApplyUserStatus, _KycController_applyUserStatus, _KycController_ensureUserStatusPolling, _KycController_stopUserStatusPolling, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_cancelPendingSession, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_assertAttestedServerPublicKey, _KycController_fail;
13
13
  import { BaseController } from "@metamask/base-controller";
14
14
  import { stringToBytes } from "@metamask/utils";
15
15
  import { x25519 } from "@noble/curves/ed25519";
16
+ import { decryptCredentials, generateKeyPair } from "./crypto.mjs";
16
17
  import { toBase64Url } from "./encoding.mjs";
17
18
  import { controllerLog } from "./logger.mjs";
18
19
  import { deriveClientMaterial } from "./ukyc/deriveClientMaterial.mjs";
@@ -20,10 +21,12 @@ import { verifyJwtChain } from "./ukyc/jwtChain.mjs";
20
21
  import { getOrCreateLocalUserSecret } from "./ukyc/localUserSecret.mjs";
21
22
  import { encodeStorageAccessTokenForHeader, signStorageAccessToken } from "./ukyc/storageAccessToken.mjs";
22
23
  import { wrapEncryptionKey } from "./ukyc/wrapEncryptionKey.mjs";
23
- import { clearVendorDisclaimerAcceptance, hasVendorDisclaimerAcceptance, ironDisclaimerIds, recordVendorDisclaimerAcceptance } from "./vendorDisclaimerAcceptance.mjs";
24
- import { clearMoonPaySession, MoonPayFrameHandler } from "./vendors/MoonPayFrameHandler.mjs";
25
24
  // === GENERAL ===
26
25
  export const controllerName = 'KycController';
26
+ const FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';
27
+ const CHANNEL_CHECK = 'ch_1';
28
+ const CHANNEL_AUTH = 'ch_2';
29
+ const CHANNEL_RESET = 'ch_reset';
27
30
  // Placeholder credentials for the SumSub sub-flow. These are demo values that
28
31
  // must be replaced with real UKYC-issued material before production use.
29
32
  const MOCK_JWT_TOKEN = 'mock-jwt-token';
@@ -114,19 +117,31 @@ const kycControllerMetadata = {
114
117
  persist: false,
115
118
  usedInUi: false,
116
119
  },
117
- vendorDisclaimersAccepted: {
120
+ termsAcceptedAt: {
118
121
  includeInDebugSnapshot: true,
119
122
  includeInStateLogs: true,
120
123
  persist: true,
121
124
  usedInUi: false,
122
125
  },
123
- providerDisclaimersAccepted: {
126
+ acceptedDisclaimerIds: {
124
127
  includeInDebugSnapshot: true,
125
128
  includeInStateLogs: true,
126
129
  persist: true,
127
130
  usedInUi: false,
128
131
  },
129
- idosDisclaimersAccepted: {
132
+ termsAcceptedVendor: {
133
+ includeInDebugSnapshot: true,
134
+ includeInStateLogs: true,
135
+ persist: true,
136
+ usedInUi: false,
137
+ },
138
+ sumsubTncAccepted: {
139
+ includeInDebugSnapshot: true,
140
+ includeInStateLogs: true,
141
+ persist: true,
142
+ usedInUi: false,
143
+ },
144
+ idosTncAccepted: {
130
145
  includeInDebugSnapshot: true,
131
146
  includeInStateLogs: true,
132
147
  persist: true,
@@ -138,13 +153,13 @@ const kycControllerMetadata = {
138
153
  persist: false,
139
154
  usedInUi: false,
140
155
  },
141
- vendorDisclaimers: {
156
+ disclaimers: {
142
157
  includeInDebugSnapshot: false,
143
158
  includeInStateLogs: false,
144
159
  persist: false,
145
160
  usedInUi: true,
146
161
  },
147
- vendorError: {
162
+ disclaimersError: {
148
163
  includeInDebugSnapshot: true,
149
164
  includeInStateLogs: true,
150
165
  persist: false,
@@ -162,13 +177,13 @@ const kycControllerMetadata = {
162
177
  persist: false,
163
178
  usedInUi: true,
164
179
  },
165
- moonpaySessionToken: {
180
+ sessionToken: {
166
181
  includeInDebugSnapshot: false,
167
182
  includeInStateLogs: false,
168
183
  persist: false,
169
184
  usedInUi: false,
170
185
  },
171
- moonpayAccessToken: {
186
+ accessToken: {
172
187
  includeInDebugSnapshot: false,
173
188
  includeInStateLogs: false,
174
189
  persist: false,
@@ -229,17 +244,6 @@ const kycControllerMetadata = {
229
244
  usedInUi: true,
230
245
  },
231
246
  };
232
- /**
233
- * Constructs the default {@link KycVendorDisclaimersAccepted} value.
234
- *
235
- * @returns The default vendor-disclaimer acceptance map.
236
- */
237
- export function getDefaultKycVendorDisclaimersAccepted() {
238
- return { moonpay: null, iron: null };
239
- }
240
- export function getDefaultKycProviderDisclaimersAccepted() {
241
- return { sumsub: null };
242
- }
243
247
  /**
244
248
  * Constructs the default {@link KycController} state.
245
249
  *
@@ -251,16 +255,18 @@ export function getDefaultKycControllerState() {
251
255
  statusMessage: '',
252
256
  error: null,
253
257
  email: null,
254
- vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),
255
- providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),
256
- idosDisclaimersAccepted: null,
258
+ termsAcceptedAt: null,
259
+ acceptedDisclaimerIds: [],
260
+ termsAcceptedVendor: null,
261
+ sumsubTncAccepted: null,
262
+ idosTncAccepted: null,
257
263
  credentialReusabilityConsentGiven: null,
258
- vendorDisclaimers: [],
259
- vendorError: null,
264
+ disclaimers: [],
265
+ disclaimersError: null,
260
266
  sessionDisclaimers: null,
261
267
  geoCountry: null,
262
- moonpaySessionToken: null,
263
- moonpayAccessToken: null,
268
+ sessionToken: null,
269
+ accessToken: null,
264
270
  moonpayCustomerId: null,
265
271
  activeVendor: 'moonpay',
266
272
  activeProduct: null,
@@ -304,62 +310,45 @@ function isConsentConflictError(error) {
304
310
  error.httpStatus === 409);
305
311
  }
306
312
  /**
307
- *
308
- * @param value - The value to validate.
309
- * @returns `true` when `value` is a valid consent record list.
310
- */
311
- function isValidConsentRecordList(value) {
312
- return (Array.isArray(value) &&
313
- value.every((item) => typeof item === 'object' &&
314
- item !== null &&
315
- typeof item.key === 'string' &&
316
- typeof item.version === 'string'));
317
- }
318
- /**
319
- * Maps accepted disclaimer records onto unconsented catalog documents.
313
+ * Maps a session-disclaimer catalog into the `{ key, version }` records the
314
+ * record-consents API expects, or an empty list when the user declined that
315
+ * category.
320
316
  *
321
317
  * @param documents - Catalog documents for one consent category.
322
- * @param accepted - Accepted `{ key, version }` records from the caller.
323
- * @returns Consent records to POST, omitting already-consented documents.
318
+ * @param accepted - Whether the user accepted that category.
319
+ * @returns Consent records, or `[]` when not accepted.
324
320
  */
325
- function consentRecordsFromAcceptedList(documents, accepted) {
326
- if (accepted.length === 0) {
321
+ function consentRecordsFromCatalog(documents, accepted) {
322
+ if (!accepted) {
327
323
  return [];
328
324
  }
329
- const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
330
325
  return documents
331
- .filter((document) => !document.consented &&
332
- acceptedKeys.has(`${document.key}:${document.version}`))
326
+ .filter((document) => !document.consented)
333
327
  .map(({ key, version }) => ({ key, version }));
334
328
  }
335
329
  /**
336
- * Whether accepted disclaimers reference a missing catalog category.
330
+ * Whether an accepted T&C2 category has no catalog documents. An empty list
331
+ * would otherwise skip the POST and count as success.
337
332
  *
338
333
  * @param documents - Catalog documents for one consent category.
339
- * @param accepted - Accepted `{ key, version }` records from the caller.
340
- * @returns `true` when the caller accepted docs but the catalog is empty.
334
+ * @param accepted - Whether the user accepted that category.
335
+ * @returns `true` when the user accepted and the catalog is empty.
341
336
  */
342
337
  function isAcceptedCategoryEmpty(documents, accepted) {
343
- return accepted.length > 0 && documents.length === 0;
338
+ return accepted && documents.length === 0;
344
339
  }
345
340
  /**
346
- * Whether accepted disclaimers are still missing consent after a 409 re-GET:
347
- * empty catalog or any accepted document still unconsented.
341
+ * Whether an accepted category is still missing consent after a 409 re-GET:
342
+ * empty catalog or any document still unconsented.
348
343
  *
349
344
  * @param documents - Latest catalog documents for one consent category.
350
- * @param accepted - Accepted `{ key, version }` records from the caller.
345
+ * @param accepted - Whether the user accepted that category.
351
346
  * @returns `true` when accepted documents are not fully consented.
352
347
  */
353
348
  function acceptedCategoryStillMissing(documents, accepted) {
354
- if (accepted.length === 0) {
355
- return false;
356
- }
357
- if (documents.length === 0) {
358
- return true;
359
- }
360
- const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
361
- const relevant = documents.filter((document) => acceptedKeys.has(`${document.key}:${document.version}`));
362
- return (relevant.length === 0 || relevant.some((document) => !document.consented));
349
+ return (accepted &&
350
+ (documents.length === 0 ||
351
+ documents.some((document) => !document.consented)));
363
352
  }
364
353
  /**
365
354
  * Vendors other than MoonPay skip Check/Auth frames and use the empty-shell
@@ -395,9 +384,9 @@ const MESSENGER_EXPOSED_METHODS = [
395
384
  /**
396
385
  * `KycController` orchestrates the vendor-backed KYC / identity-verification
397
386
  * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per
398
- * product surface used by ramps and card. It owns all state and HTTP
399
- * orchestration (via `KycService`), while vendor protocol handling and
400
- * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.
387
+ * product surface used by ramps and card. It owns all state, HTTP
388
+ * orchestration (via `KycService`), crypto, and the frame message protocol;
389
+ * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.
401
390
  */
402
391
  export class KycController extends BaseController {
403
392
  /**
@@ -421,8 +410,10 @@ export class KycController extends BaseController {
421
410
  });
422
411
  _KycController_instances.add(this);
423
412
  _KycController_sumsubLauncher.set(this, void 0);
424
- /** MoonPay-specific frame protocol and non-persisted credentials. */
425
- _KycController_moonPayFrames.set(this, void 0);
413
+ /** MoonPay Check/Auth frame X25519 keypair (never persisted). */
414
+ _KycController_moonpayFrameKeypair.set(this, null);
415
+ /** Auth-frame client token, kept out of state. */
416
+ _KycController_authClientToken.set(this, null);
426
417
  /**
427
418
  * Monotonic flow generation. Incremented by {@link reset} and
428
419
  * {@link clearState} so in-flight async work (e.g. the KYC-required check)
@@ -459,13 +450,6 @@ export class KycController extends BaseController {
459
450
  __classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
460
451
  __classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
461
452
  __classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
462
- __classPrivateFieldSet(this, _KycController_moonPayFrames, new MoonPayFrameHandler({
463
- getState: () => this.state,
464
- update: (updater) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, updater),
465
- fail: (message) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, message),
466
- onAuthenticated: async () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this),
467
- requireTermsReacceptance: () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this),
468
- }), "f");
469
453
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
470
454
  }
471
455
  /**
@@ -490,16 +474,16 @@ export class KycController extends BaseController {
490
474
  // consumer drive it (or call `reset` first to start over).
491
475
  const vendor = params?.vendor ?? 'moonpay';
492
476
  if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
493
- if (vendor === 'moonpay') {
494
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").ensureKeypair();
477
+ if (vendor === 'moonpay' && !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
478
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, generateKeyPair(), "f");
495
479
  }
496
480
  return;
497
481
  }
498
482
  if (vendor === 'moonpay') {
499
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").startFlow();
483
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, generateKeyPair(), "f");
500
484
  }
501
485
  else {
502
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
486
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
503
487
  }
504
488
  // `initialize` starts a fresh flow, so `activeProduct` is always reset to
505
489
  // this call's product (or `null`). Otherwise a prior run's product could
@@ -510,9 +494,14 @@ export class KycController extends BaseController {
510
494
  state.email = params.email;
511
495
  }
512
496
  state.activeVendor = vendor;
513
- // MoonPay Check/Auth artifacts must not survive a switch to another vendor
497
+ // MoonPay Check/Auth artifacts must not survive a switch to another
498
+ // vendor: leftover `sessionToken` would keep `buildCheckFrameUrl` alive,
499
+ // leftover `accessToken` / `#authClientToken` would keep Auth / KYC
500
+ // calls bound to MoonPay, and leftover `moonpayCustomerId` would make
501
+ // `getCustomerIdentity` report a MoonPay id under the wrong vendor.
514
502
  if (vendor !== 'moonpay') {
515
- clearMoonPaySession(state);
503
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
504
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
516
505
  }
517
506
  state.activeProduct = params?.product ?? null;
518
507
  });
@@ -560,14 +549,16 @@ export class KycController extends BaseController {
560
549
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
561
550
  return;
562
551
  }
563
- const hasTerms = hasVendorDisclaimerAcceptance(this.state.vendorDisclaimersAccepted, vendor);
552
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, vendor);
553
+ const hasTerms = Boolean(this.state.termsAcceptedAt) &&
554
+ this.state.acceptedDisclaimerIds.length > 0;
564
555
  if (hasTerms && this.state.email) {
565
556
  if (usesConsentsFlow(vendor)) {
566
557
  // Consents-path vendors require T&C2 flags; if they weren't persisted
567
558
  // (i.e. null from pre-migration state), require reacceptance.
568
- const { providerDisclaimersAccepted, idosDisclaimersAccepted } = this.state;
569
- if (providerDisclaimersAccepted.sumsub === null ||
570
- idosDisclaimersAccepted === null) {
559
+ const sumsubTncSigned = this.state.sumsubTncAccepted;
560
+ const idosTncSigned = this.state.idosTncAccepted;
561
+ if (sumsubTncSigned === null || idosTncSigned === null) {
571
562
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
572
563
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
573
564
  state.phase = 'terms';
@@ -576,19 +567,12 @@ export class KycController extends BaseController {
576
567
  return;
577
568
  }
578
569
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
579
- providerDisclaimersAccepted: providerDisclaimersAccepted.sumsub,
580
- idosDisclaimersAccepted,
570
+ sumsubTncSigned,
571
+ idosTncSigned,
581
572
  credentialReusabilityConsentGiven: this.state.credentialReusabilityConsentGiven ?? false,
582
573
  });
583
574
  }
584
575
  else {
585
- // TODO: should this be here? or should it exist at all?
586
- if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {
587
- await this.loadDisclaimers();
588
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
589
- return;
590
- }
591
- }
592
576
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
593
577
  }
594
578
  return;
@@ -622,8 +606,9 @@ export class KycController extends BaseController {
622
606
  // after this request succeeds.
623
607
  state.activeVendor = params.vendor;
624
608
  if (params.vendor !== 'moonpay') {
625
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
626
- clearMoonPaySession(state);
609
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
610
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
611
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
627
612
  }
628
613
  });
629
614
  const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
@@ -632,6 +617,10 @@ export class KycController extends BaseController {
632
617
  vendor: params.vendor,
633
618
  email: params.email,
634
619
  });
620
+ if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
621
+ return;
622
+ }
623
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, params.vendor);
635
624
  }
636
625
  catch (error) {
637
626
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
@@ -665,13 +654,13 @@ export class KycController extends BaseController {
665
654
  country,
666
655
  });
667
656
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
668
- state.vendorDisclaimers = disclaimers;
669
- state.vendorError = null;
657
+ state.disclaimers = disclaimers;
658
+ state.disclaimersError = null;
670
659
  });
671
660
  }
672
661
  catch (error) {
673
662
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
674
- state.vendorError = `Failed to load disclaimers: ${String(error)}`;
663
+ state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;
675
664
  });
676
665
  }
677
666
  }
@@ -684,47 +673,44 @@ export class KycController extends BaseController {
684
673
  * @param params.product - The consuming feature the flow runs for. See
685
674
  * {@link initialize} for how the product drives the automatic post
686
675
  * authentication continuation.
687
- * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the
688
- * customer accepted (`{ key, version }` records). Required for every vendor
689
- * so callers explicitly declare acceptance.
690
- * @param params.idosDisclaimersAccepted - idOS disclaimer documents the
691
- * customer accepted (`{ key, version }` records). Required for every vendor
692
- * so callers explicitly declare acceptance.
676
+ * @param params.sumsubTncSigned - Whether Sumsub T&C were accepted (T&C2).
677
+ * Required for every vendor so callers explicitly declare acceptance.
678
+ * @param params.idosTncSigned - Whether idOS T&C were accepted (T&C2).
679
+ * Required for every vendor so callers explicitly declare acceptance.
693
680
  * @param params.credentialReusabilityConsentGiven - Whether the customer
694
681
  * consented to reuse existing idOS credentials. Used when recording
695
682
  * session-scoped disclaimers on the consents path. Defaults to `false`.
696
683
  */
697
684
  async acceptTermsAndStartSession(params) {
698
- const providerDisclaimersAccepted = params?.providerDisclaimersAccepted;
699
- const idosDisclaimersAccepted = params?.idosDisclaimersAccepted;
700
- if (!isValidConsentRecordList(providerDisclaimersAccepted) ||
701
- !isValidConsentRecordList(idosDisclaimersAccepted)) {
685
+ const sumsubTncSigned = params?.sumsubTncSigned;
686
+ const idosTncSigned = params?.idosTncSigned;
687
+ if (typeof sumsubTncSigned !== 'boolean' ||
688
+ typeof idosTncSigned !== 'boolean') {
702
689
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing T&C2 acceptance flags.');
703
690
  return;
704
691
  }
705
- const credentialReusabilityConsentGiven = params?.credentialReusabilityConsentGiven ?? false;
692
+ const credentialReusabilityConsentGiven = params.credentialReusabilityConsentGiven ?? false;
706
693
  const termsAcceptedAt = new Date().toISOString();
707
- const disclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
694
+ const disclaimerIds = this.state.disclaimers.map((disclaimer) => disclaimer.id);
708
695
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
709
- if (params?.email) {
696
+ if (params.email) {
710
697
  state.email = params.email;
711
698
  }
712
- if (params?.product) {
699
+ if (params.product) {
713
700
  state.activeProduct = params.product;
714
701
  }
715
- state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(state.vendorDisclaimersAccepted, state.activeVendor, { termsAcceptedAt, disclaimerIds });
716
- state.providerDisclaimersAccepted = {
717
- ...state.providerDisclaimersAccepted,
718
- sumsub: providerDisclaimersAccepted,
719
- };
720
- state.idosDisclaimersAccepted = idosDisclaimersAccepted;
702
+ state.termsAcceptedAt = termsAcceptedAt;
703
+ state.acceptedDisclaimerIds = disclaimerIds;
704
+ state.termsAcceptedVendor = state.activeVendor;
705
+ state.sumsubTncAccepted = sumsubTncSigned;
706
+ state.idosTncAccepted = idosTncSigned;
721
707
  state.credentialReusabilityConsentGiven =
722
708
  credentialReusabilityConsentGiven;
723
709
  });
724
710
  if (usesConsentsFlow(this.state.activeVendor)) {
725
711
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
726
- providerDisclaimersAccepted,
727
- idosDisclaimersAccepted,
712
+ sumsubTncSigned,
713
+ idosTncSigned,
728
714
  credentialReusabilityConsentGiven,
729
715
  });
730
716
  return;
@@ -736,12 +722,7 @@ export class KycController extends BaseController {
736
722
  */
737
723
  clearSavedTerms() {
738
724
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
739
- state.vendorDisclaimersAccepted =
740
- getDefaultKycVendorDisclaimersAccepted();
741
- state.providerDisclaimersAccepted =
742
- getDefaultKycProviderDisclaimersAccepted();
743
- state.idosDisclaimersAccepted = null;
744
- state.credentialReusabilityConsentGiven = null;
725
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
745
726
  });
746
727
  }
747
728
  /**
@@ -755,7 +736,68 @@ export class KycController extends BaseController {
755
736
  * @returns An object whose optional `reply` should be posted back.
756
737
  */
757
738
  async handleFrameMessage(params) {
758
- return await __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").handleMessage(params.message);
739
+ const payload = params.message;
740
+ if (!payload) {
741
+ return {};
742
+ }
743
+ if (payload.kind === 'handshake') {
744
+ const channelId = payload.meta?.channelId;
745
+ return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };
746
+ }
747
+ if (payload.kind !== 'complete') {
748
+ return {};
749
+ }
750
+ const channelId = payload.meta?.channelId;
751
+ // Only honor a Check/Auth `complete` for the MoonPay frame the flow is
752
+ // currently waiting on. This drops stale or duplicate messages — e.g. a
753
+ // late post after `reset()` (phase `idle`), after the flow already
754
+ // advanced past this frame, or after a vendor switch — so they cannot
755
+ // resurrect tokens, rewind `phase`, or recapture `moonpayCustomerId` on a
756
+ // controller that has moved on. Frame messages are external input and,
757
+ // unlike the async steps, are not covered by the `#generation` guard.
758
+ let expectedPhase = null;
759
+ if (channelId === CHANNEL_CHECK) {
760
+ expectedPhase = 'check';
761
+ }
762
+ else if (channelId === CHANNEL_AUTH) {
763
+ expectedPhase = 'auth';
764
+ }
765
+ if (!expectedPhase ||
766
+ this.state.phase !== expectedPhase ||
767
+ this.state.activeVendor !== 'moonpay') {
768
+ return {};
769
+ }
770
+ const status = payload.payload?.status;
771
+ const credsEnvelope = payload.payload?.credentials;
772
+ const customerId = payload.payload?.customer?.id ?? null;
773
+ if (customerId) {
774
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
775
+ state.moonpayCustomerId = customerId;
776
+ });
777
+ }
778
+ if (!status) {
779
+ return {};
780
+ }
781
+ let accessToken;
782
+ let clientToken;
783
+ if (credsEnvelope && __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
784
+ try {
785
+ const { credentials } = decryptCredentials(credsEnvelope, __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").privateKey);
786
+ accessToken = credentials.accessToken;
787
+ clientToken = credentials.clientToken;
788
+ }
789
+ catch (error) {
790
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Failed to decrypt frame credentials: ${String(error)}`);
791
+ return {};
792
+ }
793
+ }
794
+ if (channelId === CHANNEL_CHECK) {
795
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleCheckOutcome).call(this, status, accessToken, clientToken);
796
+ return {};
797
+ }
798
+ // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.
799
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleAuthOutcome).call(this, status, accessToken);
800
+ return {};
759
801
  }
760
802
  /**
761
803
  * Builds the Check-frame URL, or `null` when no session exists yet.
@@ -763,7 +805,17 @@ export class KycController extends BaseController {
763
805
  * @returns The Check-frame URL or `null`.
764
806
  */
765
807
  buildCheckFrameUrl() {
766
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildCheckFrameUrl();
808
+ if (this.state.activeVendor !== 'moonpay' ||
809
+ !this.state.sessionToken ||
810
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
811
+ return null;
812
+ }
813
+ const url = new URL(`${FRAMES_BASE_URL}/check-connection`);
814
+ url.searchParams.set('sessionToken', this.state.sessionToken);
815
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
816
+ url.searchParams.set('channelId', CHANNEL_CHECK);
817
+ url.searchParams.set('skipKyc', 'true');
818
+ return url.toString();
767
819
  }
768
820
  /**
769
821
  * Builds the Auth-frame URL, or `null` when no client token is available.
@@ -771,7 +823,16 @@ export class KycController extends BaseController {
771
823
  * @returns The Auth-frame URL or `null`.
772
824
  */
773
825
  buildAuthFrameUrl() {
774
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildAuthFrameUrl();
826
+ if (this.state.activeVendor !== 'moonpay' ||
827
+ !__classPrivateFieldGet(this, _KycController_authClientToken, "f") ||
828
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
829
+ return null;
830
+ }
831
+ const url = new URL(`${FRAMES_BASE_URL}/auth`);
832
+ url.searchParams.set('clientToken', __classPrivateFieldGet(this, _KycController_authClientToken, "f"));
833
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
834
+ url.searchParams.set('channelId', CHANNEL_AUTH);
835
+ return url.toString();
775
836
  }
776
837
  /**
777
838
  * Builds the Reset-frame URL.
@@ -779,7 +840,9 @@ export class KycController extends BaseController {
779
840
  * @returns The Reset-frame URL.
780
841
  */
781
842
  buildResetFrameUrl() {
782
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildResetFrameUrl();
843
+ const url = new URL(`${FRAMES_BASE_URL}/reset`);
844
+ url.searchParams.set('channelId', CHANNEL_RESET);
845
+ return url.toString();
783
846
  }
784
847
  /**
785
848
  * Checks whether KYC is required for a product and caches the result.
@@ -790,9 +853,9 @@ export class KycController extends BaseController {
790
853
  * @returns Whether KYC is required.
791
854
  */
792
855
  async checkKycRequired(params) {
793
- const { moonpayAccessToken } = this.state;
794
- if (!moonpayAccessToken) {
795
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing moonpayAccessToken — repeat the authentication step.');
856
+ const { accessToken } = this.state;
857
+ if (!accessToken) {
858
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing accessToken — repeat the authentication step.');
796
859
  return false;
797
860
  }
798
861
  const country = params.country ?? this.state.geoCountry;
@@ -808,11 +871,7 @@ export class KycController extends BaseController {
808
871
  state.statusMessage = 'Checking KYC status...';
809
872
  });
810
873
  try {
811
- const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', {
812
- accessToken: moonpayAccessToken,
813
- country,
814
- capabilities: [{ product: params.product }],
815
- });
874
+ const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', { accessToken, country, capabilities: [{ product: params.product }] });
816
875
  // The flow was reset while the check was in flight; discard the result
817
876
  // rather than resurrecting a done/cached state on an idle controller.
818
877
  const applied = __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
@@ -1097,11 +1156,13 @@ export class KycController extends BaseController {
1097
1156
  state.phase = 'idle';
1098
1157
  state.statusMessage = '';
1099
1158
  state.error = null;
1100
- state.vendorDisclaimers = [];
1101
- state.vendorError = null;
1159
+ state.disclaimers = [];
1160
+ state.disclaimersError = null;
1102
1161
  state.sessionDisclaimers = null;
1103
1162
  state.credentialReusabilityConsentGiven = null;
1104
- clearMoonPaySession(state);
1163
+ state.sessionToken = null;
1164
+ state.accessToken = null;
1165
+ state.moonpayCustomerId = null;
1105
1166
  state.activeVendor = 'moonpay';
1106
1167
  state.activeProduct = null;
1107
1168
  state.sumsub = {
@@ -1128,7 +1189,7 @@ export class KycController extends BaseController {
1128
1189
  });
1129
1190
  }
1130
1191
  }
1131
- _KycController_sumsubLauncher = new WeakMap(), _KycController_moonPayFrames = new WeakMap(), _KycController_generation = new WeakMap(), _KycController_sessionStatusPollIntervalMs = new WeakMap(), _KycController_pollTimer = new WeakMap(), _KycController_pollToken = new WeakMap(), _KycController_userStatusPollIntervalMs = new WeakMap(), _KycController_userStatusPollTimer = new WeakMap(), _KycController_userStatusPolling = new WeakMap(), _KycController_userStatusPollToken = new WeakMap(), _KycController_instances = new WeakSet(), _KycController_localUserSecretStore = function _KycController_localUserSecretStore() {
1192
+ _KycController_sumsubLauncher = new WeakMap(), _KycController_moonpayFrameKeypair = new WeakMap(), _KycController_authClientToken = new WeakMap(), _KycController_generation = new WeakMap(), _KycController_sessionStatusPollIntervalMs = new WeakMap(), _KycController_pollTimer = new WeakMap(), _KycController_pollToken = new WeakMap(), _KycController_userStatusPollIntervalMs = new WeakMap(), _KycController_userStatusPollTimer = new WeakMap(), _KycController_userStatusPolling = new WeakMap(), _KycController_userStatusPollToken = new WeakMap(), _KycController_instances = new WeakSet(), _KycController_localUserSecretStore = function _KycController_localUserSecretStore() {
1132
1193
  return {
1133
1194
  get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
1134
1195
  set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
@@ -1140,14 +1201,13 @@ _KycController_sumsubLauncher = new WeakMap(), _KycController_moonPayFrames = ne
1140
1201
  * SumSub — skipping MoonPay Check/Auth frames.
1141
1202
  *
1142
1203
  * @param consents - T&C2 flags mapped onto the session disclaimer catalog.
1143
- * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.
1144
- * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.
1204
+ * @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
1205
+ * @param consents.idosTncSigned - Whether idOS T&C were accepted.
1145
1206
  * @param consents.credentialReusabilityConsentGiven - Whether credential
1146
1207
  * reuse was accepted.
1147
1208
  */
1148
1209
  async function _KycController_startConsentsSession(consents) {
1149
- const { email } = this.state;
1150
- const acceptedDisclaimerIds = ironDisclaimerIds(this.state.vendorDisclaimersAccepted);
1210
+ const { email, acceptedDisclaimerIds } = this.state;
1151
1211
  if (!email) {
1152
1212
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for consents session.');
1153
1213
  return;
@@ -1165,7 +1225,7 @@ async function _KycController_startConsentsSession(consents) {
1165
1225
  state.sumsub.result = null;
1166
1226
  state.sumsub.sessionStatus = null;
1167
1227
  // Consents-path vendors have no MoonPay session/access tokens.
1168
- clearMoonPaySession(state);
1228
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
1169
1229
  });
1170
1230
  try {
1171
1231
  await this.messenger.call('KycService:submitVendorDisclaimers', {
@@ -1282,8 +1342,8 @@ async function _KycController_startConsentsSession(consents) {
1282
1342
  *
1283
1343
  * @param sessionId - The UKYC session id.
1284
1344
  * @param consents - T&C2 flags mapped onto catalog documents.
1285
- * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.
1286
- * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.
1345
+ * @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
1346
+ * @param consents.idosTncSigned - Whether idOS T&C were accepted.
1287
1347
  * @param consents.credentialReusabilityConsentGiven - Whether credential
1288
1348
  * reuse was accepted.
1289
1349
  * @param generation - Flow generation captured by the caller.
@@ -1297,12 +1357,12 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1297
1357
  state.sessionDisclaimers = catalog;
1298
1358
  state.statusMessage = 'Submitting consents...';
1299
1359
  });
1300
- if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosDisclaimersAccepted) ||
1301
- isAcceptedCategoryEmpty(catalog.kycProvider, consents.providerDisclaimersAccepted)) {
1360
+ if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosTncSigned) ||
1361
+ isAcceptedCategoryEmpty(catalog.kycProvider, consents.sumsubTncSigned)) {
1302
1362
  throw new Error('Session disclaimer catalog is missing documents for an accepted category.');
1303
1363
  }
1304
- const idOS = consentRecordsFromAcceptedList(catalog.idOS, consents.idosDisclaimersAccepted);
1305
- const kycProvider = consentRecordsFromAcceptedList(catalog.kycProvider, consents.providerDisclaimersAccepted);
1364
+ const idOS = consentRecordsFromCatalog(catalog.idOS, consents.idosTncSigned);
1365
+ const kycProvider = consentRecordsFromCatalog(catalog.kycProvider, consents.sumsubTncSigned);
1306
1366
  const reuseUnchanged = catalog.credentialReusabilityConsentGiven ===
1307
1367
  consents.credentialReusabilityConsentGiven;
1308
1368
  if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {
@@ -1333,9 +1393,8 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1333
1393
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1334
1394
  state.sessionDisclaimers = latest;
1335
1395
  });
1336
- // TODO: Should we really be doing client side validation of these?
1337
- const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosDisclaimersAccepted);
1338
- const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.providerDisclaimersAccepted);
1396
+ const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosTncSigned);
1397
+ const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.sumsubTncSigned);
1339
1398
  const stillMissingReuse = consents.credentialReusabilityConsentGiven &&
1340
1399
  !latest.credentialReusabilityConsentGiven;
1341
1400
  if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {
@@ -1347,9 +1406,7 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1347
1406
  * Creates a vendor session from the currently stored terms + email.
1348
1407
  */
1349
1408
  async function _KycController_createSession() {
1350
- const { email } = this.state;
1351
- const termsAcceptedAt = this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;
1352
- const acceptedDisclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
1409
+ const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;
1353
1410
  if (!email) {
1354
1411
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for session creation.');
1355
1412
  return;
@@ -1364,7 +1421,7 @@ async function _KycController_createSession() {
1364
1421
  // (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot
1365
1422
  // return a URL tied to an old client token, and `checkKycRequired` cannot
1366
1423
  // run with an access token from an earlier authentication. The Check/Auth
1367
- // frames re-populate these for the new session. Because `moonpaySessionToken` is
1424
+ // frames re-populate these for the new session. Because `sessionToken` is
1368
1425
  // cleared here and only re-set on success, a failed creation leaves it
1369
1426
  // `null` rather than resurrecting the previous session.
1370
1427
  // Capture the flow generation so a `reset()` landing while the create
@@ -1372,18 +1429,18 @@ async function _KycController_createSession() {
1372
1429
  // the now-idle controller (failure). The synchronous update below runs
1373
1430
  // before any `await`, so it needs no guard.
1374
1431
  const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
1375
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clearAuthentication();
1432
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
1376
1433
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1377
1434
  state.error = null;
1378
1435
  state.phase = 'session';
1379
1436
  state.statusMessage = 'Creating session...';
1380
- state.moonpaySessionToken = null;
1381
- state.moonpayAccessToken = null;
1437
+ state.sessionToken = null;
1438
+ state.accessToken = null;
1382
1439
  });
1383
1440
  try {
1384
1441
  const { sessionToken } = await this.messenger.call('KycService:createSession', { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds });
1385
1442
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1386
- state.moonpaySessionToken = sessionToken;
1443
+ state.sessionToken = sessionToken;
1387
1444
  state.phase = 'check';
1388
1445
  state.statusMessage = 'Authenticating via Check frame...';
1389
1446
  });
@@ -1409,13 +1466,82 @@ async function _KycController_createSession() {
1409
1466
  });
1410
1467
  await this.loadDisclaimers();
1411
1468
  }
1412
- }, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state, vendor) {
1413
- const targetVendor = vendor ?? state.activeVendor;
1414
- state.vendorDisclaimersAccepted = clearVendorDisclaimerAcceptance(state.vendorDisclaimersAccepted, targetVendor);
1415
- state.providerDisclaimersAccepted =
1416
- getDefaultKycProviderDisclaimersAccepted();
1417
- state.idosDisclaimersAccepted = null;
1469
+ }, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state) {
1470
+ state.termsAcceptedAt = null;
1471
+ state.acceptedDisclaimerIds = [];
1472
+ state.termsAcceptedVendor = null;
1473
+ state.sumsubTncAccepted = null;
1474
+ state.idosTncAccepted = null;
1418
1475
  state.credentialReusabilityConsentGiven = null;
1476
+ }, _KycController_clearMoonPaySession = function _KycController_clearMoonPaySession(state) {
1477
+ state.moonpayCustomerId = null;
1478
+ state.sessionToken = null;
1479
+ state.accessToken = null;
1480
+ }, _KycController_dropTermsUnlessForVendor = function _KycController_dropTermsUnlessForVendor(vendor) {
1481
+ if (__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, vendor)) {
1482
+ return;
1483
+ }
1484
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1485
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
1486
+ });
1487
+ }, _KycController_hasTermsForVendor = function _KycController_hasTermsForVendor(vendor) {
1488
+ if (this.state.termsAcceptedVendor === null) {
1489
+ return false;
1490
+ }
1491
+ return this.state.termsAcceptedVendor === vendor;
1492
+ }, _KycController_handleCheckOutcome =
1493
+ /**
1494
+ * Applies a Check-frame outcome.
1495
+ *
1496
+ * @param status - The frame status.
1497
+ * @param accessToken - The decrypted access token, if any.
1498
+ * @param clientToken - The decrypted client token, if any.
1499
+ */
1500
+ async function _KycController_handleCheckOutcome(status, accessToken, clientToken) {
1501
+ if (status === 'active' && accessToken) {
1502
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1503
+ state.accessToken = accessToken;
1504
+ state.phase = 'form';
1505
+ state.statusMessage = 'Already authenticated. Review to submit.';
1506
+ });
1507
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
1508
+ return;
1509
+ }
1510
+ if (status === 'connectionRequired' && clientToken) {
1511
+ __classPrivateFieldSet(this, _KycController_authClientToken, clientToken, "f");
1512
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1513
+ state.phase = 'auth';
1514
+ state.statusMessage = 'Verify your email via OTP in the Auth frame.';
1515
+ });
1516
+ return;
1517
+ }
1518
+ if (status === 'termsAcceptanceRequired') {
1519
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
1520
+ return;
1521
+ }
1522
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Check frame returned status: ${status}`);
1523
+ }, _KycController_handleAuthOutcome =
1524
+ /**
1525
+ * Applies an Auth-frame outcome.
1526
+ *
1527
+ * @param status - The frame status.
1528
+ * @param accessToken - The decrypted access token, if any.
1529
+ */
1530
+ async function _KycController_handleAuthOutcome(status, accessToken) {
1531
+ if (status === 'active' && accessToken) {
1532
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1533
+ state.accessToken = accessToken;
1534
+ state.phase = 'form';
1535
+ state.statusMessage = 'Authenticated. Review to submit.';
1536
+ });
1537
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
1538
+ return;
1539
+ }
1540
+ if (status === 'termsAcceptanceRequired') {
1541
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
1542
+ return;
1543
+ }
1544
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Auth frame returned status: ${status}`);
1419
1545
  }, _KycController_continueAfterAuthentication =
1420
1546
  /**
1421
1547
  * Continues the flow once authentication has completed (phase `form`).
@@ -1467,7 +1593,7 @@ async function _KycController_continueAfterAuthentication() {
1467
1593
  return {
1468
1594
  vendor: 'moonpay',
1469
1595
  vendorMetadata: {
1470
- moonPayAccessToken: this.state.moonpayAccessToken,
1596
+ moonPayAccessToken: this.state.accessToken,
1471
1597
  moonPayUserId: this.state.moonpayCustomerId,
1472
1598
  },
1473
1599
  };
@@ -1535,8 +1661,7 @@ async function _KycController_createUkycSession(generation) {
1535
1661
  // authorizes later storage reads without granting write or delete access.
1536
1662
  const ukycCapabilityToken = signStorageAccessToken({
1537
1663
  material: clientMaterial,
1538
- // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write
1539
- operations: ['read', 'write'],
1664
+ operations: ['read'],
1540
1665
  expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),
1541
1666
  });
1542
1667
  const wrappedUkycCapabilityToken = wrapEncryptionKey(sessionClientPrivateKey, capabilityTokenSchema.serverPublicKey.x, stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)));
@@ -1723,7 +1848,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
1723
1848
  __classPrivateFieldSet(this, _KycController_pollTimer, null, "f");
1724
1849
  }
1725
1850
  }, _KycController_cancelPendingSession = function _KycController_cancelPendingSession() {
1726
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
1851
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
1727
1852
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopPolling).call(this);
1728
1853
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
1729
1854
  __classPrivateFieldSet(this, _KycController_generation, __classPrivateFieldGet(this, _KycController_generation, "f") + 1, "f");