@metamask-previews/kyc-controller 0.0.0-preview-e0510042f → 0.0.0-preview-fe4b3be11

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 (52) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/KycController.cjs +31 -17
  3. package/dist/KycController.cjs.map +1 -1
  4. package/dist/KycController.d.cts +3 -3
  5. package/dist/KycController.d.cts.map +1 -1
  6. package/dist/KycController.d.mts +3 -3
  7. package/dist/KycController.d.mts.map +1 -1
  8. package/dist/KycController.mjs +31 -17
  9. package/dist/KycController.mjs.map +1 -1
  10. package/dist/KycService-method-action-types.cjs.map +1 -1
  11. package/dist/KycService-method-action-types.d.cts +23 -6
  12. package/dist/KycService-method-action-types.d.cts.map +1 -1
  13. package/dist/KycService-method-action-types.d.mts +23 -6
  14. package/dist/KycService-method-action-types.d.mts.map +1 -1
  15. package/dist/KycService-method-action-types.mjs.map +1 -1
  16. package/dist/KycService.cjs +91 -118
  17. package/dist/KycService.cjs.map +1 -1
  18. package/dist/KycService.d.cts +38 -12
  19. package/dist/KycService.d.cts.map +1 -1
  20. package/dist/KycService.d.mts +38 -12
  21. package/dist/KycService.d.mts.map +1 -1
  22. package/dist/KycService.mjs +91 -118
  23. package/dist/KycService.mjs.map +1 -1
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +3 -3
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.mts +3 -3
  28. package/dist/index.d.mts.map +1 -1
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/logger.cjs +9 -0
  31. package/dist/logger.cjs.map +1 -0
  32. package/dist/logger.d.cts +6 -0
  33. package/dist/logger.d.cts.map +1 -0
  34. package/dist/logger.d.mts +6 -0
  35. package/dist/logger.d.mts.map +1 -0
  36. package/dist/logger.mjs +6 -0
  37. package/dist/logger.mjs.map +1 -0
  38. package/dist/types.cjs.map +1 -1
  39. package/dist/types.d.cts +15 -6
  40. package/dist/types.d.cts.map +1 -1
  41. package/dist/types.d.mts +15 -6
  42. package/dist/types.d.mts.map +1 -1
  43. package/dist/types.mjs.map +1 -1
  44. package/dist/ukyc/wrapEncryptionKey.cjs +4 -9
  45. package/dist/ukyc/wrapEncryptionKey.cjs.map +1 -1
  46. package/dist/ukyc/wrapEncryptionKey.d.cts +8 -10
  47. package/dist/ukyc/wrapEncryptionKey.d.cts.map +1 -1
  48. package/dist/ukyc/wrapEncryptionKey.d.mts +8 -10
  49. package/dist/ukyc/wrapEncryptionKey.d.mts.map +1 -1
  50. package/dist/ukyc/wrapEncryptionKey.mjs +4 -9
  51. package/dist/ukyc/wrapEncryptionKey.mjs.map +1 -1
  52. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
30
30
 
31
31
  ### Changed
32
32
 
33
+ - Add `KycService.fetchDisclaimersCatalog` / `KycService:fetchDisclaimersCatalog` (`GET /disclaimers?country=`, ISO 3166-1 alpha-3) for the pre-session idOS + KYC-provider catalog, plus the `KycDisclaimersCatalog` type (no `credentialReusabilityConsentGiven`). `fetchSessionDisclaimers` remains session-scoped (`GET /sessions/{sessionId}/disclaimers` → `KycSessionDisclaimers`). ([#10011](https://github.com/MetaMask/core/pull/10011))
34
+ - **BREAKING:** Rename `KycService.fetchDisclaimers` / `KycService:fetchDisclaimers` / `KycServiceFetchDisclaimersAction` to `fetchVendorDisclaimers` / `KycService:fetchVendorDisclaimers` / `KycServiceFetchVendorDisclaimersAction`. ([#10011](https://github.com/MetaMask/core/pull/10011))
33
35
  - **BREAKING:** Rename `fractalEncryptionBaseUrl` to `idosEnclaveBaseUrl`, `KycService.fetchJwks` / `KycService:fetchJwks` / `KycServiceFetchJwksAction` to `fetchIdosEnclaveJwks` / `KycService:fetchIdosEnclaveJwks` / `KycServiceFetchIdosEnclaveJwksAction`, and related Fractal encryption naming to idOS enclave. ([#10008](https://github.com/MetaMask/core/pull/10008))
34
36
  - **BREAKING:** Verify `encryptionDataKey` against idOS enclave JWKS (`KycService:fetchIdosEnclaveJwks` / `idosEnclaveBaseUrl`) and `ukycCapabilityToken` against idOS relay JWKS (`KycService:fetchIdosRelayJwks` / `idosRelayBaseUrl`) when wrapping UKYC authorizations, instead of validating both schemas against Fractal. Hosts must supply `idosRelayBaseUrl` on `KycService` construction (same class of requirement as `idosEnclaveBaseUrl`). ([#10008](https://github.com/MetaMask/core/pull/10008))
35
37
  - **BREAKING:** Require `sessionClientPublicKey` (unpadded base64url X25519 public key) and `residenceCountry` (ISO 3166-1 alpha-3) on `KycService.createUkycSession` (`POST /sessions`). The controller generates the per-session keypair before creating the session and uses the private half to wrap authorizations; residence country is taken from the resolved geo country. ([#9993](https://github.com/MetaMask/core/pull/9993))
@@ -40,9 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
40
42
  - **BREAKING:** Require `sumsubTncSigned` and `idosTncSigned` on `acceptTermsAndStartSession` for every vendor, so callers explicitly declare T&C2 acceptance. Zero-argument calls and omitted flags fail instead of defaulting to `true`. ([#9908](https://github.com/MetaMask/core/pull/9908))
41
43
  - Rename `CreateUkycSessionParams.vendorId` to `vendor` for consistency with other service methods. ([#9908](https://github.com/MetaMask/core/pull/9908))
42
44
  - Bump `@metamask/base-data-service` from `^0.1.3` to `^1.0.0` ([#9972](https://github.com/MetaMask/core/pull/9972))
45
+ - Replace `KycController` `console.error` tracing with the `@metamask/utils` debug logger (`createProjectLogger` / `createModuleLogger`), so flow diagnostics are opt-in via `DEBUG=kyc-controller*` instead of always printing to the console. ([#10054](https://github.com/MetaMask/core/pull/10054))
43
46
 
44
47
  ### Fixed
45
48
 
49
+ - Stop routing `KycService` write endpoints through the query cache. Every `POST` (`createSession`, `checkKycRequired`, `createVendorCustomer`, `submitVendorDisclaimers`, `submitSessionDisclaimers`, `createUkycSession`, `setAuthorizations`, `createJourney`) now issues its request directly instead of via `fetchQuery`. Previously these were modelled as queries, so two overlapping calls sharing a `queryKey` were deduplicated into a single request — a second `createVendorCustomer` while the first was in flight never reached the API — and their responses were retained in the cache and published on the messenger as `cacheUpdated` payloads, which for these endpoints include session tokens and applicant access tokens. Writes are also no longer retried by the service policy, so a failed non-idempotent request cannot create duplicate records server-side. ([#10007](https://github.com/MetaMask/core/pull/10007))
50
+ - Stop incorrectly prefixing the session client public key onto wrapped `encryptionDataKey` and `ukycCapabilityToken` values from `wrapEncryptionKey`. `data` is now ciphertext+tag only; the server already has the client public key from session creation. ([#10036](https://github.com/MetaMask/core/pull/10036))
46
51
  - Clear leftover MoonPay `sessionToken`, `accessToken`, and Check/Auth frame credentials when `initialize` or `createVendorCustomer` switches to another vendor, so `buildCheckFrameUrl` cannot return a MoonPay URL for a consents-path session. ([#9908](https://github.com/MetaMask/core/pull/9908))
47
52
  - Rewind the consents path when SumSub fails before completion (thrown step or SDK close without `Completed`), instead of refreshing user status and forcing `phase` to `done`. A terminal UKYC rejection after the SDK completed still finishes as `done` so the decision can be reflected in user status. ([#9908](https://github.com/MetaMask/core/pull/9908))
48
53
  - Make `createVendorCustomer` a no-op during in-progress phases (matching `initialize`), so a vendor switch cannot leave Check/Auth frames attached to the wrong vendor. ([#9908](https://github.com/MetaMask/core/pull/9908))
@@ -10,7 +10,7 @@ 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_keypair, _KycController_authClientToken, _KycController_generation, _KycController_sessionStatusPollIntervalMs, _KycController_pollTimer, _KycController_pollToken, _KycController_userStatusPollIntervalMs, _KycController_userStatusPollTimer, _KycController_userStatusPolling, _KycController_userStatusPollToken, _KycController_localUserSecretStore, _KycController_startConsentsSession, _KycController_recordSessionDisclaimers, _KycController_createSession, _KycController_clearAcceptedTerms, _KycController_clearMoonPaySession, _KycController_dropTermsUnlessForVendor, _KycController_hasTermsForVendor, _KycController_handleCheckOutcome, _KycController_handleAuthOutcome, _KycController_continueAfterAuthentication, _KycController_requireTermsReacceptance, _KycController_buildUkycSessionVendorFields, _KycController_createUkycSession, _KycController_fetchAndApplyUserStatus, _KycController_applyUserStatus, _KycController_ensureUserStatusPolling, _KycController_stopUserStatusPolling, _KycController_startSessionStatusPolling, _KycController_pollSessionStatusOnce, _KycController_stopPolling, _KycController_cancelPendingSession, _KycController_updateIfCurrent, _KycController_applyUpdate, _KycController_assertAttestedServerPublicKey, _KycController_fail;
13
+ 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
15
  exports.KycController = exports.getDefaultKycControllerState = exports.controllerName = void 0;
16
16
  const base_controller_1 = require("@metamask/base-controller");
@@ -18,6 +18,7 @@ const utils_1 = require("@metamask/utils");
18
18
  const ed25519_1 = require("@noble/curves/ed25519");
19
19
  const crypto_js_1 = require("./crypto.cjs");
20
20
  const encoding_js_1 = require("./encoding.cjs");
21
+ const logger_js_1 = require("./logger.cjs");
21
22
  const deriveClientMaterial_js_1 = require("./ukyc/deriveClientMaterial.cjs");
22
23
  const jwtChain_js_1 = require("./ukyc/jwtChain.cjs");
23
24
  const localUserSecret_js_1 = require("./ukyc/localUserSecret.cjs");
@@ -413,8 +414,8 @@ class KycController extends base_controller_1.BaseController {
413
414
  });
414
415
  _KycController_instances.add(this);
415
416
  _KycController_sumsubLauncher.set(this, void 0);
416
- /** Ephemeral X25519 keypair for the frame key exchange (never persisted). */
417
- _KycController_keypair.set(this, void 0);
417
+ /** MoonPay Check/Auth frame X25519 keypair (never persisted). */
418
+ _KycController_moonpayFrameKeypair.set(this, null);
418
419
  /** Auth-frame client token, kept out of state. */
419
420
  _KycController_authClientToken.set(this, null);
420
421
  /**
@@ -453,7 +454,6 @@ class KycController extends base_controller_1.BaseController {
453
454
  __classPrivateFieldSet(this, _KycController_sumsubLauncher, sumsubLauncher, "f");
454
455
  __classPrivateFieldSet(this, _KycController_sessionStatusPollIntervalMs, sessionStatusPollIntervalMs, "f");
455
456
  __classPrivateFieldSet(this, _KycController_userStatusPollIntervalMs, userStatusPollIntervalMs, "f");
456
- __classPrivateFieldSet(this, _KycController_keypair, (0, crypto_js_1.generateKeyPair)(), "f");
457
457
  this.messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);
458
458
  }
459
459
  /**
@@ -476,10 +476,19 @@ class KycController extends base_controller_1.BaseController {
476
476
  // forces `phase` back through `session`/`check`, breaking an in-flight
477
477
  // Check/Auth frame flow. Leave the active flow untouched and let the
478
478
  // consumer drive it (or call `reset` first to start over).
479
+ const vendor = params?.vendor ?? 'moonpay';
479
480
  if (IN_PROGRESS_PHASES.includes(this.state.phase)) {
481
+ if (vendor === 'moonpay' && !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
482
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, (0, crypto_js_1.generateKeyPair)(), "f");
483
+ }
480
484
  return;
481
485
  }
482
- const vendor = params?.vendor ?? 'moonpay';
486
+ if (vendor === 'moonpay') {
487
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, (0, crypto_js_1.generateKeyPair)(), "f");
488
+ }
489
+ else {
490
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
491
+ }
483
492
  // `initialize` starts a fresh flow, so `activeProduct` is always reset to
484
493
  // this call's product (or `null`). Otherwise a prior run's product could
485
494
  // linger and cause `#continueAfterAuthentication` to auto-run the check /
@@ -602,6 +611,7 @@ class KycController extends base_controller_1.BaseController {
602
611
  state.activeVendor = params.vendor;
603
612
  if (params.vendor !== 'moonpay') {
604
613
  __classPrivateFieldSet(this, _KycController_authClientToken, null, "f");
614
+ __classPrivateFieldSet(this, _KycController_moonpayFrameKeypair, null, "f");
605
615
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_clearMoonPaySession).call(this, state);
606
616
  }
607
617
  });
@@ -643,7 +653,7 @@ class KycController extends base_controller_1.BaseController {
643
653
  state.geoCountry = country;
644
654
  });
645
655
  }
646
- const disclaimers = await this.messenger.call('KycService:fetchDisclaimers', {
656
+ const disclaimers = await this.messenger.call('KycService:fetchVendorDisclaimers', {
647
657
  vendor: this.state.activeVendor,
648
658
  country,
649
659
  });
@@ -774,9 +784,9 @@ class KycController extends base_controller_1.BaseController {
774
784
  }
775
785
  let accessToken;
776
786
  let clientToken;
777
- if (credsEnvelope) {
787
+ if (credsEnvelope && __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
778
788
  try {
779
- const { credentials } = (0, crypto_js_1.decryptCredentials)(credsEnvelope, __classPrivateFieldGet(this, _KycController_keypair, "f").privateKey);
789
+ const { credentials } = (0, crypto_js_1.decryptCredentials)(credsEnvelope, __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").privateKey);
780
790
  accessToken = credentials.accessToken;
781
791
  clientToken = credentials.clientToken;
782
792
  }
@@ -799,12 +809,14 @@ class KycController extends base_controller_1.BaseController {
799
809
  * @returns The Check-frame URL or `null`.
800
810
  */
801
811
  buildCheckFrameUrl() {
802
- if (this.state.activeVendor !== 'moonpay' || !this.state.sessionToken) {
812
+ if (this.state.activeVendor !== 'moonpay' ||
813
+ !this.state.sessionToken ||
814
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
803
815
  return null;
804
816
  }
805
817
  const url = new URL(`${FRAMES_BASE_URL}/check-connection`);
806
818
  url.searchParams.set('sessionToken', this.state.sessionToken);
807
- url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_keypair, "f").publicKeyHex);
819
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
808
820
  url.searchParams.set('channelId', CHANNEL_CHECK);
809
821
  url.searchParams.set('skipKyc', 'true');
810
822
  return url.toString();
@@ -815,12 +827,14 @@ class KycController extends base_controller_1.BaseController {
815
827
  * @returns The Auth-frame URL or `null`.
816
828
  */
817
829
  buildAuthFrameUrl() {
818
- if (this.state.activeVendor !== 'moonpay' || !__classPrivateFieldGet(this, _KycController_authClientToken, "f")) {
830
+ if (this.state.activeVendor !== 'moonpay' ||
831
+ !__classPrivateFieldGet(this, _KycController_authClientToken, "f") ||
832
+ !__classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f")) {
819
833
  return null;
820
834
  }
821
835
  const url = new URL(`${FRAMES_BASE_URL}/auth`);
822
836
  url.searchParams.set('clientToken', __classPrivateFieldGet(this, _KycController_authClientToken, "f"));
823
- url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_keypair, "f").publicKeyHex);
837
+ url.searchParams.set('publicKey', __classPrivateFieldGet(this, _KycController_moonpayFrameKeypair, "f").publicKeyHex);
824
838
  url.searchParams.set('channelId', CHANNEL_AUTH);
825
839
  return url.toString();
826
840
  }
@@ -1180,7 +1194,7 @@ class KycController extends base_controller_1.BaseController {
1180
1194
  }
1181
1195
  }
1182
1196
  exports.KycController = KycController;
1183
- _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() {
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() {
1184
1198
  return {
1185
1199
  get: async (path, entropySourceId) => this.messenger.call('UserStorageController:performGetStorage', path, entropySourceId),
1186
1200
  set: async (path, value, entropySourceId) => this.messenger.call('UserStorageController:performSetStorage', path, value, entropySourceId),
@@ -1242,7 +1256,7 @@ async function _KycController_startConsentsSession(consents) {
1242
1256
  await this.refreshKycStatus();
1243
1257
  }
1244
1258
  catch (statusError) {
1245
- console.error('KYC status refresh failed:', statusError);
1259
+ (0, logger_js_1.controllerLog)('KYC status refresh failed:', statusError);
1246
1260
  }
1247
1261
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1248
1262
  state.phase = 'done';
@@ -1278,7 +1292,7 @@ async function _KycController_startConsentsSession(consents) {
1278
1292
  await this.refreshKycStatus();
1279
1293
  }
1280
1294
  catch (statusError) {
1281
- console.error('KYC status refresh failed:', statusError);
1295
+ (0, logger_js_1.controllerLog)('KYC status refresh failed:', statusError);
1282
1296
  }
1283
1297
  __classPrivateFieldGet(this, _KycController_instances, "m", _KycController_updateIfCurrent).call(this, generation, (state) => {
1284
1298
  if (state.phase !== 'error' && state.phase !== 'done') {
@@ -1306,7 +1320,7 @@ async function _KycController_startConsentsSession(consents) {
1306
1320
  });
1307
1321
  return;
1308
1322
  }
1309
- console.error('Consents session failed:', error);
1323
+ (0, logger_js_1.controllerLog)('Consents session failed:', error);
1310
1324
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {
1311
1325
  return;
1312
1326
  }
@@ -1437,7 +1451,7 @@ async function _KycController_createSession() {
1437
1451
  });
1438
1452
  }
1439
1453
  catch (error) {
1440
- console.error('Session creation failed:', error);
1454
+ (0, logger_js_1.controllerLog)('Session creation failed:', error);
1441
1455
  // A reset() superseded this flow while the request was in flight; leave
1442
1456
  // the idle controller alone rather than forcing it back to `terms`.
1443
1457
  if (__classPrivateFieldGet(this, _KycController_generation, "f") !== generation) {