@metamask-previews/kyc-controller 0.0.0-preview-6b4bcdab3 → 0.0.0-preview-0b5bfc2

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 (42) hide show
  1. package/CHANGELOG.md +3 -42
  2. package/dist/KycController-method-action-types.cjs.map +1 -1
  3. package/dist/KycController-method-action-types.d.cts +2 -48
  4. package/dist/KycController-method-action-types.d.cts.map +1 -1
  5. package/dist/KycController-method-action-types.d.mts +2 -48
  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 +13 -472
  9. package/dist/KycController.cjs.map +1 -1
  10. package/dist/KycController.d.cts +5 -109
  11. package/dist/KycController.d.cts.map +1 -1
  12. package/dist/KycController.d.mts +5 -109
  13. package/dist/KycController.d.mts.map +1 -1
  14. package/dist/KycController.mjs +13 -472
  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 +2 -38
  18. package/dist/KycService-method-action-types.d.cts.map +1 -1
  19. package/dist/KycService-method-action-types.d.mts +2 -38
  20. package/dist/KycService-method-action-types.d.mts.map +1 -1
  21. package/dist/KycService-method-action-types.mjs.map +1 -1
  22. package/dist/KycService.cjs +29 -184
  23. package/dist/KycService.cjs.map +1 -1
  24. package/dist/KycService.d.cts +14 -99
  25. package/dist/KycService.d.cts.map +1 -1
  26. package/dist/KycService.d.mts +14 -99
  27. package/dist/KycService.d.mts.map +1 -1
  28. package/dist/KycService.mjs +30 -185
  29. package/dist/KycService.mjs.map +1 -1
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +5 -5
  32. package/dist/index.d.cts.map +1 -1
  33. package/dist/index.d.mts +5 -5
  34. package/dist/index.d.mts.map +1 -1
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/types.cjs.map +1 -1
  37. package/dist/types.d.cts +10 -49
  38. package/dist/types.d.cts.map +1 -1
  39. package/dist/types.d.mts +10 -49
  40. package/dist/types.d.mts.map +1 -1
  41. package/dist/types.mjs.map +1 -1
  42. package/package.json +2 -2
@@ -9,7 +9,7 @@ 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_keypair, _KycController_authClientToken, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_userStatusPollIntervalMs, _KycController_userStatusPollTimer, _KycController_userStatusPolling, _KycController_userStatusPollToken, _KycController_localUserSecretStore, _KycController_startConsentsSession, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_hasTermsForVendor, _KycController_handleCheckOutcome, _KycController_handleAuthOutcome, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_buildUkycSessionVendorFields, _KycController_fetchAndApplyUserStatus, _KycController_applyUserStatus, _KycController_ensureUserStatusPolling, _KycController_stopUserStatusPolling, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_fail;
12
+ var _KycController_instances, _KycController_sumsubLauncher, _KycController_keypair, _KycController_authClientToken, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_localUserSecretStore, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_handleCheckOutcome, _KycController_handleAuthOutcome, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_fail;
13
13
  import { BaseController } from "@metamask/base-controller";
14
14
  import { x25519 } from "@noble/curves/ed25519";
15
15
  import { decryptCredentials, generateKeyPair } from "./crypto.mjs";
@@ -84,12 +84,6 @@ const SUCCESSFUL_SESSION_STATUSES = new Set([
84
84
  // to do, so the sub-flow stops before launching the SDK and surfaces this
85
85
  // message.
86
86
  const VENDOR_PROCESSING_MESSAGE = 'Your KYC has been submitted and is being processed by the vendor.';
87
- // UKYC / relay error indicating the applicant already finished KYC. Mapped to
88
- // the simplified `completed` user status for the Money toast surface.
89
- const SESSION_NOT_IN_VALID_STATE = 'session_not_in_valid_state';
90
- // How often to refresh the user-keyed `GET /kyc/status` while the simplified
91
- // status is still `pending`. Overridable via the constructor.
92
- const DEFAULT_USER_STATUS_POLL_INTERVAL_MS = 15000;
93
87
  const kycControllerMetadata = {
94
88
  phase: {
95
89
  includeInDebugSnapshot: true,
@@ -127,24 +121,6 @@ const kycControllerMetadata = {
127
121
  persist: true,
128
122
  usedInUi: false,
129
123
  },
130
- termsAcceptedVendor: {
131
- includeInDebugSnapshot: true,
132
- includeInStateLogs: true,
133
- persist: true,
134
- usedInUi: false,
135
- },
136
- sumsubTncAccepted: {
137
- includeInDebugSnapshot: true,
138
- includeInStateLogs: true,
139
- persist: true,
140
- usedInUi: false,
141
- },
142
- idosTncAccepted: {
143
- includeInDebugSnapshot: true,
144
- includeInStateLogs: true,
145
- persist: true,
146
- usedInUi: false,
147
- },
148
124
  disclaimers: {
149
125
  includeInDebugSnapshot: false,
150
126
  includeInStateLogs: false,
@@ -181,12 +157,6 @@ const kycControllerMetadata = {
181
157
  persist: false,
182
158
  usedInUi: false,
183
159
  },
184
- activeVendor: {
185
- includeInDebugSnapshot: true,
186
- includeInStateLogs: true,
187
- persist: false,
188
- usedInUi: true,
189
- },
190
160
  activeProduct: {
191
161
  includeInDebugSnapshot: true,
192
162
  includeInStateLogs: true,
@@ -205,24 +175,6 @@ const kycControllerMetadata = {
205
175
  persist: true,
206
176
  usedInUi: false,
207
177
  },
208
- userStatus: {
209
- includeInDebugSnapshot: true,
210
- includeInStateLogs: true,
211
- persist: true,
212
- usedInUi: true,
213
- },
214
- userStatusSumsubSessionId: {
215
- includeInDebugSnapshot: false,
216
- includeInStateLogs: false,
217
- persist: true,
218
- usedInUi: true,
219
- },
220
- userStatusErrorCode: {
221
- includeInDebugSnapshot: true,
222
- includeInStateLogs: true,
223
- persist: true,
224
- usedInUi: true,
225
- },
226
178
  sumsub: {
227
179
  includeInDebugSnapshot: false,
228
180
  includeInStateLogs: false,
@@ -243,22 +195,15 @@ export function getDefaultKycControllerState() {
243
195
  email: null,
244
196
  termsAcceptedAt: null,
245
197
  acceptedDisclaimerIds: [],
246
- termsAcceptedVendor: null,
247
- sumsubTncAccepted: null,
248
- idosTncAccepted: null,
249
198
  disclaimers: [],
250
199
  disclaimersError: null,
251
200
  geoCountry: null,
252
201
  sessionToken: null,
253
202
  accessToken: null,
254
203
  moonpayCustomerId: null,
255
- activeVendor: 'moonpay',
256
204
  activeProduct: null,
257
205
  kycRequiredByProduct: {},
258
206
  lastCheckedAt: null,
259
- userStatus: null,
260
- userStatusSumsubSessionId: null,
261
- userStatusErrorCode: null,
262
207
  sumsub: {
263
208
  status: 'idle',
264
209
  result: null,
@@ -268,34 +213,11 @@ export function getDefaultKycControllerState() {
268
213
  },
269
214
  };
270
215
  }
271
- /**
272
- * Whether an error indicates the applicant already finished KYC — the UKYC /
273
- * relay `session_not_in_valid_state` signal — which the controller maps to the
274
- * simplified `completed` user status.
275
- *
276
- * @param error - The caught error.
277
- * @returns `true` when the error carries the `session_not_in_valid_state`
278
- * marker.
279
- */
280
- function isSessionAlreadyCompletedError(error) {
281
- return String(error).includes(SESSION_NOT_IN_VALID_STATE);
282
- }
283
- /**
284
- * Vendors other than MoonPay skip Check/Auth frames and use the empty-shell
285
- * customer + consents path instead.
286
- *
287
- * @param vendor - The identity vendor for the current flow.
288
- * @returns `true` when the vendor uses the consents session path.
289
- */
290
- function usesConsentsFlow(vendor) {
291
- return vendor !== 'moonpay';
292
- }
293
216
  // === MESSENGER ===
294
217
  const MESSENGER_EXPOSED_METHODS = [
295
218
  'initialize',
296
219
  'loadDisclaimers',
297
220
  'acceptTermsAndStartSession',
298
- 'createVendorCustomer',
299
221
  'clearSavedTerms',
300
222
  'handleFrameMessage',
301
223
  'buildCheckFrameUrl',
@@ -303,8 +225,6 @@ const MESSENGER_EXPOSED_METHODS = [
303
225
  'buildResetFrameUrl',
304
226
  'checkKycRequired',
305
227
  'getKycStatus',
306
- 'getCustomerIdentity',
307
- 'refreshKycStatus',
308
228
  'startSumSub',
309
229
  'getSessionStatus',
310
230
  'reset',
@@ -327,10 +247,8 @@ export class KycController extends BaseController {
327
247
  * @param options.sumsubLauncher - The platform SumSub launcher adapter.
328
248
  * @param options.sessionStatusPollIntervalMs - How often to poll the UKYC
329
249
  * session status after the SumSub SDK completes.
330
- * @param options.userStatusPollIntervalMs - How often to refresh the
331
- * user-keyed KYC status while it is still `pending`.
332
250
  */
333
- constructor({ messenger, state, sumsubLauncher, sessionStatusPollIntervalMs = DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS, userStatusPollIntervalMs = DEFAULT_USER_STATUS_POLL_INTERVAL_MS, }) {
251
+ constructor({ messenger, state, sumsubLauncher, sessionStatusPollIntervalMs = DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS, }) {
334
252
  super({
335
253
  messenger,
336
254
  metadata: kycControllerMetadata,
@@ -361,23 +279,8 @@ export class KycController extends BaseController {
361
279
  * let an already-awaiting request finish and reschedule.
362
280
  */
363
281
  _KycController_pollToken.set(this, 0);
364
- /** Interval, in milliseconds, between user-keyed status polls. */
365
- _KycController_userStatusPollIntervalMs.set(this, void 0);
366
- /** Handle for the scheduled next user-status poll, or `null`. */
367
- _KycController_userStatusPollTimer.set(this, null);
368
- /**
369
- * Whether a user-status poll loop is currently active. Tracked separately
370
- * from {@link #userStatusPollTimer} because a scheduled tick clears the timer
371
- * handle before awaiting `fetchKycStatus`; relying on the handle alone would
372
- * let a concurrent {@link refreshKycStatus} start a second loop on the same
373
- * token during that in-flight window.
374
- */
375
- _KycController_userStatusPolling.set(this, false);
376
- /** Monotonic token for the user-status poll loop (see `#pollToken`). */
377
- _KycController_userStatusPollToken.set(this, 0);
378
282
  __classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
379
283
  __classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
380
- __classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
381
284
  __classPrivateFieldSet(this, _KycController_keypair, generateKeyPair(), "f");
382
285
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
383
286
  }
@@ -392,8 +295,6 @@ export class KycController extends BaseController {
392
295
  * authentication completes (and chains into document verification when KYC
393
296
  * is required). When omitted, the flow stops at `form` and the consumer must
394
297
  * call `checkKycRequired` manually.
395
- * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors
396
- * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.
397
298
  */
398
299
  async initialize(params) {
399
300
  // A repeat `initialize` while a session flow is already in progress must
@@ -404,7 +305,6 @@ export class KycController extends BaseController {
404
305
  if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
405
306
  return;
406
307
  }
407
- const vendor = params?.vendor ?? 'moonpay';
408
308
  // `initialize` starts a fresh flow, so `activeProduct` is always reset to
409
309
  // this call's product (or `null`). Otherwise a prior run's product could
410
310
  // linger and cause `#continueAfterAuthentication` to auto-run the check /
@@ -413,19 +313,6 @@ export class KycController extends BaseController {
413
313
  if (params?.email) {
414
314
  state.email = params.email;
415
315
  }
416
- // Terms acceptance is vendor-scoped: reusing another vendor's saved
417
- // acceptance would skip loading this vendor's disclaimers and submit its
418
- // ids to the wrong vendor.
419
- if (!__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, vendor)) {
420
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
421
- }
422
- state.activeVendor = vendor;
423
- // `moonpayCustomerId` is only ever issued by the MoonPay Check / Auth
424
- // frames. Leaving it set while the flow switches to another vendor would
425
- // make `getCustomerIdentity` report a MoonPay id under the wrong vendor.
426
- if (vendor !== 'moonpay') {
427
- state.moonpayCustomerId = null;
428
- }
429
316
  state.activeProduct = params?.product ?? null;
430
317
  });
431
318
  // Capture the flow generation so a `reset()` landing while the async
@@ -442,48 +329,10 @@ export class KycController extends BaseController {
442
329
  catch {
443
330
  // Ignore; disclaimers loading will surface a country error if needed.
444
331
  }
445
- if (usesConsentsFlow(vendor) && this.state.email) {
446
- try {
447
- await this.messenger.call('KycService:createVendorCustomer', {
448
- vendor,
449
- email: this.state.email,
450
- });
451
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
452
- return;
453
- }
454
- }
455
- catch (error) {
456
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
457
- return;
458
- }
459
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Vendor customer creation failed: ${String(error)}`);
460
- return;
461
- }
462
- }
463
332
  const hasTerms = Boolean(this.state.termsAcceptedAt) &&
464
333
  this.state.acceptedDisclaimerIds.length > 0;
465
334
  if (hasTerms && this.state.email) {
466
- if (usesConsentsFlow(vendor)) {
467
- // Consents-path vendors require T&C2 flags; if they weren't persisted
468
- // (i.e. null from pre-migration state), require reacceptance.
469
- const sumsubTncSigned = this.state.sumsubTncAccepted;
470
- const idosTncSigned = this.state.idosTncAccepted;
471
- if (sumsubTncSigned === null || idosTncSigned === null) {
472
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
473
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
474
- state.phase = 'terms';
475
- });
476
- await this.loadDisclaimers();
477
- return;
478
- }
479
- await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, {
480
- sumsubTncSigned,
481
- idosTncSigned,
482
- });
483
- }
484
- else {
485
- await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
486
- }
335
+ await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
487
336
  return;
488
337
  }
489
338
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
@@ -491,43 +340,6 @@ export class KycController extends BaseController {
491
340
  });
492
341
  await this.loadDisclaimers();
493
342
  }
494
- /**
495
- * Creates (or resumes) an empty-shell customer for the given identity
496
- * vendor. Exposed so a consumer can ensure the customer exists before
497
- * showing T&C screens independently of {@link initialize}.
498
- *
499
- * @param params - The parameters.
500
- * @param params.vendor - Identity vendor for the customer.
501
- * @param params.email - Email for the vendor customer.
502
- */
503
- async createVendorCustomer(params) {
504
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
505
- state.email = params.email;
506
- // See `initialize`: acceptance recorded for another vendor cannot carry
507
- // over, and a MoonPay-issued customer id must not survive a switch to
508
- // another vendor or `getCustomerIdentity` reports the wrong vendor.
509
- if (!__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_hasTermsForVendor).call(this, params.vendor)) {
510
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
511
- }
512
- state.activeVendor = params.vendor;
513
- if (params.vendor !== 'moonpay') {
514
- state.moonpayCustomerId = null;
515
- }
516
- });
517
- const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
518
- try {
519
- await this.messenger.call('KycService:createVendorCustomer', {
520
- vendor: params.vendor,
521
- email: params.email,
522
- });
523
- }
524
- catch (error) {
525
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
526
- return;
527
- }
528
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, `Vendor customer creation failed: ${String(error)}`);
529
- }
530
- }
531
343
  /**
532
344
  * Loads the disclaimers for the resolved (or provided) country.
533
345
  *
@@ -548,10 +360,7 @@ export class KycController extends BaseController {
548
360
  state.geoCountry = country;
549
361
  });
550
362
  }
551
- const disclaimers = await this.messenger.call('KycService:fetchDisclaimers', {
552
- vendor: this.state.activeVendor,
553
- country,
554
- });
363
+ const disclaimers = await this.messenger.call('KycService:fetchDisclaimers', { country });
555
364
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
556
365
  state.disclaimers = disclaimers;
557
366
  state.disclaimersError = null;
@@ -567,43 +376,25 @@ export class KycController extends BaseController {
567
376
  * Captures terms acceptance for the currently loaded disclaimers and creates
568
377
  * a session.
569
378
  *
570
- * @param params - The parameters.
379
+ * @param params - Optional parameters.
571
380
  * @param params.email - The account email to associate with the session.
572
381
  * @param params.product - The consuming feature the flow runs for. See
573
382
  * {@link initialize} for how the product drives the automatic post
574
383
  * authentication continuation.
575
- * @param params.sumsubTncSigned - Whether Sumsub T&C were accepted (T&C2).
576
- * Required for every vendor so callers explicitly declare acceptance.
577
- * @param params.idosTncSigned - Whether idOS T&C were accepted (T&C2).
578
- * Required for every vendor so callers explicitly declare acceptance.
579
384
  */
580
385
  async acceptTermsAndStartSession(params) {
581
- const sumsubTncSigned = params?.sumsubTncSigned;
582
- const idosTncSigned = params?.idosTncSigned;
583
- if (typeof sumsubTncSigned !== 'boolean' ||
584
- typeof idosTncSigned !== 'boolean') {
585
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing T&C2 acceptance flags.');
586
- return;
587
- }
588
386
  const termsAcceptedAt = new Date().toISOString();
589
387
  const disclaimerIds = this.state.disclaimers.map((disclaimer) => disclaimer.id);
590
388
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
591
- if (params.email) {
389
+ if (params?.email) {
592
390
  state.email = params.email;
593
391
  }
594
- if (params.product) {
392
+ if (params?.product) {
595
393
  state.activeProduct = params.product;
596
394
  }
597
395
  state.termsAcceptedAt = termsAcceptedAt;
598
396
  state.acceptedDisclaimerIds = disclaimerIds;
599
- state.termsAcceptedVendor = state.activeVendor;
600
- state.sumsubTncAccepted = sumsubTncSigned;
601
- state.idosTncAccepted = idosTncSigned;
602
397
  });
603
- if (usesConsentsFlow(this.state.activeVendor)) {
604
- await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_startConsentsSession).call(this, { sumsubTncSigned, idosTncSigned });
605
- return;
606
- }
607
398
  await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_createSession).call(this);
608
399
  }
609
400
  /**
@@ -785,25 +576,6 @@ export class KycController extends BaseController {
785
576
  getKycStatus(params) {
786
577
  return this.state.kycRequiredByProduct[params.product];
787
578
  }
788
- /**
789
- * Returns the vendor-scoped identity for the currently authenticated
790
- * customer, or `null` when the flow has not yet captured a vendor customer
791
- * id (before authentication or after {@link reset}).
792
- *
793
- * Exposed so consumers (e.g. ramps autoramp creation) can attach the vendor
794
- * customer id to downstream calls without reading the full KYC state, which
795
- * also holds session/access tokens. The id is session-scoped and never
796
- * persisted.
797
- *
798
- * @returns The current {@link KycCustomerIdentity}, or `null`.
799
- */
800
- getCustomerIdentity() {
801
- const { moonpayCustomerId, activeVendor } = this.state;
802
- if (!moonpayCustomerId) {
803
- return null;
804
- }
805
- return { vendor: activeVendor, id: moonpayCustomerId };
806
- }
807
579
  /**
808
580
  * Runs the SumSub document-verification sub-flow end to end:
809
581
  *
@@ -884,7 +656,10 @@ export class KycController extends BaseController {
884
656
  });
885
657
  const { sessionId, kycStatus, finalStatus } = await this.messenger.call('KycService:createUkycSession', {
886
658
  jwtToken,
887
- ...__classPrivateFieldGet(this, _KycController_instances, "m", _KycController_buildUkycSessionVendorFields).call(this),
659
+ vendorMetadata: {
660
+ moonPayAccessToken: this.state.accessToken,
661
+ moonPayUserId: this.state.moonpayCustomerId,
662
+ },
888
663
  wrappedEncryptionKey,
889
664
  ukycCapabilityToken,
890
665
  });
@@ -974,28 +749,6 @@ export class KycController extends BaseController {
974
749
  return result;
975
750
  }
976
751
  catch (error) {
977
- // Applicant already finished KYC — treat as completed for Money toast.
978
- if (isSessionAlreadyCompletedError(error)) {
979
- // A reset() may have landed while `launch` was in flight; forcing
980
- // `completed` (and publishing `statusChanged`) on an idle controller
981
- // would resurrect a flow the consumer already tore down.
982
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
983
- return { alreadyCompleted: true };
984
- }
985
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUserStatus).call(this, {
986
- status: 'completed',
987
- sumsubSessionId: null,
988
- errorCode: null,
989
- });
990
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
991
- state.sumsub.status = 'complete';
992
- state.sumsub.result = { alreadyCompleted: true };
993
- state.statusMessage = 'KYC already completed.';
994
- state.phase = 'done';
995
- state.error = null;
996
- });
997
- return { alreadyCompleted: true };
998
- }
999
752
  const result = { error: String(error) };
1000
753
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1001
754
  state.sumsub.status = 'failed';
@@ -1004,31 +757,6 @@ export class KycController extends BaseController {
1004
757
  return result;
1005
758
  }
1006
759
  }
1007
- /**
1008
- * Refreshes the user-keyed simplified KYC status from `GET /kyc/status`,
1009
- * stores it on state, publishes {@link KycControllerStatusChangedEvent}, and
1010
- * schedules short-interval polling while the status is `pending`.
1011
- *
1012
- * @returns The latest status payload.
1013
- */
1014
- async refreshKycStatus() {
1015
- const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
1016
- const payload = await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fetchAndApplyUserStatus).call(this);
1017
- // A `reset()` landing while the request was in flight already stopped
1018
- // polling and left the flow idle, and the payload above is the pre-reset
1019
- // cached status. Starting a loop from it would poll — and publish
1020
- // `statusChanged` — on a torn-down flow.
1021
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1022
- return payload;
1023
- }
1024
- if (payload.status === 'pending') {
1025
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_ensureUserStatusPolling).call(this);
1026
- }
1027
- else {
1028
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
1029
- }
1030
- return payload;
1031
- }
1032
760
  /**
1033
761
  * Fetches the current UKYC session status for the active sub-flow and records
1034
762
  * it on state. Useful for a one-off refresh outside the automatic polling
@@ -1060,7 +788,6 @@ export class KycController extends BaseController {
1060
788
  // Stop any session-status polling so a late poll cannot write onto the
1061
789
  // now-idle controller.
1062
790
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopPolling).call(this);
1063
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
1064
791
  // Invalidate any in-flight async work started before this reset so its
1065
792
  // results are discarded rather than written onto the now-idle controller.
1066
793
  __classPrivateFieldSet(this, _KycController_generation, __classPrivateFieldGet(this, _KycController_generation, "f") + 1, "f");
@@ -1073,7 +800,6 @@ export class KycController extends BaseController {
1073
800
  state.sessionToken = null;
1074
801
  state.accessToken = null;
1075
802
  state.moonpayCustomerId = null;
1076
- state.activeVendor = 'moonpay';
1077
803
  state.activeProduct = null;
1078
804
  state.sumsub = {
1079
805
  status: 'idle',
@@ -1085,91 +811,11 @@ export class KycController extends BaseController {
1085
811
  });
1086
812
  }
1087
813
  }
1088
- _KycController_sumsubLauncher = new WeakMap(), _KycController_keypair = 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() {
814
+ _KycController_sumsubLauncher = new WeakMap(), _KycController_keypair = new WeakMap(), _KycController_authClientToken = new WeakMap(), _KycController_generation = new WeakMap(), _KycController_sessionStatusPollIntervalMs = new WeakMap(), _KycController_pollTimer = new WeakMap(), _KycController_pollToken = new WeakMap(), _KycController_instances = new WeakSet(), _KycController_localUserSecretStore = function _KycController_localUserSecretStore() {
1089
815
  return {
1090
816
  get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
1091
817
  set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
1092
818
  };
1093
- }, _KycController_startConsentsSession =
1094
- /**
1095
- * Consents-path vendors: post vendor signings + Sumsub/idOS ack, then
1096
- * launch SumSub — skipping MoonPay Check/Auth frames.
1097
- *
1098
- * @param consents - T&C2 boolean flags.
1099
- * @param consents.sumsubTncSigned - Whether Sumsub T&C were accepted.
1100
- * @param consents.idosTncSigned - Whether idOS T&C were accepted.
1101
- */
1102
- async function _KycController_startConsentsSession(consents) {
1103
- const { email, acceptedDisclaimerIds } = this.state;
1104
- if (!email) {
1105
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing email for consents session.');
1106
- return;
1107
- }
1108
- if (acceptedDisclaimerIds.length === 0) {
1109
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fail).call(this, 'Missing disclaimer acceptance.');
1110
- return;
1111
- }
1112
- const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
1113
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1114
- state.error = null;
1115
- state.phase = 'session';
1116
- state.statusMessage = 'Submitting consents...';
1117
- // Consents-path vendors have no MoonPay session/access tokens.
1118
- state.sessionToken = null;
1119
- state.accessToken = null;
1120
- });
1121
- try {
1122
- await this.messenger.call('KycService:submitConsents', {
1123
- disclaimerIds: acceptedDisclaimerIds,
1124
- sumsubTncSigned: consents.sumsubTncSigned,
1125
- idosTncSigned: consents.idosTncSigned,
1126
- });
1127
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1128
- return;
1129
- }
1130
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1131
- state.phase = 'submit';
1132
- state.statusMessage = 'Starting document verification...';
1133
- });
1134
- const sumsubResult = await this.startSumSub();
1135
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1136
- return;
1137
- }
1138
- const sumsubError = sumsubResult?.error;
1139
- if (typeof sumsubError === 'string') {
1140
- throw new Error(sumsubError);
1141
- }
1142
- // After SumSub, refresh user-keyed status for the Money toast and start
1143
- // polling while still pending. Soft-fail: toast refresh must not rewind
1144
- // the consent / SumSub outcome.
1145
- try {
1146
- await this.refreshKycStatus();
1147
- }
1148
- catch (statusError) {
1149
- console.error('KYC status refresh failed:', statusError);
1150
- }
1151
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1152
- if (state.phase !== 'error' && state.phase !== 'done') {
1153
- state.phase = 'done';
1154
- state.statusMessage = 'KYC submitted.';
1155
- }
1156
- });
1157
- }
1158
- catch (error) {
1159
- console.error('Consents session failed:', error);
1160
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1161
- return;
1162
- }
1163
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1164
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearAcceptedTerms).call(this, state);
1165
- state.activeProduct = null;
1166
- state.error = `Consents session failed: ${String(error)}`;
1167
- state.statusMessage =
1168
- 'Consent / verification failed — accept the terms to try again.';
1169
- state.phase = 'terms';
1170
- });
1171
- await this.loadDisclaimers();
1172
- }
1173
819
  }, _KycController_createSession =
1174
820
  /**
1175
821
  * Creates a vendor session from the currently stored terms + email.
@@ -1238,14 +884,6 @@ async function _KycController_createSession() {
1238
884
  }, _KycController_clearAcceptedTerms = function _KycController_clearAcceptedTerms(state) {
1239
885
  state.termsAcceptedAt = null;
1240
886
  state.acceptedDisclaimerIds = [];
1241
- state.termsAcceptedVendor = null;
1242
- state.sumsubTncAccepted = null;
1243
- state.idosTncAccepted = null;
1244
- }, _KycController_hasTermsForVendor = function _KycController_hasTermsForVendor(vendor) {
1245
- if (this.state.termsAcceptedVendor === null) {
1246
- return false;
1247
- }
1248
- return this.state.termsAcceptedVendor === vendor;
1249
887
  }, _KycController_handleCheckOutcome =
1250
888
  /**
1251
889
  * Applies a Check-frame outcome.
@@ -1343,101 +981,6 @@ async function _KycController_continueAfterAuthentication() {
1343
981
  state.statusMessage =
1344
982
  'The vendor updated its Terms of Use — please re-accept.';
1345
983
  });
1346
- }, _KycController_buildUkycSessionVendorFields = function _KycController_buildUkycSessionVendorFields() {
1347
- if (this.state.activeVendor === 'moonpay') {
1348
- return {
1349
- vendor: 'moonpay',
1350
- vendorMetadata: {
1351
- moonPayAccessToken: this.state.accessToken,
1352
- moonPayUserId: this.state.moonpayCustomerId,
1353
- },
1354
- };
1355
- }
1356
- return { vendor: this.state.activeVendor };
1357
- }, _KycController_fetchAndApplyUserStatus =
1358
- /**
1359
- * Fetches `GET /kyc/status` and applies it to state without managing the
1360
- * poll loop (used by both {@link refreshKycStatus} and the poll tick).
1361
- *
1362
- * @returns The latest status payload.
1363
- */
1364
- async function _KycController_fetchAndApplyUserStatus() {
1365
- const generation = __classPrivateFieldGet(this, _KycController_generation, "f");
1366
- const response = await this.messenger.call('KycService:fetchKycStatus');
1367
- if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1368
- return {
1369
- status: this.state.userStatus ?? 'not-started',
1370
- sumsubSessionId: this.state.userStatusSumsubSessionId,
1371
- errorCode: this.state.userStatusErrorCode,
1372
- };
1373
- }
1374
- const payload = {
1375
- status: response.status,
1376
- sumsubSessionId: response.sumsubSessionId ?? null,
1377
- errorCode: response.errorCode ?? null,
1378
- };
1379
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUserStatus).call(this, payload);
1380
- return payload;
1381
- }, _KycController_applyUserStatus = function _KycController_applyUserStatus(payload) {
1382
- const previous = this.state.userStatus;
1383
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_applyUpdate).call(this, (state) => {
1384
- state.userStatus = payload.status;
1385
- state.userStatusSumsubSessionId = payload.sumsubSessionId;
1386
- state.userStatusErrorCode = payload.errorCode;
1387
- });
1388
- if (previous !== payload.status) {
1389
- this.messenger.publish(`${controllerName}:statusChanged`, payload);
1390
- }
1391
- }, _KycController_ensureUserStatusPolling = function _KycController_ensureUserStatusPolling() {
1392
- if (__classPrivateFieldGet(this, _KycController_userStatusPolling, "f")) {
1393
- return;
1394
- }
1395
- __classPrivateFieldSet(this, _KycController_userStatusPolling, true, "f");
1396
- const token = __classPrivateFieldGet(this, _KycController_userStatusPollToken, "f");
1397
- const tick = async () => {
1398
- try {
1399
- const payload = await __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_fetchAndApplyUserStatus).call(this);
1400
- // Race with `reset()` / `#stopUserStatusPolling` while the request was
1401
- // in flight — do not reschedule onto an idle controller.
1402
- /* istanbul ignore next */
1403
- if (__classPrivateFieldGet(this, _KycController_userStatusPollToken, "f") !== token) {
1404
- return;
1405
- }
1406
- if (payload.status !== 'pending') {
1407
- __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_stopUserStatusPolling).call(this);
1408
- return;
1409
- }
1410
- }
1411
- catch {
1412
- // Keep polling on transient errors, unless the loop was superseded.
1413
- /* istanbul ignore next */
1414
- if (__classPrivateFieldGet(this, _KycController_userStatusPollToken, "f") !== token) {
1415
- return;
1416
- }
1417
- }
1418
- __classPrivateFieldSet(this, _KycController_userStatusPollTimer, setTimeout(() => {
1419
- __classPrivateFieldSet(this, _KycController_userStatusPollTimer, null, "f");
1420
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1421
- tick();
1422
- }, __classPrivateFieldGet(this, _KycController_userStatusPollIntervalMs, "f")), "f");
1423
- // Allow the process to exit while a pending-status poll is scheduled.
1424
- // React Native / browser timers are numbers with no `unref`, hence the
1425
- // optional call.
1426
- __classPrivateFieldGet(this, _KycController_userStatusPollTimer, "f").unref?.();
1427
- };
1428
- __classPrivateFieldSet(this, _KycController_userStatusPollTimer, setTimeout(() => {
1429
- __classPrivateFieldSet(this, _KycController_userStatusPollTimer, null, "f");
1430
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
1431
- tick();
1432
- }, __classPrivateFieldGet(this, _KycController_userStatusPollIntervalMs, "f")), "f");
1433
- __classPrivateFieldGet(this, _KycController_userStatusPollTimer, "f").unref?.();
1434
- }, _KycController_stopUserStatusPolling = function _KycController_stopUserStatusPolling() {
1435
- __classPrivateFieldSet(this, _KycController_userStatusPollToken, __classPrivateFieldGet(this, _KycController_userStatusPollToken, "f") + 1, "f");
1436
- __classPrivateFieldSet(this, _KycController_userStatusPolling, false, "f");
1437
- if (__classPrivateFieldGet(this, _KycController_userStatusPollTimer, "f") !== null) {
1438
- clearTimeout(__classPrivateFieldGet(this, _KycController_userStatusPollTimer, "f"));
1439
- __classPrivateFieldSet(this, _KycController_userStatusPollTimer, null, "f");
1440
- }
1441
984
  }, _KycController_startSessionStatusPolling =
1442
985
  /**
1443
986
  * Begins polling the UKYC session status until a terminal decision is
@@ -1523,9 +1066,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
1523
1066
  return true;
1524
1067
  }, _KycController_applyUpdate = function _KycController_applyUpdate(updater) {
1525
1068
  this.update((state) => {
1526
- // `@ts-expect-error` cannot be used: ts-bridge does not surface
1527
- // TS2589, so the directive is unused and fails the build.
1528
- // type issue only happens at the IDE level.
1069
+ // @ts-expect-error Avoid "type instantiation is excessively deep".
1529
1070
  updater(state);
1530
1071
  });
1531
1072
  }, _KycController_fail = function _KycController_fail(message) {