@metamask-previews/kyc-controller 0.0.0-preview-e68ab1498 → 0.0.0-preview-4b37525

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 (56) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/dist/KycController-method-action-types.cjs.map +1 -1
  3. package/dist/KycController-method-action-types.d.cts +12 -6
  4. package/dist/KycController-method-action-types.d.cts.map +1 -1
  5. package/dist/KycController-method-action-types.d.mts +12 -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 +313 -72
  9. package/dist/KycController.cjs.map +1 -1
  10. package/dist/KycController.d.cts +27 -7
  11. package/dist/KycController.d.cts.map +1 -1
  12. package/dist/KycController.d.mts +27 -7
  13. package/dist/KycController.d.mts.map +1 -1
  14. package/dist/KycController.mjs +314 -73
  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 +60 -31
  18. package/dist/KycService-method-action-types.d.cts.map +1 -1
  19. package/dist/KycService-method-action-types.d.mts +60 -31
  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 +140 -75
  23. package/dist/KycService.cjs.map +1 -1
  24. package/dist/KycService.d.cts +181 -74
  25. package/dist/KycService.d.cts.map +1 -1
  26. package/dist/KycService.d.mts +181 -74
  27. package/dist/KycService.d.mts.map +1 -1
  28. package/dist/KycService.mjs +140 -75
  29. package/dist/KycService.mjs.map +1 -1
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +3 -3
  32. package/dist/index.d.cts.map +1 -1
  33. package/dist/index.d.mts +3 -3
  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 +49 -4
  38. package/dist/types.d.cts.map +1 -1
  39. package/dist/types.d.mts +49 -4
  40. package/dist/types.d.mts.map +1 -1
  41. package/dist/types.mjs.map +1 -1
  42. package/dist/ukyc/jwtChain.cjs +1 -1
  43. package/dist/ukyc/jwtChain.cjs.map +1 -1
  44. package/dist/ukyc/jwtChain.d.cts +2 -2
  45. package/dist/ukyc/jwtChain.d.mts +2 -2
  46. package/dist/ukyc/jwtChain.mjs +1 -1
  47. package/dist/ukyc/jwtChain.mjs.map +1 -1
  48. package/dist/ukyc/wrapEncryptionKey.cjs +16 -7
  49. package/dist/ukyc/wrapEncryptionKey.cjs.map +1 -1
  50. package/dist/ukyc/wrapEncryptionKey.d.cts +23 -16
  51. package/dist/ukyc/wrapEncryptionKey.d.cts.map +1 -1
  52. package/dist/ukyc/wrapEncryptionKey.d.mts +23 -16
  53. package/dist/ukyc/wrapEncryptionKey.d.mts.map +1 -1
  54. package/dist/ukyc/wrapEncryptionKey.mjs +16 -7
  55. package/dist/ukyc/wrapEncryptionKey.mjs.map +1 -1
  56. package/package.json +1 -1
@@ -19,7 +19,6 @@ const superstruct_1 = require("@metamask/superstruct");
19
19
  const utils_1 = require("@metamask/utils");
20
20
  const countryCodes_js_1 = require("./countryCodes.cjs");
21
21
  const constants_js_1 = require("./ukyc/constants.cjs");
22
- const storageAccessToken_js_1 = require("./ukyc/storageAccessToken.cjs");
23
22
  // === GENERAL ===
24
23
  /**
25
24
  * The name of the {@link KycService}, used to namespace the service's actions.
@@ -32,11 +31,13 @@ const MESSENGER_EXPOSED_METHODS = [
32
31
  'createSession',
33
32
  'checkKycRequired',
34
33
  'createVendorCustomer',
35
- 'submitConsents',
34
+ 'submitVendorDisclaimers',
35
+ 'fetchSessionDisclaimers',
36
+ 'submitSessionDisclaimers',
36
37
  'fetchKycStatus',
37
- 'getWrappingKey',
38
38
  'fetchJwks',
39
39
  'createUkycSession',
40
+ 'setAuthorizations',
40
41
  'createJourney',
41
42
  'getSessionStatus',
42
43
  ];
@@ -47,21 +48,30 @@ const DisclaimerStruct = (0, superstruct_1.type)({
47
48
  url: (0, superstruct_1.string)(),
48
49
  });
49
50
  const DisclaimersResponseStruct = (0, superstruct_1.array)(DisclaimerStruct);
51
+ const VendorSigningStruct = (0, superstruct_1.type)({
52
+ id: (0, superstruct_1.string)(),
53
+ customer_id: (0, superstruct_1.string)(),
54
+ content_id: (0, superstruct_1.optional)((0, superstruct_1.string)()),
55
+ });
56
+ const VendorSigningsResponseStruct = (0, superstruct_1.array)(VendorSigningStruct);
50
57
  const CreateSessionResponseStruct = (0, superstruct_1.type)({ sessionToken: (0, superstruct_1.string)() });
51
58
  // The live KYC API returns the flag under `required`; the service normalizes
52
59
  // this to `kycRequired` for consumers (see `checkKycRequired`).
53
60
  const KycRequiredResponseStruct = (0, superstruct_1.type)({ required: (0, superstruct_1.boolean)() });
54
- // The session server's X25519 public key, in JWK-like form, returned by
55
- // `/wrapping-key`. `x` is the base64url public key used to wrap the user key.
56
- const SessionServerPublicKeyStruct = (0, superstruct_1.type)({
61
+ // The session server's public key, in JWK-like form, returned inside an
62
+ // encryption schema from `POST /sessions`. `x` is the base64url public key
63
+ // used to wrap a secret for that schema.
64
+ const ServerPublicKeyStruct = (0, superstruct_1.type)({
57
65
  kty: (0, superstruct_1.string)(),
58
66
  crv: (0, superstruct_1.string)(),
59
67
  x: (0, superstruct_1.string)(),
68
+ kid: (0, superstruct_1.optional)((0, superstruct_1.string)()),
69
+ alg: (0, superstruct_1.optional)((0, superstruct_1.string)()),
70
+ use: (0, superstruct_1.optional)((0, superstruct_1.string)()),
60
71
  });
61
- const WrappingKeyResponseStruct = (0, superstruct_1.type)({
62
- id: (0, superstruct_1.string)(),
72
+ const EncryptionSchemaStruct = (0, superstruct_1.type)({
73
+ serverPublicKey: ServerPublicKeyStruct,
63
74
  jwtChain: (0, superstruct_1.string)(),
64
- sessionServerPublicKey: SessionServerPublicKeyStruct,
65
75
  });
66
76
  // A single Ed25519 (OKP) JWK. `type` (not `object`) keeps optional/extra JWK
67
77
  // fields (`use`, `alg`) from failing validation.
@@ -74,11 +84,10 @@ const JwkStruct = (0, superstruct_1.type)({
74
84
  const JwksResponseStruct = (0, superstruct_1.type)({ keys: (0, superstruct_1.array)(JwkStruct) });
75
85
  const UkycSessionResponseStruct = (0, superstruct_1.type)({
76
86
  sessionId: (0, superstruct_1.string)(),
77
- // The relay-side KYC decision (e.g. `approved`) and the vendor-side final
78
- // status (e.g. `pending`) at session-creation time. Present when the applicant
79
- // already has a session in flight; absent for a brand-new session.
80
- kycStatus: (0, superstruct_1.optional)((0, superstruct_1.string)()),
81
- finalStatus: (0, superstruct_1.optional)((0, superstruct_1.string)()),
87
+ // Per-secret wrapping material so the client can seal the
88
+ // `data_encryption_key` and the `ukyc_capability_token` independently.
89
+ encryptionDataKey: EncryptionSchemaStruct,
90
+ ukycCapabilityToken: EncryptionSchemaStruct,
82
91
  });
83
92
  const ApplicantAccessTokenResponseStruct = (0, superstruct_1.type)({
84
93
  status: (0, superstruct_1.string)(),
@@ -111,6 +120,18 @@ const KycUserStatusResponseStruct = (0, superstruct_1.type)({
111
120
  sumsubSessionId: (0, superstruct_1.optional)((0, superstruct_1.string)()),
112
121
  errorCode: (0, superstruct_1.optional)((0, superstruct_1.string)()),
113
122
  });
123
+ const ConsentDocumentStruct = (0, superstruct_1.type)({
124
+ key: (0, superstruct_1.string)(),
125
+ version: (0, superstruct_1.string)(),
126
+ title: (0, superstruct_1.string)(),
127
+ url: (0, superstruct_1.string)(),
128
+ consented: (0, superstruct_1.boolean)(),
129
+ });
130
+ const SessionDisclaimersResponseStruct = (0, superstruct_1.type)({
131
+ idOS: (0, superstruct_1.array)(ConsentDocumentStruct),
132
+ kycProvider: (0, superstruct_1.array)(ConsentDocumentStruct),
133
+ credentialReusabilityConsentGiven: (0, superstruct_1.boolean)(),
134
+ });
114
135
  // === SERVICE DEFINITION ===
115
136
  /**
116
137
  * `KycService` communicates with the Universal KYC (UKYC) backend to drive the
@@ -123,8 +144,9 @@ const KycUserStatusResponseStruct = (0, superstruct_1.type)({
123
144
  * `fetchQuery`: it is wrapped in the shared service policy (retries, circuit
124
145
  * breaker) and its result is exposed via the service's `QueryClient`. Read-only
125
146
  * endpoints (`fetchDisclaimers`, `fetchJwks`) are cached with a `staleTime`;
126
- * the session-creating and status-polling endpoints opt out of caching
127
- * (`staleTime`/`gcTime` of `0`) so they never serve a stale result.
147
+ * vendor-disclaimer, session-scoped disclaimer, session-creating, and
148
+ * status-polling endpoints opt out of caching (`staleTime`/`gcTime` of `0`)
149
+ * so they never serve a stale result.
128
150
  */
129
151
  class KycService extends base_data_service_1.BaseDataService {
130
152
  /**
@@ -136,8 +158,8 @@ class KycService extends base_data_service_1.BaseDataService {
136
158
  * the runtime's native `fetch`.
137
159
  * @param options.baseUrl - Base URL of the KYC API
138
160
  * @param options.fractalEncryptionBaseUrl - Base URL of the Fractal
139
- * encryption service, from which the JWKS used to verify the wrapping-key
140
- * `jwtChain` is fetched.
161
+ * encryption service, from which the JWKS used to verify encryption-schema
162
+ * `jwtChain`s is fetched.
141
163
  * @param options.queryClientConfig - Shared configuration for all queries
142
164
  * exposed by the service.
143
165
  * @param options.policyOptions - Options for the request service policy.
@@ -315,85 +337,106 @@ class KycService extends base_data_service_1.BaseDataService {
315
337
  return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, VendorCustomerResponseStruct, 'vendor customers');
316
338
  }
317
339
  /**
318
- * Posts T&C1 (vendor signings) and T&C2 (Sumsub + idOS) consents for the
319
- * authenticated user. The API responds with 204 No Content on success.
340
+ * Records vendor T&C acceptance (`POST /vendors/{vendor}/disclaimers`).
341
+ * For Iron this creates content signings from the disclaimer ids the
342
+ * customer accepted. Session-scoped idOS / KYC-provider consents are
343
+ * recorded separately via {@link submitSessionDisclaimers}. Retries re-POST
344
+ * the same ids, matching the legacy `POST /consents` signing step.
320
345
  *
321
- * @param params - The consent parameters.
346
+ * @param params - The parameters.
347
+ * @param params.vendor - Identity vendor (e.g. `iron`).
348
+ * @param params.disclaimerIds - Accepted vendor T&C ids.
349
+ * @returns The vendor signing records.
322
350
  */
323
- async submitConsents(params) {
324
- const url = new URL('/consents', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
325
- await this.fetchQuery({
351
+ async submitVendorDisclaimers(params) {
352
+ const url = new URL(`/vendors/${encodeURIComponent(params.vendor)}/disclaimers`, __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
353
+ const data = await this.fetchQuery({
326
354
  queryKey: [
327
- `${this.name}:submitConsents`,
355
+ `${this.name}:submitVendorDisclaimers`,
356
+ params.vendor,
328
357
  params.disclaimerIds,
329
- params.sumsubTncSigned,
330
- params.idosTncSigned,
331
- params.kycLevel ?? 'standard',
332
358
  ],
333
359
  queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, {
334
360
  method: 'POST',
335
- // UKYC Money/VBA consents contract still uses `ironDisclaimerIds`.
336
- body: JSON.stringify({
337
- ironDisclaimerIds: params.disclaimerIds,
338
- sumsubTncSigned: params.sumsubTncSigned,
339
- idosTncSigned: params.idosTncSigned,
340
- kycLevel: params.kycLevel ?? 'standard',
341
- }),
361
+ body: JSON.stringify({ disclaimerIds: params.disclaimerIds }),
342
362
  }),
343
363
  staleTime: 0,
344
364
  gcTime: 0,
345
365
  });
366
+ return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, VendorSigningsResponseStruct, 'vendor disclaimers');
346
367
  }
347
368
  /**
348
- * Fetches the user-keyed simplified KYC status used by Money toast / banner
349
- * surfaces (`GET /kyc/status`).
369
+ * Fetches the session-scoped idOS + KYC-provider disclaimer catalog
370
+ * (`GET /sessions/{sessionId}/disclaimers`). Requires an existing UKYC
371
+ * session; vendor T&Cs continue to come from {@link fetchDisclaimers}.
350
372
  *
351
- * @returns The simplified status payload.
373
+ * @param params - The parameters.
374
+ * @param params.sessionId - The UKYC session id.
375
+ * @returns The catalog, including which documents are already consented.
352
376
  */
353
- async fetchKycStatus() {
354
- const url = new URL('/kyc/status', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
377
+ async fetchSessionDisclaimers(params) {
378
+ const url = new URL(`/sessions/${encodeURIComponent(params.sessionId)}/disclaimers`, __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
355
379
  const data = await this.fetchQuery({
356
- queryKey: [`${this.name}:fetchKycStatus`],
380
+ queryKey: [`${this.name}:fetchSessionDisclaimers`, params.sessionId],
357
381
  queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, { method: 'GET' }),
358
- // Status is polled for toast flips, so it must always be fresh.
382
+ // Consent state can change after a POST, so always re-fetch.
359
383
  staleTime: 0,
360
384
  gcTime: 0,
361
385
  });
362
- return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, KycUserStatusResponseStruct, 'kyc status');
386
+ return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, SessionDisclaimersResponseStruct, 'session disclaimers');
363
387
  }
364
388
  /**
365
- * Requests a per-session wrapping key from the UKYC backend.
366
- *
367
- * The client sends its ephemeral X25519 public key; the backend responds with
368
- * its session public key (`sessionServerPublicKey`) and a `jwtChain` that
369
- * attests it. The caller must verify `jwtChain` against the Fractal JWKS
370
- * (see {@link KycService.fetchJwks}) before trusting the key to wrap the
371
- * `data_encryption_key`.
389
+ * Records idOS + KYC-provider consents for a UKYC session
390
+ * (`POST /sessions/{sessionId}/disclaimers`). `key`/`version` pairs must
391
+ * match the current catalog from {@link fetchSessionDisclaimers}. A 409
392
+ * means those document versions were already recorded for the session.
372
393
  *
373
- * @param params - The parameters.
374
- * @param params.sessionClientPublicKey - Our ephemeral X25519 public key
375
- * (base64url).
376
- * @returns The wrapping key id, `jwtChain`, and session server public key.
394
+ * @param params - The consent parameters.
395
+ * @returns The updated catalog after recording.
377
396
  */
378
- async getWrappingKey(params) {
379
- const url = new URL('/wrapping-key', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
397
+ async submitSessionDisclaimers(params) {
398
+ const url = new URL(`/sessions/${encodeURIComponent(params.sessionId)}/disclaimers`, __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
380
399
  const data = await this.fetchQuery({
381
- queryKey: [`${this.name}:getWrappingKey`, params.sessionClientPublicKey],
400
+ queryKey: [
401
+ `${this.name}:submitSessionDisclaimers`,
402
+ params.sessionId,
403
+ params.idOS,
404
+ params.kycProvider,
405
+ params.credentialReusabilityConsentGiven,
406
+ ],
382
407
  queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, {
383
408
  method: 'POST',
384
409
  body: JSON.stringify({
385
- sessionClientPublicKey: params.sessionClientPublicKey,
410
+ idOS: params.idOS,
411
+ kycProvider: params.kycProvider,
412
+ credentialReusabilityConsentGiven: params.credentialReusabilityConsentGiven,
386
413
  }),
387
414
  }),
388
- // A per-session key exchange must always run fresh.
389
415
  staleTime: 0,
390
416
  gcTime: 0,
391
417
  });
392
- return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, WrappingKeyResponseStruct, 'wrapping-key');
418
+ return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, SessionDisclaimersResponseStruct, 'session disclaimers');
419
+ }
420
+ /**
421
+ * Fetches the user-keyed simplified KYC status used by Money toast / banner
422
+ * surfaces (`GET /kyc/status`).
423
+ *
424
+ * @returns The simplified status payload.
425
+ */
426
+ async fetchKycStatus() {
427
+ const url = new URL('/kyc/status', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
428
+ const data = await this.fetchQuery({
429
+ queryKey: [`${this.name}:fetchKycStatus`],
430
+ queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, { method: 'GET' }),
431
+ // Status is polled for toast flips, so it must always be fresh.
432
+ staleTime: 0,
433
+ gcTime: 0,
434
+ });
435
+ return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, KycUserStatusResponseStruct, 'kyc status');
393
436
  }
394
437
  /**
395
- * Fetches the Fractal encryption service JWKS used to verify the `jwtChain`
396
- * returned by {@link KycService.getWrappingKey}.
438
+ * Fetches the Fractal encryption service JWKS used to verify the `jwtChain`s
439
+ * returned inside encryption schemas from {@link KycService.createUkycSession}.
397
440
  *
398
441
  * This is an unauthenticated request to a well-known path on the Fractal
399
442
  * host, distinct from the UKYC base URL.
@@ -402,7 +445,7 @@ class KycService extends base_data_service_1.BaseDataService {
402
445
  */
403
446
  async fetchJwks() {
404
447
  if (!__classPrivateFieldGet(this, _KycService_fractalEncryptionBaseUrl, "f")) {
405
- throw new Error('KycService: fractalEncryptionBaseUrl is not configured; cannot fetch JWKS to verify the wrapping key.');
448
+ throw new Error('KycService: fractalEncryptionBaseUrl is not configured; cannot fetch JWKS to verify encryption schemas.');
406
449
  }
407
450
  const url = new URL(constants_js_1.UKYC_JWKS_PATH, __classPrivateFieldGet(this, _KycService_fractalEncryptionBaseUrl, "f"));
408
451
  const data = await this.fetchQuery({
@@ -413,21 +456,20 @@ class KycService extends base_data_service_1.BaseDataService {
413
456
  return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, JwksResponseStruct, 'JWKS');
414
457
  }
415
458
  /**
416
- * Creates a UKYC session for the SumSub document-verification sub-flow,
417
- * handing over the wrapped `data_encryption_key` and the client-signed,
418
- * read-only `ukyc_capability_token` that authorizes later storage access for
419
- * the session.
459
+ * Creates a UKYC session for the SumSub document-verification sub-flow.
460
+ *
461
+ * The response carries per-secret encryption schemas (`encryptionDataKey` and
462
+ * `ukycCapabilityToken`) so the client can wrap the `data_encryption_key` and
463
+ * the read-only `ukyc_capability_token` and submit them via
464
+ * {@link KycService.setAuthorizations}.
420
465
  *
421
466
  * @param params - The session parameters.
422
- * @returns The UKYC session identifiers.
467
+ * @returns The UKYC session id and encryption schemas.
423
468
  */
424
469
  async createUkycSession(params) {
425
470
  const url = new URL('/sessions', __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
426
471
  const data = await this.fetchQuery({
427
- queryKey: [
428
- `${this.name}:createUkycSession`,
429
- params.wrappedEncryptionKey.sessionId,
430
- ],
472
+ queryKey: [`${this.name}:createUkycSession`, params.jwtToken],
431
473
  queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, {
432
474
  method: 'POST',
433
475
  body: JSON.stringify({
@@ -435,8 +477,6 @@ class KycService extends base_data_service_1.BaseDataService {
435
477
  vendorUserId: 'mockedId',
436
478
  jwtToken: params.jwtToken,
437
479
  vendorMetadata: params.vendorMetadata ?? {},
438
- wrappedEncryptionKey: params.wrappedEncryptionKey,
439
- ukycCapabilityToken: (0, storageAccessToken_js_1.encodeStorageAccessTokenForHeader)(params.ukycCapabilityToken),
440
480
  }),
441
481
  }),
442
482
  // A session-creating mutation must never serve a stale/cached result.
@@ -445,6 +485,31 @@ class KycService extends base_data_service_1.BaseDataService {
445
485
  });
446
486
  return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, UkycSessionResponseStruct, 'UKYC sessions');
447
487
  }
488
+ /**
489
+ * Submits the wrapped `data_encryption_key` and wrapped
490
+ * `ukyc_capability_token` for a UKYC session. Both secrets are sealed with
491
+ * `wrapEncryptionKey` against the encryption schemas returned by
492
+ * {@link KycService.createUkycSession}.
493
+ *
494
+ * @param params - The wrapped authorizations.
495
+ * @returns The session status after the authorizations are applied.
496
+ */
497
+ async setAuthorizations(params) {
498
+ const url = new URL(`/sessions/${encodeURIComponent(params.sessionId)}/authorizations`, __classPrivateFieldGet(this, _KycService_baseUrl, "f"));
499
+ const data = await this.fetchQuery({
500
+ queryKey: [`${this.name}:setAuthorizations`, params.sessionId],
501
+ queryFn: async () => __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_requestJson).call(this, url, {
502
+ method: 'POST',
503
+ body: JSON.stringify({
504
+ wrappedEncryptionDataKey: params.wrappedEncryptionDataKey,
505
+ wrappedUkycCapabilityToken: params.wrappedUkycCapabilityToken,
506
+ }),
507
+ }),
508
+ staleTime: 0,
509
+ gcTime: 0,
510
+ });
511
+ return __classPrivateFieldGet(this, _KycService_instances, "m", _KycService_validateResponse).call(this, data, SessionStatusResponseStruct, 'authorizations');
512
+ }
448
513
  /**
449
514
  * Creates (or refreshes) the SumSub verification journey for a UKYC session,
450
515
  * returning the applicant access token used to launch the SDK.
@@ -554,7 +619,7 @@ async function _KycService_requestJson(url, init, options = {}) {
554
619
  }
555
620
  throw new controller_utils_1.HttpError(response.status, `Fetching '${url.toString()}' failed with status '${response.status}'${detail ? `: ${detail}` : ''}`);
556
621
  }
557
- // Consent (and similar) endpoints return 204 No Content.
622
+ // DELETE (and similar) endpoints return 204 No Content.
558
623
  if (response.status === 204) {
559
624
  return null;
560
625
  }
@@ -1 +1 @@
1
- {"version":3,"file":"KycService.cjs","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { GeolocationControllerGetGeolocationAction } from '@metamask/geolocation-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationControllerGetBearerTokenAction } from '@metamask/profile-sync-controller/auth';\nimport type { Infer, Struct } from '@metamask/superstruct';\nimport {\n array,\n assert,\n boolean,\n enums,\n optional,\n string,\n StructError,\n type,\n} from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { Duration, inMilliseconds } from '@metamask/utils';\nimport type { QueryClientConfig } from '@tanstack/query-core';\n\nimport { alpha2ToAlpha3 } from './countryCodes.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n KycDisclaimer,\n KycSessionStatus,\n KycUserStatusResponse,\n KycVendor,\n} from './types.js';\nimport { UKYC_JWKS_PATH } from './ukyc/constants.js';\nimport { encodeStorageAccessTokenForHeader } from './ukyc/storageAccessToken.js';\nimport type { UkycStorageAccessToken } from './ukyc/storageAccessToken.js';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link KycService}, used to namespace the service's actions.\n */\nexport const serviceName = 'KycService';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getGeoCountry',\n 'fetchDisclaimers',\n 'createSession',\n 'checkKycRequired',\n 'createVendorCustomer',\n 'submitConsents',\n 'fetchKycStatus',\n 'getWrappingKey',\n 'fetchJwks',\n 'createUkycSession',\n 'createJourney',\n 'getSessionStatus',\n] as const;\n\n/**\n * Invalidates cached queries serviced by {@link KycService}.\n */\nexport type KycServiceInvalidateQueriesAction =\n DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/**\n * Actions that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceActions =\n | KycServiceMethodActions\n | KycServiceInvalidateQueriesAction;\n\n/**\n * Actions from other messengers that {@link KycService} calls.\n */\ntype AllowedActions =\n | AuthenticationControllerGetBearerTokenAction\n | GeolocationControllerGetGeolocationAction;\n\n/**\n * Published when {@link KycService}'s cache is updated.\n */\nexport type KycServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<\n typeof serviceName\n>;\n\n/**\n * Published when a single key within {@link KycService}'s cache is updated.\n */\nexport type KycServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Events that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceEvents =\n | KycServiceCacheUpdatedEvent\n | KycServiceGranularCacheUpdatedEvent;\n\n/**\n * Events from other messengers that {@link KycService} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link KycService}.\n */\nexport type KycServiceMessenger = Messenger<\n typeof serviceName,\n KycServiceActions | AllowedActions,\n KycServiceEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycService}.\n */\nexport type KycServiceOptions = {\n messenger: KycServiceMessenger;\n /**\n * A function used to make HTTP requests. Defaults to the runtime's native\n * `fetch`, so consumers do not need to inject one on platforms where `fetch`\n * is available globally (browser, React Native, Node 18+).\n */\n fetch?: typeof fetch;\n /**\n * Mandatory value that sets the base url to KYC api\n */\n baseUrl: string;\n /**\n * Base URL of the Fractal encryption service, from which the JWKS used to\n * verify the `jwtChain` returned by {@link KycService.getWrappingKey} is\n * fetched. Required to run the wrapping-key exchange in\n * {@link KycService.fetchJwks}.\n */\n fractalEncryptionBaseUrl?: string;\n /**\n * Shared configuration applied to all queries exposed by the service (e.g. a\n * default `staleTime`/`gcTime`). Each data service gets its own\n * `QueryClient`.\n */\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n};\n\n// === API RESPONSE SCHEMAS ===\n\nconst DisclaimerStruct = type({\n id: string(),\n display_name: string(),\n url: string(),\n});\nconst DisclaimersResponseStruct = array(DisclaimerStruct);\n\nconst CreateSessionResponseStruct = type({ sessionToken: string() });\n\n// The live KYC API returns the flag under `required`; the service normalizes\n// this to `kycRequired` for consumers (see `checkKycRequired`).\nconst KycRequiredResponseStruct = type({ required: boolean() });\n\n// The session server's X25519 public key, in JWK-like form, returned by\n// `/wrapping-key`. `x` is the base64url public key used to wrap the user key.\nconst SessionServerPublicKeyStruct = type({\n kty: string(),\n crv: string(),\n x: string(),\n});\n\nconst WrappingKeyResponseStruct = type({\n id: string(),\n jwtChain: string(),\n sessionServerPublicKey: SessionServerPublicKeyStruct,\n});\nexport type WrappingKeyResponse = Infer<typeof WrappingKeyResponseStruct>;\n\n// A single Ed25519 (OKP) JWK. `type` (not `object`) keeps optional/extra JWK\n// fields (`use`, `alg`) from failing validation.\nconst JwkStruct = type({\n kty: string(),\n crv: string(),\n x: string(),\n kid: string(),\n});\nconst JwksResponseStruct = type({ keys: array(JwkStruct) });\nexport type JwksResponse = Infer<typeof JwksResponseStruct>;\n\nconst UkycSessionResponseStruct = type({\n sessionId: string(),\n // The relay-side KYC decision (e.g. `approved`) and the vendor-side final\n // status (e.g. `pending`) at session-creation time. Present when the applicant\n // already has a session in flight; absent for a brand-new session.\n kycStatus: optional(string()),\n finalStatus: optional(string()),\n});\nexport type UkycSessionResponse = Infer<typeof UkycSessionResponseStruct>;\n\nconst ApplicantAccessTokenResponseStruct = type({\n status: string(),\n applicantAccessToken: string(),\n});\nexport type ApplicantAccessTokenResponse = Infer<\n typeof ApplicantAccessTokenResponseStruct\n>;\n\nconst SessionStatusResponseStruct = type({\n finalStatus: string(),\n statusMessage: optional(string()),\n externalUserId: string(),\n kycStatus: string(),\n vendor: string(),\n vendorStatus: string(),\n});\n\n// Vendor customer subset — `type` (not `object`) keeps extra vendor fields from\n// failing validation while still requiring the fields the controller needs.\nconst VendorCustomerResponseStruct = type({\n id: string(),\n email: string(),\n status: string(),\n});\nexport type VendorCustomerResponse = Infer<typeof VendorCustomerResponseStruct>;\n\nconst KYC_USER_STATUSES = [\n 'not-started',\n 'pending',\n 'need-more-information',\n 'terminal-failure',\n 'completed',\n] as const;\n\nconst KycUserStatusResponseStruct = type({\n status: enums([...KYC_USER_STATUSES]),\n sumsubSessionId: optional(string()),\n errorCode: optional(string()),\n});\n\n// === PARAM TYPES ===\n\nexport type CreateSessionParams = {\n email: string;\n termsAcceptedAt: string;\n disclaimerIds: string[];\n};\n\nexport type CheckKycRequiredParams = {\n /**\n * Identity vendor to check. Defaults to `moonpay` for the existing\n * Check/Auth path.\n */\n vendor?: KycVendor;\n /**\n * MoonPay access token. Required when `vendor` is `moonpay` (or omitted).\n */\n accessToken?: string;\n /**\n * ISO 3166-1 alpha-3 country code. Required when `vendor` is `moonpay`.\n */\n country?: string;\n capabilities?: { product: string }[];\n};\n\nexport type CreateVendorCustomerParams = {\n vendor: KycVendor;\n email: string;\n};\n\nexport type SubmitConsentsParams = {\n /**\n * Vendor disclaimer ids the customer accepted (T&C1). Mapped to the UKYC\n * wire field `ironDisclaimerIds` for the Money/VBA consents contract.\n */\n disclaimerIds: string[];\n sumsubTncSigned: boolean;\n idosTncSigned: boolean;\n kycLevel?: 'standard';\n};\n\nexport type GetWrappingKeyParams = {\n sessionClientPublicKey: string;\n};\n\n/**\n * The wrapped `data_encryption_key` sent to the UKYC backend when creating a\n * session. `encryptedKey` and `nonce` are produced by `wrapEncryptionKey`;\n * `sessionId` is the wrapping key id returned by `getWrappingKey`.\n */\nexport type WrappedEncryptionKey = {\n sessionId: string;\n encryptedKey: string;\n nonce: string;\n};\n\nexport type CreateUkycSessionParams = {\n jwtToken: string;\n /**\n * Identity vendor for the UKYC session. Defaults to `moonpay` for the\n * existing Check/Auth flow. Pass a non-MoonPay vendor (e.g. `iron`) for\n * the consents path (no MoonPay metadata required).\n */\n vendor?: KycVendor;\n /**\n * Vendor-specific metadata. Required for MoonPay (`moonPayAccessToken` /\n * `moonPayUserId`); optional / omitted for other vendors.\n */\n vendorMetadata?: Record<string, unknown>;\n wrappedEncryptionKey: WrappedEncryptionKey;\n /**\n * The client-signed `ukyc_capability_token` (envelope: payload + Ed25519\n * signature) authorizing later storage access for this session. It is minted\n * by the client with `read`-only scope — see the UKYC storage-and-auth spec\n * for how it is formed. Only the client holds the signing key, so only the\n * client can mint it. The envelope is base64url-encoded into a compact string\n * before it is sent to the backend.\n */\n ukycCapabilityToken: UkycStorageAccessToken;\n};\n\nexport type GetSessionStatusParams = {\n sessionId: string;\n};\n\n// === SERVICE DEFINITION ===\n\n/**\n * `KycService` communicates with the Universal KYC (UKYC) backend to drive the\n * identity + document-verification flow. It is stateless and platform-agnostic:\n * HTTP is performed through the runtime's native `fetch` (or an injected\n * `fetch` when provided), and the auth bearer token and geolocation come from\n * other controllers via the messenger.\n *\n * It extends {@link BaseDataService}, so every request is routed through\n * `fetchQuery`: it is wrapped in the shared service policy (retries, circuit\n * breaker) and its result is exposed via the service's `QueryClient`. Read-only\n * endpoints (`fetchDisclaimers`, `fetchJwks`) are cached with a `staleTime`;\n * the session-creating and status-polling endpoints opt out of caching\n * (`staleTime`/`gcTime` of `0`) so they never serve a stale result.\n */\nexport class KycService extends BaseDataService<\n typeof serviceName,\n KycServiceMessenger\n> {\n readonly #fetch: typeof fetch;\n\n readonly #baseUrl: string;\n\n readonly #fractalEncryptionBaseUrl: string;\n\n /**\n * Constructs a new KycService.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this service.\n * @param options.fetch - A function used to make HTTP requests. Defaults to\n * the runtime's native `fetch`.\n * @param options.baseUrl - Base URL of the KYC API\n * @param options.fractalEncryptionBaseUrl - Base URL of the Fractal\n * encryption service, from which the JWKS used to verify the wrapping-key\n * `jwtChain` is fetched.\n * @param options.queryClientConfig - Shared configuration for all queries\n * exposed by the service.\n * @param options.policyOptions - Options for the request service policy.\n */\n constructor({\n messenger,\n fetch: fetchFunction,\n baseUrl,\n fractalEncryptionBaseUrl,\n queryClientConfig = {},\n policyOptions = {},\n }: KycServiceOptions) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions,\n });\n // Fall back to the runtime's native `fetch`, bound to `globalThis` so it\n // can be invoked as a method of this instance without an illegal-invocation\n // error on platforms that check the receiver.\n if (fetchFunction) {\n this.#fetch = fetchFunction;\n } else if (typeof globalThis.fetch === 'function') {\n this.#fetch = globalThis.fetch.bind(globalThis);\n } else {\n throw new Error(\n 'KycService: fetch is not available globally and was not provided in options. Please inject a fetch implementation.',\n );\n }\n if (!baseUrl) {\n throw new Error('KycService: baseUrl is required');\n }\n this.#baseUrl = baseUrl;\n this.#fractalEncryptionBaseUrl = fractalEncryptionBaseUrl ?? '';\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Resolves the customer's country from the geolocation source and converts it\n * to an ISO 3166-1 alpha-3 code.\n *\n * @returns The alpha-3 country code.\n * @throws If the country cannot be determined or mapped.\n */\n async getGeoCountry(): Promise<string> {\n const location = await this.messenger.call(\n 'GeolocationController:getGeolocation',\n );\n // Guard nullish/empty geolocation with the documented domain error rather\n // than letting `assert(location, string())` surface a superstruct\n // assertion error (which would change how the failure reads in\n // `disclaimersError`).\n const alpha2 =\n typeof location === 'string' ? location.split('-')[0].toUpperCase() : '';\n if (!alpha2 || alpha2 === 'UNKNOWN') {\n throw new Error(\n `Unable to determine country from geolocation (got \"${String(\n location,\n )}\").`,\n );\n }\n const alpha3 = alpha2ToAlpha3(alpha2);\n if (!alpha3) {\n throw new Error(\n `Unable to map country code \"${alpha2}\" to an ISO 3166-1 alpha-3 code.`,\n );\n }\n return alpha3;\n }\n\n /**\n * Fetches the disclaimers the customer must accept before a session is\n * created.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\n async fetchDisclaimers({\n vendor = 'moonpay',\n country,\n }: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n const url = new URL(`/vendors/${vendor}/disclaimers`, this.#baseUrl);\n url.searchParams.set('country', country);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchDisclaimers`, vendor, country],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n staleTime: inMilliseconds(5, Duration.Minute),\n });\n return this.#validateResponse(\n data,\n DisclaimersResponseStruct,\n 'disclaimers',\n ) as KycDisclaimer[];\n }\n\n /**\n * Creates a vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\n async createSession(\n params: CreateSessionParams,\n ): Promise<Infer<typeof CreateSessionResponseStruct>> {\n const url = new URL('/vendors/moonpay/sessions', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:createSession`,\n params.email,\n params.termsAcceptedAt,\n params.disclaimerIds,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(params),\n }),\n // A session-creating mutation must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n CreateSessionResponseStruct,\n 'sessions',\n );\n }\n\n /**\n * Checks whether KYC is required for the given vendor, country, and\n * capabilities.\n *\n * @param params - The check parameters.\n * @returns Whether KYC is required.\n */\n async checkKycRequired(\n params: CheckKycRequiredParams,\n ): Promise<{ kycRequired: boolean }> {\n const vendor = params.vendor ?? 'moonpay';\n const url = new URL(`/vendors/${vendor}/kyc-required`, this.#baseUrl);\n const capabilities = params.capabilities ?? [{ product: 'ramps' }];\n const body =\n vendor === 'moonpay'\n ? {\n accessToken: params.accessToken,\n country: params.country,\n capabilities,\n }\n : {};\n\n // MoonPay requires accessToken and country; validate before making the request.\n if (vendor === 'moonpay') {\n if (!params.accessToken) {\n throw new Error(\n 'checkKycRequired: accessToken is required for vendor \"moonpay\".',\n );\n }\n if (!params.country) {\n throw new Error(\n 'checkKycRequired: country is required for vendor \"moonpay\".',\n );\n }\n }\n\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:checkKycRequired`,\n vendor,\n params.accessToken ?? null,\n params.country ?? null,\n capabilities,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(body),\n }),\n // The requirement can change server-side, so always re-check.\n staleTime: 0,\n gcTime: 0,\n });\n const { required } = this.#validateResponse(\n data,\n KycRequiredResponseStruct,\n 'kyc-required',\n );\n return { kycRequired: required };\n }\n\n /**\n * Creates (or resumes) an empty-shell customer for the authenticated\n * canonical user on the given identity vendor. Must run before showing\n * vendor T&C so the customer exists and resume logic can key off vendor\n * status.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor (e.g. `iron` for Money/VBA).\n * @param params.email - Email associated with the customer.\n * @returns The vendor customer record (subset validated for controller use).\n */\n async createVendorCustomer(\n params: CreateVendorCustomerParams,\n ): Promise<VendorCustomerResponse> {\n const url = new URL(`/vendors/${params.vendor}/customers`, this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:createVendorCustomer`,\n params.vendor,\n params.email,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({ email: params.email }),\n }),\n // Customer creation/resume must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n VendorCustomerResponseStruct,\n 'vendor customers',\n );\n }\n\n /**\n * Posts T&C1 (vendor signings) and T&C2 (Sumsub + idOS) consents for the\n * authenticated user. The API responds with 204 No Content on success.\n *\n * @param params - The consent parameters.\n */\n async submitConsents(params: SubmitConsentsParams): Promise<void> {\n const url = new URL('/consents', this.#baseUrl);\n await this.fetchQuery({\n queryKey: [\n `${this.name}:submitConsents`,\n params.disclaimerIds,\n params.sumsubTncSigned,\n params.idosTncSigned,\n params.kycLevel ?? 'standard',\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n // UKYC Money/VBA consents contract still uses `ironDisclaimerIds`.\n body: JSON.stringify({\n ironDisclaimerIds: params.disclaimerIds,\n sumsubTncSigned: params.sumsubTncSigned,\n idosTncSigned: params.idosTncSigned,\n kycLevel: params.kycLevel ?? 'standard',\n }),\n }),\n staleTime: 0,\n gcTime: 0,\n });\n }\n\n /**\n * Fetches the user-keyed simplified KYC status used by Money toast / banner\n * surfaces (`GET /kyc/status`).\n *\n * @returns The simplified status payload.\n */\n async fetchKycStatus(): Promise<KycUserStatusResponse> {\n const url = new URL('/kyc/status', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchKycStatus`],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n // Status is polled for toast flips, so it must always be fresh.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n KycUserStatusResponseStruct,\n 'kyc status',\n );\n }\n\n /**\n * Requests a per-session wrapping key from the UKYC backend.\n *\n * The client sends its ephemeral X25519 public key; the backend responds with\n * its session public key (`sessionServerPublicKey`) and a `jwtChain` that\n * attests it. The caller must verify `jwtChain` against the Fractal JWKS\n * (see {@link KycService.fetchJwks}) before trusting the key to wrap the\n * `data_encryption_key`.\n *\n * @param params - The parameters.\n * @param params.sessionClientPublicKey - Our ephemeral X25519 public key\n * (base64url).\n * @returns The wrapping key id, `jwtChain`, and session server public key.\n */\n async getWrappingKey(\n params: GetWrappingKeyParams,\n ): Promise<WrappingKeyResponse> {\n const url = new URL('/wrapping-key', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:getWrappingKey`, params.sessionClientPublicKey],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n sessionClientPublicKey: params.sessionClientPublicKey,\n }),\n }),\n // A per-session key exchange must always run fresh.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n WrappingKeyResponseStruct,\n 'wrapping-key',\n );\n }\n\n /**\n * Fetches the Fractal encryption service JWKS used to verify the `jwtChain`\n * returned by {@link KycService.getWrappingKey}.\n *\n * This is an unauthenticated request to a well-known path on the Fractal\n * host, distinct from the UKYC base URL.\n *\n * @returns The JWKS keys.\n */\n async fetchJwks(): Promise<JwksResponse> {\n if (!this.#fractalEncryptionBaseUrl) {\n throw new Error(\n 'KycService: fractalEncryptionBaseUrl is not configured; cannot fetch JWKS to verify the wrapping key.',\n );\n }\n const url = new URL(UKYC_JWKS_PATH, this.#fractalEncryptionBaseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchJwks`, this.#fractalEncryptionBaseUrl],\n queryFn: async () =>\n this.#requestJson(url, { method: 'GET' }, { authenticated: false }),\n staleTime: inMilliseconds(1, Duration.Hour),\n });\n return this.#validateResponse(data, JwksResponseStruct, 'JWKS');\n }\n\n /**\n * Creates a UKYC session for the SumSub document-verification sub-flow,\n * handing over the wrapped `data_encryption_key` and the client-signed,\n * read-only `ukyc_capability_token` that authorizes later storage access for\n * the session.\n *\n * @param params - The session parameters.\n * @returns The UKYC session identifiers.\n */\n async createUkycSession(\n params: CreateUkycSessionParams,\n ): Promise<UkycSessionResponse> {\n const url = new URL('/sessions', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:createUkycSession`,\n params.wrappedEncryptionKey.sessionId,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n vendorId: params.vendor ?? 'moonpay',\n vendorUserId: 'mockedId',\n jwtToken: params.jwtToken,\n vendorMetadata: params.vendorMetadata ?? {},\n wrappedEncryptionKey: params.wrappedEncryptionKey,\n ukycCapabilityToken: encodeStorageAccessTokenForHeader(\n params.ukycCapabilityToken,\n ),\n }),\n }),\n // A session-creating mutation must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'UKYC sessions',\n );\n }\n\n /**\n * Creates (or refreshes) the SumSub verification journey for a UKYC session,\n * returning the applicant access token used to launch the SDK.\n *\n * @param sessionId - The UKYC session id from `createUkycSession`.\n * @returns The applicant access token and status.\n */\n async createJourney(\n sessionId: string,\n ): Promise<ApplicantAccessTokenResponse> {\n const url = new URL(\n `/sessions/${encodeURIComponent(sessionId)}/journey`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:createJourney`, sessionId],\n queryFn: async () => this.#requestJson(url, { method: 'POST' }),\n // Journeys are (re)created on demand; do not reuse a cached token.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n ApplicantAccessTokenResponseStruct,\n 'journey',\n );\n }\n\n /**\n * Fetches the current status of a UKYC session. Polled after the SumSub SDK\n * completes to determine the final verification decision.\n *\n * @param params - The parameters.\n * @param params.sessionId - The UKYC session id.\n * @returns The session status.\n */\n async getSessionStatus(\n params: GetSessionStatusParams,\n ): Promise<KycSessionStatus> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/status`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:getSessionStatus`, params.sessionId],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n // Status is polled for a terminal decision, so it must always be fresh.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'session status',\n );\n }\n\n /**\n * Validates a parsed API response against a superstruct schema, throwing a\n * descriptive error when the response does not match.\n *\n * Unlike a bare `Struct.is` check, this surfaces exactly which field was\n * missing or had the wrong type, which is essential for diagnosing shape\n * mismatches between the client and the live API.\n *\n * @param data - The parsed response body.\n * @param struct - The superstruct schema the body is expected to satisfy.\n * @param apiName - A human-readable name of the API, used in the error message.\n * @returns The validated, typed response.\n * @throws If `data` does not match `struct`.\n */\n #validateResponse<Type, Schema>(\n data: unknown,\n struct: Struct<Type, Schema>,\n apiName: string,\n ): Type {\n try {\n assert(data, struct);\n return data;\n } catch (error) {\n const detail =\n error instanceof StructError\n ? `${error.message} (received: ${JSON.stringify(data)})`\n : // `assert` only ever throws `StructError` for the plain structs used\n // here, so this is a defensive fallback that is not exercised.\n /* istanbul ignore next */\n String(error);\n throw new Error(\n `Malformed response received from ${apiName} API: ${detail}`,\n );\n }\n }\n\n /**\n * Performs a single JSON request.\n *\n * This is meant to be used as the `queryFn` for {@link fetchQuery}, which\n * wraps it in the shared service policy (retries, circuit breaker). Requests\n * are authenticated with the wallet bearer token by default; pass\n * `{ authenticated: false }` for calls to services that do not expect it\n * (e.g. the Fractal JWKS endpoint).\n *\n * @param url - The request URL.\n * @param init - The request init (method, body).\n * @param options - Request options.\n * @param options.authenticated - Whether to attach the bearer token. Defaults\n * to `true`.\n * @returns The parsed JSON response.\n */\n async #requestJson(\n url: URL,\n init: RequestInit,\n options: { authenticated?: boolean } = {},\n ): Promise<Json> {\n const { authenticated = true } = options;\n\n const headers: Record<string, string> = {};\n\n // Only advertise a JSON body when one is actually sent; bodyless requests\n // (e.g. `createJourney`) must not carry a `Content-Type`.\n if (init.body !== undefined && init.body !== null) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (authenticated) {\n const bearerToken = await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n if (!bearerToken) {\n throw new Error(\n 'Unable to obtain an authentication bearer token — is the wallet signed in?',\n );\n }\n assert(bearerToken, string());\n headers.Authorization = `Bearer ${bearerToken}`;\n }\n\n const response = await this.#fetch(url.toString(), {\n ...init,\n headers,\n });\n if (!response.ok) {\n let detail = '';\n try {\n const errorBody: unknown = await response.json();\n if (errorBody && typeof errorBody === 'object') {\n const record = errorBody as Record<string, unknown>;\n if (typeof record.message === 'string') {\n detail = record.message;\n } else if (typeof record.error === 'string') {\n detail = record.error;\n }\n }\n } catch {\n // Ignore body parse failures; status alone is still useful.\n }\n throw new HttpError(\n response.status,\n `Fetching '${url.toString()}' failed with status '${response.status}'${\n detail ? `: ${detail}` : ''\n }`,\n );\n }\n\n // Consent (and similar) endpoints return 204 No Content.\n if (response.status === 204) {\n return null;\n }\n\n return (await response.json()) as Json;\n }\n}\n"]}
1
+ {"version":3,"file":"KycService.cjs","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseDataService } from '@metamask/base-data-service';\nimport type {\n DataServiceCacheUpdatedEvent,\n DataServiceGranularCacheUpdatedEvent,\n DataServiceInvalidateQueriesAction,\n} from '@metamask/base-data-service';\nimport type { CreateServicePolicyOptions } from '@metamask/controller-utils';\nimport { HttpError } from '@metamask/controller-utils';\nimport type { GeolocationControllerGetGeolocationAction } from '@metamask/geolocation-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationControllerGetBearerTokenAction } from '@metamask/profile-sync-controller/auth';\nimport type { Infer, Struct } from '@metamask/superstruct';\nimport {\n array,\n assert,\n boolean,\n enums,\n optional,\n string,\n StructError,\n type,\n} from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { Duration, inMilliseconds } from '@metamask/utils';\nimport type { QueryClientConfig } from '@tanstack/query-core';\n\nimport { alpha2ToAlpha3 } from './countryCodes.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n KycConsentRecord,\n KycDisclaimer,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycUserStatusResponse,\n KycVendor,\n KycVendorSigning,\n} from './types.js';\nimport { UKYC_JWKS_PATH } from './ukyc/constants.js';\n\n// === GENERAL ===\n\n/**\n * The name of the {@link KycService}, used to namespace the service's actions.\n */\nexport const serviceName = 'KycService';\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'getGeoCountry',\n 'fetchDisclaimers',\n 'createSession',\n 'checkKycRequired',\n 'createVendorCustomer',\n 'submitVendorDisclaimers',\n 'fetchSessionDisclaimers',\n 'submitSessionDisclaimers',\n 'fetchKycStatus',\n 'fetchJwks',\n 'createUkycSession',\n 'setAuthorizations',\n 'createJourney',\n 'getSessionStatus',\n] as const;\n\n/**\n * Invalidates cached queries serviced by {@link KycService}.\n */\nexport type KycServiceInvalidateQueriesAction =\n DataServiceInvalidateQueriesAction<typeof serviceName>;\n\n/**\n * Actions that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceActions =\n | KycServiceMethodActions\n | KycServiceInvalidateQueriesAction;\n\n/**\n * Actions from other messengers that {@link KycService} calls.\n */\ntype AllowedActions =\n | AuthenticationControllerGetBearerTokenAction\n | GeolocationControllerGetGeolocationAction;\n\n/**\n * Published when {@link KycService}'s cache is updated.\n */\nexport type KycServiceCacheUpdatedEvent = DataServiceCacheUpdatedEvent<\n typeof serviceName\n>;\n\n/**\n * Published when a single key within {@link KycService}'s cache is updated.\n */\nexport type KycServiceGranularCacheUpdatedEvent =\n DataServiceGranularCacheUpdatedEvent<typeof serviceName>;\n\n/**\n * Events that {@link KycService} exposes to other consumers.\n */\nexport type KycServiceEvents =\n | KycServiceCacheUpdatedEvent\n | KycServiceGranularCacheUpdatedEvent;\n\n/**\n * Events from other messengers that {@link KycService} subscribes to.\n */\ntype AllowedEvents = never;\n\n/**\n * The messenger restricted to actions and events accessed by\n * {@link KycService}.\n */\nexport type KycServiceMessenger = Messenger<\n typeof serviceName,\n KycServiceActions | AllowedActions,\n KycServiceEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycService}.\n */\nexport type KycServiceOptions = {\n messenger: KycServiceMessenger;\n /**\n * A function used to make HTTP requests. Defaults to the runtime's native\n * `fetch`, so consumers do not need to inject one on platforms where `fetch`\n * is available globally (browser, React Native, Node 18+).\n */\n fetch?: typeof fetch;\n /**\n * Mandatory value that sets the base url to KYC api\n */\n baseUrl: string;\n /**\n * Base URL of the Fractal encryption service, from which the JWKS used to\n * verify encryption-schema `jwtChain`s is fetched.\n */\n fractalEncryptionBaseUrl?: string;\n /**\n * Shared configuration applied to all queries exposed by the service (e.g. a\n * default `staleTime`/`gcTime`). Each data service gets its own\n * `QueryClient`.\n */\n queryClientConfig?: QueryClientConfig;\n policyOptions?: CreateServicePolicyOptions;\n};\n\n// === API RESPONSE SCHEMAS ===\n\nconst DisclaimerStruct = type({\n id: string(),\n display_name: string(),\n url: string(),\n});\nconst DisclaimersResponseStruct = array(DisclaimerStruct);\n\nconst VendorSigningStruct = type({\n id: string(),\n customer_id: string(),\n content_id: optional(string()),\n});\nconst VendorSigningsResponseStruct = array(VendorSigningStruct);\n\nconst CreateSessionResponseStruct = type({ sessionToken: string() });\n\n// The live KYC API returns the flag under `required`; the service normalizes\n// this to `kycRequired` for consumers (see `checkKycRequired`).\nconst KycRequiredResponseStruct = type({ required: boolean() });\n\n// The session server's public key, in JWK-like form, returned inside an\n// encryption schema from `POST /sessions`. `x` is the base64url public key\n// used to wrap a secret for that schema.\nconst ServerPublicKeyStruct = type({\n kty: string(),\n crv: string(),\n x: string(),\n kid: optional(string()),\n alg: optional(string()),\n use: optional(string()),\n});\n\nconst EncryptionSchemaStruct = type({\n serverPublicKey: ServerPublicKeyStruct,\n jwtChain: string(),\n});\nexport type EncryptionSchema = Infer<typeof EncryptionSchemaStruct>;\n\n// A single Ed25519 (OKP) JWK. `type` (not `object`) keeps optional/extra JWK\n// fields (`use`, `alg`) from failing validation.\nconst JwkStruct = type({\n kty: string(),\n crv: string(),\n x: string(),\n kid: string(),\n});\nconst JwksResponseStruct = type({ keys: array(JwkStruct) });\nexport type JwksResponse = Infer<typeof JwksResponseStruct>;\n\nconst UkycSessionResponseStruct = type({\n sessionId: string(),\n // Per-secret wrapping material so the client can seal the\n // `data_encryption_key` and the `ukyc_capability_token` independently.\n encryptionDataKey: EncryptionSchemaStruct,\n ukycCapabilityToken: EncryptionSchemaStruct,\n});\nexport type UkycSessionResponse = Infer<typeof UkycSessionResponseStruct>;\n\nconst ApplicantAccessTokenResponseStruct = type({\n status: string(),\n applicantAccessToken: string(),\n});\nexport type ApplicantAccessTokenResponse = Infer<\n typeof ApplicantAccessTokenResponseStruct\n>;\n\nconst SessionStatusResponseStruct = type({\n finalStatus: string(),\n statusMessage: optional(string()),\n externalUserId: string(),\n kycStatus: string(),\n vendor: string(),\n vendorStatus: string(),\n});\n\n// Vendor customer subset — `type` (not `object`) keeps extra vendor fields from\n// failing validation while still requiring the fields the controller needs.\nconst VendorCustomerResponseStruct = type({\n id: string(),\n email: string(),\n status: string(),\n});\nexport type VendorCustomerResponse = Infer<typeof VendorCustomerResponseStruct>;\n\nconst KYC_USER_STATUSES = [\n 'not-started',\n 'pending',\n 'need-more-information',\n 'terminal-failure',\n 'completed',\n] as const;\n\nconst KycUserStatusResponseStruct = type({\n status: enums([...KYC_USER_STATUSES]),\n sumsubSessionId: optional(string()),\n errorCode: optional(string()),\n});\n\nconst ConsentDocumentStruct = type({\n key: string(),\n version: string(),\n title: string(),\n url: string(),\n consented: boolean(),\n});\n\nconst SessionDisclaimersResponseStruct = type({\n idOS: array(ConsentDocumentStruct),\n kycProvider: array(ConsentDocumentStruct),\n credentialReusabilityConsentGiven: boolean(),\n});\n\n// === PARAM TYPES ===\n\nexport type CreateSessionParams = {\n email: string;\n termsAcceptedAt: string;\n disclaimerIds: string[];\n};\n\nexport type CheckKycRequiredParams = {\n /**\n * Identity vendor to check. Defaults to `moonpay` for the existing\n * Check/Auth path.\n */\n vendor?: KycVendor;\n /**\n * MoonPay access token. Required when `vendor` is `moonpay` (or omitted).\n */\n accessToken?: string;\n /**\n * ISO 3166-1 alpha-3 country code. Required when `vendor` is `moonpay`.\n */\n country?: string;\n capabilities?: { product: string }[];\n};\n\nexport type CreateVendorCustomerParams = {\n vendor: KycVendor;\n email: string;\n};\n\nexport type SubmitVendorDisclaimersParams = {\n /** Identity vendor whose T&Cs were accepted (currently `iron`). */\n vendor: KycVendor;\n /** Disclaimer ids from {@link KycService.fetchDisclaimers}. */\n disclaimerIds: string[];\n};\n\nexport type FetchSessionDisclaimersParams = {\n /** UKYC session id from {@link KycService.createUkycSession}. */\n sessionId: string;\n};\n\nexport type SubmitSessionDisclaimersParams = {\n /** UKYC session id from {@link KycService.createUkycSession}. */\n sessionId: string;\n /** Consents to the idOS legal documents (`key`/`version` from the catalog). */\n idOS: KycConsentRecord[];\n /**\n * Consents to the KYC provider (SumSub) legal documents (`key`/`version`\n * from the catalog).\n */\n kycProvider: KycConsentRecord[];\n /** Consent to reuse the user's existing idOS credentials. */\n credentialReusabilityConsentGiven: boolean;\n};\n\nexport type CreateUkycSessionParams = {\n jwtToken: string;\n /**\n * Identity vendor for the UKYC session. Defaults to `moonpay` for the\n * existing Check/Auth flow. Pass a non-MoonPay vendor (e.g. `iron`) for\n * the consents path (no MoonPay metadata required).\n */\n vendor?: KycVendor;\n /**\n * Vendor-specific metadata. Required for MoonPay (`moonPayAccessToken` /\n * `moonPayUserId`); optional / omitted for other vendors.\n */\n vendorMetadata?: Record<string, unknown>;\n};\n\n/**\n * Encrypted capability authorization payload (base64url nonce + ciphertext)\n * accepted by `POST /sessions/:sessionId/authorizations`. Produced by\n * `wrapEncryptionKey` for both the `data_encryption_key` and the\n * `ukyc_capability_token`.\n */\nexport type CapabilityAuthorization = {\n nonce: string;\n data: string;\n};\n\nexport type SetAuthorizationsParams = {\n sessionId: string;\n wrappedEncryptionDataKey: CapabilityAuthorization;\n wrappedUkycCapabilityToken: CapabilityAuthorization;\n};\n\nexport type GetSessionStatusParams = {\n sessionId: string;\n};\n\n// === SERVICE DEFINITION ===\n\n/**\n * `KycService` communicates with the Universal KYC (UKYC) backend to drive the\n * identity + document-verification flow. It is stateless and platform-agnostic:\n * HTTP is performed through the runtime's native `fetch` (or an injected\n * `fetch` when provided), and the auth bearer token and geolocation come from\n * other controllers via the messenger.\n *\n * It extends {@link BaseDataService}, so every request is routed through\n * `fetchQuery`: it is wrapped in the shared service policy (retries, circuit\n * breaker) and its result is exposed via the service's `QueryClient`. Read-only\n * endpoints (`fetchDisclaimers`, `fetchJwks`) are cached with a `staleTime`;\n * vendor-disclaimer, session-scoped disclaimer, session-creating, and\n * status-polling endpoints opt out of caching (`staleTime`/`gcTime` of `0`)\n * so they never serve a stale result.\n */\nexport class KycService extends BaseDataService<\n typeof serviceName,\n KycServiceMessenger\n> {\n readonly #fetch: typeof fetch;\n\n readonly #baseUrl: string;\n\n readonly #fractalEncryptionBaseUrl: string;\n\n /**\n * Constructs a new KycService.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this service.\n * @param options.fetch - A function used to make HTTP requests. Defaults to\n * the runtime's native `fetch`.\n * @param options.baseUrl - Base URL of the KYC API\n * @param options.fractalEncryptionBaseUrl - Base URL of the Fractal\n * encryption service, from which the JWKS used to verify encryption-schema\n * `jwtChain`s is fetched.\n * @param options.queryClientConfig - Shared configuration for all queries\n * exposed by the service.\n * @param options.policyOptions - Options for the request service policy.\n */\n constructor({\n messenger,\n fetch: fetchFunction,\n baseUrl,\n fractalEncryptionBaseUrl,\n queryClientConfig = {},\n policyOptions = {},\n }: KycServiceOptions) {\n super({\n name: serviceName,\n messenger,\n queryClientConfig,\n policyOptions,\n });\n // Fall back to the runtime's native `fetch`, bound to `globalThis` so it\n // can be invoked as a method of this instance without an illegal-invocation\n // error on platforms that check the receiver.\n if (fetchFunction) {\n this.#fetch = fetchFunction;\n } else if (typeof globalThis.fetch === 'function') {\n this.#fetch = globalThis.fetch.bind(globalThis);\n } else {\n throw new Error(\n 'KycService: fetch is not available globally and was not provided in options. Please inject a fetch implementation.',\n );\n }\n if (!baseUrl) {\n throw new Error('KycService: baseUrl is required');\n }\n this.#baseUrl = baseUrl;\n this.#fractalEncryptionBaseUrl = fractalEncryptionBaseUrl ?? '';\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Resolves the customer's country from the geolocation source and converts it\n * to an ISO 3166-1 alpha-3 code.\n *\n * @returns The alpha-3 country code.\n * @throws If the country cannot be determined or mapped.\n */\n async getGeoCountry(): Promise<string> {\n const location = await this.messenger.call(\n 'GeolocationController:getGeolocation',\n );\n // Guard nullish/empty geolocation with the documented domain error rather\n // than letting `assert(location, string())` surface a superstruct\n // assertion error (which would change how the failure reads in\n // `disclaimersError`).\n const alpha2 =\n typeof location === 'string' ? location.split('-')[0].toUpperCase() : '';\n if (!alpha2 || alpha2 === 'UNKNOWN') {\n throw new Error(\n `Unable to determine country from geolocation (got \"${String(\n location,\n )}\").`,\n );\n }\n const alpha3 = alpha2ToAlpha3(alpha2);\n if (!alpha3) {\n throw new Error(\n `Unable to map country code \"${alpha2}\" to an ISO 3166-1 alpha-3 code.`,\n );\n }\n return alpha3;\n }\n\n /**\n * Fetches the disclaimers the customer must accept before a session is\n * created.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\n async fetchDisclaimers({\n vendor = 'moonpay',\n country,\n }: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n const url = new URL(`/vendors/${vendor}/disclaimers`, this.#baseUrl);\n url.searchParams.set('country', country);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchDisclaimers`, vendor, country],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n staleTime: inMilliseconds(5, Duration.Minute),\n });\n return this.#validateResponse(\n data,\n DisclaimersResponseStruct,\n 'disclaimers',\n ) as KycDisclaimer[];\n }\n\n /**\n * Creates a vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\n async createSession(\n params: CreateSessionParams,\n ): Promise<Infer<typeof CreateSessionResponseStruct>> {\n const url = new URL('/vendors/moonpay/sessions', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:createSession`,\n params.email,\n params.termsAcceptedAt,\n params.disclaimerIds,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(params),\n }),\n // A session-creating mutation must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n CreateSessionResponseStruct,\n 'sessions',\n );\n }\n\n /**\n * Checks whether KYC is required for the given vendor, country, and\n * capabilities.\n *\n * @param params - The check parameters.\n * @returns Whether KYC is required.\n */\n async checkKycRequired(\n params: CheckKycRequiredParams,\n ): Promise<{ kycRequired: boolean }> {\n const vendor = params.vendor ?? 'moonpay';\n const url = new URL(`/vendors/${vendor}/kyc-required`, this.#baseUrl);\n const capabilities = params.capabilities ?? [{ product: 'ramps' }];\n const body =\n vendor === 'moonpay'\n ? {\n accessToken: params.accessToken,\n country: params.country,\n capabilities,\n }\n : {};\n\n // MoonPay requires accessToken and country; validate before making the request.\n if (vendor === 'moonpay') {\n if (!params.accessToken) {\n throw new Error(\n 'checkKycRequired: accessToken is required for vendor \"moonpay\".',\n );\n }\n if (!params.country) {\n throw new Error(\n 'checkKycRequired: country is required for vendor \"moonpay\".',\n );\n }\n }\n\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:checkKycRequired`,\n vendor,\n params.accessToken ?? null,\n params.country ?? null,\n capabilities,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(body),\n }),\n // The requirement can change server-side, so always re-check.\n staleTime: 0,\n gcTime: 0,\n });\n const { required } = this.#validateResponse(\n data,\n KycRequiredResponseStruct,\n 'kyc-required',\n );\n return { kycRequired: required };\n }\n\n /**\n * Creates (or resumes) an empty-shell customer for the authenticated\n * canonical user on the given identity vendor. Must run before showing\n * vendor T&C so the customer exists and resume logic can key off vendor\n * status.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor (e.g. `iron` for Money/VBA).\n * @param params.email - Email associated with the customer.\n * @returns The vendor customer record (subset validated for controller use).\n */\n async createVendorCustomer(\n params: CreateVendorCustomerParams,\n ): Promise<VendorCustomerResponse> {\n const url = new URL(`/vendors/${params.vendor}/customers`, this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:createVendorCustomer`,\n params.vendor,\n params.email,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({ email: params.email }),\n }),\n // Customer creation/resume must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n VendorCustomerResponseStruct,\n 'vendor customers',\n );\n }\n\n /**\n * Records vendor T&C acceptance (`POST /vendors/{vendor}/disclaimers`).\n * For Iron this creates content signings from the disclaimer ids the\n * customer accepted. Session-scoped idOS / KYC-provider consents are\n * recorded separately via {@link submitSessionDisclaimers}. Retries re-POST\n * the same ids, matching the legacy `POST /consents` signing step.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor (e.g. `iron`).\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n */\n async submitVendorDisclaimers(\n params: SubmitVendorDisclaimersParams,\n ): Promise<KycVendorSigning[]> {\n const url = new URL(\n `/vendors/${encodeURIComponent(params.vendor)}/disclaimers`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:submitVendorDisclaimers`,\n params.vendor,\n params.disclaimerIds,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({ disclaimerIds: params.disclaimerIds }),\n }),\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n VendorSigningsResponseStruct,\n 'vendor disclaimers',\n );\n }\n\n /**\n * Fetches the session-scoped idOS + KYC-provider disclaimer catalog\n * (`GET /sessions/{sessionId}/disclaimers`). Requires an existing UKYC\n * session; vendor T&Cs continue to come from {@link fetchDisclaimers}.\n *\n * @param params - The parameters.\n * @param params.sessionId - The UKYC session id.\n * @returns The catalog, including which documents are already consented.\n */\n async fetchSessionDisclaimers(\n params: FetchSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/disclaimers`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchSessionDisclaimers`, params.sessionId],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n // Consent state can change after a POST, so always re-fetch.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n SessionDisclaimersResponseStruct,\n 'session disclaimers',\n );\n }\n\n /**\n * Records idOS + KYC-provider consents for a UKYC session\n * (`POST /sessions/{sessionId}/disclaimers`). `key`/`version` pairs must\n * match the current catalog from {@link fetchSessionDisclaimers}. A 409\n * means those document versions were already recorded for the session.\n *\n * @param params - The consent parameters.\n * @returns The updated catalog after recording.\n */\n async submitSessionDisclaimers(\n params: SubmitSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/disclaimers`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [\n `${this.name}:submitSessionDisclaimers`,\n params.sessionId,\n params.idOS,\n params.kycProvider,\n params.credentialReusabilityConsentGiven,\n ],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n idOS: params.idOS,\n kycProvider: params.kycProvider,\n credentialReusabilityConsentGiven:\n params.credentialReusabilityConsentGiven,\n }),\n }),\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n SessionDisclaimersResponseStruct,\n 'session disclaimers',\n );\n }\n\n /**\n * Fetches the user-keyed simplified KYC status used by Money toast / banner\n * surfaces (`GET /kyc/status`).\n *\n * @returns The simplified status payload.\n */\n async fetchKycStatus(): Promise<KycUserStatusResponse> {\n const url = new URL('/kyc/status', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchKycStatus`],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n // Status is polled for toast flips, so it must always be fresh.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n KycUserStatusResponseStruct,\n 'kyc status',\n );\n }\n\n /**\n * Fetches the Fractal encryption service JWKS used to verify the `jwtChain`s\n * returned inside encryption schemas from {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the Fractal\n * host, distinct from the UKYC base URL.\n *\n * @returns The JWKS keys.\n */\n async fetchJwks(): Promise<JwksResponse> {\n if (!this.#fractalEncryptionBaseUrl) {\n throw new Error(\n 'KycService: fractalEncryptionBaseUrl is not configured; cannot fetch JWKS to verify encryption schemas.',\n );\n }\n const url = new URL(UKYC_JWKS_PATH, this.#fractalEncryptionBaseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:fetchJwks`, this.#fractalEncryptionBaseUrl],\n queryFn: async () =>\n this.#requestJson(url, { method: 'GET' }, { authenticated: false }),\n staleTime: inMilliseconds(1, Duration.Hour),\n });\n return this.#validateResponse(data, JwksResponseStruct, 'JWKS');\n }\n\n /**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * The response carries per-secret encryption schemas (`encryptionDataKey` and\n * `ukycCapabilityToken`) so the client can wrap the `data_encryption_key` and\n * the read-only `ukyc_capability_token` and submit them via\n * {@link KycService.setAuthorizations}.\n *\n * @param params - The session parameters.\n * @returns The UKYC session id and encryption schemas.\n */\n async createUkycSession(\n params: CreateUkycSessionParams,\n ): Promise<UkycSessionResponse> {\n const url = new URL('/sessions', this.#baseUrl);\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:createUkycSession`, params.jwtToken],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n vendorId: params.vendor ?? 'moonpay',\n vendorUserId: 'mockedId',\n jwtToken: params.jwtToken,\n vendorMetadata: params.vendorMetadata ?? {},\n }),\n }),\n // A session-creating mutation must never serve a stale/cached result.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'UKYC sessions',\n );\n }\n\n /**\n * Submits the wrapped `data_encryption_key` and wrapped\n * `ukyc_capability_token` for a UKYC session. Both secrets are sealed with\n * `wrapEncryptionKey` against the encryption schemas returned by\n * {@link KycService.createUkycSession}.\n *\n * @param params - The wrapped authorizations.\n * @returns The session status after the authorizations are applied.\n */\n async setAuthorizations(\n params: SetAuthorizationsParams,\n ): Promise<KycSessionStatus> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/authorizations`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:setAuthorizations`, params.sessionId],\n queryFn: async () =>\n this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n wrappedEncryptionDataKey: params.wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken: params.wrappedUkycCapabilityToken,\n }),\n }),\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'authorizations',\n );\n }\n\n /**\n * Creates (or refreshes) the SumSub verification journey for a UKYC session,\n * returning the applicant access token used to launch the SDK.\n *\n * @param sessionId - The UKYC session id from `createUkycSession`.\n * @returns The applicant access token and status.\n */\n async createJourney(\n sessionId: string,\n ): Promise<ApplicantAccessTokenResponse> {\n const url = new URL(\n `/sessions/${encodeURIComponent(sessionId)}/journey`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:createJourney`, sessionId],\n queryFn: async () => this.#requestJson(url, { method: 'POST' }),\n // Journeys are (re)created on demand; do not reuse a cached token.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n ApplicantAccessTokenResponseStruct,\n 'journey',\n );\n }\n\n /**\n * Fetches the current status of a UKYC session. Polled after the SumSub SDK\n * completes to determine the final verification decision.\n *\n * @param params - The parameters.\n * @param params.sessionId - The UKYC session id.\n * @returns The session status.\n */\n async getSessionStatus(\n params: GetSessionStatusParams,\n ): Promise<KycSessionStatus> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/status`,\n this.#baseUrl,\n );\n const data = await this.fetchQuery({\n queryKey: [`${this.name}:getSessionStatus`, params.sessionId],\n queryFn: async () => this.#requestJson(url, { method: 'GET' }),\n // Status is polled for a terminal decision, so it must always be fresh.\n staleTime: 0,\n gcTime: 0,\n });\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'session status',\n );\n }\n\n /**\n * Validates a parsed API response against a superstruct schema, throwing a\n * descriptive error when the response does not match.\n *\n * Unlike a bare `Struct.is` check, this surfaces exactly which field was\n * missing or had the wrong type, which is essential for diagnosing shape\n * mismatches between the client and the live API.\n *\n * @param data - The parsed response body.\n * @param struct - The superstruct schema the body is expected to satisfy.\n * @param apiName - A human-readable name of the API, used in the error message.\n * @returns The validated, typed response.\n * @throws If `data` does not match `struct`.\n */\n #validateResponse<Type, Schema>(\n data: unknown,\n struct: Struct<Type, Schema>,\n apiName: string,\n ): Type {\n try {\n assert(data, struct);\n return data;\n } catch (error) {\n const detail =\n error instanceof StructError\n ? `${error.message} (received: ${JSON.stringify(data)})`\n : // `assert` only ever throws `StructError` for the plain structs used\n // here, so this is a defensive fallback that is not exercised.\n /* istanbul ignore next */\n String(error);\n throw new Error(\n `Malformed response received from ${apiName} API: ${detail}`,\n );\n }\n }\n\n /**\n * Performs a single JSON request.\n *\n * This is meant to be used as the `queryFn` for {@link fetchQuery}, which\n * wraps it in the shared service policy (retries, circuit breaker). Requests\n * are authenticated with the wallet bearer token by default; pass\n * `{ authenticated: false }` for calls to services that do not expect it\n * (e.g. the Fractal JWKS endpoint).\n *\n * @param url - The request URL.\n * @param init - The request init (method, body).\n * @param options - Request options.\n * @param options.authenticated - Whether to attach the bearer token. Defaults\n * to `true`.\n * @returns The parsed JSON response.\n */\n async #requestJson(\n url: URL,\n init: RequestInit,\n options: { authenticated?: boolean } = {},\n ): Promise<Json> {\n const { authenticated = true } = options;\n\n const headers: Record<string, string> = {};\n\n // Only advertise a JSON body when one is actually sent; bodyless requests\n // (e.g. `createJourney`) must not carry a `Content-Type`.\n if (init.body !== undefined && init.body !== null) {\n headers['Content-Type'] = 'application/json';\n }\n\n if (authenticated) {\n const bearerToken = await this.messenger.call(\n 'AuthenticationController:getBearerToken',\n );\n if (!bearerToken) {\n throw new Error(\n 'Unable to obtain an authentication bearer token — is the wallet signed in?',\n );\n }\n assert(bearerToken, string());\n headers.Authorization = `Bearer ${bearerToken}`;\n }\n\n const response = await this.#fetch(url.toString(), {\n ...init,\n headers,\n });\n if (!response.ok) {\n let detail = '';\n try {\n const errorBody: unknown = await response.json();\n if (errorBody && typeof errorBody === 'object') {\n const record = errorBody as Record<string, unknown>;\n if (typeof record.message === 'string') {\n detail = record.message;\n } else if (typeof record.error === 'string') {\n detail = record.error;\n }\n }\n } catch {\n // Ignore body parse failures; status alone is still useful.\n }\n throw new HttpError(\n response.status,\n `Fetching '${url.toString()}' failed with status '${response.status}'${\n detail ? `: ${detail}` : ''\n }`,\n );\n }\n\n // DELETE (and similar) endpoints return 204 No Content.\n if (response.status === 204) {\n return null;\n }\n\n return (await response.json()) as Json;\n }\n}\n"]}