@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
@@ -10,12 +10,13 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
10
10
  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");
11
11
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
12
  };
13
- 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;
13
+ 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;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.KycController = exports.getDefaultKycControllerState = exports.getDefaultKycProviderDisclaimersAccepted = exports.getDefaultKycVendorDisclaimersAccepted = exports.controllerName = void 0;
15
+ exports.KycController = exports.getDefaultKycControllerState = exports.controllerName = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
17
17
  const utils_1 = require("@metamask/utils");
18
18
  const ed25519_1 = require("@noble/curves/ed25519");
19
+ const crypto_js_1 = require("./crypto.cjs");
19
20
  const encoding_js_1 = require("./encoding.cjs");
20
21
  const logger_js_1 = require("./logger.cjs");
21
22
  const deriveClientMaterial_js_1 = require("./ukyc/deriveClientMaterial.cjs");
@@ -23,10 +24,12 @@ const jwtChain_js_1 = require("./ukyc/jwtChain.cjs");
23
24
  const localUserSecret_js_1 = require("./ukyc/localUserSecret.cjs");
24
25
  const storageAccessToken_js_1 = require("./ukyc/storageAccessToken.cjs");
25
26
  const wrapEncryptionKey_js_1 = require("./ukyc/wrapEncryptionKey.cjs");
26
- const vendorDisclaimerAcceptance_js_1 = require("./vendorDisclaimerAcceptance.cjs");
27
- const MoonPayFrameHandler_js_1 = require("./vendors/MoonPayFrameHandler.cjs");
28
27
  // === GENERAL ===
29
28
  exports.controllerName = 'KycController';
29
+ const FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';
30
+ const CHANNEL_CHECK = 'ch_1';
31
+ const CHANNEL_AUTH = 'ch_2';
32
+ const CHANNEL_RESET = 'ch_reset';
30
33
  // Placeholder credentials for the SumSub sub-flow. These are demo values that
31
34
  // must be replaced with real UKYC-issued material before production use.
32
35
  const MOCK_JWT_TOKEN = 'mock-jwt-token';
@@ -117,19 +120,31 @@ const kycControllerMetadata = {
117
120
  persist: false,
118
121
  usedInUi: false,
119
122
  },
120
- vendorDisclaimersAccepted: {
123
+ termsAcceptedAt: {
121
124
  includeInDebugSnapshot: true,
122
125
  includeInStateLogs: true,
123
126
  persist: true,
124
127
  usedInUi: false,
125
128
  },
126
- providerDisclaimersAccepted: {
129
+ acceptedDisclaimerIds: {
127
130
  includeInDebugSnapshot: true,
128
131
  includeInStateLogs: true,
129
132
  persist: true,
130
133
  usedInUi: false,
131
134
  },
132
- idosDisclaimersAccepted: {
135
+ termsAcceptedVendor: {
136
+ includeInDebugSnapshot: true,
137
+ includeInStateLogs: true,
138
+ persist: true,
139
+ usedInUi: false,
140
+ },
141
+ sumsubTncAccepted: {
142
+ includeInDebugSnapshot: true,
143
+ includeInStateLogs: true,
144
+ persist: true,
145
+ usedInUi: false,
146
+ },
147
+ idosTncAccepted: {
133
148
  includeInDebugSnapshot: true,
134
149
  includeInStateLogs: true,
135
150
  persist: true,
@@ -141,13 +156,13 @@ const kycControllerMetadata = {
141
156
  persist: false,
142
157
  usedInUi: false,
143
158
  },
144
- vendorDisclaimers: {
159
+ disclaimers: {
145
160
  includeInDebugSnapshot: false,
146
161
  includeInStateLogs: false,
147
162
  persist: false,
148
163
  usedInUi: true,
149
164
  },
150
- vendorError: {
165
+ disclaimersError: {
151
166
  includeInDebugSnapshot: true,
152
167
  includeInStateLogs: true,
153
168
  persist: false,
@@ -165,13 +180,13 @@ const kycControllerMetadata = {
165
180
  persist: false,
166
181
  usedInUi: true,
167
182
  },
168
- moonpaySessionToken: {
183
+ sessionToken: {
169
184
  includeInDebugSnapshot: false,
170
185
  includeInStateLogs: false,
171
186
  persist: false,
172
187
  usedInUi: false,
173
188
  },
174
- moonpayAccessToken: {
189
+ accessToken: {
175
190
  includeInDebugSnapshot: false,
176
191
  includeInStateLogs: false,
177
192
  persist: false,
@@ -232,19 +247,6 @@ const kycControllerMetadata = {
232
247
  usedInUi: true,
233
248
  },
234
249
  };
235
- /**
236
- * Constructs the default {@link KycVendorDisclaimersAccepted} value.
237
- *
238
- * @returns The default vendor-disclaimer acceptance map.
239
- */
240
- function getDefaultKycVendorDisclaimersAccepted() {
241
- return { moonpay: null, iron: null };
242
- }
243
- exports.getDefaultKycVendorDisclaimersAccepted = getDefaultKycVendorDisclaimersAccepted;
244
- function getDefaultKycProviderDisclaimersAccepted() {
245
- return { sumsub: null };
246
- }
247
- exports.getDefaultKycProviderDisclaimersAccepted = getDefaultKycProviderDisclaimersAccepted;
248
250
  /**
249
251
  * Constructs the default {@link KycController} state.
250
252
  *
@@ -256,16 +258,18 @@ function getDefaultKycControllerState() {
256
258
  statusMessage: '',
257
259
  error: null,
258
260
  email: null,
259
- vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),
260
- providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),
261
- idosDisclaimersAccepted: null,
261
+ termsAcceptedAt: null,
262
+ acceptedDisclaimerIds: [],
263
+ termsAcceptedVendor: null,
264
+ sumsubTncAccepted: null,
265
+ idosTncAccepted: null,
262
266
  credentialReusabilityConsentGiven: null,
263
- vendorDisclaimers: [],
264
- vendorError: null,
267
+ disclaimers: [],
268
+ disclaimersError: null,
265
269
  sessionDisclaimers: null,
266
270
  geoCountry: null,
267
- moonpaySessionToken: null,
268
- moonpayAccessToken: null,
271
+ sessionToken: null,
272
+ accessToken: null,
269
273
  moonpayCustomerId: null,
270
274
  activeVendor: 'moonpay',
271
275
  activeProduct: null,
@@ -310,62 +314,45 @@ function isConsentConflictError(error) {
310
314
  error.httpStatus === 409);
311
315
  }
312
316
  /**
313
- *
314
- * @param value - The value to validate.
315
- * @returns `true` when `value` is a valid consent record list.
316
- */
317
- function isValidConsentRecordList(value) {
318
- return (Array.isArray(value) &&
319
- value.every((item) => typeof item === 'object' &&
320
- item !== null &&
321
- typeof item.key === 'string' &&
322
- typeof item.version === 'string'));
323
- }
324
- /**
325
- * Maps accepted disclaimer records onto unconsented catalog documents.
317
+ * Maps a session-disclaimer catalog into the `{ key, version }` records the
318
+ * record-consents API expects, or an empty list when the user declined that
319
+ * category.
326
320
  *
327
321
  * @param documents - Catalog documents for one consent category.
328
- * @param accepted - Accepted `{ key, version }` records from the caller.
329
- * @returns Consent records to POST, omitting already-consented documents.
322
+ * @param accepted - Whether the user accepted that category.
323
+ * @returns Consent records, or `[]` when not accepted.
330
324
  */
331
- function consentRecordsFromAcceptedList(documents, accepted) {
332
- if (accepted.length === 0) {
325
+ function consentRecordsFromCatalog(documents, accepted) {
326
+ if (!accepted) {
333
327
  return [];
334
328
  }
335
- const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
336
329
  return documents
337
- .filter((document) => !document.consented &&
338
- acceptedKeys.has(`${document.key}:${document.version}`))
330
+ .filter((document) => !document.consented)
339
331
  .map(({ key, version }) => ({ key, version }));
340
332
  }
341
333
  /**
342
- * Whether accepted disclaimers reference a missing catalog category.
334
+ * Whether an accepted T&C2 category has no catalog documents. An empty list
335
+ * would otherwise skip the POST and count as success.
343
336
  *
344
337
  * @param documents - Catalog documents for one consent category.
345
- * @param accepted - Accepted `{ key, version }` records from the caller.
346
- * @returns `true` when the caller accepted docs but the catalog is empty.
338
+ * @param accepted - Whether the user accepted that category.
339
+ * @returns `true` when the user accepted and the catalog is empty.
347
340
  */
348
341
  function isAcceptedCategoryEmpty(documents, accepted) {
349
- return accepted.length > 0 && documents.length === 0;
342
+ return accepted && documents.length === 0;
350
343
  }
351
344
  /**
352
- * Whether accepted disclaimers are still missing consent after a 409 re-GET:
353
- * empty catalog or any accepted document still unconsented.
345
+ * Whether an accepted category is still missing consent after a 409 re-GET:
346
+ * empty catalog or any document still unconsented.
354
347
  *
355
348
  * @param documents - Latest catalog documents for one consent category.
356
- * @param accepted - Accepted `{ key, version }` records from the caller.
349
+ * @param accepted - Whether the user accepted that category.
357
350
  * @returns `true` when accepted documents are not fully consented.
358
351
  */
359
352
  function acceptedCategoryStillMissing(documents, accepted) {
360
- if (accepted.length === 0) {
361
- return false;
362
- }
363
- if (documents.length === 0) {
364
- return true;
365
- }
366
- const acceptedKeys = new Set(accepted.map((record) => `${record.key}:${record.version}`));
367
- const relevant = documents.filter((document) => acceptedKeys.has(`${document.key}:${document.version}`));
368
- return (relevant.length === 0 || relevant.some((document) => !document.consented));
353
+ return (accepted &&
354
+ (documents.length === 0 ||
355
+ documents.some((document) => !document.consented)));
369
356
  }
370
357
  /**
371
358
  * Vendors other than MoonPay skip Check/Auth frames and use the empty-shell
@@ -401,9 +388,9 @@ const MESSENGER_EXPOSED_METHODS = [
401
388
  /**
402
389
  * `KycController` orchestrates the vendor-backed KYC / identity-verification
403
390
  * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per
404
- * product surface used by ramps and card. It owns all state and HTTP
405
- * orchestration (via `KycService`), while vendor protocol handling and
406
- * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.
391
+ * product surface used by ramps and card. It owns all state, HTTP
392
+ * orchestration (via `KycService`), crypto, and the frame message protocol;
393
+ * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.
407
394
  */
408
395
  class KycController extends base_controller_1.BaseController {
409
396
  /**
@@ -427,8 +414,10 @@ class KycController extends base_controller_1.BaseController {
427
414
  });
428
415
  _KycController_instances.add(this);
429
416
  _KycController_sumsubLauncher.set(this, void 0);
430
- /** MoonPay-specific frame protocol and non-persisted credentials. */
431
- _KycController_moonPayFrames.set(this, void 0);
417
+ /** MoonPay Check/Auth frame X25519 keypair (never persisted). */
418
+ _KycController_moonpayFrameKeypair.set(this, null);
419
+ /** Auth-frame client token, kept out of state. */
420
+ _KycController_authClientToken.set(this, null);
432
421
  /**
433
422
  * Monotonic flow generation. Incremented by {@link reset} and
434
423
  * {@link clearState} so in-flight async work (e.g. the KYC-required check)
@@ -465,13 +454,6 @@ class KycController extends base_controller_1.BaseController {
465
454
  __classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
466
455
  __classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
467
456
  __classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
468
- __classPrivateFieldSet(this, _KycController_moonPayFrames, new MoonPayFrameHandler_js_1.MoonPayFrameHandler({
469
- getState: () => this.state,
470
- update: (updater) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, updater),
471
- fail: (message) => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, message),
472
- onAuthenticated: async () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this),
473
- requireTermsReacceptance: () => __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this),
474
- }), "f");
475
457
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
476
458
  }
477
459
  /**
@@ -496,16 +478,16 @@ class KycController extends base_controller_1.BaseController {
496
478
  // consumer drive it (or call `reset` first to start over).
497
479
  const vendor = params?.vendor ?? 'moonpay';
498
480
  if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
499
- if (vendor === 'moonpay') {
500
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").ensureKeypair();
481
+ if (vendor === 'moonpay' && !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
482
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, (0, crypto_js_1.generateKeyPair)(), "f");
501
483
  }
502
484
  return;
503
485
  }
504
486
  if (vendor === 'moonpay') {
505
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").startFlow();
487
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, (0, crypto_js_1.generateKeyPair)(), "f");
506
488
  }
507
489
  else {
508
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
490
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
509
491
  }
510
492
  // `initialize` starts a fresh flow, so `activeProduct` is always reset to
511
493
  // this call's product (or `null`). Otherwise a prior run's product could
@@ -516,9 +498,14 @@ class KycController extends base_controller_1.BaseController {
516
498
  state.email = params.email;
517
499
  }
518
500
  state.activeVendor = vendor;
519
- // MoonPay Check/Auth artifacts must not survive a switch to another vendor
501
+ // MoonPay Check/Auth artifacts must not survive a switch to another
502
+ // vendor: leftover `sessionToken` would keep `buildCheckFrameUrl` alive,
503
+ // leftover `accessToken` / `#authClientToken` would keep Auth / KYC
504
+ // calls bound to MoonPay, and leftover `moonpayCustomerId` would make
505
+ // `getCustomerIdentity` report a MoonPay id under the wrong vendor.
520
506
  if (vendor !== 'moonpay') {
521
- (0, MoonPayFrameHandler_js_1.clearMoonPaySession)(state);
507
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
508
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
522
509
  }
523
510
  state.activeProduct = params?.product ?? null;
524
511
  });
@@ -566,14 +553,16 @@ class KycController extends base_controller_1.BaseController {
566
553
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
567
554
  return;
568
555
  }
569
- const hasTerms = (0, vendorDisclaimerAcceptance_js_1.hasVendorDisclaimerAcceptance)(this.state.vendorDisclaimersAccepted, vendor);
556
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, vendor);
557
+ const hasTerms = Boolean(this.state.termsAcceptedAt) &&
558
+ this.state.acceptedDisclaimerIds.length > 0;
570
559
  if (hasTerms && this.state.email) {
571
560
  if (usesConsentsFlow(vendor)) {
572
561
  // Consents-path vendors require T&C2 flags; if they weren't persisted
573
562
  // (i.e. null from pre-migration state), require reacceptance.
574
- const { providerDisclaimersAccepted, idosDisclaimersAccepted } = this.state;
575
- if (providerDisclaimersAccepted.sumsub === null ||
576
- idosDisclaimersAccepted === null) {
563
+ const sumsubTncSigned = this.state.sumsubTncAccepted;
564
+ const idosTncSigned = this.state.idosTncAccepted;
565
+ if (sumsubTncSigned === null || idosTncSigned === null) {
577
566
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
578
567
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
579
568
  state.phase = 'terms';
@@ -582,19 +571,12 @@ class KycController extends base_controller_1.BaseController {
582
571
  return;
583
572
  }
584
573
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
585
- providerDisclaimersAccepted: providerDisclaimersAccepted.sumsub,
586
- idosDisclaimersAccepted,
574
+ sumsubTncSigned,
575
+ idosTncSigned,
587
576
  credentialReusabilityConsentGiven: this.state.credentialReusabilityConsentGiven ?? false,
588
577
  });
589
578
  }
590
579
  else {
591
- // TODO: should this be here? or should it exist at all?
592
- if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {
593
- await this.loadDisclaimers();
594
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
595
- return;
596
- }
597
- }
598
580
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
599
581
  }
600
582
  return;
@@ -628,8 +610,9 @@ class KycController extends base_controller_1.BaseController {
628
610
  // after this request succeeds.
629
611
  state.activeVendor = params.vendor;
630
612
  if (params.vendor !== 'moonpay') {
631
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
632
- (0, MoonPayFrameHandler_js_1.clearMoonPaySession)(state);
613
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
614
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
615
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
633
616
  }
634
617
  });
635
618
  const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
@@ -638,6 +621,10 @@ class KycController extends base_controller_1.BaseController {
638
621
  vendor: params.vendor,
639
622
  email: params.email,
640
623
  });
624
+ if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
625
+ return;
626
+ }
627
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_dropTermsUnlessForVendor).call(this, params.vendor);
641
628
  }
642
629
  catch (error) {
643
630
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
@@ -671,13 +658,13 @@ class KycController extends base_controller_1.BaseController {
671
658
  country,
672
659
  });
673
660
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
674
- state.vendorDisclaimers = disclaimers;
675
- state.vendorError = null;
661
+ state.disclaimers = disclaimers;
662
+ state.disclaimersError = null;
676
663
  });
677
664
  }
678
665
  catch (error) {
679
666
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
680
- state.vendorError = `Failed to load disclaimers: ${String(error)}`;
667
+ state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;
681
668
  });
682
669
  }
683
670
  }
@@ -690,47 +677,44 @@ class KycController extends base_controller_1.BaseController {
690
677
  * @param params.product - The consuming feature the flow runs for. See
691
678
  * {@link initialize} for how the product drives the automatic post
692
679
  * authentication continuation.
693
- * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the
694
- * customer accepted (`{ key, version }` records). Required for every vendor
695
- * so callers explicitly declare acceptance.
696
- * @param params.idosDisclaimersAccepted - idOS disclaimer documents the
697
- * customer accepted (`{ key, version }` records). Required for every vendor
698
- * so callers explicitly declare acceptance.
680
+ * @param params.sumsubTncSigned - Whether Sumsub T&C were accepted (T&C2).
681
+ * Required for every vendor so callers explicitly declare acceptance.
682
+ * @param params.idosTncSigned - Whether idOS T&C were accepted (T&C2).
683
+ * Required for every vendor so callers explicitly declare acceptance.
699
684
  * @param params.credentialReusabilityConsentGiven - Whether the customer
700
685
  * consented to reuse existing idOS credentials. Used when recording
701
686
  * session-scoped disclaimers on the consents path. Defaults to `false`.
702
687
  */
703
688
  async acceptTermsAndStartSession(params) {
704
- const providerDisclaimersAccepted = params?.providerDisclaimersAccepted;
705
- const idosDisclaimersAccepted = params?.idosDisclaimersAccepted;
706
- if (!isValidConsentRecordList(providerDisclaimersAccepted) ||
707
- !isValidConsentRecordList(idosDisclaimersAccepted)) {
689
+ const sumsubTncSigned = params?.sumsubTncSigned;
690
+ const idosTncSigned = params?.idosTncSigned;
691
+ if (typeof sumsubTncSigned !== 'boolean' ||
692
+ typeof idosTncSigned !== 'boolean') {
708
693
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing T&C2 acceptance flags.');
709
694
  return;
710
695
  }
711
- const credentialReusabilityConsentGiven = params?.credentialReusabilityConsentGiven ?? false;
696
+ const credentialReusabilityConsentGiven = params.credentialReusabilityConsentGiven ?? false;
712
697
  const termsAcceptedAt = new Date().toISOString();
713
- const disclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
698
+ const disclaimerIds = this.state.disclaimers.map((disclaimer) => disclaimer.id);
714
699
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
715
- if (params?.email) {
700
+ if (params.email) {
716
701
  state.email = params.email;
717
702
  }
718
- if (params?.product) {
703
+ if (params.product) {
719
704
  state.activeProduct = params.product;
720
705
  }
721
- state.vendorDisclaimersAccepted = (0, vendorDisclaimerAcceptance_js_1.recordVendorDisclaimerAcceptance)(state.vendorDisclaimersAccepted, state.activeVendor, { termsAcceptedAt, disclaimerIds });
722
- state.providerDisclaimersAccepted = {
723
- ...state.providerDisclaimersAccepted,
724
- sumsub: providerDisclaimersAccepted,
725
- };
726
- state.idosDisclaimersAccepted = idosDisclaimersAccepted;
706
+ state.termsAcceptedAt = termsAcceptedAt;
707
+ state.acceptedDisclaimerIds = disclaimerIds;
708
+ state.termsAcceptedVendor = state.activeVendor;
709
+ state.sumsubTncAccepted = sumsubTncSigned;
710
+ state.idosTncAccepted = idosTncSigned;
727
711
  state.credentialReusabilityConsentGiven =
728
712
  credentialReusabilityConsentGiven;
729
713
  });
730
714
  if (usesConsentsFlow(this.state.activeVendor)) {
731
715
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
732
- providerDisclaimersAccepted,
733
- idosDisclaimersAccepted,
716
+ sumsubTncSigned,
717
+ idosTncSigned,
734
718
  credentialReusabilityConsentGiven,
735
719
  });
736
720
  return;
@@ -742,12 +726,7 @@ class KycController extends base_controller_1.BaseController {
742
726
  */
743
727
  clearSavedTerms() {
744
728
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
745
- state.vendorDisclaimersAccepted =
746
- getDefaultKycVendorDisclaimersAccepted();
747
- state.providerDisclaimersAccepted =
748
- getDefaultKycProviderDisclaimersAccepted();
749
- state.idosDisclaimersAccepted = null;
750
- state.credentialReusabilityConsentGiven = null;
729
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
751
730
  });
752
731
  }
753
732
  /**
@@ -761,7 +740,68 @@ class KycController extends base_controller_1.BaseController {
761
740
  * @returns An object whose optional `reply` should be posted back.
762
741
  */
763
742
  async handleFrameMessage(params) {
764
- return await __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").handleMessage(params.message);
743
+ const payload = params.message;
744
+ if (!payload) {
745
+ return {};
746
+ }
747
+ if (payload.kind === 'handshake') {
748
+ const channelId = payload.meta?.channelId;
749
+ return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };
750
+ }
751
+ if (payload.kind !== 'complete') {
752
+ return {};
753
+ }
754
+ const channelId = payload.meta?.channelId;
755
+ // Only honor a Check/Auth `complete` for the MoonPay frame the flow is
756
+ // currently waiting on. This drops stale or duplicate messages — e.g. a
757
+ // late post after `reset()` (phase `idle`), after the flow already
758
+ // advanced past this frame, or after a vendor switch — so they cannot
759
+ // resurrect tokens, rewind `phase`, or recapture `moonpayCustomerId` on a
760
+ // controller that has moved on. Frame messages are external input and,
761
+ // unlike the async steps, are not covered by the `#generation` guard.
762
+ let expectedPhase = null;
763
+ if (channelId === CHANNEL_CHECK) {
764
+ expectedPhase = 'check';
765
+ }
766
+ else if (channelId === CHANNEL_AUTH) {
767
+ expectedPhase = 'auth';
768
+ }
769
+ if (!expectedPhase ||
770
+ this.state.phase !== expectedPhase ||
771
+ this.state.activeVendor !== 'moonpay') {
772
+ return {};
773
+ }
774
+ const status = payload.payload?.status;
775
+ const credsEnvelope = payload.payload?.credentials;
776
+ const customerId = payload.payload?.customer?.id ?? null;
777
+ if (customerId) {
778
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
779
+ state.moonpayCustomerId = customerId;
780
+ });
781
+ }
782
+ if (!status) {
783
+ return {};
784
+ }
785
+ let accessToken;
786
+ let clientToken;
787
+ if (credsEnvelope && __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
788
+ try {
789
+ const { credentials } = (0, crypto_js_1.decryptCredentials)(credsEnvelope, __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").privateKey);
790
+ accessToken = credentials.accessToken;
791
+ clientToken = credentials.clientToken;
792
+ }
793
+ catch (error) {
794
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Failed to decrypt frame credentials: ${String(error)}`);
795
+ return {};
796
+ }
797
+ }
798
+ if (channelId === CHANNEL_CHECK) {
799
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleCheckOutcome).call(this, status, accessToken, clientToken);
800
+ return {};
801
+ }
802
+ // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.
803
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_handleAuthOutcome).call(this, status, accessToken);
804
+ return {};
765
805
  }
766
806
  /**
767
807
  * Builds the Check-frame URL, or `null` when no session exists yet.
@@ -769,7 +809,17 @@ class KycController extends base_controller_1.BaseController {
769
809
  * @returns The Check-frame URL or `null`.
770
810
  */
771
811
  buildCheckFrameUrl() {
772
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildCheckFrameUrl();
812
+ if (this.state.activeVendor !== 'moonpay' ||
813
+ !this.state.sessionToken ||
814
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
815
+ return null;
816
+ }
817
+ const url = new URL(`${FRAMES_BASE_URL}/check-connection`);
818
+ url.searchParams.set('sessionToken', this.state.sessionToken);
819
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
820
+ url.searchParams.set('channelId', CHANNEL_CHECK);
821
+ url.searchParams.set('skipKyc', 'true');
822
+ return url.toString();
773
823
  }
774
824
  /**
775
825
  * Builds the Auth-frame URL, or `null` when no client token is available.
@@ -777,7 +827,16 @@ class KycController extends base_controller_1.BaseController {
777
827
  * @returns The Auth-frame URL or `null`.
778
828
  */
779
829
  buildAuthFrameUrl() {
780
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildAuthFrameUrl();
830
+ if (this.state.activeVendor !== 'moonpay' ||
831
+ !__classPrivateFieldGet(this, _KycController_authClientToken, "f") ||
832
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
833
+ return null;
834
+ }
835
+ const url = new URL(`${FRAMES_BASE_URL}/auth`);
836
+ url.searchParams.set('clientToken', __classPrivateFieldGet(this, _KycController_authClientToken, "f"));
837
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
838
+ url.searchParams.set('channelId', CHANNEL_AUTH);
839
+ return url.toString();
781
840
  }
782
841
  /**
783
842
  * Builds the Reset-frame URL.
@@ -785,7 +844,9 @@ class KycController extends base_controller_1.BaseController {
785
844
  * @returns The Reset-frame URL.
786
845
  */
787
846
  buildResetFrameUrl() {
788
- return __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").buildResetFrameUrl();
847
+ const url = new URL(`${FRAMES_BASE_URL}/reset`);
848
+ url.searchParams.set('channelId', CHANNEL_RESET);
849
+ return url.toString();
789
850
  }
790
851
  /**
791
852
  * Checks whether KYC is required for a product and caches the result.
@@ -796,9 +857,9 @@ class KycController extends base_controller_1.BaseController {
796
857
  * @returns Whether KYC is required.
797
858
  */
798
859
  async checkKycRequired(params) {
799
- const { moonpayAccessToken } = this.state;
800
- if (!moonpayAccessToken) {
801
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing moonpayAccessToken — repeat the authentication step.');
860
+ const { accessToken } = this.state;
861
+ if (!accessToken) {
862
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing accessToken — repeat the authentication step.');
802
863
  return false;
803
864
  }
804
865
  const country = params.country ?? this.state.geoCountry;
@@ -814,11 +875,7 @@ class KycController extends base_controller_1.BaseController {
814
875
  state.statusMessage = 'Checking KYC status...';
815
876
  });
816
877
  try {
817
- const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', {
818
- accessToken: moonpayAccessToken,
819
- country,
820
- capabilities: [{ product: params.product }],
821
- });
878
+ const { kycRequired } = await this.messenger.call('KycService:checkKycRequired', { accessToken, country, capabilities: [{ product: params.product }] });
822
879
  // The flow was reset while the check was in flight; discard the result
823
880
  // rather than resurrecting a done/cached state on an idle controller.
824
881
  const applied = __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
@@ -1103,11 +1160,13 @@ class KycController extends base_controller_1.BaseController {
1103
1160
  state.phase = 'idle';
1104
1161
  state.statusMessage = '';
1105
1162
  state.error = null;
1106
- state.vendorDisclaimers = [];
1107
- state.vendorError = null;
1163
+ state.disclaimers = [];
1164
+ state.disclaimersError = null;
1108
1165
  state.sessionDisclaimers = null;
1109
1166
  state.credentialReusabilityConsentGiven = null;
1110
- (0, MoonPayFrameHandler_js_1.clearMoonPaySession)(state);
1167
+ state.sessionToken = null;
1168
+ state.accessToken = null;
1169
+ state.moonpayCustomerId = null;
1111
1170
  state.activeVendor = 'moonpay';
1112
1171
  state.activeProduct = null;
1113
1172
  state.sumsub = {
@@ -1135,7 +1194,7 @@ class KycController extends base_controller_1.BaseController {
1135
1194
  }
1136
1195
  }
1137
1196
  exports.KycController = KycController;
1138
- _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() {
1197
+ _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() {
1139
1198
  return {
1140
1199
  get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
1141
1200
  set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
@@ -1147,14 +1206,13 @@ _KycController_sumsubLauncher = new WeakMap(), _KycController_moonPayFrames = ne
1147
1206
  * SumSub — skipping MoonPay Check/Auth frames.
1148
1207
  *
1149
1208
  * @param consents - T&C2 flags mapped onto the session disclaimer catalog.
1150
- * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.
1151
- * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.
1209
+ * @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
1210
+ * @param consents.idosTncSigned - Whether idOS T&C were accepted.
1152
1211
  * @param consents.credentialReusabilityConsentGiven - Whether credential
1153
1212
  * reuse was accepted.
1154
1213
  */
1155
1214
  async function _KycController_startConsentsSession(consents) {
1156
- const { email } = this.state;
1157
- const acceptedDisclaimerIds = (0, vendorDisclaimerAcceptance_js_1.ironDisclaimerIds)(this.state.vendorDisclaimersAccepted);
1215
+ const { email, acceptedDisclaimerIds } = this.state;
1158
1216
  if (!email) {
1159
1217
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for consents session.');
1160
1218
  return;
@@ -1172,7 +1230,7 @@ async function _KycController_startConsentsSession(consents) {
1172
1230
  state.sumsub.result = null;
1173
1231
  state.sumsub.sessionStatus = null;
1174
1232
  // Consents-path vendors have no MoonPay session/access tokens.
1175
- (0, MoonPayFrameHandler_js_1.clearMoonPaySession)(state);
1233
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
1176
1234
  });
1177
1235
  try {
1178
1236
  await this.messenger.call('KycService:submitVendorDisclaimers', {
@@ -1289,8 +1347,8 @@ async function _KycController_startConsentsSession(consents) {
1289
1347
  *
1290
1348
  * @param sessionId - The UKYC session id.
1291
1349
  * @param consents - T&C2 flags mapped onto catalog documents.
1292
- * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.
1293
- * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.
1350
+ * @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
1351
+ * @param consents.idosTncSigned - Whether idOS T&C were accepted.
1294
1352
  * @param consents.credentialReusabilityConsentGiven - Whether credential
1295
1353
  * reuse was accepted.
1296
1354
  * @param generation - Flow generation captured by the caller.
@@ -1304,12 +1362,12 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1304
1362
  state.sessionDisclaimers = catalog;
1305
1363
  state.statusMessage = 'Submitting consents...';
1306
1364
  });
1307
- if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosDisclaimersAccepted) ||
1308
- isAcceptedCategoryEmpty(catalog.kycProvider, consents.providerDisclaimersAccepted)) {
1365
+ if (isAcceptedCategoryEmpty(catalog.idOS, consents.idosTncSigned) ||
1366
+ isAcceptedCategoryEmpty(catalog.kycProvider, consents.sumsubTncSigned)) {
1309
1367
  throw new Error('Session disclaimer catalog is missing documents for an accepted category.');
1310
1368
  }
1311
- const idOS = consentRecordsFromAcceptedList(catalog.idOS, consents.idosDisclaimersAccepted);
1312
- const kycProvider = consentRecordsFromAcceptedList(catalog.kycProvider, consents.providerDisclaimersAccepted);
1369
+ const idOS = consentRecordsFromCatalog(catalog.idOS, consents.idosTncSigned);
1370
+ const kycProvider = consentRecordsFromCatalog(catalog.kycProvider, consents.sumsubTncSigned);
1313
1371
  const reuseUnchanged = catalog.credentialReusabilityConsentGiven ===
1314
1372
  consents.credentialReusabilityConsentGiven;
1315
1373
  if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {
@@ -1340,9 +1398,8 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1340
1398
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1341
1399
  state.sessionDisclaimers = latest;
1342
1400
  });
1343
- // TODO: Should we really be doing client side validation of these?
1344
- const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosDisclaimersAccepted);
1345
- const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.providerDisclaimersAccepted);
1401
+ const stillMissingIdos = acceptedCategoryStillMissing(latest.idOS, consents.idosTncSigned);
1402
+ const stillMissingProvider = acceptedCategoryStillMissing(latest.kycProvider, consents.sumsubTncSigned);
1346
1403
  const stillMissingReuse = consents.credentialReusabilityConsentGiven &&
1347
1404
  !latest.credentialReusabilityConsentGiven;
1348
1405
  if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {
@@ -1354,9 +1411,7 @@ async function _KycController_recordSessionDisclaimers(sessionId, consents, gene
1354
1411
  * Creates a vendor session from the currently stored terms + email.
1355
1412
  */
1356
1413
  async function _KycController_createSession() {
1357
- const { email } = this.state;
1358
- const termsAcceptedAt = this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;
1359
- const acceptedDisclaimerIds = this.state.vendorDisclaimers.map((disclaimer) => disclaimer.id);
1414
+ const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;
1360
1415
  if (!email) {
1361
1416
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for session creation.');
1362
1417
  return;
@@ -1371,7 +1426,7 @@ async function _KycController_createSession() {
1371
1426
  // (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot
1372
1427
  // return a URL tied to an old client token, and `checkKycRequired` cannot
1373
1428
  // run with an access token from an earlier authentication. The Check/Auth
1374
- // frames re-populate these for the new session. Because `moonpaySessionToken` is
1429
+ // frames re-populate these for the new session. Because `sessionToken` is
1375
1430
  // cleared here and only re-set on success, a failed creation leaves it
1376
1431
  // `null` rather than resurrecting the previous session.
1377
1432
  // Capture the flow generation so a `reset()` landing while the create
@@ -1379,18 +1434,18 @@ async function _KycController_createSession() {
1379
1434
  // the now-idle controller (failure). The synchronous update below runs
1380
1435
  // before any `await`, so it needs no guard.
1381
1436
  const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
1382
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clearAuthentication();
1437
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
1383
1438
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1384
1439
  state.error = null;
1385
1440
  state.phase = 'session';
1386
1441
  state.statusMessage = 'Creating session...';
1387
- state.moonpaySessionToken = null;
1388
- state.moonpayAccessToken = null;
1442
+ state.sessionToken = null;
1443
+ state.accessToken = null;
1389
1444
  });
1390
1445
  try {
1391
1446
  const { sessionToken } = await this.messenger.call('KycService:createSession', { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds });
1392
1447
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1393
- state.moonpaySessionToken = sessionToken;
1448
+ state.sessionToken = sessionToken;
1394
1449
  state.phase = 'check';
1395
1450
  state.statusMessage = 'Authenticating via Check frame...';
1396
1451
  });
@@ -1416,13 +1471,82 @@ async function _KycController_createSession() {
1416
1471
  });
1417
1472
  await this.loadDisclaimers();
1418
1473
  }
1419
- }, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state, vendor) {
1420
- const targetVendor = vendor ?? state.activeVendor;
1421
- state.vendorDisclaimersAccepted = (0, vendorDisclaimerAcceptance_js_1.clearVendorDisclaimerAcceptance)(state.vendorDisclaimersAccepted, targetVendor);
1422
- state.providerDisclaimersAccepted =
1423
- getDefaultKycProviderDisclaimersAccepted();
1424
- state.idosDisclaimersAccepted = null;
1474
+ }, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state) {
1475
+ state.termsAcceptedAt = null;
1476
+ state.acceptedDisclaimerIds = [];
1477
+ state.termsAcceptedVendor = null;
1478
+ state.sumsubTncAccepted = null;
1479
+ state.idosTncAccepted = null;
1425
1480
  state.credentialReusabilityConsentGiven = null;
1481
+ }, _KycController_clearMoonPaySession = function _KycController_clearMoonPaySession(state) {
1482
+ state.moonpayCustomerId = null;
1483
+ state.sessionToken = null;
1484
+ state.accessToken = null;
1485
+ }, _KycController_dropTermsUnlessForVendor = function _KycController_dropTermsUnlessForVendor(vendor) {
1486
+ if (__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, vendor)) {
1487
+ return;
1488
+ }
1489
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1490
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
1491
+ });
1492
+ }, _KycController_hasTermsForVendor = function _KycController_hasTermsForVendor(vendor) {
1493
+ if (this.state.termsAcceptedVendor === null) {
1494
+ return false;
1495
+ }
1496
+ return this.state.termsAcceptedVendor === vendor;
1497
+ }, _KycController_handleCheckOutcome =
1498
+ /**
1499
+ * Applies a Check-frame outcome.
1500
+ *
1501
+ * @param status - The frame status.
1502
+ * @param accessToken - The decrypted access token, if any.
1503
+ * @param clientToken - The decrypted client token, if any.
1504
+ */
1505
+ async function _KycController_handleCheckOutcome(status, accessToken, clientToken) {
1506
+ if (status === 'active' && accessToken) {
1507
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1508
+ state.accessToken = accessToken;
1509
+ state.phase = 'form';
1510
+ state.statusMessage = 'Already authenticated. Review to submit.';
1511
+ });
1512
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
1513
+ return;
1514
+ }
1515
+ if (status === 'connectionRequired' && clientToken) {
1516
+ __classPrivateFieldSet(this, _KycController_authClientToken, clientToken, "f");
1517
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1518
+ state.phase = 'auth';
1519
+ state.statusMessage = 'Verify your email via OTP in the Auth frame.';
1520
+ });
1521
+ return;
1522
+ }
1523
+ if (status === 'termsAcceptanceRequired') {
1524
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
1525
+ return;
1526
+ }
1527
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Check frame returned status: ${status}`);
1528
+ }, _KycController_handleAuthOutcome =
1529
+ /**
1530
+ * Applies an Auth-frame outcome.
1531
+ *
1532
+ * @param status - The frame status.
1533
+ * @param accessToken - The decrypted access token, if any.
1534
+ */
1535
+ async function _KycController_handleAuthOutcome(status, accessToken) {
1536
+ if (status === 'active' && accessToken) {
1537
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1538
+ state.accessToken = accessToken;
1539
+ state.phase = 'form';
1540
+ state.statusMessage = 'Authenticated. Review to submit.';
1541
+ });
1542
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_continueAfterAuthentication).call(this);
1543
+ return;
1544
+ }
1545
+ if (status === 'termsAcceptanceRequired') {
1546
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_requireTermsReacceptance).call(this);
1547
+ return;
1548
+ }
1549
+ __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Auth frame returned status: ${status}`);
1426
1550
  }, _KycController_continueAfterAuthentication =
1427
1551
  /**
1428
1552
  * Continues the flow once authentication has completed (phase `form`).
@@ -1474,7 +1598,7 @@ async function _KycController_continueAfterAuthentication() {
1474
1598
  return {
1475
1599
  vendor: 'moonpay',
1476
1600
  vendorMetadata: {
1477
- moonPayAccessToken: this.state.moonpayAccessToken,
1601
+ moonPayAccessToken: this.state.accessToken,
1478
1602
  moonPayUserId: this.state.moonpayCustomerId,
1479
1603
  },
1480
1604
  };
@@ -1542,8 +1666,7 @@ async function _KycController_createUkycSession(generation) {
1542
1666
  // authorizes later storage reads without granting write or delete access.
1543
1667
  const ukycCapabilityToken = (0, storageAccessToken_js_1.signStorageAccessToken)({
1544
1668
  material: clientMaterial,
1545
- // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write
1546
- operations: ['read', 'write'],
1669
+ operations: ['read'],
1547
1670
  expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),
1548
1671
  });
1549
1672
  const wrappedUkycCapabilityToken = (0, wrapEncryptionKey_js_1.wrapEncryptionKey)(sessionClientPrivateKey, capabilityTokenSchema.serverPublicKey.x, (0, utils_1.stringToBytes)((0, storageAccessToken_js_1.encodeStorageAccessTokenForHeader)(ukycCapabilityToken)));
@@ -1730,7 +1853,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
1730
1853
  __classPrivateFieldSet(this, _KycController_pollTimer, null, "f");
1731
1854
  }
1732
1855
  }, _KycController_cancelPendingSession = function _KycController_cancelPendingSession() {
1733
- __classPrivateFieldGet(this, _KycController_moonPayFrames, "f").clear();
1856
+ __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
1734
1857
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopPolling).call(this);
1735
1858
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
1736
1859
  __classPrivateFieldSet(this, _KycController_generation, __classPrivateFieldGet(this, _KycController_generation, "f") + 1, "f");