@metamask-previews/kyc-controller 0.10.0-preview-aeb52ce4f → 0.11.0-preview-a583980c5

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.
package/CHANGELOG.md CHANGED
@@ -7,10 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - Add optional `partnerIdentityToken` to `CreateUkycSessionParams`; `KycService.createUkycSession` sends it on `POST /sessions` when provided ([#10872](https://github.com/MetaMask/core/pull/10872))
13
+ - `KycController.startSession` now forwards the partner identity token minted for the selected vendor when creating a UKYC session
14
+
15
+ ### Changed
16
+
17
+ - Cache successful `KycService.fetchIdosEnclaveJwks` and `KycService.fetchIdosRelayJwks` responses in the service query cache for 24 hours ([#10894](https://github.com/MetaMask/core/pull/10894))
18
+ - `KycService:invalidateQueries` drops the cached keys
19
+ - Session creation and capability-authorization refresh throw a short, displayable error when fetching issuer signing keys fails or an encryption schema's `jwtChain` does not verify. The original error is preserved on `cause` ([#10834](https://github.com/MetaMask/core/pull/10834))
20
+
21
+ ## [0.11.0]
22
+
10
23
  ### Changed
11
24
 
12
25
  - Bump `@metamask/base-controller` from `^10.0.0` to `^10.1.0` ([#10864](https://github.com/MetaMask/core/pull/10864))
13
- - Bump `@metamask/profile-sync-controller` from `^34.0.3` to `^34.1.0` ([#10905](https://github.com/MetaMask/core/pull/10905))
26
+ - Bump `@metamask/profile-sync-controller` from `^34.0.3` to `^35.0.0` ([#10905](https://github.com/MetaMask/core/pull/10905), [#10925](https://github.com/MetaMask/core/pull/10925))
14
27
 
15
28
  ### Removed
16
29
 
@@ -178,7 +191,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
178
191
 
179
192
  - Initial Release ([#10145](https://github.com/MetaMask/core/pull/10145))
180
193
 
181
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.10.0...HEAD
194
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.11.0...HEAD
195
+ [0.11.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.10.0...@metamask/kyc-controller@0.11.0
182
196
  [0.10.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.9.0...@metamask/kyc-controller@0.10.0
183
197
  [0.9.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.8.0...@metamask/kyc-controller@0.9.0
184
198
  [0.8.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.7.0...@metamask/kyc-controller@0.8.0
@@ -9,8 +9,8 @@ import type { KycController } from './KycController.js';
9
9
  *
10
10
  * The verified email stored on controller state comes from the partner
11
11
  * identity token. When that request returns HTTP 422, a stored email is
12
- * kept for an existing session. Creating a vendor customer requires the
13
- * token and sends it as `partnerIdentityToken`.
12
+ * kept for an existing session. Creating a vendor customer and UKYC session
13
+ * requires the token, which both requests send as `partnerIdentityToken`.
14
14
  *
15
15
  * @param params - The session parameters.
16
16
  * @param params.vendor - Identity vendor for the session.
@@ -1 +1 @@
1
- {"version":3,"file":"KycController-method-action-types.js","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycController } from './KycController.js';\n\n/**\n * Starts a KYC session for the given vendor. Reuses a latest vendor session\n * when one exists; otherwise creates a UKYC session.\n *\n * The verified email stored on controller state comes from the partner\n * identity token. When that request returns HTTP 422, a stored email is\n * kept for an existing session. Creating a vendor customer requires the\n * token and sends it as `partnerIdentityToken`.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\nexport type KycControllerGetProviderFlowStatusAction = {\n type: `KycController:getProviderFlowStatus`;\n handler: KycController['getProviderFlowStatus'];\n};\n\n/**\n * Returns the session already stored on state.\n *\n * Starts session-status polling when `finalStatus` is not `approved`,\n * `rejected`, or `retry`. Does not fetch status or refresh capability\n * authorization.\n *\n * @returns The session status stored at call time.\n * @throws If there is no session on state.\n */\nexport type KycControllerRefreshSessionStatusAction = {\n type: `KycController:refreshSessionStatus`;\n handler: KycController['refreshSessionStatus'];\n};\n\n/**\n * Returns the persisted session status.\n *\n * Does not call the network and does not start session-status polling.\n *\n * @returns The session on state, or `null` when none is stored.\n */\nexport type KycControllerReadSessionStatusAction = {\n type: `KycController:readSessionStatus`;\n handler: KycController['readSessionStatus'];\n};\n\n/**\n * Fetches `GET /sessions/{id}/status` once and writes the result onto state.\n *\n * Does not start the session-status polling timer.\n *\n * @param sessionId - UKYC session id.\n * @returns The fetched session status.\n */\nexport type KycControllerFetchSessionStatusOnceAction = {\n type: `KycController:fetchSessionStatusOnce`;\n handler: KycController['fetchSessionStatusOnce'];\n};\n\n/**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The first poll runs\n * immediately. Each later wait starts at 10 seconds and grows by 10 seconds\n * after every poll, including a failed one. Starting the loop again resets\n * that delay. The loop stops once `finalStatus` is `approved`, `rejected`,\n * or `retry`, or when {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\nexport type KycControllerStartSessionStatusPollingAction = {\n type: `KycController:startSessionStatusPolling`;\n handler: KycController['startSessionStatusPolling'];\n};\n\n/**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\nexport type KycControllerFetchSessionDisclaimersAction = {\n type: `KycController:fetchSessionDisclaimers`;\n handler: KycController['fetchSessionDisclaimers'];\n};\n\n/**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\nexport type KycControllerRecordSessionDisclaimersAction = {\n type: `KycController:recordSessionDisclaimers`;\n handler: KycController['recordSessionDisclaimers'];\n};\n\n/**\n * Fetches the current session status and reports whether consent was given.\n *\n * @returns Whether `consentStatus` is `given`.\n * @throws If there is no session on state.\n */\nexport type KycControllerHasCompletedSessionDisclaimersAction = {\n type: `KycController:hasCompletedSessionDisclaimers`;\n handler: KycController['hasCompletedSessionDisclaimers'];\n};\n\n/**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\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 */\nexport type KycControllerFetchVendorDisclaimersAction = {\n type: `KycController:fetchVendorDisclaimers`;\n handler: KycController['fetchVendorDisclaimers'];\n};\n\n/**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\nexport type KycControllerRecordVendorDisclaimersAction = {\n type: `KycController:recordVendorDisclaimers`;\n handler: KycController['recordVendorDisclaimers'];\n};\n\n/**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\nexport type KycControllerHasCompletedVendorDisclaimersAction = {\n type: `KycController:hasCompletedVendorDisclaimers`;\n handler: KycController['hasCompletedVendorDisclaimers'];\n};\n\n/**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\nexport type KycControllerLaunchProviderFlowAction = {\n type: `KycController:launchProviderFlow`;\n handler: KycController['launchProviderFlow'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerStartSessionAction\n | KycControllerResetAction\n | KycControllerClearStateAction\n | KycControllerGetSessionStatusForVendorAction\n | KycControllerGetProviderFlowStatusAction\n | KycControllerRefreshSessionStatusAction\n | KycControllerReadSessionStatusAction\n | KycControllerFetchSessionStatusOnceAction\n | KycControllerStartSessionStatusPollingAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerRecordSessionDisclaimersAction\n | KycControllerHasCompletedSessionDisclaimersAction\n | KycControllerFetchVendorDisclaimersAction\n | KycControllerRecordVendorDisclaimersAction\n | KycControllerHasCompletedVendorDisclaimersAction\n | KycControllerLaunchProviderFlowAction;\n"]}
1
+ {"version":3,"file":"KycController-method-action-types.js","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycController } from './KycController.js';\n\n/**\n * Starts a KYC session for the given vendor. Reuses a latest vendor session\n * when one exists; otherwise creates a UKYC session.\n *\n * The verified email stored on controller state comes from the partner\n * identity token. When that request returns HTTP 422, a stored email is\n * kept for an existing session. Creating a vendor customer and UKYC session\n * requires the token, which both requests send as `partnerIdentityToken`.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\nexport type KycControllerGetProviderFlowStatusAction = {\n type: `KycController:getProviderFlowStatus`;\n handler: KycController['getProviderFlowStatus'];\n};\n\n/**\n * Returns the session already stored on state.\n *\n * Starts session-status polling when `finalStatus` is not `approved`,\n * `rejected`, or `retry`. Does not fetch status or refresh capability\n * authorization.\n *\n * @returns The session status stored at call time.\n * @throws If there is no session on state.\n */\nexport type KycControllerRefreshSessionStatusAction = {\n type: `KycController:refreshSessionStatus`;\n handler: KycController['refreshSessionStatus'];\n};\n\n/**\n * Returns the persisted session status.\n *\n * Does not call the network and does not start session-status polling.\n *\n * @returns The session on state, or `null` when none is stored.\n */\nexport type KycControllerReadSessionStatusAction = {\n type: `KycController:readSessionStatus`;\n handler: KycController['readSessionStatus'];\n};\n\n/**\n * Fetches `GET /sessions/{id}/status` once and writes the result onto state.\n *\n * Does not start the session-status polling timer.\n *\n * @param sessionId - UKYC session id.\n * @returns The fetched session status.\n */\nexport type KycControllerFetchSessionStatusOnceAction = {\n type: `KycController:fetchSessionStatusOnce`;\n handler: KycController['fetchSessionStatusOnce'];\n};\n\n/**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The first poll runs\n * immediately. Each later wait starts at 10 seconds and grows by 10 seconds\n * after every poll, including a failed one. Starting the loop again resets\n * that delay. The loop stops once `finalStatus` is `approved`, `rejected`,\n * or `retry`, or when {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\nexport type KycControllerStartSessionStatusPollingAction = {\n type: `KycController:startSessionStatusPolling`;\n handler: KycController['startSessionStatusPolling'];\n};\n\n/**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\nexport type KycControllerFetchSessionDisclaimersAction = {\n type: `KycController:fetchSessionDisclaimers`;\n handler: KycController['fetchSessionDisclaimers'];\n};\n\n/**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\nexport type KycControllerRecordSessionDisclaimersAction = {\n type: `KycController:recordSessionDisclaimers`;\n handler: KycController['recordSessionDisclaimers'];\n};\n\n/**\n * Fetches the current session status and reports whether consent was given.\n *\n * @returns Whether `consentStatus` is `given`.\n * @throws If there is no session on state.\n */\nexport type KycControllerHasCompletedSessionDisclaimersAction = {\n type: `KycController:hasCompletedSessionDisclaimers`;\n handler: KycController['hasCompletedSessionDisclaimers'];\n};\n\n/**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\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 */\nexport type KycControllerFetchVendorDisclaimersAction = {\n type: `KycController:fetchVendorDisclaimers`;\n handler: KycController['fetchVendorDisclaimers'];\n};\n\n/**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\nexport type KycControllerRecordVendorDisclaimersAction = {\n type: `KycController:recordVendorDisclaimers`;\n handler: KycController['recordVendorDisclaimers'];\n};\n\n/**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\nexport type KycControllerHasCompletedVendorDisclaimersAction = {\n type: `KycController:hasCompletedVendorDisclaimers`;\n handler: KycController['hasCompletedVendorDisclaimers'];\n};\n\n/**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\nexport type KycControllerLaunchProviderFlowAction = {\n type: `KycController:launchProviderFlow`;\n handler: KycController['launchProviderFlow'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerStartSessionAction\n | KycControllerResetAction\n | KycControllerClearStateAction\n | KycControllerGetSessionStatusForVendorAction\n | KycControllerGetProviderFlowStatusAction\n | KycControllerRefreshSessionStatusAction\n | KycControllerReadSessionStatusAction\n | KycControllerFetchSessionStatusOnceAction\n | KycControllerStartSessionStatusPollingAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerRecordSessionDisclaimersAction\n | KycControllerHasCompletedSessionDisclaimersAction\n | KycControllerFetchVendorDisclaimersAction\n | KycControllerRecordVendorDisclaimersAction\n | KycControllerHasCompletedVendorDisclaimersAction\n | KycControllerLaunchProviderFlowAction;\n"]}
@@ -133,8 +133,8 @@ export declare class KycController extends BaseController<typeof controllerName,
133
133
  *
134
134
  * The verified email stored on controller state comes from the partner
135
135
  * identity token. When that request returns HTTP 422, a stored email is
136
- * kept for an existing session. Creating a vendor customer requires the
137
- * token and sends it as `partnerIdentityToken`.
136
+ * kept for an existing session. Creating a vendor customer and UKYC session
137
+ * requires the token, which both requests send as `partnerIdentityToken`.
138
138
  *
139
139
  * @param params - The session parameters.
140
140
  * @param params.vendor - Identity vendor for the session.
@@ -1 +1 @@
1
- {"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8DAA8D,EAE/D,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,qDAAqD,EAAE,MAAM,wCAAwC,CAAC;AACpH,OAAO,KAAK,EACV,4CAA4C,EAC5C,4CAA4C,EAC7C,MAAM,gDAAgD,CAAC;AAKxD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAanF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM/D,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,SAAS,EACT,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAoBpB,eAAO,MAAM,cAAc,kBAAkB,CAAC;AAE9C,eAAO,MAAM,0BAA0B,YACrC,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,CACA,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAchF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,oEAAoE;IACpE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IAEzB,gDAAgD;IAChD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAE1B,wEAAwE;IACxE,aAAa,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAEvC,oEAAoE;IACpE,kBAAkB,EAAE,qBAAqB,CAAC;IAG1C;;;;OAIG;IACH,yBAAyB,EAAE,4BAA4B,CAAC;IACxD;;;;;;OAMG;IACH,2BAA2B,EAAE,8BAA8B,CAAC;IAC5D;;;;;OAKG;IACH,uBAAuB,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACnD;;;;;OAKG;IACH,iCAAiC,EAAE,OAAO,GAAG,IAAI,CAAC;CACnD,CAAC;AA2DF;;;;GAIG;AACH,wBAAgB,sCAAsC,IAAI,4BAA4B,CAErF;AAED;;;;GAIG;AACH,wBAAgB,wCAAwC,IAAI,8BAA8B,CAEzF;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,kBAAkB,CAYjE;AAED;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GACrC;IACE,2DAA2D;IAC3D,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,GACD;IACE,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,CAAC;AAuBN,MAAM,MAAM,2BAA2B,GAAG,wBAAwB,CAChE,OAAO,cAAc,EACrB,kBAAkB,CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,2BAA2B,GAC3B,0BAA0B,CAAC;AAE/B,KAAK,cAAc,GACf,uBAAuB,GACvB,4CAA4C,GAC5C,4CAA4C,GAC5C,qDAAqD,GACrD,8DAA8D,CAAC;AAEnE,MAAM,MAAM,6BAA6B,GAAG,0BAA0B,CACpE,OAAO,cAAc,EACrB,kBAAkB,CACnB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,6BAA6B,CAAC;AAEhE,KAAK,aAAa,GAAG,KAAK,CAAC;AAE3B,MAAM,MAAM,sBAAsB,GAAG,SAAS,CAC5C,OAAO,cAAc,EACrB,oBAAoB,GAAG,cAAc,EACrC,mBAAmB,GAAG,aAAa,CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,sBAAsB,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACpC;;;OAGG;IACH,cAAc,EAAE,iBAAiB,CAAC;CACnC,CAAC;AAIF;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,cAAc,CAC/C,OAAO,cAAc,EACrB,kBAAkB,EAClB,sBAAsB,CACvB;;IAcC;;;;;;;OAOG;IACH,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,oBAAoB,EAerE;IAuCD;;;;;;;;;;;;;;;OAeG;IACG,YAAY,CAAC,MAAM,EAAE;QACzB,MAAM,EAAE,SAAS,CAAC;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsF5B;IAED;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3B;IAED;;OAEG;IACH,UAAU,IAAI,IAAI,CAejB;IAED;;;;;OAKG;IACH,yBAAyB,CACvB,MAAM,EAAE,SAAS,GAChB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAElC;IAED;;;;OAIG;IACH,qBAAqB,IAAI,qBAAqB,CAE7C;IAGD;;;;;;;;;OASG;IACH,oBAAoB,IAAI,gBAAgB,CAUvC;IAED;;;;;;OAMG;IACH,iBAAiB,IAAI,gBAAgB,GAAG,IAAI,CAE3C;IAED;;;;;;;OAOG;IACG,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CASzE;IAED;;;;;;;;;;OAUG;IACH,yBAAyB,IAAI,IAAI,CA2BhC;IAgOD;;;;;;;;;;;;;;;;;OAiBG;IACG,uBAAuB,CAC3B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,qBAAqB,GAAG,qBAAqB,CAAC,CA6BxD;IAED;;;;;;;;;;;OAWG;IACG,wBAAwB,CAAC,MAAM,EAAE;QACrC,2BAA2B,EAAE,gBAAgB,EAAE,CAAC;QAChD,uBAAuB,EAAE,gBAAgB,EAAE,CAAC;QAC5C,iCAAiC,EAAE,OAAO,CAAC;KAC5C,GAAG,OAAO,CAAC,IAAI,CAAC,CAuChB;IAED;;;;;OAKG;IACG,8BAA8B,IAAI,OAAO,CAAC,OAAO,CAAC,CAcvD;IAED;;;;;;;;OAQG;IACG,sBAAsB,CAAC,MAAM,EAAE;QACnC,MAAM,CAAC,EAAE,SAAS,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAE3B;IAED;;;;;;;;OAQG;IACG,uBAAuB,CAAC,MAAM,EAAE;QACpC,aAAa,EAAE,MAAM,EAAE,CAAC;KACzB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA+B9B;IAED;;;;;;OAMG;IACG,6BAA6B,IAAI,OAAO,CAAC,OAAO,CAAC,CAmBtD;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,EACjB,MAAM,EACN,KAAK,GACN,EAAE;QACD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAGjC;CAuMF"}
@@ -1,5 +1,5 @@
1
1
  import { BaseController } from '@metamask/base-controller';
2
- import { stringToBytes } from '@metamask/utils';
2
+ import { stringToBytes, wrapError } from '@metamask/utils';
3
3
  import { x25519 } from '@noble/curves/ed25519';
4
4
  import { toBase64Url } from './encoding.js';
5
5
  import { getEmailFromPartnerIdentityToken, isEmailRequiredError, } from './partnerIdentityToken.js';
@@ -207,8 +207,8 @@ export class KycController extends BaseController {
207
207
  *
208
208
  * The verified email stored on controller state comes from the partner
209
209
  * identity token. When that request returns HTTP 422, a stored email is
210
- * kept for an existing session. Creating a vendor customer requires the
211
- * token and sends it as `partnerIdentityToken`.
210
+ * kept for an existing session. Creating a vendor customer and UKYC session
211
+ * requires the token, which both requests send as `partnerIdentityToken`.
212
212
  *
213
213
  * @param params - The session parameters.
214
214
  * @param params.vendor - Identity vendor for the session.
@@ -266,6 +266,7 @@ export class KycController extends BaseController {
266
266
  vendor: params.vendor,
267
267
  geoCountry,
268
268
  aal2Token: params.aal2Token,
269
+ partnerIdentityToken: partnerIdentity.partnerIdentityToken,
269
270
  });
270
271
  }
271
272
  const sessionStatus = await this.messenger.call('KycService:getSessionStatus', { sessionId: this.state.sessionStatus.id });
@@ -447,11 +448,13 @@ export class KycController extends BaseController {
447
448
  * kyc-api returns the existing session if one with the same vendor and
448
449
  * canonicalUserId already exists.
449
450
  *
450
- * @param params - Vendor, country, and AAL2 token used to create the session.
451
+ * @param params - Vendor, country, and tokens used to create the session.
451
452
  * @param params.vendor - Identity vendor for the UKYC session.
452
453
  * @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.
453
454
  * @param params.aal2Token - AAL2 authentication token sent as the
454
455
  * Authorization bearer value for session creation.
456
+ * @param params.partnerIdentityToken - Partner identity token minted for
457
+ * the vendor's audience.
455
458
  * @returns The created or refreshed session status.
456
459
  */
457
460
  async #createUkycSession(params) {
@@ -469,6 +472,7 @@ export class KycController extends BaseController {
469
472
  residenceCountry: params.geoCountry,
470
473
  vendor: params.vendor,
471
474
  aal2Token: params.aal2Token,
475
+ partnerIdentityToken: params.partnerIdentityToken,
472
476
  });
473
477
  return this.#setAuthorizations({
474
478
  sessionId,
@@ -814,16 +818,33 @@ export class KycController extends BaseController {
814
818
  * `encryptionDataKey` is attested by the idOS enclave; `ukycCapabilityToken`
815
819
  * by the idOS relay.
816
820
  *
821
+ * Fetch and verification failures are rethrown as a short message suitable
822
+ * for display. The original error is preserved on `cause`.
823
+ *
817
824
  * @param encryptionDataKey - Encryption schema for the data encryption key.
818
825
  * @param capabilityTokenSchema - Encryption schema for the capability token.
826
+ * @throws When the issuer signing keys cannot be fetched, or a schema's
827
+ * `jwtChain` does not verify.
819
828
  */
820
829
  async #verifyWrappingKeys(encryptionDataKey, capabilityTokenSchema) {
821
- const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] = await Promise.all([
822
- this.messenger.call('KycService:fetchIdosEnclaveJwks'),
823
- this.messenger.call('KycService:fetchIdosRelayJwks'),
824
- ]);
825
- assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);
826
- assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);
830
+ let idosEnclaveKeys;
831
+ let idosRelayKeys;
832
+ try {
833
+ [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] = await Promise.all([
834
+ this.messenger.call('KycService:fetchIdosEnclaveJwks'),
835
+ this.messenger.call('KycService:fetchIdosRelayJwks'),
836
+ ]);
837
+ }
838
+ catch (error) {
839
+ throw wrapError(error, 'KycController.#verifyWrappingKeys: Unable to fetch JWKS needed to verify wrapping keys.');
840
+ }
841
+ try {
842
+ assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);
843
+ assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);
844
+ }
845
+ catch (error) {
846
+ throw wrapError(error, 'KycController.#verifyWrappingKeys: Failed to verify the wrapping keys.');
847
+ }
827
848
  }
828
849
  /**
829
850
  * Derives the `data_encryption_key` from the `local_user_secret`, mints a
@@ -1 +1 @@
1
- {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAO3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5C,OAAO,EACL,gCAAgC,EAChC,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EACL,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAYpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC,kBAAkB;AAElB,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;AAE9C,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,aAAa;IACb,WAAW;IACX,WAAW;IACX,QAAQ;CACA,CAAC;AAUX,2EAA2E;AAC3E,+EAA+E;AAC/E,+EAA+E;AAC/E,wEAAwE;AACxE,MAAM,4BAA4B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEzD,8EAA8E;AAC9E,oDAAoD;AACpD,MAAM,+BAA+B,GAAG,MAAM,CAAC;AAqD/C,MAAM,qBAAqB,GAAG;IAC5B,KAAK,EAAE;QACL,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,MAAM,EAAE;QACN,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf;IACD,UAAU,EAAE;QACV,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf;IACD,aAAa,EAAE;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf;IACD,kBAAkB,EAAE;QAClB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf;IACD,yBAAyB,EAAE;QACzB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,2BAA2B,EAAE;QAC3B,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,uBAAuB,EAAE;QACvB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,iCAAiC,EAAE;QACjC,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;CAC0C,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,sCAAsC;IACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,wCAAwC;IACtD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,kBAAkB,EAAE,aAAa;QACjC,yBAAyB,EAAE,sCAAsC,EAAE;QACnE,2BAA2B,EAAE,wCAAwC,EAAE;QACvE,uBAAuB,EAAE,IAAI;QAC7B,iCAAiC,EAAE,IAAI;KACxC,CAAC;AACJ,CAAC;AAkBD,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,cAAc;IACd,OAAO;IACP,YAAY;IACZ,2BAA2B;IAC3B,uBAAuB;IACvB,sBAAsB;IACtB,mBAAmB;IACnB,wBAAwB;IACxB,2BAA2B;IAC3B,yBAAyB;IACzB,0BAA0B;IAC1B,gCAAgC;IAChC,wBAAwB;IACxB,yBAAyB;IACzB,+BAA+B;IAC/B,oBAAoB;CACZ,CAAC;AA8CX,gCAAgC;AAEhC;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,cAIlC;IACU,eAAe,CAAoB;IAEnC,qBAAqB,CAA2B;IAEzD,oEAAoE;IACpE,uBAAuB,GAAyC,IAAI,CAAC;IAErE;;;OAGG;IACH,uBAAuB,GAAG,CAAC,CAAC;IAE5B;;;;;;;OAOG;IACH,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,EAAwB;QACpE,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,qBAAqB;YAC/B,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,EAAE,GAAG,4BAA4B,EAAE,EAAE,GAAG,KAAK,EAAE;SACvD,CAAC,CAAC;QAEH,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC;QACtC,IAAI,CAAC,qBAAqB,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAE1E,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,4BAA4B,CAAC,MAAiB;QAIlD,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,MAAiC,CAAC;QACnD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,2DAA2D,EAC3D,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAC5B,CAAC;QACF,IAAI,oBAA4B,CAAC;QACjC,IAAI,CAAC;YACH,oBAAoB,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,kDAAkD,EAClD,CAAC,OAAO,CAAC,EACT,QAAQ,CACT,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO;YACL,oBAAoB;YACpB,KAAK,EAAE,gCAAgC,CAAC,oBAAoB,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,YAAY,CAAC,MAGlB;QACC,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,4BAA4B,CAC7D,MAAM,CAAC,MAAM,CACd,CAAC;QACF,MAAM,KAAK,GAAG,eAAe,EAAE,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACzD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CACb,0DAA0D,CAC3D,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACzE,IACE,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI;YAC9B,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,UAAU,EACpC,CAAC;YACD,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;YAC9B,IAAI,KAAK,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;gBACjC,KAAK,CAAC,kBAAkB,GAAG,aAAa,CAAC;YAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YACtC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,sCAAsC,EACtC,MAAM,CAAC,MAAM,CACd,CAAC;YACF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;gBACtC,CAAC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAC/C,CAAC;YAED,iGAAiG;YACjG,sFAAsF;YACtF,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E,CAAC;YACJ,CAAC;YAED,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;YACJ,CAAC;YAED,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAiC,EAAE;gBAC3D,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,oBAAoB,EAAE,eAAe,CAAC,oBAAoB;aAC3D,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,kBAAkB,CAAC;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,UAAU;gBACV,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC,CAAC;QACL,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,CAC3C,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;QACtC,CAAC,CAAC,CAAC;QACH,uCAAuC;QACvC,OAAO,IAAI,CAAC,8BAA8B,EAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;YACxB,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,kBAAkB,GAAG,aAAa,CAAC;YACzC,KAAK,CAAC,yBAAyB;gBAC7B,sCAAsC,EAAE,CAAC;YAC3C,KAAK,CAAC,2BAA2B;gBAC/B,wCAAwC,EAAE,CAAC;YAC7C,KAAK,CAAC,uBAAuB,GAAG,IAAI,CAAC;YACrC,KAAK,CAAC,iCAAiC,GAAG,IAAI,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,yBAAyB,CACvB,MAAiB;QAEjB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAED;;;;OAIG;IACH,qBAAqB;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC;IACvC,CAAC;IAED,2DAA2D;IAC3D;;;;;;;;;OASG;IACH,oBAAoB;QAClB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,IACE,CAAC,8BAA8B,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,EACzE,CAAC;YACD,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IAClC,CAAC;IAED;;;;;;OAMG;IACH,iBAAiB;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IAClC,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,sBAAsB,CAAC,SAAiB;QAC5C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,CACd,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;QACtC,CAAC,CAAC,CAAC;QACH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;;;;;;;;;OAUG;IACH,yBAAyB;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC;QAC3C,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;YACrC,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACvE,IAAI,UAAU,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;YACD,cAAc,IAAI,CAAC,CAAC;YACpB,IAAI,CAAC,uBAAuB,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC7C,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;gBACpC,8DAA8D;gBAC9D,mEAAmE;gBACnE,IAAI,EAAE,CAAC;YACT,CAAC,EAAE,+BAA+B,GAAG,cAAc,CAAC,CAAC;YACrD,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,EAAE,CAAC;QACzC,CAAC,CAAC;QAEF,mEAAmE;QACnE,IAAI,EAAE,CAAC;IACT,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,sBAAsB,CAC1B,SAAiB,EACjB,KAAa;QAEb,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,CACd,CAAC;YACF,IAAI,IAAI,CAAC,uBAAuB,KAAK,KAAK,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,iCAAiC;YACjC,IACE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;gBACxC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAC7B,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;gBACtC,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,8BAA8B,CAAC,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;gBAClE,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACjC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,uBAAuB,KAAK,KAAK,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,IAAI,CAAC,uBAAuB,IAAI,CAAC,CAAC;QAClC,IAAI,IAAI,CAAC,uBAAuB,KAAK,IAAI,EAAE,CAAC;YAC1C,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YAC3C,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACtC,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,kBAAkB,CAAC,MAIxB;QACC,wEAAwE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,wEAAwE;QACxE,MAAM,uBAAuB,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC/D,MAAM,sBAAsB,GAAG,WAAW,CACxC,MAAM,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAC7C,CAAC;QACF,mEAAmE;QACnE,wEAAwE;QACxE,qBAAqB;QACrB,MAAM,EACJ,SAAS,EACT,iBAAiB,EAAE,uBAAuB,EAC1C,mBAAmB,EAAE,qBAAqB,GAC3C,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC5D,sBAAsB;YACtB,gBAAgB,EAAE,MAAM,CAAC,UAAU;YACnC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,kBAAkB,CAAC;YAC7B,SAAS;YACT,uBAAuB;YACvB,sBAAsB;YACtB,uBAAuB;YACvB,qBAAqB;SACtB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,kBAAkB,CAAC,MAMxB;QACC,MAAM,EACJ,SAAS,EACT,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,GACtB,GAAG,MAAM,CAAC;QAEX,MAAM,IAAI,CAAC,mBAAmB,CAC5B,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;QAEF,MAAM,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,GAC5D,MAAM,IAAI,CAAC,8BAA8B,CACvC,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,CACtB,CAAC;QAEJ,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,8BAA8B,EAC9B;YACE,SAAS;YACT,wBAAwB;YACxB,0BAA0B;SAC3B,CACF,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,sBAAsB;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,uBAAuB,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;QAC/D,MAAM,sBAAsB,GAAG,WAAW,CACxC,MAAM,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAC7C,CAAC;QAEF,MAAM,EACJ,iBAAiB,EAAE,uBAAuB,EAC1C,mBAAmB,EAAE,qBAAqB,GAC3C,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,8BAA8B,EAAE;YAC5D,SAAS;YACT,sBAAsB;SACvB,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,kBAAkB,CAAC;YAC7B,SAAS;YACT,uBAAuB;YACvB,sBAAsB;YACtB,uBAAuB;YACvB,qBAAqB;SACtB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,8BAA8B;QAClC,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACrC,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,mCAAmC,CAAC,aAAa,CAAC,EAAE,CAAC;YACxD,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC;IACvC,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,uBAAuB,CAC3B,MAAqC;QAErC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAG9B,CAAC;QACF,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CACxB,6CAA6C,EAC7C,EAAE,OAAO,EAAE,CACZ,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvC,+CAA+C,EAC/C,EAAE,SAAS,EAAE,CACd,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,wBAAwB,CAAC,MAI9B;QACC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,8EAA8E;QAC9E,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC3C,+CAA+C,EAC/C,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,CAC3C,CAAC;QAEF,MAAM,IAAI,GAAG,8BAA8B,CACzC,WAAW,CAAC,IAAI,EAChB,MAAM,CAAC,uBAAuB,CAC/B,CAAC;QACF,MAAM,WAAW,GAAG,8BAA8B,CAChD,WAAW,CAAC,WAAW,EACvB,MAAM,CAAC,2BAA2B,CACnC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,qCAAqC,EAAE;gBAC/D,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;gBACtC,IAAI;gBACJ,WAAW;gBACX,iCAAiC,EAC/B,MAAM,CAAC,iCAAiC;aAC3C,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,2DAA2D;QAC7D,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,8CAA8C;YAC9C,KAAK,CAAC,2BAA2B,CAAC,MAAM;gBACtC,MAAM,CAAC,2BAA2B,CAAC;YACrC,KAAK,CAAC,uBAAuB,GAAG,MAAM,CAAC,uBAAuB,CAAC;YAC/D,KAAK,CAAC,iCAAiC;gBACrC,MAAM,CAAC,iCAAiC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,8BAA8B;QAClC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QAED,4EAA4E;QAC5E,4EAA4E;QAC5E,0BAA0B;QAC1B,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,EAAE,CAC3C,CAAC;QAEF,OAAO,aAAa,CAAC,aAAa,KAAK,OAAO,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,sBAAsB,CAAC,MAG5B;QACC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mCAAmC,EAAE,MAAM,CAAC,CAAC;IAC1E,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,uBAAuB,CAAC,MAE7B;QACC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QAE9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACxC,oCAAoC,EACpC;YACE,MAAM;YACN,aAAa,EAAE,MAAM,CAAC,aAAa;SACpC,CACF,CAAC;QAEF,2CAA2C;QAC3C,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACpB,KAAK,CAAC,yBAAyB,GAAG,gCAAgC,CAChE,KAAK,CAAC,yBAAyB,EAC/B,MAAM,EACN;gBACE,aAAa,EAAE,MAAM,CAAC,aAAa;aACpC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,6BAA6B;QACjC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC;YAChD,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU;SAC/B,CAAC,CAAC;QAEH,2CAA2C;QAC3C,OAAO,6BAA6B,CAClC,IAAI,CAAC,KAAK,CAAC,yBAAyB,EACpC,IAAI,CAAC,KAAK,CAAC,MAAM,EACjB,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,EACjB,MAAM,EACN,KAAK,GAIN;QACC,+DAA+D;QAC/D,OAAO,IAAI,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,iBAAiB,CAAC,MAGvB;QACC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,kBAAkB,GAAG,QAAQ,CAAC;YACtC,CAAC,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,8DAA8D;YAC9D,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACxD,0BAA0B,EAC1B,SAAS,CACV,CAAC;YAEF,yEAAyE;YACzE,kEAAkE;YAClE,sEAAsE;YACtE,yBAAyB;YACzB,IAAI,iBAAiB,GAAG,KAAK,CAAC;YAC9B,IAAI,SAAS,GAAG,KAAK,CAAC;YAEtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;gBAC/C,oBAAoB;gBACpB,iBAAiB,EAAE,KAAK,IAAI,EAAE;oBAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvC,0BAA0B,EAC1B,SAAS,CACV,CAAC;oBACF,OAAO,OAAO,CAAC,oBAAoB,CAAC;gBACtC,CAAC;gBACD,cAAc,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;oBAC9B,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAChC,iBAAiB,GAAG,IAAI,CAAC;oBAC3B,CAAC;oBACD,IAAI,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC7B,SAAS,GAAG,IAAI,CAAC;oBACnB,CAAC;gBACH,CAAC;gBACD,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;gBAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK;aAC9B,CAAC,CAAC;YAEH,iEAAiE;YACjE,sDAAsD;YACtD,iBAAiB,KAAK,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3D,SAAS,KAAK,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAEhD,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;YACtD,IAAI,oBAAoB,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC;gBAC3C,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,kBAAkB,GAAG,QAAQ,CAAC;gBACtC,CAAC,CAAC,CAAC;gBACH,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,IAAI,iBAAiB,EAAE,CAAC;gBACtB,wEAAwE;gBACxE,6CAA6C;gBAC7C,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,aAAa,GAAG;wBACpB,GAAG,oBAAoB;wBACvB,WAAW,EAAE,SAAS;qBACvB,CAAC;oBACF,KAAK,CAAC,kBAAkB,GAAG,WAAW,CAAC;gBACzC,CAAC,CAAC,CAAC;gBACH,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACjC,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;gBACpB,KAAK,CAAC,kBAAkB,GAAG,WAAW,CAAC;YACzC,CAAC,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC;gBAC/C,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;oBACpB,KAAK,CAAC,kBAAkB,GAAG,QAAQ,CAAC;gBACtC,CAAC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,mBAAmB,CACvB,iBAAmC,EACnC,qBAAuC;QAEvC,MAAM,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,GACxD,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAiC,CAAC;YACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,+BAA+B,CAAC;SACrD,CAAC,CAAC;QACL,6BAA6B,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;QAClE,6BAA6B,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;IACtE,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,8BAA8B,CAClC,uBAAmC,EACnC,iBAAmC,EACnC,qBAAuC;QAKvC,MAAM,eAAe,GAAG,MAAM,0BAA0B,CACtD,IAAI,CAAC,qBAAqB,CAC3B,CAAC;QACF,MAAM,cAAc,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;QAC7D,MAAM,wBAAwB,GAAG,iBAAiB,CAChD,uBAAuB,EACvB,iBAAiB,CAAC,eAAe,CAAC,CAAC,EACnC,cAAc,CAAC,iBAAiB,CACjC,CAAC;QAEF,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;YACjD,QAAQ,EAAE,cAAc;YACxB,wGAAwG;YACxG,UAAU,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;YAC7B,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,4BAA4B,CAAC;SAC/D,CAAC,CAAC;QACH,MAAM,0BAA0B,GAAG,iBAAiB,CAClD,uBAAuB,EACvB,qBAAqB,CAAC,eAAe,CAAC,CAAC,EACvC,aAAa,CAAC,iCAAiC,CAAC,mBAAmB,CAAC,CAAC,CACtE,CAAC;QAEF,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,CAAC;IAClE,CAAC;CACF","sourcesContent":["import type {\n AuthenticatedUserStorageServicePutIdentitySharingConsentAction,\n IdentitySharingAudience,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationControllerGetPartnerIdentityTokenAction } from '@metamask/profile-sync-controller/auth';\nimport type {\n UserStorageControllerPerformGetStorageAction,\n UserStorageControllerPerformSetStorageAction,\n} from '@metamask/profile-sync-controller/user-storage';\nimport { stringToBytes } from '@metamask/utils';\nimport { x25519 } from '@noble/curves/ed25519';\n\nimport { toBase64Url } from './encoding.js';\nimport type { KycControllerMethodActions } from './KycController-method-action-types.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n CapabilityAuthorization,\n EncryptionSchema,\n} from './KycService.js';\nimport {\n getEmailFromPartnerIdentityToken,\n isEmailRequiredError,\n} from './partnerIdentityToken.js';\nimport {\n isSumSubFlowCompleted,\n isSumSubFlowFailed,\n} from './providers/sumsub.js';\nimport type { KycSumSubLauncher } from './providers/sumsub.js';\nimport { consentRecordsFromAcceptedList } from './sessionDisclaimers.js';\nimport {\n needsCapabilityAuthorizationRefresh,\n FINAL_STATUSES_TO_STOP_POLLING,\n} from './types.js';\nimport type {\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { assertAttestedServerPublicKey } from './ukyc/jwtChain.js';\nimport {\n getOrCreateLocalUserSecret,\n UkycLocalUserSecretStore,\n} from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n areVendorDisclaimersCompleted,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimers.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nexport const KYC_PROVIDER_FLOW_STATUSES = [\n 'not_started',\n 'submitted',\n 'abandoned',\n 'failed',\n] as const;\n\n/**\n * Durable outcome of the identity-provider flow.\n *\n * Unlike the KYC session's `finalStatus`, this distinguishes a newly-created\n * pending session from a provider flow that the customer actually submitted.\n */\nexport type KycProviderFlowStatus = (typeof KYC_PROVIDER_FLOW_STATUSES)[number];\n\n// Lifetime of the read-only `ukyc_capability_token` minted when creating a\n// UKYC session. The storage-and-auth spec requires the token's `expires_at` to\n// cover the KYC session's expected lifetime — including the provider journey —\n// rather than a fixed short window, so this is a session-scoped window.\nconst UKYC_CAPABILITY_TOKEN_TTL_MS = 72 * 60 * 60 * 1000;\n\n// First wait between UKYC session-status polls. Each later wait grows by this\n// step, so the delays are 10s, 20s, 30s, and so on.\nconst SESSION_STATUS_POLL_INTERVAL_MS = 10_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\n vendor: KycVendor | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Latest UKYC session status, or `null` when none has been fetched. */\n sessionStatus: KycSessionStatus | null;\n\n /** Last durable identity-provider flow outcome for this session. */\n providerFlowStatus: KycProviderFlowStatus;\n\n // TODO: Check if we need truly need to persist these accepted disclaimers\n /**\n * Persisted vendor-disclaimer acceptance (T&C1) with fixed `moonpay` and\n * `iron` keys. MoonPay stores only `termsAcceptedAt`; Iron stores\n * `disclaimerIds`.\n */\n vendorDisclaimersAccepted: KycVendorDisclaimersAccepted;\n /**\n * KYC-provider disclaimer documents the customer accepted during the last\n * terms acceptance (persisted `{ key, version }` records under `sumsub`).\n * Consents-path vendors require this when resuming a session. `null` for\n * acceptance recorded before this field existed (treated as requiring\n * reacceptance).\n */\n providerDisclaimersAccepted: KycProviderDisclaimersAccepted;\n /**\n * idOS disclaimer documents the customer accepted during the last terms\n * acceptance (persisted `{ key, version }` records). Consents-path vendors\n * require this when resuming a session. `null` for acceptance recorded\n * before this field existed (treated as requiring reacceptance).\n */\n idosDisclaimersAccepted: KycConsentRecord[] | null;\n /**\n * Whether the customer consented to reuse existing idOS credentials\n * during this session. Applied when recording session-scoped disclaimers.\n * Not persisted: a new UKYC session must collect reuse consent again.\n * `null` when never set (treated as `false`).\n */\n credentialReusabilityConsentGiven: boolean | null;\n};\n\nconst kycControllerMetadata = {\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: false,\n },\n vendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sessionStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n providerFlowStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n vendorDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n providerDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n idosDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n credentialReusabilityConsentGiven: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n} satisfies StateMetadata<KycControllerState>;\n\n/**\n * Constructs the default {@link KycVendorDisclaimersAccepted} value.\n *\n * @returns The default vendor-disclaimer acceptance map.\n */\nexport function getDefaultKycVendorDisclaimersAccepted(): KycVendorDisclaimersAccepted {\n return { moonpay: null, iron: null };\n}\n\n/**\n * Constructs the default {@link KycProviderDisclaimersAccepted} value.\n *\n * @returns The default provider-disclaimer acceptance map.\n */\nexport function getDefaultKycProviderDisclaimersAccepted(): KycProviderDisclaimersAccepted {\n return { sumsub: null };\n}\n\n/**\n * Constructs the default {@link KycController} state.\n *\n * @returns The default state.\n */\nexport function getDefaultKycControllerState(): KycControllerState {\n return {\n email: null,\n vendor: null,\n geoCountry: null,\n sessionStatus: null,\n providerFlowStatus: 'not_started',\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n };\n}\n\n/**\n * Parameters for {@link KycController.fetchSessionDisclaimers}. Provide\n * exactly one of `sessionId` or `country`.\n */\nexport type FetchSessionDisclaimersParams =\n | {\n /** UKYC session id from `KycService.createUkycSession`. */\n sessionId: string;\n country?: never;\n }\n | {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n sessionId?: never;\n };\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'startSession',\n 'reset',\n 'clearState',\n 'getSessionStatusForVendor',\n 'getProviderFlowStatus',\n 'refreshSessionStatus',\n 'readSessionStatus',\n 'fetchSessionStatusOnce',\n 'startSessionStatusPolling',\n 'fetchSessionDisclaimers',\n 'recordSessionDisclaimers',\n 'hasCompletedSessionDisclaimers',\n 'fetchVendorDisclaimers',\n 'recordVendorDisclaimers',\n 'hasCompletedVendorDisclaimers',\n 'launchProviderFlow',\n] as const;\n\nexport type KycControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerActions =\n | KycControllerGetStateAction\n | KycControllerMethodActions;\n\ntype AllowedActions =\n | KycServiceMethodActions\n | UserStorageControllerPerformGetStorageAction\n | UserStorageControllerPerformSetStorageAction\n | AuthenticationControllerGetPartnerIdentityTokenAction\n | AuthenticatedUserStorageServicePutIdentitySharingConsentAction;\n\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n};\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * `KycController` orchestrates the vendor-backed KYC / identity-verification\n * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per\n * product surface used by ramps and card. It owns all state and HTTP\n * orchestration (via `KycService`), while vendor protocol handling and\n * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n readonly #localUserSecretStore: UkycLocalUserSecretStore;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #sessionStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped when the loop stops so an in-flight fetch\n * neither writes state nor schedules a follow-up.\n */\n #sessionStatusPollToken = 0;\n\n /**\n * Constructs a new {@link KycController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - Partial initial state; merged over defaults.\n * @param options.sumsubLauncher - The platform SumSub launcher adapter.\n */\n constructor({ messenger, state, sumsubLauncher }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#localUserSecretStore = new UkycLocalUserSecretStore(this.messenger);\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Records identity-sharing consent for the vendor's audience, then mints a\n * partner identity token and reads the verified email claim from JWT `ext`.\n *\n * @param vendor - Identity vendor whose partner audience to request.\n * @returns The minted token and its verified email, or `null` when the\n * profile has no verified email (HTTP 422 / `EmailRequiredError`).\n */\n async #getPartnerIdentityForVendor(vendor: KycVendor): Promise<{\n partnerIdentityToken: string;\n email: string;\n } | null> {\n // TODO: Fix this typing. Safe for now as only Iron is used\n const audience = vendor as IdentitySharingAudience;\n await this.messenger.call(\n 'AuthenticatedUserStorageService:putIdentitySharingConsent',\n { audience, granted: true },\n );\n let partnerIdentityToken: string;\n try {\n partnerIdentityToken = await this.messenger.call(\n 'AuthenticationController:getPartnerIdentityToken',\n ['email'],\n audience,\n );\n } catch (error) {\n if (isEmailRequiredError(error)) {\n return null;\n }\n throw error;\n }\n return {\n partnerIdentityToken,\n email: getEmailFromPartnerIdentityToken(partnerIdentityToken),\n };\n }\n\n /**\n * Starts a KYC session for the given vendor. Reuses a latest vendor session\n * when one exists; otherwise creates a UKYC session.\n *\n * The verified email stored on controller state comes from the partner\n * identity token. When that request returns HTTP 422, a stored email is\n * kept for an existing session. Creating a vendor customer requires the\n * token and sends it as `partnerIdentityToken`.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\n async startSession(params: {\n vendor: KycVendor;\n aal2Token?: string;\n }): Promise<KycSessionStatus> {\n const partnerIdentity = await this.#getPartnerIdentityForVendor(\n params.vendor,\n );\n const email = partnerIdentity?.email ?? this.state.email;\n if (!email) {\n throw new Error('KycController missing verified email for vendor');\n }\n if (this.state.email !== null && this.state.email !== email) {\n throw new Error(\n 'KycController already initialized with a different email',\n );\n }\n if (this.state.vendor !== null && this.state.vendor !== params.vendor) {\n throw new Error(\n 'KycController already initialized with a different vendor',\n );\n }\n\n const geoCountry = await this.messenger.call('KycService:getGeoCountry');\n if (\n this.state.geoCountry !== null &&\n this.state.geoCountry !== geoCountry\n ) {\n throw new Error(\n 'KycController already initialized with a different geoCountry',\n );\n }\n\n this.update((state) => {\n state.email = email;\n state.vendor = params.vendor;\n state.geoCountry = geoCountry;\n if (state.sessionStatus === null) {\n state.providerFlowStatus = 'not_started';\n }\n });\n\n if (this.state.sessionStatus === null) {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatusForVendor',\n params.vendor,\n );\n if (sessionStatus !== null) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return this.#refreshAuthorizationsIfNeeded();\n }\n\n // TODO: Probably move this into it's own method? Feels like startSession is a little overloaded.\n // It's assumed that if the session does not exist, the customer does not exist either\n if (!params.aal2Token) {\n throw new Error(\n 'KycController.startSession: aal2Token is required to create a KYC session.',\n );\n }\n\n if (!partnerIdentity) {\n throw new Error(\n 'KycController missing partner identity token for vendor',\n );\n }\n\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n partnerIdentityToken: partnerIdentity.partnerIdentityToken,\n });\n\n return this.#createUkycSession({\n vendor: params.vendor,\n geoCountry,\n aal2Token: params.aal2Token,\n });\n }\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId: this.state.sessionStatus.id },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n // TODO: Should we resume polling here?\n return this.#refreshAuthorizationsIfNeeded();\n }\n\n /**\n * Stops session-status polling and restores default controller state.\n */\n async reset(): Promise<void> {\n this.#stopSessionStatusPolling();\n this.clearState();\n }\n\n /**\n * Restores the controller to its default state.\n */\n clearState(): void {\n this.#stopSessionStatusPolling();\n this.update((state) => {\n state.email = null;\n state.vendor = null;\n state.geoCountry = null;\n state.sessionStatus = null;\n state.providerFlowStatus = 'not_started';\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\n getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n return this.messenger.call('KycService:getSessionStatusForVendor', vendor);\n }\n\n /**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\n getProviderFlowStatus(): KycProviderFlowStatus {\n return this.state.providerFlowStatus;\n }\n\n // TODO: Perhaps this should be renamed to resumeSession()?\n /**\n * Returns the session already stored on state.\n *\n * Starts session-status polling when `finalStatus` is not `approved`,\n * `rejected`, or `retry`. Does not fetch status or refresh capability\n * authorization.\n *\n * @returns The session status stored at call time.\n * @throws If there is no session on state.\n */\n refreshSessionStatus(): KycSessionStatus {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n if (\n !FINAL_STATUSES_TO_STOP_POLLING.has(this.state.sessionStatus.finalStatus)\n ) {\n this.startSessionStatusPolling();\n }\n return this.state.sessionStatus;\n }\n\n /**\n * Returns the persisted session status.\n *\n * Does not call the network and does not start session-status polling.\n *\n * @returns The session on state, or `null` when none is stored.\n */\n readSessionStatus(): KycSessionStatus | null {\n return this.state.sessionStatus;\n }\n\n /**\n * Fetches `GET /sessions/{id}/status` once and writes the result onto state.\n *\n * Does not start the session-status polling timer.\n *\n * @param sessionId - UKYC session id.\n * @returns The fetched session status.\n */\n async fetchSessionStatusOnce(sessionId: string): Promise<KycSessionStatus> {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n /**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The first poll runs\n * immediately. Each later wait starts at 10 seconds and grows by 10 seconds\n * after every poll, including a failed one. Starting the loop again resets\n * that delay. The loop stops once `finalStatus` is `approved`, `rejected`,\n * or `retry`, or when {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\n startSessionStatusPolling(): void {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n this.#stopSessionStatusPolling();\n const token = this.#sessionStatusPollToken;\n let completedPolls = 0;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n completedPolls += 1;\n this.#sessionStatusPollTimer = setTimeout(() => {\n this.#sessionStatusPollTimer = null;\n // `tick` swallows its own errors and therefore never rejects.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, SESSION_STATUS_POLL_INTERVAL_MS * completedPolls);\n this.#sessionStatusPollTimer.unref?.();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }\n\n /**\n * Fetches session status for the polled session and records it when it\n * differs from state.\n *\n * @param sessionId - Session the loop started for.\n * @param token - Polling token captured when the loop started.\n * @returns Whether the loop should stop.\n */\n async #pollSessionStatusOnce(\n sessionId: string,\n token: number,\n ): Promise<boolean> {\n try {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n if (this.#sessionStatusPollToken !== token) {\n return true;\n }\n\n // TODO: This check seems fragile\n if (\n JSON.stringify(this.state.sessionStatus) !==\n JSON.stringify(sessionStatus)\n ) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n }\n\n if (FINAL_STATUSES_TO_STOP_POLLING.has(sessionStatus.finalStatus)) {\n this.#stopSessionStatusPolling();\n return true;\n }\n return false;\n } catch {\n return this.#sessionStatusPollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop.\n */\n #stopSessionStatusPolling(): void {\n this.#sessionStatusPollToken += 1;\n if (this.#sessionStatusPollTimer !== null) {\n clearTimeout(this.#sessionStatusPollTimer);\n this.#sessionStatusPollTimer = null;\n }\n }\n\n /**\n * Creates or reuses a UKYC session, wraps the `data_encryption_key` and\n * `ukyc_capability_token` against the returned encryption schemas, and\n * submits both via authorizations. Stores the resulting session status.\n * kyc-api returns the existing session if one with the same vendor and\n * canonicalUserId already exists.\n *\n * @param params - Vendor, country, and AAL2 token used to create the session.\n * @param params.vendor - Identity vendor for the UKYC session.\n * @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.\n * @param params.aal2Token - AAL2 authentication token sent as the\n * Authorization bearer value for session creation.\n * @returns The created or refreshed session status.\n */\n async #createUkycSession(params: {\n vendor: KycVendor;\n geoCountry: string;\n aal2Token: string;\n }): Promise<KycSessionStatus> {\n // Establish a per-session X25519 keypair used to seal both secrets. The\n // private half stays on the device; the public half is registered on the\n // session so the server can open later authorizations. Each encryption\n // schema from session creation supplies the matching server public key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n // Residence is the ISO 3166-1 alpha-3 country already resolved for\n // disclaimers / KYC-required; fetch it if this sub-flow started without\n // that earlier step.\n const {\n sessionId,\n encryptionDataKey: encryptionDataKeySchema,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n sessionClientPublicKey,\n residenceCountry: params.geoCountry,\n vendor: params.vendor,\n aal2Token: params.aal2Token,\n });\n\n return this.#setAuthorizations({\n sessionId,\n sessionClientPrivateKey,\n sessionClientPublicKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n });\n }\n\n /**\n * Verifies encryption schemas, wraps the `data_encryption_key` and\n * `ukyc_capability_token`, and submits both via\n * {@link KycService.setAuthorizations}. Stores the resulting session status.\n *\n * @param params - Session key material and encryption schemas.\n * @param params.sessionId - UKYC session id to authorize.\n * @param params.sessionClientPrivateKey - Per-session X25519 private key\n * used to seal both secrets.\n * @param params.sessionClientPublicKey - Matching public key registered on\n * the session (must correspond to `sessionClientPrivateKey`).\n * @param params.encryptionDataKeySchema - Encryption schema for the data\n * encryption key.\n * @param params.capabilityTokenSchema - Encryption schema for the capability\n * token.\n * @returns The session status after authorizations are applied.\n */\n async #setAuthorizations(params: {\n sessionId: string;\n sessionClientPrivateKey: Uint8Array;\n sessionClientPublicKey: string;\n encryptionDataKeySchema: EncryptionSchema;\n capabilityTokenSchema: EncryptionSchema;\n }): Promise<KycSessionStatus> {\n const {\n sessionId,\n sessionClientPrivateKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n } = params;\n\n await this.#verifyWrappingKeys(\n encryptionDataKeySchema,\n capabilityTokenSchema,\n );\n\n const { wrappedEncryptionDataKey, wrappedUkycCapabilityToken } =\n await this.#generateWrappedAuthorizations(\n sessionClientPrivateKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n );\n\n const sessionStatus = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n\n return sessionStatus;\n }\n\n /**\n * Mints a new per-session X25519 keypair, reissues wrapping keys for the\n * current session, and submits wrapped authorizations.\n *\n * @returns The session status after authorizations are applied.\n * @throws If there is no session on state.\n */\n async #refreshAuthorizations(): Promise<KycSessionStatus> {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n\n const {\n encryptionDataKey: encryptionDataKeySchema,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:resetWrappingKeys', {\n sessionId,\n sessionClientPublicKey,\n });\n\n return this.#setAuthorizations({\n sessionId,\n sessionClientPrivateKey,\n sessionClientPublicKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n });\n }\n\n /**\n * Refreshes and resubmits the UKYC capability authorization when the current\n * session reports it as `new` or `expired`. Uses the `sessionStatus` already\n * on state (callers are responsible for refreshing status when needed).\n * No-ops when KYC has already finished (`finalStatus` is `approved` or\n * `rejected`) or the capability token is `pending`, `stored`, or `wiped`.\n *\n * @returns The current or refreshed session status.\n * @throws If there is no session on state when a refresh is required.\n */\n async #refreshAuthorizationsIfNeeded(): Promise<KycSessionStatus> {\n const { sessionStatus } = this.state;\n if (!sessionStatus) {\n throw new Error('No session was found');\n }\n\n if (!needsCapabilityAuthorizationRefresh(sessionStatus)) {\n return sessionStatus;\n }\n return this.#refreshAuthorizations();\n }\n\n /**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\n async fetchSessionDisclaimers(\n params: FetchSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers | KycDisclaimersCatalog> {\n const { sessionId, country } = params as {\n sessionId?: string;\n country?: string;\n };\n if (sessionId && country) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n if (country) {\n return this.messenger.call(\n 'KycService:fetchSessionDisclaimersByCountry',\n { country },\n );\n }\n\n if (!sessionId) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n return catalog;\n }\n\n /**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\n async recordSessionDisclaimers(params: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: Check if these can simply be mapped to `{key, version}` pairs instead\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n const idOS = consentRecordsFromAcceptedList(\n disclaimers.idOS,\n params.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n disclaimers.kycProvider,\n params.providerDisclaimersAccepted,\n );\n\n try {\n await this.messenger.call('KycService:submitSessionDisclaimers', {\n sessionId: this.state.sessionStatus.id,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n params.credentialReusabilityConsentGiven,\n });\n } catch {\n // A 409 means the session already recorded these consents.\n }\n this.update((state) => {\n // TODO: This shouldn't be hardcoded to sumsub\n state.providerDisclaimersAccepted.sumsub =\n params.providerDisclaimersAccepted;\n state.idosDisclaimersAccepted = params.idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n params.credentialReusabilityConsentGiven;\n });\n }\n\n /**\n * Fetches the current session status and reports whether consent was given.\n *\n * @returns Whether `consentStatus` is `given`.\n * @throws If there is no session on state.\n */\n async hasCompletedSessionDisclaimers(): Promise<boolean> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: remove this explicit call to the service and use the state directly\n // after we have established the pattern for resuming a session after wallet\n // restart more concretely\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId: this.state.sessionStatus.id },\n );\n\n return sessionStatus.consentStatus === 'given';\n }\n\n /**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\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 fetchVendorDisclaimers(params: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n return this.messenger.call('KycService:fetchVendorDisclaimers', params);\n }\n\n /**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\n async recordVendorDisclaimers(params: {\n disclaimerIds: string[];\n }): Promise<KycVendorSigning[]> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n\n if (!this.state.email) {\n throw new Error('No email was found');\n }\n\n const { vendor } = this.state;\n\n const signings = await this.messenger.call(\n 'KycService:submitVendorDisclaimers',\n {\n vendor,\n disclaimerIds: params.disclaimerIds,\n },\n );\n\n // TODO: this only works for Iron right now\n this.update((state) => {\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n vendor,\n {\n disclaimerIds: params.disclaimerIds,\n },\n );\n });\n\n return signings;\n }\n\n /**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\n async hasCompletedVendorDisclaimers(): Promise<boolean> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n if (!this.state.geoCountry) {\n throw new Error('No geoCountry was found');\n }\n\n const fetched = await this.fetchVendorDisclaimers({\n vendor: this.state.vendor,\n country: this.state.geoCountry,\n });\n\n // TODO: this only works for Iron right now\n return areVendorDisclaimersCompleted(\n this.state.vendorDisclaimersAccepted,\n this.state.vendor,\n fetched,\n );\n }\n\n /**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n launchProviderFlow({\n locale,\n debug,\n }: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n // Currently only sumsub is supported and must be used for Iron\n return this.#launchSumsubFlow({ locale, debug });\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. fetches the SumSub applicant access token; and\n * 2. presents the SDK via the injected launcher.\n *\n * Capability authorization must already be valid on\n * {@link KycControllerState.sessionStatus} (see\n * {@link KycController.#refreshAuthorizationsIfNeeded}).\n *\n * @param params - Optional parameters.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n async #launchSumsubFlow(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n const sessionId = this.state.sessionStatus?.id;\n if (!this.#sumsubLauncher.isAvailable() || !sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n try {\n // TODO: check if the sumsub and idos disclaimers are accepted\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n\n // Track whether the SDK ever reported a successful completion or its own\n // failure. A resolved `launch` alone does not imply success — the\n // applicant may have abandoned the flow, or the SDK may have reported\n // that it could not run.\n let reachedCompletion = false;\n let sdkFailed = false;\n\n const result = await this.#sumsubLauncher.launch({\n applicantAccessToken,\n onTokenExpiration: async () => {\n const journey = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return journey.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n if (isSumSubFlowFailed(next)) {\n sdkFailed = true;\n }\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // Some native SDKs resolve with their final status without first\n // delivering the corresponding state-change callback.\n reachedCompletion ||= isSumSubFlowCompleted(result.status);\n sdkFailed ||= isSumSubFlowFailed(result.status);\n\n const currentSessionStatus = this.state.sessionStatus;\n if (currentSessionStatus?.id !== sessionId) {\n return 'failed';\n }\n\n if (sdkFailed) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n if (reachedCompletion) {\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result.\n this.update((state) => {\n state.sessionStatus = {\n ...currentSessionStatus,\n finalStatus: 'pending',\n };\n state.providerFlowStatus = 'submitted';\n });\n this.startSessionStatusPolling();\n return 'submitted';\n }\n\n this.update((state) => {\n state.providerFlowStatus = 'abandoned';\n });\n return 'abandoned';\n } catch {\n if (this.state.sessionStatus?.id === sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n }\n return 'failed';\n }\n }\n\n /**\n * Verifies each schema's jwtChain against the matching issuer JWKS, then\n * confirms the returned server public key matches the value attested inside\n * the verified JWT payload before trusting it for wrapping.\n * `encryptionDataKey` is attested by the idOS enclave; `ukycCapabilityToken`\n * by the idOS relay.\n *\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n */\n async #verifyWrappingKeys(\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<void> {\n const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] =\n await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n }\n\n /**\n * Derives the `data_encryption_key` from the `local_user_secret`, mints a\n * capability token, and wraps both for the session server. Only the wrapped\n * (encrypted) material ever leaves the device.\n *\n * Only the client holds the signing key derived from `local_user_secret`, so\n * only the client can mint the token.\n *\n * @param sessionClientPrivateKey - Per-session X25519 private key used to\n * seal both secrets.\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n * @returns The wrapped encryption key and capability token.\n */\n async #generateWrappedAuthorizations(\n sessionClientPrivateKey: Uint8Array,\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<{\n wrappedEncryptionDataKey: CapabilityAuthorization;\n wrappedUkycCapabilityToken: CapabilityAuthorization;\n }> {\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore,\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionDataKey = wrapEncryptionKey(\n sessionClientPrivateKey,\n encryptionDataKey.serverPublicKey.x,\n clientMaterial.dataEncryptionKey,\n );\n\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write\n operations: ['read', 'write'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n const wrappedUkycCapabilityToken = wrapEncryptionKey(\n sessionClientPrivateKey,\n capabilityTokenSchema.serverPublicKey.x,\n stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)),\n );\n\n return { wrappedEncryptionDataKey, wrappedUkycCapabilityToken };\n }\n}\n"]}
1
+ {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AuthenticatedUserStorageServicePutIdentitySharingConsentAction,\n IdentitySharingAudience,\n} from '@metamask/authenticated-user-storage';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { AuthenticationControllerGetPartnerIdentityTokenAction } from '@metamask/profile-sync-controller/auth';\nimport type {\n UserStorageControllerPerformGetStorageAction,\n UserStorageControllerPerformSetStorageAction,\n} from '@metamask/profile-sync-controller/user-storage';\nimport { stringToBytes, wrapError } from '@metamask/utils';\nimport { x25519 } from '@noble/curves/ed25519';\n\nimport { toBase64Url } from './encoding.js';\nimport type { KycControllerMethodActions } from './KycController-method-action-types.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n CapabilityAuthorization,\n EncryptionSchema,\n} from './KycService.js';\nimport {\n getEmailFromPartnerIdentityToken,\n isEmailRequiredError,\n} from './partnerIdentityToken.js';\nimport {\n isSumSubFlowCompleted,\n isSumSubFlowFailed,\n} from './providers/sumsub.js';\nimport type { KycSumSubLauncher } from './providers/sumsub.js';\nimport { consentRecordsFromAcceptedList } from './sessionDisclaimers.js';\nimport {\n needsCapabilityAuthorizationRefresh,\n FINAL_STATUSES_TO_STOP_POLLING,\n} from './types.js';\nimport type {\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { assertAttestedServerPublicKey } from './ukyc/jwtChain.js';\nimport type { Jwk } from './ukyc/jwtChain.js';\nimport {\n getOrCreateLocalUserSecret,\n UkycLocalUserSecretStore,\n} from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n areVendorDisclaimersCompleted,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimers.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nexport const KYC_PROVIDER_FLOW_STATUSES = [\n 'not_started',\n 'submitted',\n 'abandoned',\n 'failed',\n] as const;\n\n/**\n * Durable outcome of the identity-provider flow.\n *\n * Unlike the KYC session's `finalStatus`, this distinguishes a newly-created\n * pending session from a provider flow that the customer actually submitted.\n */\nexport type KycProviderFlowStatus = (typeof KYC_PROVIDER_FLOW_STATUSES)[number];\n\n// Lifetime of the read-only `ukyc_capability_token` minted when creating a\n// UKYC session. The storage-and-auth spec requires the token's `expires_at` to\n// cover the KYC session's expected lifetime — including the provider journey —\n// rather than a fixed short window, so this is a session-scoped window.\nconst UKYC_CAPABILITY_TOKEN_TTL_MS = 72 * 60 * 60 * 1000;\n\n// First wait between UKYC session-status polls. Each later wait grows by this\n// step, so the delays are 10s, 20s, 30s, and so on.\nconst SESSION_STATUS_POLL_INTERVAL_MS = 10_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\n vendor: KycVendor | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Latest UKYC session status, or `null` when none has been fetched. */\n sessionStatus: KycSessionStatus | null;\n\n /** Last durable identity-provider flow outcome for this session. */\n providerFlowStatus: KycProviderFlowStatus;\n\n // TODO: Check if we need truly need to persist these accepted disclaimers\n /**\n * Persisted vendor-disclaimer acceptance (T&C1) with fixed `moonpay` and\n * `iron` keys. MoonPay stores only `termsAcceptedAt`; Iron stores\n * `disclaimerIds`.\n */\n vendorDisclaimersAccepted: KycVendorDisclaimersAccepted;\n /**\n * KYC-provider disclaimer documents the customer accepted during the last\n * terms acceptance (persisted `{ key, version }` records under `sumsub`).\n * Consents-path vendors require this when resuming a session. `null` for\n * acceptance recorded before this field existed (treated as requiring\n * reacceptance).\n */\n providerDisclaimersAccepted: KycProviderDisclaimersAccepted;\n /**\n * idOS disclaimer documents the customer accepted during the last terms\n * acceptance (persisted `{ key, version }` records). Consents-path vendors\n * require this when resuming a session. `null` for acceptance recorded\n * before this field existed (treated as requiring reacceptance).\n */\n idosDisclaimersAccepted: KycConsentRecord[] | null;\n /**\n * Whether the customer consented to reuse existing idOS credentials\n * during this session. Applied when recording session-scoped disclaimers.\n * Not persisted: a new UKYC session must collect reuse consent again.\n * `null` when never set (treated as `false`).\n */\n credentialReusabilityConsentGiven: boolean | null;\n};\n\nconst kycControllerMetadata = {\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: false,\n },\n vendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sessionStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n providerFlowStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n vendorDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n providerDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n idosDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n credentialReusabilityConsentGiven: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n} satisfies StateMetadata<KycControllerState>;\n\n/**\n * Constructs the default {@link KycVendorDisclaimersAccepted} value.\n *\n * @returns The default vendor-disclaimer acceptance map.\n */\nexport function getDefaultKycVendorDisclaimersAccepted(): KycVendorDisclaimersAccepted {\n return { moonpay: null, iron: null };\n}\n\n/**\n * Constructs the default {@link KycProviderDisclaimersAccepted} value.\n *\n * @returns The default provider-disclaimer acceptance map.\n */\nexport function getDefaultKycProviderDisclaimersAccepted(): KycProviderDisclaimersAccepted {\n return { sumsub: null };\n}\n\n/**\n * Constructs the default {@link KycController} state.\n *\n * @returns The default state.\n */\nexport function getDefaultKycControllerState(): KycControllerState {\n return {\n email: null,\n vendor: null,\n geoCountry: null,\n sessionStatus: null,\n providerFlowStatus: 'not_started',\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n };\n}\n\n/**\n * Parameters for {@link KycController.fetchSessionDisclaimers}. Provide\n * exactly one of `sessionId` or `country`.\n */\nexport type FetchSessionDisclaimersParams =\n | {\n /** UKYC session id from `KycService.createUkycSession`. */\n sessionId: string;\n country?: never;\n }\n | {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n sessionId?: never;\n };\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'startSession',\n 'reset',\n 'clearState',\n 'getSessionStatusForVendor',\n 'getProviderFlowStatus',\n 'refreshSessionStatus',\n 'readSessionStatus',\n 'fetchSessionStatusOnce',\n 'startSessionStatusPolling',\n 'fetchSessionDisclaimers',\n 'recordSessionDisclaimers',\n 'hasCompletedSessionDisclaimers',\n 'fetchVendorDisclaimers',\n 'recordVendorDisclaimers',\n 'hasCompletedVendorDisclaimers',\n 'launchProviderFlow',\n] as const;\n\nexport type KycControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerActions =\n | KycControllerGetStateAction\n | KycControllerMethodActions;\n\ntype AllowedActions =\n | KycServiceMethodActions\n | UserStorageControllerPerformGetStorageAction\n | UserStorageControllerPerformSetStorageAction\n | AuthenticationControllerGetPartnerIdentityTokenAction\n | AuthenticatedUserStorageServicePutIdentitySharingConsentAction;\n\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n};\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * `KycController` orchestrates the vendor-backed KYC / identity-verification\n * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per\n * product surface used by ramps and card. It owns all state and HTTP\n * orchestration (via `KycService`), while vendor protocol handling and\n * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n readonly #localUserSecretStore: UkycLocalUserSecretStore;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #sessionStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped when the loop stops so an in-flight fetch\n * neither writes state nor schedules a follow-up.\n */\n #sessionStatusPollToken = 0;\n\n /**\n * Constructs a new {@link KycController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - Partial initial state; merged over defaults.\n * @param options.sumsubLauncher - The platform SumSub launcher adapter.\n */\n constructor({ messenger, state, sumsubLauncher }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#localUserSecretStore = new UkycLocalUserSecretStore(this.messenger);\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Records identity-sharing consent for the vendor's audience, then mints a\n * partner identity token and reads the verified email claim from JWT `ext`.\n *\n * @param vendor - Identity vendor whose partner audience to request.\n * @returns The minted token and its verified email, or `null` when the\n * profile has no verified email (HTTP 422 / `EmailRequiredError`).\n */\n async #getPartnerIdentityForVendor(vendor: KycVendor): Promise<{\n partnerIdentityToken: string;\n email: string;\n } | null> {\n // TODO: Fix this typing. Safe for now as only Iron is used\n const audience = vendor as IdentitySharingAudience;\n await this.messenger.call(\n 'AuthenticatedUserStorageService:putIdentitySharingConsent',\n { audience, granted: true },\n );\n let partnerIdentityToken: string;\n try {\n partnerIdentityToken = await this.messenger.call(\n 'AuthenticationController:getPartnerIdentityToken',\n ['email'],\n audience,\n );\n } catch (error) {\n if (isEmailRequiredError(error)) {\n return null;\n }\n throw error;\n }\n return {\n partnerIdentityToken,\n email: getEmailFromPartnerIdentityToken(partnerIdentityToken),\n };\n }\n\n /**\n * Starts a KYC session for the given vendor. Reuses a latest vendor session\n * when one exists; otherwise creates a UKYC session.\n *\n * The verified email stored on controller state comes from the partner\n * identity token. When that request returns HTTP 422, a stored email is\n * kept for an existing session. Creating a vendor customer and UKYC session\n * requires the token, which both requests send as `partnerIdentityToken`.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\n async startSession(params: {\n vendor: KycVendor;\n aal2Token?: string;\n }): Promise<KycSessionStatus> {\n const partnerIdentity = await this.#getPartnerIdentityForVendor(\n params.vendor,\n );\n const email = partnerIdentity?.email ?? this.state.email;\n if (!email) {\n throw new Error('KycController missing verified email for vendor');\n }\n if (this.state.email !== null && this.state.email !== email) {\n throw new Error(\n 'KycController already initialized with a different email',\n );\n }\n if (this.state.vendor !== null && this.state.vendor !== params.vendor) {\n throw new Error(\n 'KycController already initialized with a different vendor',\n );\n }\n\n const geoCountry = await this.messenger.call('KycService:getGeoCountry');\n if (\n this.state.geoCountry !== null &&\n this.state.geoCountry !== geoCountry\n ) {\n throw new Error(\n 'KycController already initialized with a different geoCountry',\n );\n }\n\n this.update((state) => {\n state.email = email;\n state.vendor = params.vendor;\n state.geoCountry = geoCountry;\n if (state.sessionStatus === null) {\n state.providerFlowStatus = 'not_started';\n }\n });\n\n if (this.state.sessionStatus === null) {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatusForVendor',\n params.vendor,\n );\n if (sessionStatus !== null) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return this.#refreshAuthorizationsIfNeeded();\n }\n\n // TODO: Probably move this into it's own method? Feels like startSession is a little overloaded.\n // It's assumed that if the session does not exist, the customer does not exist either\n if (!params.aal2Token) {\n throw new Error(\n 'KycController.startSession: aal2Token is required to create a KYC session.',\n );\n }\n\n if (!partnerIdentity) {\n throw new Error(\n 'KycController missing partner identity token for vendor',\n );\n }\n\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n partnerIdentityToken: partnerIdentity.partnerIdentityToken,\n });\n\n return this.#createUkycSession({\n vendor: params.vendor,\n geoCountry,\n aal2Token: params.aal2Token,\n partnerIdentityToken: partnerIdentity.partnerIdentityToken,\n });\n }\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId: this.state.sessionStatus.id },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n // TODO: Should we resume polling here?\n return this.#refreshAuthorizationsIfNeeded();\n }\n\n /**\n * Stops session-status polling and restores default controller state.\n */\n async reset(): Promise<void> {\n this.#stopSessionStatusPolling();\n this.clearState();\n }\n\n /**\n * Restores the controller to its default state.\n */\n clearState(): void {\n this.#stopSessionStatusPolling();\n this.update((state) => {\n state.email = null;\n state.vendor = null;\n state.geoCountry = null;\n state.sessionStatus = null;\n state.providerFlowStatus = 'not_started';\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\n getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n return this.messenger.call('KycService:getSessionStatusForVendor', vendor);\n }\n\n /**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\n getProviderFlowStatus(): KycProviderFlowStatus {\n return this.state.providerFlowStatus;\n }\n\n // TODO: Perhaps this should be renamed to resumeSession()?\n /**\n * Returns the session already stored on state.\n *\n * Starts session-status polling when `finalStatus` is not `approved`,\n * `rejected`, or `retry`. Does not fetch status or refresh capability\n * authorization.\n *\n * @returns The session status stored at call time.\n * @throws If there is no session on state.\n */\n refreshSessionStatus(): KycSessionStatus {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n if (\n !FINAL_STATUSES_TO_STOP_POLLING.has(this.state.sessionStatus.finalStatus)\n ) {\n this.startSessionStatusPolling();\n }\n return this.state.sessionStatus;\n }\n\n /**\n * Returns the persisted session status.\n *\n * Does not call the network and does not start session-status polling.\n *\n * @returns The session on state, or `null` when none is stored.\n */\n readSessionStatus(): KycSessionStatus | null {\n return this.state.sessionStatus;\n }\n\n /**\n * Fetches `GET /sessions/{id}/status` once and writes the result onto state.\n *\n * Does not start the session-status polling timer.\n *\n * @param sessionId - UKYC session id.\n * @returns The fetched session status.\n */\n async fetchSessionStatusOnce(sessionId: string): Promise<KycSessionStatus> {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n /**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The first poll runs\n * immediately. Each later wait starts at 10 seconds and grows by 10 seconds\n * after every poll, including a failed one. Starting the loop again resets\n * that delay. The loop stops once `finalStatus` is `approved`, `rejected`,\n * or `retry`, or when {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\n startSessionStatusPolling(): void {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n this.#stopSessionStatusPolling();\n const token = this.#sessionStatusPollToken;\n let completedPolls = 0;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n completedPolls += 1;\n this.#sessionStatusPollTimer = setTimeout(() => {\n this.#sessionStatusPollTimer = null;\n // `tick` swallows its own errors and therefore never rejects.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, SESSION_STATUS_POLL_INTERVAL_MS * completedPolls);\n this.#sessionStatusPollTimer.unref?.();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }\n\n /**\n * Fetches session status for the polled session and records it when it\n * differs from state.\n *\n * @param sessionId - Session the loop started for.\n * @param token - Polling token captured when the loop started.\n * @returns Whether the loop should stop.\n */\n async #pollSessionStatusOnce(\n sessionId: string,\n token: number,\n ): Promise<boolean> {\n try {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n if (this.#sessionStatusPollToken !== token) {\n return true;\n }\n\n // TODO: This check seems fragile\n if (\n JSON.stringify(this.state.sessionStatus) !==\n JSON.stringify(sessionStatus)\n ) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n }\n\n if (FINAL_STATUSES_TO_STOP_POLLING.has(sessionStatus.finalStatus)) {\n this.#stopSessionStatusPolling();\n return true;\n }\n return false;\n } catch {\n return this.#sessionStatusPollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop.\n */\n #stopSessionStatusPolling(): void {\n this.#sessionStatusPollToken += 1;\n if (this.#sessionStatusPollTimer !== null) {\n clearTimeout(this.#sessionStatusPollTimer);\n this.#sessionStatusPollTimer = null;\n }\n }\n\n /**\n * Creates or reuses a UKYC session, wraps the `data_encryption_key` and\n * `ukyc_capability_token` against the returned encryption schemas, and\n * submits both via authorizations. Stores the resulting session status.\n * kyc-api returns the existing session if one with the same vendor and\n * canonicalUserId already exists.\n *\n * @param params - Vendor, country, and tokens used to create the session.\n * @param params.vendor - Identity vendor for the UKYC session.\n * @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.\n * @param params.aal2Token - AAL2 authentication token sent as the\n * Authorization bearer value for session creation.\n * @param params.partnerIdentityToken - Partner identity token minted for\n * the vendor's audience.\n * @returns The created or refreshed session status.\n */\n async #createUkycSession(params: {\n vendor: KycVendor;\n geoCountry: string;\n aal2Token: string;\n partnerIdentityToken: string;\n }): Promise<KycSessionStatus> {\n // Establish a per-session X25519 keypair used to seal both secrets. The\n // private half stays on the device; the public half is registered on the\n // session so the server can open later authorizations. Each encryption\n // schema from session creation supplies the matching server public key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n // Residence is the ISO 3166-1 alpha-3 country already resolved for\n // disclaimers / KYC-required; fetch it if this sub-flow started without\n // that earlier step.\n const {\n sessionId,\n encryptionDataKey: encryptionDataKeySchema,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n sessionClientPublicKey,\n residenceCountry: params.geoCountry,\n vendor: params.vendor,\n aal2Token: params.aal2Token,\n partnerIdentityToken: params.partnerIdentityToken,\n });\n\n return this.#setAuthorizations({\n sessionId,\n sessionClientPrivateKey,\n sessionClientPublicKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n });\n }\n\n /**\n * Verifies encryption schemas, wraps the `data_encryption_key` and\n * `ukyc_capability_token`, and submits both via\n * {@link KycService.setAuthorizations}. Stores the resulting session status.\n *\n * @param params - Session key material and encryption schemas.\n * @param params.sessionId - UKYC session id to authorize.\n * @param params.sessionClientPrivateKey - Per-session X25519 private key\n * used to seal both secrets.\n * @param params.sessionClientPublicKey - Matching public key registered on\n * the session (must correspond to `sessionClientPrivateKey`).\n * @param params.encryptionDataKeySchema - Encryption schema for the data\n * encryption key.\n * @param params.capabilityTokenSchema - Encryption schema for the capability\n * token.\n * @returns The session status after authorizations are applied.\n */\n async #setAuthorizations(params: {\n sessionId: string;\n sessionClientPrivateKey: Uint8Array;\n sessionClientPublicKey: string;\n encryptionDataKeySchema: EncryptionSchema;\n capabilityTokenSchema: EncryptionSchema;\n }): Promise<KycSessionStatus> {\n const {\n sessionId,\n sessionClientPrivateKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n } = params;\n\n await this.#verifyWrappingKeys(\n encryptionDataKeySchema,\n capabilityTokenSchema,\n );\n\n const { wrappedEncryptionDataKey, wrappedUkycCapabilityToken } =\n await this.#generateWrappedAuthorizations(\n sessionClientPrivateKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n );\n\n const sessionStatus = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n\n return sessionStatus;\n }\n\n /**\n * Mints a new per-session X25519 keypair, reissues wrapping keys for the\n * current session, and submits wrapped authorizations.\n *\n * @returns The session status after authorizations are applied.\n * @throws If there is no session on state.\n */\n async #refreshAuthorizations(): Promise<KycSessionStatus> {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n\n const {\n encryptionDataKey: encryptionDataKeySchema,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:resetWrappingKeys', {\n sessionId,\n sessionClientPublicKey,\n });\n\n return this.#setAuthorizations({\n sessionId,\n sessionClientPrivateKey,\n sessionClientPublicKey,\n encryptionDataKeySchema,\n capabilityTokenSchema,\n });\n }\n\n /**\n * Refreshes and resubmits the UKYC capability authorization when the current\n * session reports it as `new` or `expired`. Uses the `sessionStatus` already\n * on state (callers are responsible for refreshing status when needed).\n * No-ops when KYC has already finished (`finalStatus` is `approved` or\n * `rejected`) or the capability token is `pending`, `stored`, or `wiped`.\n *\n * @returns The current or refreshed session status.\n * @throws If there is no session on state when a refresh is required.\n */\n async #refreshAuthorizationsIfNeeded(): Promise<KycSessionStatus> {\n const { sessionStatus } = this.state;\n if (!sessionStatus) {\n throw new Error('No session was found');\n }\n\n if (!needsCapabilityAuthorizationRefresh(sessionStatus)) {\n return sessionStatus;\n }\n return this.#refreshAuthorizations();\n }\n\n /**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\n async fetchSessionDisclaimers(\n params: FetchSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers | KycDisclaimersCatalog> {\n const { sessionId, country } = params as {\n sessionId?: string;\n country?: string;\n };\n if (sessionId && country) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n if (country) {\n return this.messenger.call(\n 'KycService:fetchSessionDisclaimersByCountry',\n { country },\n );\n }\n\n if (!sessionId) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n return catalog;\n }\n\n /**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\n async recordSessionDisclaimers(params: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: Check if these can simply be mapped to `{key, version}` pairs instead\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n const idOS = consentRecordsFromAcceptedList(\n disclaimers.idOS,\n params.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n disclaimers.kycProvider,\n params.providerDisclaimersAccepted,\n );\n\n try {\n await this.messenger.call('KycService:submitSessionDisclaimers', {\n sessionId: this.state.sessionStatus.id,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n params.credentialReusabilityConsentGiven,\n });\n } catch {\n // A 409 means the session already recorded these consents.\n }\n this.update((state) => {\n // TODO: This shouldn't be hardcoded to sumsub\n state.providerDisclaimersAccepted.sumsub =\n params.providerDisclaimersAccepted;\n state.idosDisclaimersAccepted = params.idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n params.credentialReusabilityConsentGiven;\n });\n }\n\n /**\n * Fetches the current session status and reports whether consent was given.\n *\n * @returns Whether `consentStatus` is `given`.\n * @throws If there is no session on state.\n */\n async hasCompletedSessionDisclaimers(): Promise<boolean> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: remove this explicit call to the service and use the state directly\n // after we have established the pattern for resuming a session after wallet\n // restart more concretely\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId: this.state.sessionStatus.id },\n );\n\n return sessionStatus.consentStatus === 'given';\n }\n\n /**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\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 fetchVendorDisclaimers(params: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n return this.messenger.call('KycService:fetchVendorDisclaimers', params);\n }\n\n /**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\n async recordVendorDisclaimers(params: {\n disclaimerIds: string[];\n }): Promise<KycVendorSigning[]> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n\n if (!this.state.email) {\n throw new Error('No email was found');\n }\n\n const { vendor } = this.state;\n\n const signings = await this.messenger.call(\n 'KycService:submitVendorDisclaimers',\n {\n vendor,\n disclaimerIds: params.disclaimerIds,\n },\n );\n\n // TODO: this only works for Iron right now\n this.update((state) => {\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n vendor,\n {\n disclaimerIds: params.disclaimerIds,\n },\n );\n });\n\n return signings;\n }\n\n /**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\n async hasCompletedVendorDisclaimers(): Promise<boolean> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n if (!this.state.geoCountry) {\n throw new Error('No geoCountry was found');\n }\n\n const fetched = await this.fetchVendorDisclaimers({\n vendor: this.state.vendor,\n country: this.state.geoCountry,\n });\n\n // TODO: this only works for Iron right now\n return areVendorDisclaimersCompleted(\n this.state.vendorDisclaimersAccepted,\n this.state.vendor,\n fetched,\n );\n }\n\n /**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n launchProviderFlow({\n locale,\n debug,\n }: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n // Currently only sumsub is supported and must be used for Iron\n return this.#launchSumsubFlow({ locale, debug });\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. fetches the SumSub applicant access token; and\n * 2. presents the SDK via the injected launcher.\n *\n * Capability authorization must already be valid on\n * {@link KycControllerState.sessionStatus} (see\n * {@link KycController.#refreshAuthorizationsIfNeeded}).\n *\n * @param params - Optional parameters.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n async #launchSumsubFlow(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n const sessionId = this.state.sessionStatus?.id;\n if (!this.#sumsubLauncher.isAvailable() || !sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n try {\n // TODO: check if the sumsub and idos disclaimers are accepted\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n\n // Track whether the SDK ever reported a successful completion or its own\n // failure. A resolved `launch` alone does not imply success — the\n // applicant may have abandoned the flow, or the SDK may have reported\n // that it could not run.\n let reachedCompletion = false;\n let sdkFailed = false;\n\n const result = await this.#sumsubLauncher.launch({\n applicantAccessToken,\n onTokenExpiration: async () => {\n const journey = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return journey.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n if (isSumSubFlowFailed(next)) {\n sdkFailed = true;\n }\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // Some native SDKs resolve with their final status without first\n // delivering the corresponding state-change callback.\n reachedCompletion ||= isSumSubFlowCompleted(result.status);\n sdkFailed ||= isSumSubFlowFailed(result.status);\n\n const currentSessionStatus = this.state.sessionStatus;\n if (currentSessionStatus?.id !== sessionId) {\n return 'failed';\n }\n\n if (sdkFailed) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n if (reachedCompletion) {\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result.\n this.update((state) => {\n state.sessionStatus = {\n ...currentSessionStatus,\n finalStatus: 'pending',\n };\n state.providerFlowStatus = 'submitted';\n });\n this.startSessionStatusPolling();\n return 'submitted';\n }\n\n this.update((state) => {\n state.providerFlowStatus = 'abandoned';\n });\n return 'abandoned';\n } catch {\n if (this.state.sessionStatus?.id === sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n }\n return 'failed';\n }\n }\n\n /**\n * Verifies each schema's jwtChain against the matching issuer JWKS, then\n * confirms the returned server public key matches the value attested inside\n * the verified JWT payload before trusting it for wrapping.\n * `encryptionDataKey` is attested by the idOS enclave; `ukycCapabilityToken`\n * by the idOS relay.\n *\n * Fetch and verification failures are rethrown as a short message suitable\n * for display. The original error is preserved on `cause`.\n *\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n * @throws When the issuer signing keys cannot be fetched, or a schema's\n * `jwtChain` does not verify.\n */\n async #verifyWrappingKeys(\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<void> {\n let idosEnclaveKeys: Jwk[];\n let idosRelayKeys: Jwk[];\n try {\n [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] = await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n } catch (error) {\n throw wrapError(\n error,\n 'KycController.#verifyWrappingKeys: Unable to fetch JWKS needed to verify wrapping keys.',\n );\n }\n\n try {\n assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n } catch (error) {\n throw wrapError(\n error,\n 'KycController.#verifyWrappingKeys: Failed to verify the wrapping keys.',\n );\n }\n }\n\n /**\n * Derives the `data_encryption_key` from the `local_user_secret`, mints a\n * capability token, and wraps both for the session server. Only the wrapped\n * (encrypted) material ever leaves the device.\n *\n * Only the client holds the signing key derived from `local_user_secret`, so\n * only the client can mint the token.\n *\n * @param sessionClientPrivateKey - Per-session X25519 private key used to\n * seal both secrets.\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n * @returns The wrapped encryption key and capability token.\n */\n async #generateWrappedAuthorizations(\n sessionClientPrivateKey: Uint8Array,\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<{\n wrappedEncryptionDataKey: CapabilityAuthorization;\n wrappedUkycCapabilityToken: CapabilityAuthorization;\n }> {\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore,\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionDataKey = wrapEncryptionKey(\n sessionClientPrivateKey,\n encryptionDataKey.serverPublicKey.x,\n clientMaterial.dataEncryptionKey,\n );\n\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write\n operations: ['read', 'write'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n const wrappedUkycCapabilityToken = wrapEncryptionKey(\n sessionClientPrivateKey,\n capabilityTokenSchema.serverPublicKey.x,\n stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)),\n );\n\n return { wrappedEncryptionDataKey, wrappedUkycCapabilityToken };\n }\n}\n"]}
@@ -118,7 +118,8 @@ export type KycServiceSubmitSessionDisclaimersAction = {
118
118
  * {@link KycService.createUkycSession}.
119
119
  *
120
120
  * This is an unauthenticated request to a well-known path on the idOS enclave
121
- * host, distinct from the UKYC base URL.
121
+ * host, distinct from the UKYC base URL. A successful response is cached in
122
+ * the service query cache for 24 hours.
122
123
  *
123
124
  * @returns The JWKS keys.
124
125
  */
@@ -131,7 +132,8 @@ export type KycServiceFetchIdosEnclaveJwksAction = {
131
132
  * schema's `jwtChain` from {@link KycService.createUkycSession}.
132
133
  *
133
134
  * This is an unauthenticated request to a well-known path on the idOS relay
134
- * host, distinct from both the UKYC base URL and the idOS enclave.
135
+ * host, distinct from both the UKYC base URL and the idOS enclave. A
136
+ * successful response is cached in the service query cache for 24 hours.
135
137
  *
136
138
  * @returns The JWKS keys.
137
139
  */
@@ -156,6 +158,8 @@ export type KycServiceFetchIdosRelayJwksAction = {
156
158
  * @param params - The session parameters.
157
159
  * @param params.aal2Token - AAL2 authentication token used as the
158
160
  * Authorization bearer value.
161
+ * @param params.partnerIdentityToken - Optional partner identity token for
162
+ * the session's vendor audience, sent as `partnerIdentityToken`.
159
163
  * @returns The UKYC session id and encryption schemas.
160
164
  */
161
165
  export type KycServiceCreateUkycSessionAction = {
@@ -1 +1 @@
1
- {"version":3,"file":"KycService-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycService-method-action-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KycService-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycService-method-action-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"KycService-method-action-types.js","sourceRoot":"","sources":["../src/KycService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycService } from './KycService.js';\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 */\nexport type KycServiceGetGeoCountryAction = {\n type: `KycService:getGeoCountry`;\n handler: KycService['getGeoCountry'];\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 */\nexport type KycServiceFetchVendorDisclaimersAction = {\n type: `KycService:fetchVendorDisclaimers`;\n handler: KycService['fetchVendorDisclaimers'];\n};\n\n/**\n * Creates a MoonPay vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\nexport type KycServiceCreateMoonpaySessionAction = {\n type: `KycService:createMoonpaySession`;\n handler: KycService['createMoonpaySession'];\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.partnerIdentityToken - Partner identity token minted by\n * `AuthenticationController:getPartnerIdentityToken`.\n * @returns The vendor customer record (subset validated for controller use).\n */\nexport type KycServiceCreateVendorCustomerAction = {\n type: `KycService:createVendorCustomer`;\n handler: KycService['createVendorCustomer'];\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 */\nexport type KycServiceSubmitVendorDisclaimersAction = {\n type: `KycService:submitVendorDisclaimers`;\n handler: KycService['submitVendorDisclaimers'];\n};\n\n/**\n * Fetches the global idOS + KYC-provider disclaimer catalog\n * (`GET /disclaimers?country=`). Carries no consent state — per-document\n * `consented` flags and `credentialReusabilityConsentGiven` are\n * session-scoped via {@link fetchSessionDisclaimersBySessionId}. Vendor T&Cs continue to\n * come from {@link fetchVendorDisclaimers}.\n *\n * @param params - The parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog documents.\n */\nexport type KycServiceFetchSessionDisclaimersByCountryAction = {\n type: `KycService:fetchSessionDisclaimersByCountry`;\n handler: KycService['fetchSessionDisclaimersByCountry'];\n};\n\n/**\n * Fetches the session-scoped idOS + KYC-provider disclaimer catalog\n * (`GET /sessions/{sessionId}/disclaimers`), including per-session\n * `consented` flags and `credentialReusabilityConsentGiven`. For the\n * pre-session global catalog use {@link fetchSessionDisclaimersByCountry}.\n * Vendor T&Cs continue to come from {@link fetchVendorDisclaimers}.\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 */\nexport type KycServiceFetchSessionDisclaimersBySessionIdAction = {\n type: `KycService:fetchSessionDisclaimersBySessionId`;\n handler: KycService['fetchSessionDisclaimersBySessionId'];\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 fetchSessionDisclaimersBySessionId}. 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 */\nexport type KycServiceSubmitSessionDisclaimersAction = {\n type: `KycService:submitSessionDisclaimers`;\n handler: KycService['submitSessionDisclaimers'];\n};\n\n/**\n * Fetches the idOS enclave JWKS used to verify the\n * `encryptionDataKey` schema's `jwtChain` from\n * {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS enclave\n * host, distinct from the UKYC base URL.\n *\n * @returns The JWKS keys.\n */\nexport type KycServiceFetchIdosEnclaveJwksAction = {\n type: `KycService:fetchIdosEnclaveJwks`;\n handler: KycService['fetchIdosEnclaveJwks'];\n};\n\n/**\n * Fetches the idOS relay JWKS used to verify the `ukycCapabilityToken`\n * schema's `jwtChain` from {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS relay\n * host, distinct from both the UKYC base URL and the idOS enclave.\n *\n * @returns The JWKS keys.\n */\nexport type KycServiceFetchIdosRelayJwksAction = {\n type: `KycService:fetchIdosRelayJwks`;\n handler: KycService['fetchIdosRelayJwks'];\n};\n\n/**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * The client registers its per-session X25519 public key so the server can\n * later open boxes sealed with the matching private key, and supplies the\n * customer's ISO 3166-1 alpha-3 country of residence. The response\n * 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 * Session creation is authenticated with `params.aal2Token` as the\n * `Authorization` bearer value, instead of the wallet bearer token.\n *\n * @param params - The session parameters.\n * @param params.aal2Token - AAL2 authentication token used as the\n * Authorization bearer value.\n * @returns The UKYC session id and encryption schemas.\n */\nexport type KycServiceCreateUkycSessionAction = {\n type: `KycService:createUkycSession`;\n handler: KycService['createUkycSession'];\n};\n\n/**\n * Reissues wrapping keys for an existing UKYC session\n * (`POST /sessions/{sessionId}/wrapping-keys`).\n *\n * The client registers a new per-session X25519 public key so the server can\n * open boxes sealed with the matching private key. The response matches\n * {@link KycService.createUkycSession}: a session id plus per-secret\n * encryption schemas (`encryptionDataKey` and `ukycCapabilityToken`) used to\n * wrap and submit authorizations.\n *\n * @param params - The session whose wrapping keys should be reset.\n * @param params.sessionId - UKYC session id.\n * @param params.sessionClientPublicKey - Per-session X25519 public key\n * (unpadded base64url) registered on the session.\n * @returns The session id and fresh encryption schemas.\n */\nexport type KycServiceResetWrappingKeysAction = {\n type: `KycService:resetWrappingKeys`;\n handler: KycService['resetWrappingKeys'];\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 */\nexport type KycServiceSetAuthorizationsAction = {\n type: `KycService:setAuthorizations`;\n handler: KycService['setAuthorizations'];\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 */\nexport type KycServiceCreateJourneyAction = {\n type: `KycService:createJourney`;\n handler: KycService['createJourney'];\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 */\nexport type KycServiceGetSessionStatusAction = {\n type: `KycService:getSessionStatus`;\n handler: KycService['getSessionStatus'];\n};\n\n/**\n * Fetches the latest UKYC session status for an identity vendor\n * (`GET /sessions/latest/status/{vendor}`).\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when no latest session exists.\n */\nexport type KycServiceGetSessionStatusForVendorAction = {\n type: `KycService:getSessionStatusForVendor`;\n handler: KycService['getSessionStatusForVendor'];\n};\n\n/**\n * Union of all KycService action types.\n */\nexport type KycServiceMethodActions =\n | KycServiceGetGeoCountryAction\n | KycServiceFetchVendorDisclaimersAction\n | KycServiceCreateMoonpaySessionAction\n | KycServiceCreateVendorCustomerAction\n | KycServiceSubmitVendorDisclaimersAction\n | KycServiceFetchSessionDisclaimersByCountryAction\n | KycServiceFetchSessionDisclaimersBySessionIdAction\n | KycServiceSubmitSessionDisclaimersAction\n | KycServiceFetchIdosEnclaveJwksAction\n | KycServiceFetchIdosRelayJwksAction\n | KycServiceCreateUkycSessionAction\n | KycServiceResetWrappingKeysAction\n | KycServiceSetAuthorizationsAction\n | KycServiceCreateJourneyAction\n | KycServiceGetSessionStatusAction\n | KycServiceGetSessionStatusForVendorAction;\n"]}
1
+ {"version":3,"file":"KycService-method-action-types.js","sourceRoot":"","sources":["../src/KycService-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycService } from './KycService.js';\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 */\nexport type KycServiceGetGeoCountryAction = {\n type: `KycService:getGeoCountry`;\n handler: KycService['getGeoCountry'];\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 */\nexport type KycServiceFetchVendorDisclaimersAction = {\n type: `KycService:fetchVendorDisclaimers`;\n handler: KycService['fetchVendorDisclaimers'];\n};\n\n/**\n * Creates a MoonPay vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\nexport type KycServiceCreateMoonpaySessionAction = {\n type: `KycService:createMoonpaySession`;\n handler: KycService['createMoonpaySession'];\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.partnerIdentityToken - Partner identity token minted by\n * `AuthenticationController:getPartnerIdentityToken`.\n * @returns The vendor customer record (subset validated for controller use).\n */\nexport type KycServiceCreateVendorCustomerAction = {\n type: `KycService:createVendorCustomer`;\n handler: KycService['createVendorCustomer'];\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 */\nexport type KycServiceSubmitVendorDisclaimersAction = {\n type: `KycService:submitVendorDisclaimers`;\n handler: KycService['submitVendorDisclaimers'];\n};\n\n/**\n * Fetches the global idOS + KYC-provider disclaimer catalog\n * (`GET /disclaimers?country=`). Carries no consent state — per-document\n * `consented` flags and `credentialReusabilityConsentGiven` are\n * session-scoped via {@link fetchSessionDisclaimersBySessionId}. Vendor T&Cs continue to\n * come from {@link fetchVendorDisclaimers}.\n *\n * @param params - The parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog documents.\n */\nexport type KycServiceFetchSessionDisclaimersByCountryAction = {\n type: `KycService:fetchSessionDisclaimersByCountry`;\n handler: KycService['fetchSessionDisclaimersByCountry'];\n};\n\n/**\n * Fetches the session-scoped idOS + KYC-provider disclaimer catalog\n * (`GET /sessions/{sessionId}/disclaimers`), including per-session\n * `consented` flags and `credentialReusabilityConsentGiven`. For the\n * pre-session global catalog use {@link fetchSessionDisclaimersByCountry}.\n * Vendor T&Cs continue to come from {@link fetchVendorDisclaimers}.\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 */\nexport type KycServiceFetchSessionDisclaimersBySessionIdAction = {\n type: `KycService:fetchSessionDisclaimersBySessionId`;\n handler: KycService['fetchSessionDisclaimersBySessionId'];\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 fetchSessionDisclaimersBySessionId}. 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 */\nexport type KycServiceSubmitSessionDisclaimersAction = {\n type: `KycService:submitSessionDisclaimers`;\n handler: KycService['submitSessionDisclaimers'];\n};\n\n/**\n * Fetches the idOS enclave JWKS used to verify the\n * `encryptionDataKey` schema's `jwtChain` from\n * {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS enclave\n * host, distinct from the UKYC base URL. A successful response is cached in\n * the service query cache for 24 hours.\n *\n * @returns The JWKS keys.\n */\nexport type KycServiceFetchIdosEnclaveJwksAction = {\n type: `KycService:fetchIdosEnclaveJwks`;\n handler: KycService['fetchIdosEnclaveJwks'];\n};\n\n/**\n * Fetches the idOS relay JWKS used to verify the `ukycCapabilityToken`\n * schema's `jwtChain` from {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS relay\n * host, distinct from both the UKYC base URL and the idOS enclave. A\n * successful response is cached in the service query cache for 24 hours.\n *\n * @returns The JWKS keys.\n */\nexport type KycServiceFetchIdosRelayJwksAction = {\n type: `KycService:fetchIdosRelayJwks`;\n handler: KycService['fetchIdosRelayJwks'];\n};\n\n/**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * The client registers its per-session X25519 public key so the server can\n * later open boxes sealed with the matching private key, and supplies the\n * customer's ISO 3166-1 alpha-3 country of residence. The response\n * 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 * Session creation is authenticated with `params.aal2Token` as the\n * `Authorization` bearer value, instead of the wallet bearer token.\n *\n * @param params - The session parameters.\n * @param params.aal2Token - AAL2 authentication token used as the\n * Authorization bearer value.\n * @param params.partnerIdentityToken - Optional partner identity token for\n * the session's vendor audience, sent as `partnerIdentityToken`.\n * @returns The UKYC session id and encryption schemas.\n */\nexport type KycServiceCreateUkycSessionAction = {\n type: `KycService:createUkycSession`;\n handler: KycService['createUkycSession'];\n};\n\n/**\n * Reissues wrapping keys for an existing UKYC session\n * (`POST /sessions/{sessionId}/wrapping-keys`).\n *\n * The client registers a new per-session X25519 public key so the server can\n * open boxes sealed with the matching private key. The response matches\n * {@link KycService.createUkycSession}: a session id plus per-secret\n * encryption schemas (`encryptionDataKey` and `ukycCapabilityToken`) used to\n * wrap and submit authorizations.\n *\n * @param params - The session whose wrapping keys should be reset.\n * @param params.sessionId - UKYC session id.\n * @param params.sessionClientPublicKey - Per-session X25519 public key\n * (unpadded base64url) registered on the session.\n * @returns The session id and fresh encryption schemas.\n */\nexport type KycServiceResetWrappingKeysAction = {\n type: `KycService:resetWrappingKeys`;\n handler: KycService['resetWrappingKeys'];\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 */\nexport type KycServiceSetAuthorizationsAction = {\n type: `KycService:setAuthorizations`;\n handler: KycService['setAuthorizations'];\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 */\nexport type KycServiceCreateJourneyAction = {\n type: `KycService:createJourney`;\n handler: KycService['createJourney'];\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 */\nexport type KycServiceGetSessionStatusAction = {\n type: `KycService:getSessionStatus`;\n handler: KycService['getSessionStatus'];\n};\n\n/**\n * Fetches the latest UKYC session status for an identity vendor\n * (`GET /sessions/latest/status/{vendor}`).\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when no latest session exists.\n */\nexport type KycServiceGetSessionStatusForVendorAction = {\n type: `KycService:getSessionStatusForVendor`;\n handler: KycService['getSessionStatusForVendor'];\n};\n\n/**\n * Union of all KycService action types.\n */\nexport type KycServiceMethodActions =\n | KycServiceGetGeoCountryAction\n | KycServiceFetchVendorDisclaimersAction\n | KycServiceCreateMoonpaySessionAction\n | KycServiceCreateVendorCustomerAction\n | KycServiceSubmitVendorDisclaimersAction\n | KycServiceFetchSessionDisclaimersByCountryAction\n | KycServiceFetchSessionDisclaimersBySessionIdAction\n | KycServiceSubmitSessionDisclaimersAction\n | KycServiceFetchIdosEnclaveJwksAction\n | KycServiceFetchIdosRelayJwksAction\n | KycServiceCreateUkycSessionAction\n | KycServiceResetWrappingKeysAction\n | KycServiceSetAuthorizationsAction\n | KycServiceCreateJourneyAction\n | KycServiceGetSessionStatusAction\n | KycServiceGetSessionStatusForVendorAction;\n"]}
@@ -304,6 +304,12 @@ export type CreateUkycSessionParams = {
304
304
  * token.
305
305
  */
306
306
  aal2Token: string;
307
+ /**
308
+ * Partner identity token minted by
309
+ * `AuthenticationController:getPartnerIdentityToken` for the session's
310
+ * vendor audience. Omitted from the request body when not provided.
311
+ */
312
+ partnerIdentityToken?: string;
307
313
  };
308
314
  /**
309
315
  * Encrypted capability authorization payload (base64url nonce + ciphertext)
@@ -335,10 +341,11 @@ export type ResetWrappingKeysParams = {
335
341
  };
336
342
  /**
337
343
  * `KycService` communicates with the Universal KYC (UKYC) backend to drive the
338
- * identity + document-verification flow. It is stateless and platform-agnostic:
339
- * HTTP is performed through the runtime's native `fetch` (or an injected
340
- * `fetch` when provided), and the auth bearer token and geolocation come from
341
- * other controllers via the messenger.
344
+ * identity + document-verification flow. It does not persist session state and
345
+ * is platform-agnostic: HTTP is performed through the runtime's native `fetch`
346
+ * (or an injected `fetch` when provided), and the auth bearer token and
347
+ * geolocation come from other controllers via the messenger. Successful
348
+ * well-known JWKS responses are kept in the service query cache for 24 hours.
342
349
  *
343
350
  * HTTP endpoints call `#requestJson` (via the injected or native `fetch`).
344
351
  */
@@ -457,7 +464,8 @@ export declare class KycService extends BaseDataService<typeof serviceName, KycS
457
464
  * {@link KycService.createUkycSession}.
458
465
  *
459
466
  * This is an unauthenticated request to a well-known path on the idOS enclave
460
- * host, distinct from the UKYC base URL.
467
+ * host, distinct from the UKYC base URL. A successful response is cached in
468
+ * the service query cache for 24 hours.
461
469
  *
462
470
  * @returns The JWKS keys.
463
471
  */
@@ -467,7 +475,8 @@ export declare class KycService extends BaseDataService<typeof serviceName, KycS
467
475
  * schema's `jwtChain` from {@link KycService.createUkycSession}.
468
476
  *
469
477
  * This is an unauthenticated request to a well-known path on the idOS relay
470
- * host, distinct from both the UKYC base URL and the idOS enclave.
478
+ * host, distinct from both the UKYC base URL and the idOS enclave. A
479
+ * successful response is cached in the service query cache for 24 hours.
471
480
  *
472
481
  * @returns The JWKS keys.
473
482
  */
@@ -489,6 +498,8 @@ export declare class KycService extends BaseDataService<typeof serviceName, KycS
489
498
  * @param params - The session parameters.
490
499
  * @param params.aal2Token - AAL2 authentication token used as the
491
500
  * Authorization bearer value.
501
+ * @param params.partnerIdentityToken - Optional partner identity token for
502
+ * the session's vendor audience, sent as `partnerIdentityToken`.
492
503
  * @returns The UKYC session id and encryption schemas.
493
504
  */
494
505
  createUkycSession(params: CreateUkycSessionParams): Promise<UkycSessionResponse>;
@@ -1 +1 @@
1
- {"version":3,"file":"KycService.d.ts","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KycService.d.ts","sourceRoot":"","sources":["../src/KycService.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { BaseDataService } from '@metamask/base-data-service';
2
2
  import { HttpError } from '@metamask/controller-utils';
3
3
  import { array, assert, boolean, optional, string, StructError, type, } from '@metamask/superstruct';
4
+ import { Duration, inMilliseconds } from '@metamask/utils';
4
5
  import { alpha2ToAlpha3 } from './countryCodes.js';
5
6
  import { UKYC_JWKS_PATH } from './ukyc/constants.js';
6
7
  // === GENERAL ===
@@ -121,13 +122,17 @@ const SessionDisclaimersResponseStruct = type({
121
122
  kycProvider: array(ConsentDocumentStruct),
122
123
  credentialReusabilityConsentGiven: boolean(),
123
124
  });
125
+ // Successful well-known JWKS responses stay fresh for one day. Issuer keys
126
+ // rotate infrequently, and session creation verifies against them more than once.
127
+ const JWKS_CACHE_TTL_MS = inMilliseconds(1, Duration.Day);
124
128
  // === SERVICE DEFINITION ===
125
129
  /**
126
130
  * `KycService` communicates with the Universal KYC (UKYC) backend to drive the
127
- * identity + document-verification flow. It is stateless and platform-agnostic:
128
- * HTTP is performed through the runtime's native `fetch` (or an injected
129
- * `fetch` when provided), and the auth bearer token and geolocation come from
130
- * other controllers via the messenger.
131
+ * identity + document-verification flow. It does not persist session state and
132
+ * is platform-agnostic: HTTP is performed through the runtime's native `fetch`
133
+ * (or an injected `fetch` when provided), and the auth bearer token and
134
+ * geolocation come from other controllers via the messenger. Successful
135
+ * well-known JWKS responses are kept in the service query cache for 24 hours.
131
136
  *
132
137
  * HTTP endpoints call `#requestJson` (via the injected or native `fetch`).
133
138
  */
@@ -335,6 +340,12 @@ export class KycService extends BaseDataService {
335
340
  /**
336
341
  * Fetches a well-known JWKS from `baseUrl`.
337
342
  *
343
+ * A successful response stays fresh in the service query cache for 24 hours.
344
+ * A later call for the same URL within that window returns the cached keys.
345
+ * Failed and malformed responses are not cached. Concurrent callers for the
346
+ * same URL share one in-flight request. `KycService:invalidateQueries` drops
347
+ * the cached keys.
348
+ *
338
349
  * @param baseUrl - Host base URL that serves `/.well-known/jwks.json`.
339
350
  * @param responseLabel - Label used in malformed-response errors.
340
351
  * @param missingConfigMessage - Error thrown when `baseUrl` is empty.
@@ -345,8 +356,18 @@ export class KycService extends BaseDataService {
345
356
  throw new Error(missingConfigMessage);
346
357
  }
347
358
  const url = new URL(UKYC_JWKS_PATH, baseUrl);
348
- const data = await this.#requestJson(url, { method: 'GET' }, { authenticated: false });
349
- return this.#validateResponse(data, JwksResponseStruct, responseLabel);
359
+ return this.fetchQuery({
360
+ queryKey: [`${serviceName}:fetchWellKnownJwks`, url.toString()],
361
+ queryFn: async () => {
362
+ const data = await this.#requestJson(url, { method: 'GET' }, { authenticated: false });
363
+ return this.#validateResponse(data, JwksResponseStruct, responseLabel);
364
+ },
365
+ staleTime: JWKS_CACHE_TTL_MS,
366
+ // fetchQuery does not subscribe an observer, so the entry is inactive
367
+ // immediately. Without gcTime the default 5-minute GC would drop it
368
+ // while it is still fresh.
369
+ gcTime: JWKS_CACHE_TTL_MS,
370
+ });
350
371
  }
351
372
  /**
352
373
  * Fetches the idOS enclave JWKS used to verify the
@@ -354,7 +375,8 @@ export class KycService extends BaseDataService {
354
375
  * {@link KycService.createUkycSession}.
355
376
  *
356
377
  * This is an unauthenticated request to a well-known path on the idOS enclave
357
- * host, distinct from the UKYC base URL.
378
+ * host, distinct from the UKYC base URL. A successful response is cached in
379
+ * the service query cache for 24 hours.
358
380
  *
359
381
  * @returns The JWKS keys.
360
382
  */
@@ -366,7 +388,8 @@ export class KycService extends BaseDataService {
366
388
  * schema's `jwtChain` from {@link KycService.createUkycSession}.
367
389
  *
368
390
  * This is an unauthenticated request to a well-known path on the idOS relay
369
- * host, distinct from both the UKYC base URL and the idOS enclave.
391
+ * host, distinct from both the UKYC base URL and the idOS enclave. A
392
+ * successful response is cached in the service query cache for 24 hours.
370
393
  *
371
394
  * @returns The JWKS keys.
372
395
  */
@@ -390,6 +413,8 @@ export class KycService extends BaseDataService {
390
413
  * @param params - The session parameters.
391
414
  * @param params.aal2Token - AAL2 authentication token used as the
392
415
  * Authorization bearer value.
416
+ * @param params.partnerIdentityToken - Optional partner identity token for
417
+ * the session's vendor audience, sent as `partnerIdentityToken`.
393
418
  * @returns The UKYC session id and encryption schemas.
394
419
  */
395
420
  async createUkycSession(params) {
@@ -405,6 +430,9 @@ export class KycService extends BaseDataService {
405
430
  sessionClientPublicKey: params.sessionClientPublicKey,
406
431
  residenceCountry: params.residenceCountry,
407
432
  vendorMetadata: params.vendorMetadata ?? {},
433
+ ...(params.partnerIdentityToken && {
434
+ partnerIdentityToken: params.partnerIdentityToken,
435
+ }),
408
436
  }),
409
437
  }, { bearerToken: params.aal2Token });
410
438
  return this.#validateResponse(data, UkycSessionResponseStruct, 'UKYC sessions');
@@ -1 +1 @@
1
- {"version":3,"file":"KycService.js","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 optional,\n string,\n StructError,\n type,\n} from '@metamask/superstruct';\nimport type { Json } 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 KycDisclaimersCatalog,\n KycSessionDisclaimers,\n KycSessionStatus,\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 'fetchVendorDisclaimers',\n 'createMoonpaySession',\n 'createVendorCustomer',\n 'submitVendorDisclaimers',\n 'fetchSessionDisclaimersByCountry',\n 'fetchSessionDisclaimersBySessionId',\n 'submitSessionDisclaimers',\n 'fetchIdosEnclaveJwks',\n 'fetchIdosRelayJwks',\n 'createUkycSession',\n 'resetWrappingKeys',\n 'setAuthorizations',\n 'createJourney',\n 'getSessionStatus',\n 'getSessionStatusForVendor',\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 idOS enclave, from which the JWKS used to\n * verify the `encryptionDataKey` schema's `jwtChain` is fetched.\n */\n idosEnclaveBaseUrl?: string;\n /**\n * Base URL of the idOS relay, from which the JWKS used to verify the\n * `ukycCapabilityToken` schema's `jwtChain` is fetched.\n */\n idosRelayBaseUrl?: 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 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 id: string(),\n finalStatus: string(),\n statusMessage: optional(string()),\n externalUserId: string(),\n kycStatus: string(),\n vendor: string(),\n vendorStatus: string(),\n consentStatus: optional(string()),\n idOSStatus: optional(string()),\n capabilityAuthorizationStatus: optional(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 CatalogDocumentFields = {\n key: string(),\n version: string(),\n title: string(),\n url: string(),\n} as const;\n\nconst CatalogDocumentStruct = type(CatalogDocumentFields);\n\n// Session documents also report whether that version was already consented to.\nconst ConsentDocumentStruct = type({\n ...CatalogDocumentFields,\n consented: boolean(),\n});\n\n/**\n * Global catalog from `GET /disclaimers` (no per-document `consented` flag and\n * no credential-reuse flag).\n */\nconst GlobalDisclaimersResponseStruct = type({\n idOS: array(CatalogDocumentStruct),\n kycProvider: array(CatalogDocumentStruct),\n});\n\n/** Session catalog from `GET`/`POST /sessions/{id}/disclaimers`. */\nconst SessionDisclaimersResponseStruct = type({\n idOS: array(ConsentDocumentStruct),\n kycProvider: array(ConsentDocumentStruct),\n credentialReusabilityConsentGiven: boolean(),\n});\n\n// === PARAM TYPES ===\n\nexport type CreateMoonpaySessionParams = {\n partnerIdentityToken: string;\n termsAcceptedAt: string;\n disclaimerIds: string[];\n};\n\nexport type CreateVendorCustomerParams = {\n vendor: KycVendor;\n partnerIdentityToken: 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.fetchVendorDisclaimers}. */\n disclaimerIds: string[];\n};\n\nexport type FetchSessionDisclaimersByCountryParams = {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n};\n\nexport type FetchSessionDisclaimersBySessionIdParams = {\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 /**\n * The client's per-session X25519 public key (unpadded base64url). Generated\n * with the matching private key used later to wrap authorizations, so the\n * session server can open those boxes.\n */\n sessionClientPublicKey: string;\n /**\n * Country of residence in ISO 3166-1 alpha-3 format (e.g. `USA`, `GBR`).\n */\n residenceCountry: 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 * AAL2 authentication token sent as the `Authorization` bearer value for\n * `POST /sessions`. Other KYC requests continue to use the wallet bearer\n * token.\n */\n aal2Token: string;\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\nexport type ResetWrappingKeysParams = {\n /** UKYC session id whose wrapping keys should be reissued. */\n sessionId: string;\n /**\n * The client's per-session X25519 public key (unpadded base64url). Generated\n * with the matching private key used to wrap the refreshed authorizations,\n * so the session server can open those boxes.\n */\n sessionClientPublicKey: 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 * HTTP endpoints call `#requestJson` (via the injected or native `fetch`).\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 #idosEnclaveBaseUrl: string;\n\n readonly #idosRelayBaseUrl: 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.idosEnclaveBaseUrl - Base URL of the idOS enclave, from\n * which the JWKS used to verify the `encryptionDataKey` schema's `jwtChain`\n * is fetched.\n * @param options.idosRelayBaseUrl - Base URL of the idOS relay, from which\n * the JWKS used to verify the `ukycCapabilityToken` schema's `jwtChain` is\n * 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 idosEnclaveBaseUrl,\n idosRelayBaseUrl,\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.#idosEnclaveBaseUrl = idosEnclaveBaseUrl ?? '';\n this.#idosRelayBaseUrl = idosRelayBaseUrl ?? '';\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 // `vendorError`).\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 fetchVendorDisclaimers({\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.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n DisclaimersResponseStruct,\n 'disclaimers',\n );\n }\n\n /**\n * Creates a MoonPay vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\n async createMoonpaySession(\n params: CreateMoonpaySessionParams,\n ): Promise<Infer<typeof CreateSessionResponseStruct>> {\n const url = new URL('/vendors/moonpay/sessions', this.#baseUrl);\n const data = await this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(params),\n });\n return this.#validateResponse(\n data,\n CreateSessionResponseStruct,\n 'sessions',\n );\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.partnerIdentityToken - Partner identity token minted by\n * `AuthenticationController:getPartnerIdentityToken`.\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n partnerIdentityToken: params.partnerIdentityToken,\n }),\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({ disclaimerIds: params.disclaimerIds }),\n });\n return this.#validateResponse(\n data,\n VendorSigningsResponseStruct,\n 'vendor disclaimers',\n );\n }\n\n /**\n * Fetches the global idOS + KYC-provider disclaimer catalog\n * (`GET /disclaimers?country=`). Carries no consent state — per-document\n * `consented` flags and `credentialReusabilityConsentGiven` are\n * session-scoped via {@link fetchSessionDisclaimersBySessionId}. Vendor T&Cs continue to\n * come from {@link fetchVendorDisclaimers}.\n *\n * @param params - The parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog documents.\n */\n async fetchSessionDisclaimersByCountry({\n country,\n }: FetchSessionDisclaimersByCountryParams): Promise<KycDisclaimersCatalog> {\n if (country.length !== 3) {\n throw new Error(\n `KycService.fetchSessionDisclaimersByCountry: country must be an ISO 3166-1 alpha-3 code (received \"${country}\").`,\n );\n }\n\n const url = new URL('/disclaimers', this.#baseUrl);\n url.searchParams.set('country', country);\n const data = await this.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n GlobalDisclaimersResponseStruct,\n 'disclaimers',\n );\n }\n\n /**\n * Fetches the session-scoped idOS + KYC-provider disclaimer catalog\n * (`GET /sessions/{sessionId}/disclaimers`), including per-session\n * `consented` flags and `credentialReusabilityConsentGiven`. For the\n * pre-session global catalog use {@link fetchSessionDisclaimersByCountry}.\n * Vendor T&Cs continue to come from {@link fetchVendorDisclaimers}.\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 fetchSessionDisclaimersBySessionId({\n sessionId,\n }: FetchSessionDisclaimersBySessionIdParams): Promise<KycSessionDisclaimers> {\n const url = new URL(\n `/sessions/${encodeURIComponent(sessionId)}/disclaimers`,\n this.#baseUrl,\n );\n const data = await this.#requestJson(url, { method: 'GET' });\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 fetchSessionDisclaimersBySessionId}. 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.#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 return this.#validateResponse(\n data,\n SessionDisclaimersResponseStruct,\n 'session disclaimers',\n );\n }\n\n /**\n * Fetches a well-known JWKS from `baseUrl`.\n *\n * @param baseUrl - Host base URL that serves `/.well-known/jwks.json`.\n * @param responseLabel - Label used in malformed-response errors.\n * @param missingConfigMessage - Error thrown when `baseUrl` is empty.\n * @returns The JWKS keys.\n */\n async #fetchWellKnownJwks(\n baseUrl: string,\n responseLabel: string,\n missingConfigMessage: string,\n ): Promise<JwksResponse> {\n if (!baseUrl) {\n throw new Error(missingConfigMessage);\n }\n const url = new URL(UKYC_JWKS_PATH, baseUrl);\n const data = await this.#requestJson(\n url,\n { method: 'GET' },\n { authenticated: false },\n );\n return this.#validateResponse(data, JwksResponseStruct, responseLabel);\n }\n\n /**\n * Fetches the idOS enclave JWKS used to verify the\n * `encryptionDataKey` schema's `jwtChain` from\n * {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS enclave\n * host, distinct from the UKYC base URL.\n *\n * @returns The JWKS keys.\n */\n async fetchIdosEnclaveJwks(): Promise<JwksResponse> {\n return this.#fetchWellKnownJwks(\n this.#idosEnclaveBaseUrl,\n 'idOS enclave JWKS',\n 'KycService: idosEnclaveBaseUrl is not configured; cannot fetch JWKS to verify the encryptionDataKey schema.',\n );\n }\n\n /**\n * Fetches the idOS relay JWKS used to verify the `ukycCapabilityToken`\n * schema's `jwtChain` from {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS relay\n * host, distinct from both the UKYC base URL and the idOS enclave.\n *\n * @returns The JWKS keys.\n */\n async fetchIdosRelayJwks(): Promise<JwksResponse> {\n return this.#fetchWellKnownJwks(\n this.#idosRelayBaseUrl,\n 'idOS relay JWKS',\n 'KycService: idosRelayBaseUrl is not configured; cannot fetch JWKS to verify the ukycCapabilityToken schema.',\n );\n }\n\n /**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * The client registers its per-session X25519 public key so the server can\n * later open boxes sealed with the matching private key, and supplies the\n * customer's ISO 3166-1 alpha-3 country of residence. The response\n * 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 * Session creation is authenticated with `params.aal2Token` as the\n * `Authorization` bearer value, instead of the wallet bearer token.\n *\n * @param params - The session parameters.\n * @param params.aal2Token - AAL2 authentication token used as the\n * Authorization bearer value.\n * @returns The UKYC session id and encryption schemas.\n */\n async createUkycSession(\n params: CreateUkycSessionParams,\n ): Promise<UkycSessionResponse> {\n if (!params.aal2Token) {\n throw new Error(\n 'KycService.createUkycSession: aal2Token is required to authenticate session creation.',\n );\n }\n\n const url = new URL('/sessions', this.#baseUrl);\n const data = await this.#requestJson(\n url,\n {\n method: 'POST',\n body: JSON.stringify({\n vendorId: params.vendor ?? 'moonpay',\n vendorUserId: 'mockedId',\n sessionClientPublicKey: params.sessionClientPublicKey,\n residenceCountry: params.residenceCountry,\n vendorMetadata: params.vendorMetadata ?? {},\n }),\n },\n { bearerToken: params.aal2Token },\n );\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'UKYC sessions',\n );\n }\n\n /**\n * Reissues wrapping keys for an existing UKYC session\n * (`POST /sessions/{sessionId}/wrapping-keys`).\n *\n * The client registers a new per-session X25519 public key so the server can\n * open boxes sealed with the matching private key. The response matches\n * {@link KycService.createUkycSession}: a session id plus per-secret\n * encryption schemas (`encryptionDataKey` and `ukycCapabilityToken`) used to\n * wrap and submit authorizations.\n *\n * @param params - The session whose wrapping keys should be reset.\n * @param params.sessionId - UKYC session id.\n * @param params.sessionClientPublicKey - Per-session X25519 public key\n * (unpadded base64url) registered on the session.\n * @returns The session id and fresh encryption schemas.\n */\n async resetWrappingKeys(\n params: ResetWrappingKeysParams,\n ): Promise<UkycSessionResponse> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/wrapping-keys`,\n this.#baseUrl,\n );\n const data = await this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n sessionClientPublicKey: params.sessionClientPublicKey,\n }),\n });\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'wrapping keys',\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n wrappedEncryptionDataKey: params.wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken: params.wrappedUkycCapabilityToken,\n }),\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.#requestJson(url, { method: 'POST' });\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.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'session status',\n );\n }\n\n /**\n * Fetches the latest UKYC session status for an identity vendor\n * (`GET /sessions/latest/status/{vendor}`).\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when no latest session exists.\n */\n async getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n const url = new URL(\n `/sessions/latest/status/${encodeURIComponent(vendor)}`,\n this.#baseUrl,\n );\n try {\n const data = await this.#requestJson(url, { method: 'GET' });\n if (data === null) {\n return null;\n }\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'latest session status',\n );\n } catch (error) {\n if (error instanceof HttpError && error.httpStatus === 404) {\n return null;\n }\n throw error;\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 via `fetch`.\n *\n * Requests 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 idOS enclave or idOS relay JWKS endpoints). Pass `bearerToken`\n * to send that value instead of the wallet bearer token.\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 * @param options.bearerToken - Authorization bearer value. When omitted, the\n * wallet bearer token from `AuthenticationController:getBearerToken` is used.\n * @returns The parsed JSON response.\n */\n async #requestJson(\n url: URL,\n init: RequestInit,\n options: { authenticated?: boolean; bearerToken?: string } = {},\n ): Promise<Json> {\n const { authenticated = true, bearerToken } = 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 resolvedBearerToken =\n bearerToken ??\n (await this.messenger.call('AuthenticationController:getBearerToken'));\n if (!resolvedBearerToken) {\n throw new Error(\n 'Unable to obtain an authentication bearer token — is the wallet signed in?',\n );\n }\n assert(resolvedBearerToken, string());\n headers.Authorization = `Bearer ${resolvedBearerToken}`;\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"]}
1
+ {"version":3,"file":"KycService.js","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 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 KycDisclaimersCatalog,\n KycSessionDisclaimers,\n KycSessionStatus,\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 'fetchVendorDisclaimers',\n 'createMoonpaySession',\n 'createVendorCustomer',\n 'submitVendorDisclaimers',\n 'fetchSessionDisclaimersByCountry',\n 'fetchSessionDisclaimersBySessionId',\n 'submitSessionDisclaimers',\n 'fetchIdosEnclaveJwks',\n 'fetchIdosRelayJwks',\n 'createUkycSession',\n 'resetWrappingKeys',\n 'setAuthorizations',\n 'createJourney',\n 'getSessionStatus',\n 'getSessionStatusForVendor',\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 idOS enclave, from which the JWKS used to\n * verify the `encryptionDataKey` schema's `jwtChain` is fetched.\n */\n idosEnclaveBaseUrl?: string;\n /**\n * Base URL of the idOS relay, from which the JWKS used to verify the\n * `ukycCapabilityToken` schema's `jwtChain` is fetched.\n */\n idosRelayBaseUrl?: 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 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 id: string(),\n finalStatus: string(),\n statusMessage: optional(string()),\n externalUserId: string(),\n kycStatus: string(),\n vendor: string(),\n vendorStatus: string(),\n consentStatus: optional(string()),\n idOSStatus: optional(string()),\n capabilityAuthorizationStatus: optional(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 CatalogDocumentFields = {\n key: string(),\n version: string(),\n title: string(),\n url: string(),\n} as const;\n\nconst CatalogDocumentStruct = type(CatalogDocumentFields);\n\n// Session documents also report whether that version was already consented to.\nconst ConsentDocumentStruct = type({\n ...CatalogDocumentFields,\n consented: boolean(),\n});\n\n/**\n * Global catalog from `GET /disclaimers` (no per-document `consented` flag and\n * no credential-reuse flag).\n */\nconst GlobalDisclaimersResponseStruct = type({\n idOS: array(CatalogDocumentStruct),\n kycProvider: array(CatalogDocumentStruct),\n});\n\n/** Session catalog from `GET`/`POST /sessions/{id}/disclaimers`. */\nconst SessionDisclaimersResponseStruct = type({\n idOS: array(ConsentDocumentStruct),\n kycProvider: array(ConsentDocumentStruct),\n credentialReusabilityConsentGiven: boolean(),\n});\n\n// === PARAM TYPES ===\n\nexport type CreateMoonpaySessionParams = {\n partnerIdentityToken: string;\n termsAcceptedAt: string;\n disclaimerIds: string[];\n};\n\nexport type CreateVendorCustomerParams = {\n vendor: KycVendor;\n partnerIdentityToken: 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.fetchVendorDisclaimers}. */\n disclaimerIds: string[];\n};\n\nexport type FetchSessionDisclaimersByCountryParams = {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n};\n\nexport type FetchSessionDisclaimersBySessionIdParams = {\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 /**\n * The client's per-session X25519 public key (unpadded base64url). Generated\n * with the matching private key used later to wrap authorizations, so the\n * session server can open those boxes.\n */\n sessionClientPublicKey: string;\n /**\n * Country of residence in ISO 3166-1 alpha-3 format (e.g. `USA`, `GBR`).\n */\n residenceCountry: 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 * AAL2 authentication token sent as the `Authorization` bearer value for\n * `POST /sessions`. Other KYC requests continue to use the wallet bearer\n * token.\n */\n aal2Token: string;\n /**\n * Partner identity token minted by\n * `AuthenticationController:getPartnerIdentityToken` for the session's\n * vendor audience. Omitted from the request body when not provided.\n */\n partnerIdentityToken?: string;\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\nexport type ResetWrappingKeysParams = {\n /** UKYC session id whose wrapping keys should be reissued. */\n sessionId: string;\n /**\n * The client's per-session X25519 public key (unpadded base64url). Generated\n * with the matching private key used to wrap the refreshed authorizations,\n * so the session server can open those boxes.\n */\n sessionClientPublicKey: string;\n};\n\n// Successful well-known JWKS responses stay fresh for one day. Issuer keys\n// rotate infrequently, and session creation verifies against them more than once.\nconst JWKS_CACHE_TTL_MS = inMilliseconds(1, Duration.Day);\n\n// === SERVICE DEFINITION ===\n\n/**\n * `KycService` communicates with the Universal KYC (UKYC) backend to drive the\n * identity + document-verification flow. It does not persist session state and\n * is platform-agnostic: HTTP is performed through the runtime's native `fetch`\n * (or an injected `fetch` when provided), and the auth bearer token and\n * geolocation come from other controllers via the messenger. Successful\n * well-known JWKS responses are kept in the service query cache for 24 hours.\n *\n * HTTP endpoints call `#requestJson` (via the injected or native `fetch`).\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 #idosEnclaveBaseUrl: string;\n\n readonly #idosRelayBaseUrl: 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.idosEnclaveBaseUrl - Base URL of the idOS enclave, from\n * which the JWKS used to verify the `encryptionDataKey` schema's `jwtChain`\n * is fetched.\n * @param options.idosRelayBaseUrl - Base URL of the idOS relay, from which\n * the JWKS used to verify the `ukycCapabilityToken` schema's `jwtChain` is\n * 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 idosEnclaveBaseUrl,\n idosRelayBaseUrl,\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.#idosEnclaveBaseUrl = idosEnclaveBaseUrl ?? '';\n this.#idosRelayBaseUrl = idosRelayBaseUrl ?? '';\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 // `vendorError`).\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 fetchVendorDisclaimers({\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.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n DisclaimersResponseStruct,\n 'disclaimers',\n );\n }\n\n /**\n * Creates a MoonPay vendor session via the UKYC backend.\n *\n * @param params - The session parameters.\n * @returns The created session token.\n */\n async createMoonpaySession(\n params: CreateMoonpaySessionParams,\n ): Promise<Infer<typeof CreateSessionResponseStruct>> {\n const url = new URL('/vendors/moonpay/sessions', this.#baseUrl);\n const data = await this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify(params),\n });\n return this.#validateResponse(\n data,\n CreateSessionResponseStruct,\n 'sessions',\n );\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.partnerIdentityToken - Partner identity token minted by\n * `AuthenticationController:getPartnerIdentityToken`.\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n partnerIdentityToken: params.partnerIdentityToken,\n }),\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({ disclaimerIds: params.disclaimerIds }),\n });\n return this.#validateResponse(\n data,\n VendorSigningsResponseStruct,\n 'vendor disclaimers',\n );\n }\n\n /**\n * Fetches the global idOS + KYC-provider disclaimer catalog\n * (`GET /disclaimers?country=`). Carries no consent state — per-document\n * `consented` flags and `credentialReusabilityConsentGiven` are\n * session-scoped via {@link fetchSessionDisclaimersBySessionId}. Vendor T&Cs continue to\n * come from {@link fetchVendorDisclaimers}.\n *\n * @param params - The parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog documents.\n */\n async fetchSessionDisclaimersByCountry({\n country,\n }: FetchSessionDisclaimersByCountryParams): Promise<KycDisclaimersCatalog> {\n if (country.length !== 3) {\n throw new Error(\n `KycService.fetchSessionDisclaimersByCountry: country must be an ISO 3166-1 alpha-3 code (received \"${country}\").`,\n );\n }\n\n const url = new URL('/disclaimers', this.#baseUrl);\n url.searchParams.set('country', country);\n const data = await this.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n GlobalDisclaimersResponseStruct,\n 'disclaimers',\n );\n }\n\n /**\n * Fetches the session-scoped idOS + KYC-provider disclaimer catalog\n * (`GET /sessions/{sessionId}/disclaimers`), including per-session\n * `consented` flags and `credentialReusabilityConsentGiven`. For the\n * pre-session global catalog use {@link fetchSessionDisclaimersByCountry}.\n * Vendor T&Cs continue to come from {@link fetchVendorDisclaimers}.\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 fetchSessionDisclaimersBySessionId({\n sessionId,\n }: FetchSessionDisclaimersBySessionIdParams): Promise<KycSessionDisclaimers> {\n const url = new URL(\n `/sessions/${encodeURIComponent(sessionId)}/disclaimers`,\n this.#baseUrl,\n );\n const data = await this.#requestJson(url, { method: 'GET' });\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 fetchSessionDisclaimersBySessionId}. 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.#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 return this.#validateResponse(\n data,\n SessionDisclaimersResponseStruct,\n 'session disclaimers',\n );\n }\n\n /**\n * Fetches a well-known JWKS from `baseUrl`.\n *\n * A successful response stays fresh in the service query cache for 24 hours.\n * A later call for the same URL within that window returns the cached keys.\n * Failed and malformed responses are not cached. Concurrent callers for the\n * same URL share one in-flight request. `KycService:invalidateQueries` drops\n * the cached keys.\n *\n * @param baseUrl - Host base URL that serves `/.well-known/jwks.json`.\n * @param responseLabel - Label used in malformed-response errors.\n * @param missingConfigMessage - Error thrown when `baseUrl` is empty.\n * @returns The JWKS keys.\n */\n async #fetchWellKnownJwks(\n baseUrl: string,\n responseLabel: string,\n missingConfigMessage: string,\n ): Promise<JwksResponse> {\n if (!baseUrl) {\n throw new Error(missingConfigMessage);\n }\n const url = new URL(UKYC_JWKS_PATH, baseUrl);\n return this.fetchQuery({\n queryKey: [`${serviceName}:fetchWellKnownJwks`, url.toString()],\n queryFn: async () => {\n const data = await this.#requestJson(\n url,\n { method: 'GET' },\n { authenticated: false },\n );\n return this.#validateResponse(data, JwksResponseStruct, responseLabel);\n },\n staleTime: JWKS_CACHE_TTL_MS,\n // fetchQuery does not subscribe an observer, so the entry is inactive\n // immediately. Without gcTime the default 5-minute GC would drop it\n // while it is still fresh.\n gcTime: JWKS_CACHE_TTL_MS,\n });\n }\n\n /**\n * Fetches the idOS enclave JWKS used to verify the\n * `encryptionDataKey` schema's `jwtChain` from\n * {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS enclave\n * host, distinct from the UKYC base URL. A successful response is cached in\n * the service query cache for 24 hours.\n *\n * @returns The JWKS keys.\n */\n async fetchIdosEnclaveJwks(): Promise<JwksResponse> {\n return this.#fetchWellKnownJwks(\n this.#idosEnclaveBaseUrl,\n 'idOS enclave JWKS',\n 'KycService: idosEnclaveBaseUrl is not configured; cannot fetch JWKS to verify the encryptionDataKey schema.',\n );\n }\n\n /**\n * Fetches the idOS relay JWKS used to verify the `ukycCapabilityToken`\n * schema's `jwtChain` from {@link KycService.createUkycSession}.\n *\n * This is an unauthenticated request to a well-known path on the idOS relay\n * host, distinct from both the UKYC base URL and the idOS enclave. A\n * successful response is cached in the service query cache for 24 hours.\n *\n * @returns The JWKS keys.\n */\n async fetchIdosRelayJwks(): Promise<JwksResponse> {\n return this.#fetchWellKnownJwks(\n this.#idosRelayBaseUrl,\n 'idOS relay JWKS',\n 'KycService: idosRelayBaseUrl is not configured; cannot fetch JWKS to verify the ukycCapabilityToken schema.',\n );\n }\n\n /**\n * Creates a UKYC session for the SumSub document-verification sub-flow.\n *\n * The client registers its per-session X25519 public key so the server can\n * later open boxes sealed with the matching private key, and supplies the\n * customer's ISO 3166-1 alpha-3 country of residence. The response\n * 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 * Session creation is authenticated with `params.aal2Token` as the\n * `Authorization` bearer value, instead of the wallet bearer token.\n *\n * @param params - The session parameters.\n * @param params.aal2Token - AAL2 authentication token used as the\n * Authorization bearer value.\n * @param params.partnerIdentityToken - Optional partner identity token for\n * the session's vendor audience, sent as `partnerIdentityToken`.\n * @returns The UKYC session id and encryption schemas.\n */\n async createUkycSession(\n params: CreateUkycSessionParams,\n ): Promise<UkycSessionResponse> {\n if (!params.aal2Token) {\n throw new Error(\n 'KycService.createUkycSession: aal2Token is required to authenticate session creation.',\n );\n }\n\n const url = new URL('/sessions', this.#baseUrl);\n const data = await this.#requestJson(\n url,\n {\n method: 'POST',\n body: JSON.stringify({\n vendorId: params.vendor ?? 'moonpay',\n vendorUserId: 'mockedId',\n sessionClientPublicKey: params.sessionClientPublicKey,\n residenceCountry: params.residenceCountry,\n vendorMetadata: params.vendorMetadata ?? {},\n ...(params.partnerIdentityToken && {\n partnerIdentityToken: params.partnerIdentityToken,\n }),\n }),\n },\n { bearerToken: params.aal2Token },\n );\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'UKYC sessions',\n );\n }\n\n /**\n * Reissues wrapping keys for an existing UKYC session\n * (`POST /sessions/{sessionId}/wrapping-keys`).\n *\n * The client registers a new per-session X25519 public key so the server can\n * open boxes sealed with the matching private key. The response matches\n * {@link KycService.createUkycSession}: a session id plus per-secret\n * encryption schemas (`encryptionDataKey` and `ukycCapabilityToken`) used to\n * wrap and submit authorizations.\n *\n * @param params - The session whose wrapping keys should be reset.\n * @param params.sessionId - UKYC session id.\n * @param params.sessionClientPublicKey - Per-session X25519 public key\n * (unpadded base64url) registered on the session.\n * @returns The session id and fresh encryption schemas.\n */\n async resetWrappingKeys(\n params: ResetWrappingKeysParams,\n ): Promise<UkycSessionResponse> {\n const url = new URL(\n `/sessions/${encodeURIComponent(params.sessionId)}/wrapping-keys`,\n this.#baseUrl,\n );\n const data = await this.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n sessionClientPublicKey: params.sessionClientPublicKey,\n }),\n });\n return this.#validateResponse(\n data,\n UkycSessionResponseStruct,\n 'wrapping keys',\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.#requestJson(url, {\n method: 'POST',\n body: JSON.stringify({\n wrappedEncryptionDataKey: params.wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken: params.wrappedUkycCapabilityToken,\n }),\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.#requestJson(url, { method: 'POST' });\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.#requestJson(url, { method: 'GET' });\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'session status',\n );\n }\n\n /**\n * Fetches the latest UKYC session status for an identity vendor\n * (`GET /sessions/latest/status/{vendor}`).\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when no latest session exists.\n */\n async getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n const url = new URL(\n `/sessions/latest/status/${encodeURIComponent(vendor)}`,\n this.#baseUrl,\n );\n try {\n const data = await this.#requestJson(url, { method: 'GET' });\n if (data === null) {\n return null;\n }\n return this.#validateResponse(\n data,\n SessionStatusResponseStruct,\n 'latest session status',\n );\n } catch (error) {\n if (error instanceof HttpError && error.httpStatus === 404) {\n return null;\n }\n throw error;\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 via `fetch`.\n *\n * Requests 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 idOS enclave or idOS relay JWKS endpoints). Pass `bearerToken`\n * to send that value instead of the wallet bearer token.\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 * @param options.bearerToken - Authorization bearer value. When omitted, the\n * wallet bearer token from `AuthenticationController:getBearerToken` is used.\n * @returns The parsed JSON response.\n */\n async #requestJson(\n url: URL,\n init: RequestInit,\n options: { authenticated?: boolean; bearerToken?: string } = {},\n ): Promise<Json> {\n const { authenticated = true, bearerToken } = 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 resolvedBearerToken =\n bearerToken ??\n (await this.messenger.call('AuthenticationController:getBearerToken'));\n if (!resolvedBearerToken) {\n throw new Error(\n 'Unable to obtain an authentication bearer token — is the wallet signed in?',\n );\n }\n assert(resolvedBearerToken, string());\n headers.Authorization = `Bearer ${resolvedBearerToken}`;\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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/kyc-controller",
3
- "version": "0.10.0-preview-aeb52ce4f",
3
+ "version": "0.11.0-preview-a583980c5",
4
4
  "description": "Shared KYC / identity verification controller used across MetaMask clients",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -58,7 +58,7 @@
58
58
  "@metamask/controller-utils": "^13.0.0",
59
59
  "@metamask/geolocation-controller": "^2.0.0",
60
60
  "@metamask/messenger": "^3.0.0",
61
- "@metamask/profile-sync-controller": "^34.1.0",
61
+ "@metamask/profile-sync-controller": "^35.0.0",
62
62
  "@metamask/superstruct": "^3.4.1",
63
63
  "@metamask/utils": "^12.0.0",
64
64
  "@noble/ciphers": "^1.3.0",