@metamask-previews/kyc-controller 0.3.0-preview-0a8ce9948 → 0.3.0-preview-95a403d7b

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
@@ -9,8 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
- - **BREAKING:** `KycController.checkKycRequired` and the consents-path session (`acceptTermsAndStartSession` / a resumed `initialize`) now rethrow the underlying error after recording it on controller state. ([#10214](https://github.com/MetaMask/core/pull/10214))
13
- - A product-scoped MoonPay auto-run therefore rejects `handleFrameMessage` / `onAuthenticated` when the KYC-required check fails, instead of only setting `phase: 'error'`.
14
12
  - Bump `@metamask/profile-sync-controller` from `^32.1.0` to `^32.1.1` ([#10220](https://github.com/MetaMask/core/pull/10220))
15
13
 
16
14
  ## [0.3.0]
@@ -16,8 +16,6 @@ import type { KycController } from './KycController.js';
16
16
  * call `checkKycRequired` manually.
17
17
  * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors
18
18
  * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.
19
- * @throws If a resumed consents-path session records a failure on state.
20
- * The original error is rethrown after the controller rewinds to `terms`.
21
19
  */
22
20
  export type KycControllerInitializeAction = {
23
21
  type: `KycController:initialize`;
@@ -90,8 +88,6 @@ export type KycControllerFetchSessionDisclaimersAction = {
90
88
  * @param params.credentialReusabilityConsentGiven - Whether the customer
91
89
  * consented to reuse existing idOS credentials. Used when recording
92
90
  * session-scoped disclaimers on the consents path. Defaults to `false`.
93
- * @throws If the consents-path session records a failure on state. The
94
- * original error is rethrown after the controller rewinds to `terms`.
95
91
  */
96
92
  export type KycControllerAcceptTermsAndStartSessionAction = {
97
93
  type: `KycController:acceptTermsAndStartSession`;
@@ -152,8 +148,6 @@ export type KycControllerBuildResetFrameUrlAction = {
152
148
  * @param params.product - The consuming feature.
153
149
  * @param params.country - Optional alpha-3 country override.
154
150
  * @returns Whether KYC is required.
155
- * @throws If the KYC-required service call fails after the error is recorded
156
- * on controller state (`phase: 'error'`).
157
151
  */
158
152
  export type KycControllerCheckKycRequiredAction = {
159
153
  type: `KycController:checkKycRequired`;
@@ -1 +1 @@
1
- {"version":3,"file":"KycController-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KycController-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"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"}
@@ -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 * Resolves persisted terms + geolocation, and auto-creates a session when\n * terms are already accepted and an email is available.\n *\n * @param params - Optional parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. When\n * provided, the controller automatically runs the KYC-required check once\n * authentication completes (and chains into document verification when KYC\n * is required). When omitted, the flow stops at `form` and the consumer must\n * call `checkKycRequired` manually.\n * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors\n * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.\n * @throws If a resumed consents-path session records a failure on state.\n * The original error is rethrown after the controller rewinds to `terms`.\n */\nexport type KycControllerInitializeAction = {\n type: `KycController:initialize`;\n handler: KycController['initialize'];\n};\n\n/**\n * Creates (or resumes) an empty-shell customer for the given identity\n * vendor. Exposed so a consumer can ensure the customer exists before\n * showing T&C screens independently of {@link initialize}.\n *\n * A call while a session flow is already in progress is a no-op — matching\n * {@link initialize} — so a vendor switch cannot leave Check/Auth frames\n * attached to the wrong vendor. Call {@link reset} first to start over.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor for the customer.\n * @param params.email - Email for the vendor customer.\n */\nexport type KycControllerCreateVendorCustomerAction = {\n type: `KycController:createVendorCustomer`;\n handler: KycController['createVendorCustomer'];\n};\n\n/**\n * Loads the disclaimers for the resolved (or provided) country.\n *\n * @param params - Optional parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code override.\n */\nexport type KycControllerLoadDisclaimersAction = {\n type: `KycController:loadDisclaimers`;\n handler: KycController['loadDisclaimers'];\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 * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\n *\n * @param params - The parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.idosDisclaimersAccepted - idOS disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.credentialReusabilityConsentGiven - Whether the customer\n * consented to reuse existing idOS credentials. Used when recording\n * session-scoped disclaimers on the consents path. Defaults to `false`.\n * @throws If the consents-path session records a failure on state. The\n * original error is rethrown after the controller rewinds to `terms`.\n */\nexport type KycControllerAcceptTermsAndStartSessionAction = {\n type: `KycController:acceptTermsAndStartSession`;\n handler: KycController['acceptTermsAndStartSession'];\n};\n\n/**\n * Clears the persisted terms acceptance.\n */\nexport type KycControllerClearSavedTermsAction = {\n type: `KycController:clearSavedTerms`;\n handler: KycController['clearSavedTerms'];\n};\n\n/**\n * Handles a message posted by a Check/Auth frame and advances the flow.\n *\n * The transport-agnostic caller (WebView on mobile, iframe on web) forwards\n * the raw message and injects the returned `reply` back into the frame.\n *\n * @param params - The parameters.\n * @param params.message - The raw message posted by the frame.\n * @returns An object whose optional `reply` should be posted back.\n */\nexport type KycControllerHandleFrameMessageAction = {\n type: `KycController:handleFrameMessage`;\n handler: KycController['handleFrameMessage'];\n};\n\n/**\n * Builds the Check-frame URL, or `null` when no session exists yet.\n *\n * @returns The Check-frame URL or `null`.\n */\nexport type KycControllerBuildCheckFrameUrlAction = {\n type: `KycController:buildCheckFrameUrl`;\n handler: KycController['buildCheckFrameUrl'];\n};\n\n/**\n * Builds the Auth-frame URL, or `null` when no client token is available.\n *\n * @returns The Auth-frame URL or `null`.\n */\nexport type KycControllerBuildAuthFrameUrlAction = {\n type: `KycController:buildAuthFrameUrl`;\n handler: KycController['buildAuthFrameUrl'];\n};\n\n/**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\nexport type KycControllerBuildResetFrameUrlAction = {\n type: `KycController:buildResetFrameUrl`;\n handler: KycController['buildResetFrameUrl'];\n};\n\n/**\n * Checks whether KYC is required for a product and caches the result.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @param params.country - Optional alpha-3 country override.\n * @returns Whether KYC is required.\n * @throws If the KYC-required service call fails after the error is recorded\n * on controller state (`phase: 'error'`).\n */\nexport type KycControllerCheckKycRequiredAction = {\n type: `KycController:checkKycRequired`;\n handler: KycController['checkKycRequired'];\n};\n\n/**\n * Reads the cached \"is KYC required\" result for a product.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @returns The cached value, or `undefined` if not yet checked.\n */\nexport type KycControllerGetKycStatusAction = {\n type: `KycController:getKycStatus`;\n handler: KycController['getKycStatus'];\n};\n\n/**\n * Returns the vendor-scoped identity for the currently authenticated\n * customer, or `null` when the flow has not yet captured a vendor customer\n * id (before authentication or after {@link reset}), or when a MoonPay id\n * is present under a different `activeVendor`.\n *\n * Exposed so consumers (e.g. ramps autoramp creation) can attach the vendor\n * customer id to downstream calls without reading the full KYC state, which\n * also holds session/access tokens. The id is session-scoped and never\n * persisted.\n *\n * @returns The current {@link KycCustomerIdentity}, or `null`.\n */\nexport type KycControllerGetCustomerIdentityAction = {\n type: `KycController:getCustomerIdentity`;\n handler: KycController['getCustomerIdentity'];\n};\n\n/**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\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 SDK result.\n */\nexport type KycControllerStartSumSubAction = {\n type: `KycController:startSumSub`;\n handler: KycController['startSumSub'];\n};\n\n/**\n * Refreshes the user-keyed simplified KYC status from `GET /kyc/status`,\n * stores it on state, publishes {@link KycControllerStatusChangedEvent}, and\n * schedules short-interval polling while the status is `pending`.\n *\n * Skipped when `userStatus` is already `completed`: a follow-up\n * `GET /kyc/status` can still read a stale `pending` (for example after\n * `session_not_in_valid_state`) and must not undo that decision.\n *\n * @returns The latest status payload.\n */\nexport type KycControllerRefreshKycStatusAction = {\n type: `KycController:refreshKycStatus`;\n handler: KycController['refreshKycStatus'];\n};\n\n/**\n * Fetches the current UKYC session status for the active sub-flow and records\n * it on state. Useful for a one-off refresh outside the automatic polling\n * loop that {@link startSumSub} runs.\n *\n * @returns The fetched session status.\n * @throws If there is no active SumSub session to query.\n */\nexport type KycControllerGetSessionStatusAction = {\n type: `KycController:getSessionStatus`;\n handler: KycController['getSessionStatus'];\n};\n\n/**\n * Resets the flow to idle, clearing session tokens and sub-flow state while\n * preserving persisted terms acceptance and the per-product cache.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state, discarding everything\n * {@link reset} deliberately keeps: the session email, the persisted terms\n * acceptance, the per-product KYC-required cache and the user-keyed status.\n *\n * Intended for a full wallet reset, where no trace of the previous\n * customer may survive into the next wallet.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerInitializeAction\n | KycControllerCreateVendorCustomerAction\n | KycControllerLoadDisclaimersAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerAcceptTermsAndStartSessionAction\n | KycControllerClearSavedTermsAction\n | KycControllerHandleFrameMessageAction\n | KycControllerBuildCheckFrameUrlAction\n | KycControllerBuildAuthFrameUrlAction\n | KycControllerBuildResetFrameUrlAction\n | KycControllerCheckKycRequiredAction\n | KycControllerGetKycStatusAction\n | KycControllerGetCustomerIdentityAction\n | KycControllerStartSumSubAction\n | KycControllerRefreshKycStatusAction\n | KycControllerGetSessionStatusAction\n | KycControllerResetAction\n | KycControllerClearStateAction;\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 * Resolves persisted terms + geolocation, and auto-creates a session when\n * terms are already accepted and an email is available.\n *\n * @param params - Optional parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. When\n * provided, the controller automatically runs the KYC-required check once\n * authentication completes (and chains into document verification when KYC\n * is required). When omitted, the flow stops at `form` and the consumer must\n * call `checkKycRequired` manually.\n * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors\n * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.\n */\nexport type KycControllerInitializeAction = {\n type: `KycController:initialize`;\n handler: KycController['initialize'];\n};\n\n/**\n * Creates (or resumes) an empty-shell customer for the given identity\n * vendor. Exposed so a consumer can ensure the customer exists before\n * showing T&C screens independently of {@link initialize}.\n *\n * A call while a session flow is already in progress is a no-op — matching\n * {@link initialize} — so a vendor switch cannot leave Check/Auth frames\n * attached to the wrong vendor. Call {@link reset} first to start over.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor for the customer.\n * @param params.email - Email for the vendor customer.\n */\nexport type KycControllerCreateVendorCustomerAction = {\n type: `KycController:createVendorCustomer`;\n handler: KycController['createVendorCustomer'];\n};\n\n/**\n * Loads the disclaimers for the resolved (or provided) country.\n *\n * @param params - Optional parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code override.\n */\nexport type KycControllerLoadDisclaimersAction = {\n type: `KycController:loadDisclaimers`;\n handler: KycController['loadDisclaimers'];\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 * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\n *\n * @param params - The parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.idosDisclaimersAccepted - idOS disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.credentialReusabilityConsentGiven - Whether the customer\n * consented to reuse existing idOS credentials. Used when recording\n * session-scoped disclaimers on the consents path. Defaults to `false`.\n */\nexport type KycControllerAcceptTermsAndStartSessionAction = {\n type: `KycController:acceptTermsAndStartSession`;\n handler: KycController['acceptTermsAndStartSession'];\n};\n\n/**\n * Clears the persisted terms acceptance.\n */\nexport type KycControllerClearSavedTermsAction = {\n type: `KycController:clearSavedTerms`;\n handler: KycController['clearSavedTerms'];\n};\n\n/**\n * Handles a message posted by a Check/Auth frame and advances the flow.\n *\n * The transport-agnostic caller (WebView on mobile, iframe on web) forwards\n * the raw message and injects the returned `reply` back into the frame.\n *\n * @param params - The parameters.\n * @param params.message - The raw message posted by the frame.\n * @returns An object whose optional `reply` should be posted back.\n */\nexport type KycControllerHandleFrameMessageAction = {\n type: `KycController:handleFrameMessage`;\n handler: KycController['handleFrameMessage'];\n};\n\n/**\n * Builds the Check-frame URL, or `null` when no session exists yet.\n *\n * @returns The Check-frame URL or `null`.\n */\nexport type KycControllerBuildCheckFrameUrlAction = {\n type: `KycController:buildCheckFrameUrl`;\n handler: KycController['buildCheckFrameUrl'];\n};\n\n/**\n * Builds the Auth-frame URL, or `null` when no client token is available.\n *\n * @returns The Auth-frame URL or `null`.\n */\nexport type KycControllerBuildAuthFrameUrlAction = {\n type: `KycController:buildAuthFrameUrl`;\n handler: KycController['buildAuthFrameUrl'];\n};\n\n/**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\nexport type KycControllerBuildResetFrameUrlAction = {\n type: `KycController:buildResetFrameUrl`;\n handler: KycController['buildResetFrameUrl'];\n};\n\n/**\n * Checks whether KYC is required for a product and caches the result.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @param params.country - Optional alpha-3 country override.\n * @returns Whether KYC is required.\n */\nexport type KycControllerCheckKycRequiredAction = {\n type: `KycController:checkKycRequired`;\n handler: KycController['checkKycRequired'];\n};\n\n/**\n * Reads the cached \"is KYC required\" result for a product.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @returns The cached value, or `undefined` if not yet checked.\n */\nexport type KycControllerGetKycStatusAction = {\n type: `KycController:getKycStatus`;\n handler: KycController['getKycStatus'];\n};\n\n/**\n * Returns the vendor-scoped identity for the currently authenticated\n * customer, or `null` when the flow has not yet captured a vendor customer\n * id (before authentication or after {@link reset}), or when a MoonPay id\n * is present under a different `activeVendor`.\n *\n * Exposed so consumers (e.g. ramps autoramp creation) can attach the vendor\n * customer id to downstream calls without reading the full KYC state, which\n * also holds session/access tokens. The id is session-scoped and never\n * persisted.\n *\n * @returns The current {@link KycCustomerIdentity}, or `null`.\n */\nexport type KycControllerGetCustomerIdentityAction = {\n type: `KycController:getCustomerIdentity`;\n handler: KycController['getCustomerIdentity'];\n};\n\n/**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\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 SDK result.\n */\nexport type KycControllerStartSumSubAction = {\n type: `KycController:startSumSub`;\n handler: KycController['startSumSub'];\n};\n\n/**\n * Refreshes the user-keyed simplified KYC status from `GET /kyc/status`,\n * stores it on state, publishes {@link KycControllerStatusChangedEvent}, and\n * schedules short-interval polling while the status is `pending`.\n *\n * Skipped when `userStatus` is already `completed`: a follow-up\n * `GET /kyc/status` can still read a stale `pending` (for example after\n * `session_not_in_valid_state`) and must not undo that decision.\n *\n * @returns The latest status payload.\n */\nexport type KycControllerRefreshKycStatusAction = {\n type: `KycController:refreshKycStatus`;\n handler: KycController['refreshKycStatus'];\n};\n\n/**\n * Fetches the current UKYC session status for the active sub-flow and records\n * it on state. Useful for a one-off refresh outside the automatic polling\n * loop that {@link startSumSub} runs.\n *\n * @returns The fetched session status.\n * @throws If there is no active SumSub session to query.\n */\nexport type KycControllerGetSessionStatusAction = {\n type: `KycController:getSessionStatus`;\n handler: KycController['getSessionStatus'];\n};\n\n/**\n * Resets the flow to idle, clearing session tokens and sub-flow state while\n * preserving persisted terms acceptance and the per-product cache.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state, discarding everything\n * {@link reset} deliberately keeps: the session email, the persisted terms\n * acceptance, the per-product KYC-required cache and the user-keyed status.\n *\n * Intended for a full wallet reset, where no trace of the previous\n * customer may survive into the next wallet.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerInitializeAction\n | KycControllerCreateVendorCustomerAction\n | KycControllerLoadDisclaimersAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerAcceptTermsAndStartSessionAction\n | KycControllerClearSavedTermsAction\n | KycControllerHandleFrameMessageAction\n | KycControllerBuildCheckFrameUrlAction\n | KycControllerBuildAuthFrameUrlAction\n | KycControllerBuildResetFrameUrlAction\n | KycControllerCheckKycRequiredAction\n | KycControllerGetKycStatusAction\n | KycControllerGetCustomerIdentityAction\n | KycControllerStartSumSubAction\n | KycControllerRefreshKycStatusAction\n | KycControllerGetSessionStatusAction\n | KycControllerResetAction\n | KycControllerClearStateAction;\n"]}
@@ -211,8 +211,6 @@ export declare class KycController extends BaseController<typeof controllerName,
211
211
  * call `checkKycRequired` manually.
212
212
  * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors
213
213
  * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.
214
- * @throws If a resumed consents-path session records a failure on state.
215
- * The original error is rethrown after the controller rewinds to `terms`.
216
214
  */
217
215
  initialize(params?: {
218
216
  email?: string;
@@ -282,8 +280,6 @@ export declare class KycController extends BaseController<typeof controllerName,
282
280
  * @param params.credentialReusabilityConsentGiven - Whether the customer
283
281
  * consented to reuse existing idOS credentials. Used when recording
284
282
  * session-scoped disclaimers on the consents path. Defaults to `false`.
285
- * @throws If the consents-path session records a failure on state. The
286
- * original error is rethrown after the controller rewinds to `terms`.
287
283
  */
288
284
  acceptTermsAndStartSession(params?: {
289
285
  email?: string;
@@ -336,8 +332,6 @@ export declare class KycController extends BaseController<typeof controllerName,
336
332
  * @param params.product - The consuming feature.
337
333
  * @param params.country - Optional alpha-3 country override.
338
334
  * @returns Whether KYC is required.
339
- * @throws If the KYC-required service call fails after the error is recorded
340
- * on controller state (`phase: 'error'`).
341
335
  */
342
336
  checkKycRequired(params: {
343
337
  product: KycProduct;
@@ -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":"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"}
@@ -516,8 +516,6 @@ export class KycController extends BaseController {
516
516
  * call `checkKycRequired` manually.
517
517
  * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors
518
518
  * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.
519
- * @throws If a resumed consents-path session records a failure on state.
520
- * The original error is rethrown after the controller rewinds to `terms`.
521
519
  */
522
520
  async initialize(params) {
523
521
  // A repeat `initialize` while a session flow is already in progress must
@@ -766,8 +764,6 @@ export class KycController extends BaseController {
766
764
  * @param params.credentialReusabilityConsentGiven - Whether the customer
767
765
  * consented to reuse existing idOS credentials. Used when recording
768
766
  * session-scoped disclaimers on the consents path. Defaults to `false`.
769
- * @throws If the consents-path session records a failure on state. The
770
- * original error is rethrown after the controller rewinds to `terms`.
771
767
  */
772
768
  async acceptTermsAndStartSession(params) {
773
769
  const providerDisclaimersAccepted = params?.providerDisclaimersAccepted;
@@ -816,8 +812,6 @@ export class KycController extends BaseController {
816
812
  * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.
817
813
  * @param consents.credentialReusabilityConsentGiven - Whether credential
818
814
  * reuse was accepted.
819
- * @throws If a step after recording state fails. The original error is
820
- * rethrown after the controller rewinds to `terms`.
821
815
  */
822
816
  async #startConsentsSession(consents) {
823
817
  const { email } = this.state;
@@ -945,7 +939,6 @@ export class KycController extends BaseController {
945
939
  error: `Consents session failed: ${String(error)}`,
946
940
  statusMessage: 'Consent / verification failed — accept the terms to try again.',
947
941
  });
948
- throw error;
949
942
  }
950
943
  }
951
944
  /**
@@ -1167,10 +1160,9 @@ export class KycController extends BaseController {
1167
1160
  * document-verification sub-flow is launched. When no product is set, this is
1168
1161
  * a no-op and the flow stays at `form` for the consumer to drive manually.
1169
1162
  *
1170
- * `startSumSub` records `sumsub.status = 'failed'` and this method swallows
1171
- * that rejection so it can be awaited safely from the frame-message handler.
1172
- * `checkKycRequired` still records `phase: 'error'` and rethrows, so a
1173
- * failed auto-run check surfaces to the caller.
1163
+ * Errors are already recorded on state by `checkKycRequired` (`error`
1164
+ * phase) and `startSumSub` (`sumsub.status = 'failed'`); this method swallows
1165
+ * them so it can be awaited safely from the frame-message handler.
1174
1166
  */
1175
1167
  async #continueAfterAuthentication() {
1176
1168
  const product = this.state.activeProduct;
@@ -1241,8 +1233,6 @@ export class KycController extends BaseController {
1241
1233
  * @param params.product - The consuming feature.
1242
1234
  * @param params.country - Optional alpha-3 country override.
1243
1235
  * @returns Whether KYC is required.
1244
- * @throws If the KYC-required service call fails after the error is recorded
1245
- * on controller state (`phase: 'error'`).
1246
1236
  */
1247
1237
  async checkKycRequired(params) {
1248
1238
  const { moonpayAccessToken } = this.state;
@@ -1286,7 +1276,7 @@ export class KycController extends BaseController {
1286
1276
  return false;
1287
1277
  }
1288
1278
  this.#fail(`KYC check failed: ${String(error)}`);
1289
- throw error;
1279
+ return false;
1290
1280
  }
1291
1281
  }
1292
1282
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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","sourcesContent":["import 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 {\n UserStorageControllerPerformGetStorageAction,\n UserStorageControllerPerformSetStorageAction,\n} from '@metamask/profile-sync-controller/user-storage';\nimport type { Json } from '@metamask/utils';\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 CreateUkycSessionParams,\n EncryptionSchema,\n} from './KycService.js';\nimport { controllerLog } from './logger.js';\nimport type {\n KycConsentDocument,\n KycConsentRecord,\n KycCustomerIdentity,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycPhase,\n KycProduct,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubSdkStatus,\n KycSumSubStatus,\n KycUserStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport type { Jwk } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n clearVendorDisclaimerAcceptance,\n hasVendorDisclaimerAcceptance,\n ironDisclaimerIds,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimerAcceptance.js';\nimport {\n clearMoonPaySession,\n MoonPayFrameHandler,\n} from './vendors/MoonPayFrameHandler.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\n// Placeholder credentials for the SumSub sub-flow. These are demo values that\n// must be replaced with real UKYC-issued material before production use.\nconst MOCK_JWT_TOKEN = 'mock-jwt-token';\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 = 4 * 60 * 60 * 1000;\n\n// SumSub statuses that mean the applicant submitted (see `KycSumSubSdkStatus`\n// for what each one reports). `Completed` covers launchers that normalize the\n// platform status before forwarding it. Review decisions (`Approved`,\n// `FinallyRejected`, `TemporarilyDeclined`) are post-submission outcomes: the\n// applicant finished the SDK, so UKYC is polled for the authoritative\n// decision. Pre-submission statuses (`Ready`, `Initial`, `Incomplete`) must\n// not be recorded as a completed verification.\nconst SUMSUB_COMPLETED_STATUSES: ReadonlySet<string> =\n new Set<KycSumSubSdkStatus>([\n 'Completed',\n 'Pending',\n 'Approved',\n 'ActionCompleted',\n 'FinallyRejected',\n 'TemporarilyDeclined',\n ]);\n\n// The only status meaning the SDK could not run, rather than reporting how far\n// the applicant got before closing it.\nconst SUMSUB_FAILED_STATUS: KycSumSubSdkStatus = 'Failed';\n\nconst SUMSUB_ABANDONED_MESSAGE =\n 'Identity verification was not finished — accept the terms to try again.';\n\n/**\n * Checks whether a SumSub status means the applicant submitted the flow.\n *\n * @param status - Status from a launcher callback or launch result.\n * @returns Whether the applicant submitted, including a review decision.\n */\nfunction isSumSubFlowCompleted(status: unknown): boolean {\n return typeof status === 'string' && SUMSUB_COMPLETED_STATUSES.has(status);\n}\n\n/**\n * Checks whether the SDK failed to run, as opposed to the applicant closing it\n * early. Only the former is worth reporting as an error.\n *\n * @param result - The result the launcher resolved with.\n * @returns Whether the SDK failed to run.\n */\nfunction isSumSubLaunchFailure(result: Record<string, unknown>): boolean {\n return (\n result.status === SUMSUB_FAILED_STATUS || typeof result.error === 'string'\n );\n}\n\n// Phases that represent an active vendor-session flow (tokens issued and/or\n// Check/Auth frames in progress). A repeat `initialize` while in one of these\n// must not restart the session and disrupt the in-flight flow.\nconst IN_PROGRESS_PHASES: KycPhase[] = [\n 'session',\n 'check',\n 'auth',\n 'form',\n 'submit',\n];\n\n// How often to poll the UKYC session status after the SumSub SDK completes,\n// until a terminal status is reached. Overridable via the constructor.\nconst DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// UKYC status values. `kycStatus` (the relay-side decision) and `finalStatus`\n// (the vendor-side outcome) draw from the same vocabulary, so they are defined\n// once here and composed into the sets/checks below rather than repeated as\n// literals.\nconst KYC_STATUSES = {\n approved: 'approved',\n completed: 'completed',\n rejected: 'rejected',\n failed: 'failed',\n blocked: 'blocked',\n pending: 'pending',\n} as const;\n\n// `finalStatus` values that end the polling loop. Anything else (e.g.\n// `KYC_STATUSES.pending`) keeps polling.\nconst TERMINAL_SESSION_STATUSES: ReadonlySet<string> = new Set([\n KYC_STATUSES.approved,\n KYC_STATUSES.completed,\n KYC_STATUSES.rejected,\n KYC_STATUSES.failed,\n KYC_STATUSES.blocked,\n]);\n\n// Terminal `finalStatus` values that represent a successful verification. Any\n// other terminal status resolves the sub-flow to `failed`.\nconst SUCCESSFUL_SESSION_STATUSES: ReadonlySet<string> = new Set([\n KYC_STATUSES.approved,\n KYC_STATUSES.completed,\n]);\n\n// Session creation can report that the applicant is already approved on the\n// relay (`kycStatus === KYC_STATUSES.approved`) while the vendor is still\n// finalizing its decision (`finalStatus === KYC_STATUSES.pending`, a\n// non-terminal status). In that case there is nothing left for the applicant\n// to do, so the sub-flow stops before launching the SDK and surfaces this\n// message.\nconst VENDOR_PROCESSING_MESSAGE =\n 'Your KYC has been submitted and is being processed by the vendor.';\n\n// UKYC / relay error indicating the applicant already finished KYC. Mapped to\n// the simplified `completed` user status for the Money toast surface.\nconst SESSION_NOT_IN_VALID_STATE = 'session_not_in_valid_state';\n\n// How often to refresh the user-keyed `GET /kyc/status` while the simplified\n// status is still `pending`. Overridable via the constructor.\nconst DEFAULT_USER_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Current phase of the identity flow. */\n phase: KycPhase;\n /** Human-readable status message for the current phase. */\n statusMessage: string;\n /** The current error message, or `null`. */\n error: string | null;\n\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\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 /** Vendor disclaimers fetched for the current country. */\n vendorDisclaimers: KycDisclaimer[];\n /** Error encountered while loading vendor disclaimers, or `null`. */\n vendorError: string | null;\n /**\n * idOS / KYC-provider disclaimer catalog from `GET /disclaimers` or\n * `GET /sessions/{sessionId}/disclaimers`. `null` until the catalog has\n * been fetched (typically after a UKYC session exists).\n */\n sessionDisclaimers: KycSessionDisclaimers | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** MoonPay session token (not persisted, not logged). */\n moonpaySessionToken: string | null;\n /** MoonPay access token (not persisted, not logged). */\n moonpayAccessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\n\n /**\n * The identity vendor driving the current flow. Captured at `initialize`.\n * Defaults to `moonpay` when omitted so existing ramps/card callers keep\n * the Check/Auth frame path. Non-MoonPay vendors skip those frames.\n */\n activeVendor: KycVendor;\n\n /**\n * The product the current flow is running for. Captured at `initialize`\n * (or `acceptTermsAndStartSession`) and used to automatically run the\n * KYC-required check once authentication completes. `null` outside a\n * product-scoped flow (in which case the flow stops at `form` and the\n * consumer drives the check manually).\n */\n activeProduct: KycProduct | null;\n\n /** Cached \"is KYC required\" result per product (persisted). */\n kycRequiredByProduct: Partial<Record<KycProduct, boolean>>;\n /** ISO-8601 timestamp of the last KYC-required check (persisted). */\n lastCheckedAt: string | null;\n\n /**\n * User-keyed simplified KYC status from `GET /kyc/status` (persisted so the\n * Money toast can render across cold starts). `null` until the first\n * successful `refreshKycStatus`.\n */\n userStatus: KycUserStatus | null;\n /** Optional SumSub session id for the retryable error path. */\n userStatusSumsubSessionId: string | null;\n /** Optional machine-readable error code for terminal / EDD UX. */\n userStatusErrorCode: string | null;\n\n /** SumSub document-verification sub-flow state. */\n sumsub: {\n status: KycSumSubStatus;\n result: Json | null;\n sessionId: string | null;\n applicantAccessToken: string | null;\n /**\n * The latest UKYC session status, populated while polling after the SDK\n * completes. `null` until the first successful poll.\n */\n sessionStatus: KycSessionStatus | null;\n };\n};\n\nconst kycControllerMetadata = {\n phase: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n statusMessage: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n error: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\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: false,\n usedInUi: false,\n },\n vendorDisclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n vendorError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionDisclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n moonpaySessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n moonpayAccessToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n moonpayCustomerId: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n activeVendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n activeProduct: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n kycRequiredByProduct: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n lastCheckedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n userStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n userStatusSumsubSessionId: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: true,\n },\n userStatusErrorCode: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sumsub: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\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\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 phase: 'idle',\n statusMessage: '',\n error: null,\n email: null,\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n vendorDisclaimers: [],\n vendorError: null,\n sessionDisclaimers: null,\n geoCountry: null,\n moonpaySessionToken: null,\n moonpayAccessToken: null,\n moonpayCustomerId: null,\n activeVendor: 'moonpay',\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n userStatus: null,\n userStatusSumsubSessionId: null,\n userStatusErrorCode: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n/**\n * Whether an error indicates the applicant already finished KYC — the UKYC /\n * relay `session_not_in_valid_state` signal — which the controller maps to the\n * simplified `completed` user status.\n *\n * @param error - The caught error.\n * @returns `true` when the error carries the `session_not_in_valid_state`\n * marker.\n */\nfunction isSessionAlreadyCompletedError(error: unknown): boolean {\n return String(error).includes(SESSION_NOT_IN_VALID_STATE);\n}\n\n/**\n * Whether recording session disclaimers failed because those document\n * versions were already consented for the session (`409 Conflict`).\n *\n * @param error - The caught error.\n * @returns `true` when the error is an HTTP 409.\n */\nfunction isConsentConflictError(error: unknown): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n typeof (error as { httpStatus?: unknown }).httpStatus === 'number' &&\n (error as { httpStatus: number }).httpStatus === 409\n );\n}\n\n/**\n *\n * @param value - The value to validate.\n * @returns `true` when `value` is a valid consent record list.\n */\nfunction isValidConsentRecordList(value: unknown): value is KycConsentRecord[] {\n return (\n Array.isArray(value) &&\n value.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as KycConsentRecord).key === 'string' &&\n typeof (item as KycConsentRecord).version === 'string',\n )\n );\n}\n\n/**\n * Maps accepted disclaimer records onto unconsented catalog documents.\n *\n * @param documents - Catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns Consent records to POST, omitting already-consented documents.\n */\nfunction consentRecordsFromAcceptedList(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): KycConsentRecord[] {\n if (accepted.length === 0) {\n return [];\n }\n const acceptedKeys = new Set(\n accepted.map((record) => `${record.key}:${record.version}`),\n );\n return documents\n .filter(\n (document) =>\n !document.consented &&\n acceptedKeys.has(`${document.key}:${document.version}`),\n )\n .map(({ key, version }) => ({ key, version }));\n}\n\n/**\n * Whether accepted disclaimers reference a missing catalog category.\n *\n * @param documents - Catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns `true` when the caller accepted docs but the catalog is empty.\n */\nfunction isAcceptedCategoryEmpty(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): boolean {\n return accepted.length > 0 && documents.length === 0;\n}\n\n/**\n * Whether accepted disclaimers are still missing consent after a 409 re-GET:\n * empty catalog or any accepted document still unconsented.\n *\n * @param documents - Latest catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns `true` when accepted documents are not fully consented.\n */\nfunction acceptedCategoryStillMissing(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): boolean {\n if (accepted.length === 0) {\n return false;\n }\n if (documents.length === 0) {\n return true;\n }\n const acceptedKeys = new Set(\n accepted.map((record) => `${record.key}:${record.version}`),\n );\n const relevant = documents.filter((document) =>\n acceptedKeys.has(`${document.key}:${document.version}`),\n );\n return (\n relevant.length === 0 || relevant.some((document) => !document.consented)\n );\n}\n\n/**\n * Vendors other than MoonPay skip Check/Auth frames and use the empty-shell\n * customer + consents path instead.\n *\n * @param vendor - The identity vendor for the current flow.\n * @returns `true` when the vendor uses the consents session path.\n */\nfunction usesConsentsFlow(vendor: KycVendor): boolean {\n return vendor !== 'moonpay';\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 'initialize',\n 'loadDisclaimers',\n 'fetchSessionDisclaimers',\n 'acceptTermsAndStartSession',\n 'createVendorCustomer',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'getCustomerIdentity',\n 'refreshKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\n 'clearState',\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\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\n/**\n * Published when the user-keyed simplified KYC status changes (Money toast).\n */\nexport type KycControllerStatusChangedEvent = {\n type: `${typeof controllerName}:statusChanged`;\n payload: [\n {\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n },\n ];\n};\n\nexport type KycControllerEvents =\n | KycControllerStateChangeEvent\n | KycControllerStatusChangedEvent;\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 * How often, in milliseconds, to poll the UKYC session status after the\n * SumSub SDK completes. Defaults to\n * {@link DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS}.\n */\n sessionStatusPollIntervalMs?: number;\n /**\n * How often, in milliseconds, to refresh `GET /kyc/status` while the\n * simplified user status is `pending`. Defaults to\n * {@link DEFAULT_USER_STATUS_POLL_INTERVAL_MS}.\n */\n userStatusPollIntervalMs?: number;\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 /** MoonPay-specific frame protocol and non-persisted credentials. */\n readonly #moonPayFrames: MoonPayFrameHandler;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} and\n * {@link clearState} so in-flight async work (e.g. the KYC-required check)\n * can detect that it was superseded and avoid writing stale results onto a\n * reset controller.\n */\n #generation = 0;\n\n /** Interval, in milliseconds, between session-status polls. */\n readonly #sessionStatusPollIntervalMs: number;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #pollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped by {@link #stopPolling} (called on reset, a\n * new sub-flow, and once a terminal status is reached) so an in-flight poll\n * `tick` can detect it was superseded and neither write state nor schedule a\n * follow-up. This closes the gap where clearing the timer alone would still\n * let an already-awaiting request finish and reschedule.\n */\n #pollToken = 0;\n\n /** Interval, in milliseconds, between user-keyed status polls. */\n readonly #userStatusPollIntervalMs: number;\n\n /** Handle for the scheduled next user-status poll, or `null`. */\n #userStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Whether a user-status poll loop is currently active. Tracked separately\n * from {@link #userStatusPollTimer} because a scheduled tick clears the timer\n * handle before awaiting `fetchKycStatus`; relying on the handle alone would\n * let a concurrent {@link refreshKycStatus} start a second loop on the same\n * token during that in-flight window.\n */\n #userStatusPolling = false;\n\n /** Monotonic token for the user-status poll loop (see `#pollToken`). */\n #userStatusPollToken = 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 * @param options.sessionStatusPollIntervalMs - How often to poll the UKYC\n * session status after the SumSub SDK completes.\n * @param options.userStatusPollIntervalMs - How often to refresh the\n * user-keyed KYC status while it is still `pending`.\n */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS,\n userStatusPollIntervalMs = DEFAULT_USER_STATUS_POLL_INTERVAL_MS,\n }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#sessionStatusPollIntervalMs = sessionStatusPollIntervalMs;\n this.#userStatusPollIntervalMs = userStatusPollIntervalMs;\n this.#moonPayFrames = new MoonPayFrameHandler({\n getState: (): KycControllerState => this.state,\n update: (updater): void => this.#applyUpdate(updater),\n fail: (message): void => this.#fail(message),\n onAuthenticated: async (): Promise<void> =>\n this.#continueAfterAuthentication(),\n requireTermsReacceptance: (): void => this.#requireTermsReacceptance(),\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Builds an adapter over `UserStorageController` that the platform-agnostic\n * `getOrCreateLocalUserSecret` helper uses to persist/load the UKYC\n * `local_user_secret`.\n *\n * @returns The Encrypted User Storage adapter.\n */\n #localUserSecretStore(): UkycLocalUserSecretStore {\n return {\n get: async (\n path: string,\n entropySourceId?: string,\n ): Promise<string | null> =>\n this.messenger.call(\n 'UserStorageController:performGetStorage',\n path as `${string}.${string}`,\n entropySourceId,\n ),\n set: async (\n path: string,\n value: string,\n entropySourceId?: string,\n ): Promise<void> =>\n this.messenger.call(\n 'UserStorageController:performSetStorage',\n path as `${string}.${string}`,\n value,\n entropySourceId,\n ),\n };\n }\n\n /**\n * Resolves persisted terms + geolocation, and auto-creates a session when\n * terms are already accepted and an email is available.\n *\n * @param params - Optional parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. When\n * provided, the controller automatically runs the KYC-required check once\n * authentication completes (and chains into document verification when KYC\n * is required). When omitted, the flow stops at `form` and the consumer must\n * call `checkKycRequired` manually.\n * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors\n * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.\n * @throws If a resumed consents-path session records a failure on state.\n * The original error is rethrown after the controller rewinds to `terms`.\n */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\n vendor?: KycVendor;\n }): Promise<void> {\n // A repeat `initialize` while a session flow is already in progress must\n // not tear it down: creating a new vendor session clears the tokens and\n // forces `phase` back through `session`/`check`, breaking an in-flight\n // Check/Auth frame flow. Leave the active flow untouched and let the\n // consumer drive it (or call `reset` first to start over).\n const vendor = params?.vendor ?? 'moonpay';\n\n if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n if (vendor === 'moonpay') {\n this.#moonPayFrames.ensureKeypair();\n }\n return;\n }\n\n if (vendor === 'moonpay') {\n this.#moonPayFrames.startFlow();\n } else {\n this.#moonPayFrames.clear();\n }\n\n // `initialize` starts a fresh flow, so `activeProduct` is always reset to\n // this call's product (or `null`). Otherwise a prior run's product could\n // linger and cause `#continueAfterAuthentication` to auto-run the check /\n // sub-flow when the caller intended the manual (product-less) flow.\n this.#applyUpdate((state) => {\n if (params?.email) {\n state.email = params.email;\n }\n state.activeVendor = vendor;\n // MoonPay Check/Auth artifacts must not survive a switch to another vendor\n if (vendor !== 'moonpay') {\n clearMoonPaySession(state);\n }\n state.activeProduct = params?.product ?? null;\n });\n\n // Capture the flow generation so a `reset()` landing while the async\n // geolocation / session steps below are in flight cannot write results\n // onto an idle controller.\n const generation = this.#generation;\n\n // Resolve country for display; non-blocking.\n try {\n const country = await this.messenger.call('KycService:getGeoCountry');\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = country;\n });\n } catch {\n // Ignore; disclaimers loading will surface a country error if needed.\n }\n\n // A `reset()` / `clearState()` that landed while the geolocation request\n // was in flight supersedes this flow. Stop here rather than driving the\n // controller on into `terms` (or a new session): the steps below write\n // unconditionally, and `loadDisclaimers` captures the post-reset\n // generation, so its own guard would not catch this.\n if (this.#generation !== generation) {\n return;\n }\n\n if (usesConsentsFlow(vendor) && this.state.email) {\n try {\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor,\n email: this.state.email,\n });\n } catch (error) {\n if (this.#generation !== generation) {\n return;\n }\n this.#fail(`Vendor customer creation failed: ${String(error)}`);\n return;\n }\n }\n\n // Drop another vendor's persisted acceptance only after this flow has\n // committed (customer creation succeeded, or there was none to wait for).\n // Clearing earlier would permanently lose ramps/card terms if Iron\n // customer creation failed or a reset landed while it was in flight.\n if (this.#generation !== generation) {\n return;\n }\n const hasTerms = hasVendorDisclaimerAcceptance(\n this.state.vendorDisclaimersAccepted,\n vendor,\n );\n\n if (hasTerms && this.state.email) {\n if (usesConsentsFlow(vendor)) {\n // Consents-path vendors require T&C2 flags; if they weren't persisted\n // (i.e. null from pre-migration state), require reacceptance.\n const { providerDisclaimersAccepted, idosDisclaimersAccepted } =\n this.state;\n if (\n providerDisclaimersAccepted.sumsub === null ||\n idosDisclaimersAccepted === null\n ) {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n return;\n }\n await this.#startConsentsSession({\n providerDisclaimersAccepted: providerDisclaimersAccepted.sumsub,\n idosDisclaimersAccepted,\n credentialReusabilityConsentGiven:\n this.state.credentialReusabilityConsentGiven ?? false,\n });\n } else {\n // TODO: should this be here? or should it exist at all?\n if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {\n await this.loadDisclaimers();\n if (this.#generation !== generation) {\n return;\n }\n }\n await this.#createSession();\n }\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n }\n\n /**\n * Creates (or resumes) an empty-shell customer for the given identity\n * vendor. Exposed so a consumer can ensure the customer exists before\n * showing T&C screens independently of {@link initialize}.\n *\n * A call while a session flow is already in progress is a no-op — matching\n * {@link initialize} — so a vendor switch cannot leave Check/Auth frames\n * attached to the wrong vendor. Call {@link reset} first to start over.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor for the customer.\n * @param params.email - Email for the vendor customer.\n */\n async createVendorCustomer(params: {\n vendor: KycVendor;\n email: string;\n }): Promise<void> {\n if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\n }\n\n this.#applyUpdate((state) => {\n state.email = params.email;\n // MoonPay Check/Auth artifacts must not survive a switch to another\n // vendor — see `initialize`. Terms for another vendor are dropped only\n // after this request succeeds.\n state.activeVendor = params.vendor;\n if (params.vendor !== 'moonpay') {\n this.#moonPayFrames.clear();\n clearMoonPaySession(state);\n }\n });\n const generation = this.#generation;\n try {\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n email: params.email,\n });\n } catch (error) {\n if (this.#generation !== generation) {\n return;\n }\n this.#fail(`Vendor customer creation failed: ${String(error)}`);\n }\n }\n\n /**\n * Loads the disclaimers for the resolved (or provided) country.\n *\n * @param params - Optional parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code override.\n */\n async loadDisclaimers(params?: { country?: string }): Promise<void> {\n // Capture the flow generation so a `reset()` landing while the geo /\n // disclaimers requests are in flight cannot write results onto an idle\n // controller.\n const generation = this.#generation;\n try {\n const country =\n params?.country ??\n this.state.geoCountry ??\n (await this.messenger.call('KycService:getGeoCountry'));\n if (country !== this.state.geoCountry) {\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = country;\n });\n }\n const disclaimers = await this.messenger.call(\n 'KycService:fetchVendorDisclaimers',\n {\n vendor: this.state.activeVendor,\n country,\n },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.vendorDisclaimers = disclaimers;\n state.vendorError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.vendorError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\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 const generation = this.#generation;\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 this.#updateIfCurrent(generation, (state) => {\n state.sessionDisclaimers = catalog;\n });\n return catalog;\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\n *\n * @param params - The parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.idosDisclaimersAccepted - idOS disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.credentialReusabilityConsentGiven - Whether the customer\n * consented to reuse existing idOS credentials. Used when recording\n * session-scoped disclaimers on the consents path. Defaults to `false`.\n * @throws If the consents-path session records a failure on state. The\n * original error is rethrown after the controller rewinds to `terms`.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven?: boolean;\n }): Promise<void> {\n const providerDisclaimersAccepted = params?.providerDisclaimersAccepted;\n const idosDisclaimersAccepted = params?.idosDisclaimersAccepted;\n if (\n !isValidConsentRecordList(providerDisclaimersAccepted) ||\n !isValidConsentRecordList(idosDisclaimersAccepted)\n ) {\n this.#fail('Missing T&C2 acceptance flags.');\n return;\n }\n const credentialReusabilityConsentGiven =\n params?.credentialReusabilityConsentGiven ?? false;\n\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.vendorDisclaimers.map(\n (disclaimer) => disclaimer.id,\n );\n this.#applyUpdate((state) => {\n if (params?.email) {\n state.email = params.email;\n }\n if (params?.product) {\n state.activeProduct = params.product;\n }\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n state.activeVendor,\n { termsAcceptedAt, disclaimerIds },\n );\n state.providerDisclaimersAccepted = {\n ...state.providerDisclaimersAccepted,\n sumsub: providerDisclaimersAccepted,\n };\n state.idosDisclaimersAccepted = idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n credentialReusabilityConsentGiven;\n });\n if (usesConsentsFlow(this.state.activeVendor)) {\n await this.#startConsentsSession({\n providerDisclaimersAccepted,\n idosDisclaimersAccepted,\n credentialReusabilityConsentGiven,\n });\n return;\n }\n await this.#createSession();\n }\n\n /**\n * Consents-path vendors: record vendor T&Cs, create a UKYC session,\n * record session-scoped idOS / KYC-provider disclaimers, then launch\n * SumSub — skipping MoonPay Check/Auth frames.\n *\n * @param consents - T&C2 flags mapped onto the session disclaimer catalog.\n * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param consents.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n * @throws If a step after recording state fails. The original error is\n * rethrown after the controller rewinds to `terms`.\n */\n async #startConsentsSession(consents: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n const { email } = this.state;\n const acceptedDisclaimerIds = ironDisclaimerIds(\n this.state.vendorDisclaimersAccepted,\n );\n if (!email) {\n this.#fail('Missing email for consents session.');\n return;\n }\n if (acceptedDisclaimerIds.length === 0) {\n this.#fail('Missing disclaimer acceptance.');\n return;\n }\n\n const generation = this.#generation;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Submitting consents...';\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n // Consents-path vendors have no MoonPay session/access tokens.\n clearMoonPaySession(state);\n });\n\n try {\n await this.messenger.call('KycService:submitVendorDisclaimers', {\n vendor: this.state.activeVendor,\n disclaimerIds: acceptedDisclaimerIds,\n });\n if (this.#generation !== generation) {\n return;\n }\n\n this.#updateIfCurrent(generation, (state) => {\n state.statusMessage = 'Creating session...';\n });\n\n const created = await this.#createUkycSession(generation);\n if (!created) {\n return;\n }\n\n await this.#recordSessionDisclaimers(\n created.sessionId,\n consents,\n generation,\n );\n if (this.#generation !== generation) {\n return;\n }\n\n if (created.vendorProcessing) {\n try {\n await this.refreshKycStatus();\n } catch (statusError) {\n controllerLog('KYC status refresh failed:', statusError);\n }\n this.#updateIfCurrent(generation, (state) => {\n state.phase = 'done';\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return;\n }\n this.#applyUpdate((state) => {\n state.phase = 'submit';\n state.statusMessage = 'Starting document verification...';\n });\n const sumsubResult = await this.startSumSub();\n if (this.#generation !== generation) {\n return;\n }\n // The applicant closed the SDK without submitting. Nothing failed, so\n // rewind with `error` unset and let consumers offer a retry.\n if (this.state.sumsub.status === 'abandoned') {\n await this.#rewindConsentsFlow({\n error: null,\n statusMessage: SUMSUB_ABANDONED_MESSAGE,\n keepSumSubStatus: 'abandoned',\n });\n return;\n }\n // `startSumSub` records `failed` for thrown steps, an SDK that could not\n // run, *and* a terminal UKYC rejection after a submission. Only the first\n // two rewind. A rejection writes `sessionStatus` and is a finished flow:\n // refresh user status and land on `done`.\n if (\n this.state.sumsub.status === 'failed' &&\n this.state.sumsub.sessionStatus === null\n ) {\n const sumsubError = sumsubResult?.error;\n throw new Error(\n typeof sumsubError === 'string'\n ? sumsubError\n : 'SumSub verification could not run.',\n );\n }\n // After SumSub, refresh user-keyed status for the Money toast and start\n // polling while still pending. Soft-fail: toast refresh must not rewind\n // the consent / SumSub outcome.\n try {\n await this.refreshKycStatus();\n } catch (statusError) {\n controllerLog('KYC status refresh failed:', statusError);\n }\n this.#updateIfCurrent(generation, (state) => {\n if (state.phase !== 'error' && state.phase !== 'done') {\n state.phase = 'done';\n state.statusMessage = 'KYC submitted.';\n }\n });\n } catch (error) {\n if (isSessionAlreadyCompletedError(error)) {\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUserStatus({\n status: 'completed',\n sumsubSessionId: null,\n errorCode: null,\n });\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n state.sumsub.result = { alreadyCompleted: true };\n state.statusMessage = 'KYC already completed.';\n state.phase = 'done';\n state.error = null;\n });\n return;\n }\n controllerLog('Consents session failed:', error);\n if (this.#generation !== generation) {\n return;\n }\n await this.#rewindConsentsFlow({\n error: `Consents session failed: ${String(error)}`,\n statusMessage:\n 'Consent / verification failed — accept the terms to try again.',\n });\n throw error;\n }\n }\n\n /**\n * Returns the consents path to the terms phase after a SumSub sub-flow that\n * produced no verification decision, and reloads the disclaimers the next\n * attempt has to re-accept.\n *\n * @param options - Rewind options.\n * @param options.error - Message for `error`, or `null` when the rewind is a\n * normal outcome rather than a failure.\n * @param options.statusMessage - Message for `statusMessage`.\n * @param options.keepSumSubStatus - Sub-flow status to survive the rewind,\n * for an outcome consumers still need once the call resolves. Defaults to the\n * reset `idle`.\n */\n async #rewindConsentsFlow({\n error,\n statusMessage,\n keepSumSubStatus,\n }: {\n error: string | null;\n statusMessage: string;\n keepSumSubStatus?: KycSumSubStatus;\n }): Promise<void> {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.activeProduct = null;\n state.sessionDisclaimers = null;\n // Session create ran before recording disclaimers. Drop the leftover\n // UKYC session so a later `startSumSub` cannot skip consent recording.\n state.sumsub = { ...getDefaultKycControllerState().sumsub };\n if (keepSumSubStatus) {\n state.sumsub.status = keepSumSubStatus;\n }\n state.error = error;\n state.statusMessage = statusMessage;\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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 sessionId - The UKYC session id.\n * @param consents - T&C2 flags mapped onto catalog documents.\n * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param consents.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n * @param generation - Flow generation captured by the caller.\n */\n async #recordSessionDisclaimers(\n sessionId: string,\n consents: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n },\n generation: number,\n ): Promise<void> {\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUpdate((state) => {\n state.sessionDisclaimers = catalog;\n state.statusMessage = 'Submitting consents...';\n });\n\n if (\n isAcceptedCategoryEmpty(catalog.idOS, consents.idosDisclaimersAccepted) ||\n isAcceptedCategoryEmpty(\n catalog.kycProvider,\n consents.providerDisclaimersAccepted,\n )\n ) {\n throw new Error(\n 'Session disclaimer catalog is missing documents for an accepted category.',\n );\n }\n\n const idOS = consentRecordsFromAcceptedList(\n catalog.idOS,\n consents.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n catalog.kycProvider,\n consents.providerDisclaimersAccepted,\n );\n const reuseUnchanged =\n catalog.credentialReusabilityConsentGiven ===\n consents.credentialReusabilityConsentGiven;\n if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {\n return;\n }\n\n try {\n const recorded = await this.messenger.call(\n 'KycService:submitSessionDisclaimers',\n {\n sessionId,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n consents.credentialReusabilityConsentGiven,\n },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.sessionDisclaimers = recorded;\n });\n } catch (error) {\n if (!isConsentConflictError(error)) {\n throw error;\n }\n // 409 means some document version was already recorded. Re-fetch and\n // continue only when every document the user accepted is now consented;\n // otherwise fail closed so a version bump cannot skip new docs.\n const latest = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUpdate((state) => {\n state.sessionDisclaimers = latest;\n });\n // TODO: Should we really be doing client side validation of these?\n const stillMissingIdos = acceptedCategoryStillMissing(\n latest.idOS,\n consents.idosDisclaimersAccepted,\n );\n const stillMissingProvider = acceptedCategoryStillMissing(\n latest.kycProvider,\n consents.providerDisclaimersAccepted,\n );\n const stillMissingReuse =\n consents.credentialReusabilityConsentGiven &&\n !latest.credentialReusabilityConsentGiven;\n if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {\n throw error;\n }\n }\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email } = this.state;\n const termsAcceptedAt =\n this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;\n const acceptedDisclaimerIds = this.state.vendorDisclaimers.map(\n (disclaimer) => disclaimer.id,\n );\n if (!email) {\n this.#fail('Missing email for session creation.');\n return;\n }\n if (!termsAcceptedAt || acceptedDisclaimerIds.length === 0) {\n this.#fail('Missing terms acceptance for session creation.');\n return;\n }\n\n // A new session invalidates any authentication carried over from a prior\n // session. Clear the stale session token, access token, and auth-frame\n // client token so `buildCheckFrameUrl` cannot return a URL bound to an old\n // (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot\n // return a URL tied to an old client token, and `checkKycRequired` cannot\n // run with an access token from an earlier authentication. The Check/Auth\n // frames re-populate these for the new session. Because `moonpaySessionToken` is\n // cleared here and only re-set on success, a failed creation leaves it\n // `null` rather than resurrecting the previous session.\n // Capture the flow generation so a `reset()` landing while the create\n // request is in flight cannot resurrect a session (success) or overwrite\n // the now-idle controller (failure). The synchronous update below runs\n // before any `await`, so it needs no guard.\n const generation = this.#generation;\n this.#moonPayFrames.clearAuthentication();\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.moonpaySessionToken = null;\n state.moonpayAccessToken = null;\n });\n\n try {\n const { sessionToken } = await this.messenger.call(\n 'KycService:createSession',\n { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.moonpaySessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n controllerLog('Session creation failed:', error);\n // A reset() superseded this flow while the request was in flight; leave\n // the idle controller alone rather than forcing it back to `terms`.\n if (this.#generation !== generation) {\n return;\n }\n // Invalidate the stored acceptance so the customer can retry. Also clear\n // `activeProduct` so a later `acceptTermsAndStartSession` that omits a\n // product cannot auto-run the KYC check / SumSub chain for this failed\n // flow's product — matching how `initialize` starts from a clean product.\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.activeProduct = null;\n state.error = `Session creation failed: ${String(error)}`;\n state.statusMessage =\n 'Session creation failed — accept the terms to try again.';\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n }\n }\n\n /**\n * Clears the persisted terms acceptance.\n */\n clearSavedTerms(): void {\n this.#applyUpdate((state) => {\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Clears the stored terms acceptance on the given draft state. Shared by the\n * paths that must invalidate acceptance — explicit clear, vendor terms\n * update, and session-creation failure — so they stay in sync. This is a\n * targeted invalidation and, unlike {@link reset}, deliberately leaves the\n * rest of the flow (geolocation, disclaimers, phase) untouched.\n *\n * @param state - The state to mutate.\n * @param vendor - Vendor whose acceptance to clear. Defaults to\n * `state.activeVendor`.\n */\n #clearAcceptedTerms(state: KycControllerState, vendor?: KycVendor): void {\n const targetVendor = vendor ?? state.activeVendor;\n state.vendorDisclaimersAccepted = clearVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n targetVendor,\n );\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n }\n\n /**\n * Handles a message posted by a Check/Auth frame and advances the flow.\n *\n * The transport-agnostic caller (WebView on mobile, iframe on web) forwards\n * the raw message and injects the returned `reply` back into the frame.\n *\n * @param params - The parameters.\n * @param params.message - The raw message posted by the frame.\n * @returns An object whose optional `reply` should be posted back.\n */\n async handleFrameMessage(params: {\n message: unknown;\n }): Promise<{ reply?: unknown }> {\n return await this.#moonPayFrames.handleMessage(params.message);\n }\n\n /**\n * Continues the flow once authentication has completed (phase `form`).\n *\n * When the flow is scoped to a product (see {@link initialize}), the\n * KYC-required check runs automatically, and — when KYC is required — the\n * document-verification sub-flow is launched. When no product is set, this is\n * a no-op and the flow stays at `form` for the consumer to drive manually.\n *\n * `startSumSub` records `sumsub.status = 'failed'` and this method swallows\n * that rejection so it can be awaited safely from the frame-message handler.\n * `checkKycRequired` still records `phase: 'error'` and rethrows, so a\n * failed auto-run check surfaces to the caller.\n */\n async #continueAfterAuthentication(): Promise<void> {\n const product = this.state.activeProduct;\n if (!product) {\n return;\n }\n\n // Re-entry protection lives at the frame boundary: `handleFrameMessage`\n // only honors a Check/Auth `complete` while `phase` matches and\n // `activeVendor` is MoonPay, and both outcome handlers move `phase` to\n // `form` before awaiting this method. A duplicate, late, or cross-vendor\n // `complete` therefore lands after the phase moved on (or on the wrong\n // vendor) and is dropped before it can start a second continuation. Any\n // writes here are additionally guarded by `#generation` (see\n // `checkKycRequired` / `startSumSub`) so a `reset()` mid-continuation\n // cannot corrupt state.\n const kycRequired = await this.checkKycRequired({ product });\n if (!kycRequired) {\n return;\n }\n\n try {\n await this.startSumSub();\n } catch {\n // `startSumSub` already records `sumsub.status = 'failed'`; swallow the\n // rethrown error (e.g. SDK unavailable) so the awaited continuation\n // resolves cleanly rather than surfacing as an unhandled rejection.\n }\n }\n\n /**\n * Invalidates stored terms and returns to the terms phase.\n */\n #requireTermsReacceptance(): void {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.phase = 'terms';\n state.statusMessage =\n 'The vendor updated its Terms of Use — please re-accept.';\n });\n }\n\n /**\n * Builds the Check-frame URL, or `null` when no session exists yet.\n *\n * @returns The Check-frame URL or `null`.\n */\n buildCheckFrameUrl(): string | null {\n return this.#moonPayFrames.buildCheckFrameUrl();\n }\n\n /**\n * Builds the Auth-frame URL, or `null` when no client token is available.\n *\n * @returns The Auth-frame URL or `null`.\n */\n buildAuthFrameUrl(): string | null {\n return this.#moonPayFrames.buildAuthFrameUrl();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n return this.#moonPayFrames.buildResetFrameUrl();\n }\n\n /**\n * Checks whether KYC is required for a product and caches the result.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @param params.country - Optional alpha-3 country override.\n * @returns Whether KYC is required.\n * @throws If the KYC-required service call fails after the error is recorded\n * on controller state (`phase: 'error'`).\n */\n async checkKycRequired(params: {\n product: KycProduct;\n country?: string;\n }): Promise<boolean> {\n const { moonpayAccessToken } = this.state;\n if (!moonpayAccessToken) {\n this.#fail(\n 'Missing moonpayAccessToken — repeat the authentication step.',\n );\n return false;\n }\n const country = params.country ?? this.state.geoCountry;\n if (!country) {\n this.#fail('Missing country for KYC-required check.');\n return false;\n }\n\n // Capture the flow generation so we can detect a `reset()` that happens\n // while the HTTP call is in flight and avoid writing stale results.\n const generation = this.#generation;\n\n this.#applyUpdate((state) => {\n state.phase = 'submit';\n state.statusMessage = 'Checking KYC status...';\n });\n\n try {\n const { kycRequired } = await this.messenger.call(\n 'KycService:checkKycRequired',\n {\n accessToken: moonpayAccessToken,\n country,\n capabilities: [{ product: params.product }],\n },\n );\n // The flow was reset while the check was in flight; discard the result\n // rather than resurrecting a done/cached state on an idle controller.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.kycRequiredByProduct[params.product] = kycRequired;\n state.lastCheckedAt = new Date().toISOString();\n state.phase = 'done';\n state.statusMessage = 'KYC check complete.';\n });\n if (!applied) {\n return false;\n }\n return kycRequired;\n } catch (error) {\n if (this.#generation !== generation) {\n return false;\n }\n this.#fail(`KYC check failed: ${String(error)}`);\n throw error;\n }\n }\n\n /**\n * Reads the cached \"is KYC required\" result for a product.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @returns The cached value, or `undefined` if not yet checked.\n */\n getKycStatus(params: { product: KycProduct }): boolean | undefined {\n return this.state.kycRequiredByProduct[params.product];\n }\n\n /**\n * Returns the vendor-scoped identity for the currently authenticated\n * customer, or `null` when the flow has not yet captured a vendor customer\n * id (before authentication or after {@link reset}), or when a MoonPay id\n * is present under a different `activeVendor`.\n *\n * Exposed so consumers (e.g. ramps autoramp creation) can attach the vendor\n * customer id to downstream calls without reading the full KYC state, which\n * also holds session/access tokens. The id is session-scoped and never\n * persisted.\n *\n * @returns The current {@link KycCustomerIdentity}, or `null`.\n */\n getCustomerIdentity(): KycCustomerIdentity | null {\n const { moonpayCustomerId, activeVendor } = this.state;\n // `moonpayCustomerId` is issued only by MoonPay Check/Auth frames. Never\n // pair it with another vendor, even if a switch left the fields out of\n // sync, so consumers cannot attach a MoonPay id to an Iron (or other)\n // downstream call.\n if (!moonpayCustomerId || activeVendor !== 'moonpay') {\n return null;\n }\n return { vendor: 'moonpay', id: moonpayCustomerId };\n }\n\n /**\n * Builds the vendor-specific fields spread into a\n * `KycService:createUkycSession` call, derived from the active vendor and the\n * currently captured auth state.\n *\n * MoonPay sessions must carry the access token and customer id in\n * `vendorMetadata`; other vendors carry no vendor metadata.\n *\n * @returns The vendor-specific subset of the `createUkycSession` params.\n */\n #buildUkycSessionVendorFields(): Pick<\n CreateUkycSessionParams,\n 'vendor' | 'vendorMetadata'\n > {\n if (this.state.activeVendor === 'moonpay') {\n return {\n vendor: 'moonpay',\n vendorMetadata: {\n moonPayAccessToken: this.state.moonpayAccessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n };\n }\n\n return { vendor: this.state.activeVendor };\n }\n\n /**\n * Creates 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 `sumsub.sessionId`. Returns `null`\n * when a `reset()` superseded the flow.\n *\n * @param generation - Flow generation captured by the caller.\n * @returns The created session, or `null` if superseded.\n */\n async #createUkycSession(generation: number): Promise<{\n sessionId: string;\n kycStatus?: string;\n finalStatus?: string;\n vendorProcessing: boolean;\n } | null> {\n const jwtToken = MOCK_JWT_TOKEN;\n\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 residenceCountry =\n this.state.geoCountry ??\n (await this.messenger.call('KycService:getGeoCountry'));\n if (this.#generation !== generation) {\n return null;\n }\n if (residenceCountry !== this.state.geoCountry) {\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = residenceCountry;\n });\n }\n\n const {\n sessionId,\n encryptionDataKey,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n jwtToken,\n sessionClientPublicKey,\n residenceCountry,\n ...this.#buildUkycSessionVendorFields(),\n });\n if (this.#generation !== generation) {\n return null;\n }\n\n // Verify each schema's jwtChain against the matching issuer JWKS, then\n // confirm 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` by the\n // idOS relay.\n const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] =\n await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n this.#assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n this.#assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n\n // Derive the data_encryption_key from the local_user_secret, mint a\n // read-only capability token, and wrap both for the session server. Only\n // the wrapped (encrypted) material ever leaves the device.\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 // Only the client holds the signing key derived from `local_user_secret`,\n // so only the client can mint the token; scoping it to `read` means it\n // authorizes later storage reads without granting write or delete access.\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 if (this.#generation !== generation) {\n return null;\n }\n\n const { kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n const vendorProcessing =\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending;\n\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.sessionId = sessionId;\n if (vendorProcessing) {\n state.sumsub.status = 'vendorProcessing';\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n }\n });\n if (!stillCurrent) {\n return null;\n }\n return { sessionId, kycStatus, finalStatus, vendorProcessing };\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\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 SDK result.\n */\n async startSumSub(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<Record<string, unknown>> {\n // A new sub-flow supersedes any polling still running from a prior run.\n this.#stopPolling();\n // Paused for the whole sub-flow: a tick landing while the SDK is on screen\n // publishes `statusChanged`, pulling consumers (and their signing prompts)\n // in front of a flow the applicant has not finished. Resumed in `finally`\n // so abandonment, SDK failure, and callers that do not run\n // `refreshKycStatus` (MoonPay post-auth) still restore the loop.\n this.#stopUserStatusPolling();\n\n // Capture the flow generation so each async step can detect a `reset()`\n // that lands mid-flight and avoid writing stale sub-flow state (or, worse,\n // presenting the SDK) on a controller that is now idle.\n const generation = this.#generation;\n\n try {\n if (!this.#sumsubLauncher.isAvailable()) {\n const error = 'SumSub SDK is not available in this runtime.';\n this.#applyUpdate((state) => {\n state.sumsub.status = 'failed';\n state.sumsub.result = { error };\n });\n throw new Error(error);\n }\n\n try {\n if (!this.state.sumsub.sessionId) {\n this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const created = await this.#createUkycSession(generation);\n if (!created) {\n return {};\n }\n\n // A user who already finished the journey can return to a session the\n // relay has already approved (`kycStatus`) while the vendor is still\n // finalizing its own decision (`finalStatus`). There is nothing left to\n // verify, so stop here and surface a message rather than launching the\n // SDK again.\n if (created.vendorProcessing) {\n return {\n kycStatus: created.kycStatus,\n finalStatus: created.finalStatus,\n };\n }\n }\n\n // Empty string is a valid \"no id to poll\" session id used by tests and\n // must not be coalesced away as missing.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const sessionId = this.state.sumsub.sessionId || '';\n\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'fetchingToken';\n state.sumsub.sessionId = sessionId;\n });\n\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n\n // A reset() may have landed while the session/token was being prepared.\n // Gate the `launching` write and the decision to open the SDK behind a\n // single generation check: `#updateIfCurrent` only writes when still\n // current and reports whether it did. Since there is no `await` between\n // this check and `launch` below, a successful result guarantees the SDK\n // is never presented on a flow that a concurrent reset() returned to idle.\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'launching';\n state.sumsub.applicantAccessToken = applicantAccessToken;\n });\n if (!stillCurrent) {\n return {};\n }\n\n // Track whether the SDK ever reported a successful completion. A resolved\n // `launch` alone does not imply success — the applicant may have\n // abandoned the flow or the SDK may have reported a non-success outcome.\n let reachedCompletion = false;\n\n const result = await this.#sumsubLauncher.launch({\n applicantAccessToken,\n onTokenExpiration: async () => {\n // A reset() may have superseded this flow while the SDK stayed open.\n // Refuse to refresh against the now-stale UKYC session rather than\n // silently keeping an orphaned SDK alive.\n if (this.#generation !== generation) {\n throw new Error(\n 'KYC flow was reset; SumSub session is no longer active.',\n );\n }\n const refreshed = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return refreshed.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = isSumSubFlowCompleted(next)\n ? 'complete'\n : 'inProgress';\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\n // A resolved `launch` alone is not the final outcome: only a submission\n // is worth polling for a decision. Without one, the SDK status is the\n // only way to tell a failure from an applicant who closed the SDK early\n // — the UKYC session leaves its initial state as soon as the journey is\n // created, so it cannot stand in for \"the applicant finished\".\n let settledStatus: KycSumSubStatus = 'abandoned';\n if (reachedCompletion) {\n settledStatus = 'polling';\n } else if (isSumSubLaunchFailure(result)) {\n settledStatus = 'failed';\n }\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = settledStatus;\n state.sumsub.result = result as Json;\n });\n\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result. Poll the session status\n // until it reaches a terminal decision. Guard on `applied` so a `reset()`\n // that landed during `launch` cannot start polling on an idle flow.\n if (applied && reachedCompletion) {\n if (sessionId) {\n await this.#startSessionStatusPolling(sessionId);\n } else {\n // No session id to poll against; fall back to treating the SDK\n // completion as the final outcome.\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n });\n }\n }\n return result;\n } catch (error) {\n // Applicant already finished KYC — treat as completed for Money toast.\n if (isSessionAlreadyCompletedError(error)) {\n // A reset() may have landed while `launch` was in flight; forcing\n // `completed` (and publishing `statusChanged`) on an idle controller\n // would resurrect a flow the consumer already tore down.\n if (this.#generation !== generation) {\n return { alreadyCompleted: true };\n }\n this.#applyUserStatus({\n status: 'completed',\n sumsubSessionId: null,\n errorCode: null,\n });\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n state.sumsub.result = { alreadyCompleted: true };\n state.statusMessage = 'KYC already completed.';\n state.phase = 'done';\n state.error = null;\n });\n return { alreadyCompleted: true };\n }\n const result = { error: String(error) };\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'failed';\n state.sumsub.result = result;\n });\n return result;\n }\n } finally {\n if (this.#generation === generation) {\n try {\n await this.refreshKycStatus();\n } catch (error) {\n controllerLog('KYC status refresh failed:', error);\n }\n }\n }\n }\n\n /**\n * Refreshes the user-keyed simplified KYC status from `GET /kyc/status`,\n * stores it on state, publishes {@link KycControllerStatusChangedEvent}, and\n * schedules short-interval polling while the status is `pending`.\n *\n * Skipped when `userStatus` is already `completed`: a follow-up\n * `GET /kyc/status` can still read a stale `pending` (for example after\n * `session_not_in_valid_state`) and must not undo that decision.\n *\n * @returns The latest status payload.\n */\n async refreshKycStatus(): Promise<{\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }> {\n if (this.state.userStatus === 'completed') {\n return {\n status: 'completed',\n sumsubSessionId: this.state.userStatusSumsubSessionId,\n errorCode: this.state.userStatusErrorCode,\n };\n }\n\n const generation = this.#generation;\n const payload = await this.#fetchAndApplyUserStatus();\n // A `reset()` landing while the request was in flight already stopped\n // polling and left the flow idle, and the payload above is the pre-reset\n // cached status. Starting a loop from it would poll — and publish\n // `statusChanged` — on a torn-down flow.\n if (this.#generation !== generation) {\n return payload;\n }\n if (payload.status === 'pending') {\n this.#ensureUserStatusPolling();\n } else {\n this.#stopUserStatusPolling();\n }\n return payload;\n }\n\n /**\n * Fetches `GET /kyc/status` and applies it to state without managing the\n * poll loop (used by both {@link refreshKycStatus} and the poll tick).\n *\n * @returns The latest status payload.\n */\n async #fetchAndApplyUserStatus(): Promise<{\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }> {\n const generation = this.#generation;\n const response = await this.messenger.call('KycService:fetchKycStatus');\n if (this.#generation !== generation) {\n return {\n status: this.state.userStatus ?? 'not-started',\n sumsubSessionId: this.state.userStatusSumsubSessionId,\n errorCode: this.state.userStatusErrorCode,\n };\n }\n const payload = {\n status: response.status,\n sumsubSessionId: response.sumsubSessionId ?? null,\n errorCode: response.errorCode ?? null,\n };\n this.#applyUserStatus(payload);\n return payload;\n }\n\n /**\n * Writes user-keyed status onto state and publishes `statusChanged` when the\n * value actually changes.\n *\n * @param payload - The status payload to apply.\n * @param payload.status - User-keyed KYC status from `GET /kyc/status`.\n * @param payload.sumsubSessionId - Optional SumSub session id from status.\n * @param payload.errorCode - Optional error code from status.\n */\n #applyUserStatus(payload: {\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }): void {\n const previous = this.state.userStatus;\n this.#applyUpdate((state) => {\n state.userStatus = payload.status;\n state.userStatusSumsubSessionId = payload.sumsubSessionId;\n state.userStatusErrorCode = payload.errorCode;\n });\n if (previous !== payload.status) {\n this.messenger.publish(`${controllerName}:statusChanged`, payload);\n }\n }\n\n /**\n * Starts the user-status poll loop when not already running and status is\n * still `pending`.\n */\n #ensureUserStatusPolling(): void {\n if (this.#userStatusPolling) {\n return;\n }\n this.#userStatusPolling = true;\n const token = this.#userStatusPollToken;\n const tick = async (): Promise<void> => {\n try {\n const payload = await this.#fetchAndApplyUserStatus();\n // Race with `reset()` / `#stopUserStatusPolling` while the request was\n // in flight — do not reschedule onto an idle controller.\n /* istanbul ignore next */\n if (this.#userStatusPollToken !== token) {\n return;\n }\n if (payload.status !== 'pending') {\n this.#stopUserStatusPolling();\n return;\n }\n } catch {\n // Keep polling on transient errors, unless the loop was superseded.\n /* istanbul ignore next */\n if (this.#userStatusPollToken !== token) {\n return;\n }\n }\n this.#userStatusPollTimer = setTimeout(() => {\n this.#userStatusPollTimer = null;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#userStatusPollIntervalMs);\n // Allow the process to exit while a pending-status poll is scheduled.\n // React Native / browser timers are numbers with no `unref`, hence the\n // optional call.\n this.#userStatusPollTimer.unref?.();\n };\n this.#userStatusPollTimer = setTimeout(() => {\n this.#userStatusPollTimer = null;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#userStatusPollIntervalMs);\n this.#userStatusPollTimer.unref?.();\n }\n\n /**\n * Stops the user-keyed status poll loop.\n */\n #stopUserStatusPolling(): void {\n this.#userStatusPollToken += 1;\n this.#userStatusPolling = false;\n if (this.#userStatusPollTimer !== null) {\n clearTimeout(this.#userStatusPollTimer);\n this.#userStatusPollTimer = null;\n }\n }\n\n /**\n * Fetches the current UKYC session status for the active sub-flow and records\n * it on state. Useful for a one-off refresh outside the automatic polling\n * loop that {@link startSumSub} runs.\n *\n * @returns The fetched session status.\n * @throws If there is no active SumSub session to query.\n */\n async getSessionStatus(): Promise<KycSessionStatus> {\n const { sessionId } = this.state.sumsub;\n if (!sessionId) {\n throw new Error('Cannot fetch session status: no active SumSub session.');\n }\n\n // Capture the flow generation so a `reset()` landing while the request is\n // in flight cannot write the result onto an idle controller.\n const generation = this.#generation;\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n /**\n * Begins polling the UKYC session status until a terminal decision is\n * reached. The first poll runs immediately (and is awaited by\n * {@link startSumSub}); subsequent polls are scheduled every\n * `#sessionStatusPollIntervalMs`.\n *\n * @param sessionId - The UKYC session id to poll.\n * @returns A promise that resolves once the first poll settles.\n */\n async #startSessionStatusPolling(sessionId: string): Promise<void> {\n // Supersede any prior loop and claim a fresh token for this one. Because\n // `#stopPolling` bumps the token, any in-flight poll from a previous loop\n // sees a mismatch and neither writes state nor reschedules.\n this.#stopPolling();\n const token = this.#pollToken;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n this.#pollTimer = setTimeout(() => {\n this.#pollTimer = null;\n // `tick` swallows its own errors (see `#pollSessionStatusOnce`) and\n // therefore never rejects, so this fire-and-forget scheduled poll\n // cannot surface as an unhandled rejection.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#sessionStatusPollIntervalMs);\n };\n\n await tick();\n }\n\n /**\n * Performs a single session-status poll: fetches the status, records it, and\n * resolves the sub-flow when the status is terminal.\n *\n * Transient errors are swallowed so the loop keeps polling; the last good\n * `sessionStatus` is deliberately preserved rather than being overwritten\n * with the error.\n *\n * @param sessionId - The UKYC session id to poll.\n * @param token - The polling token captured when the loop started.\n * @returns `true` when the loop should stop (terminal status or superseded\n * by a reset / new sub-flow), `false` when it should keep polling.\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 // Superseded while the request was in flight — drop the result.\n if (this.#pollToken !== token) {\n return true;\n }\n const isTerminal = TERMINAL_SESSION_STATUSES.has(\n sessionStatus.finalStatus,\n );\n this.#applyUpdate((state) => {\n state.sumsub.sessionStatus = sessionStatus;\n if (isTerminal) {\n state.sumsub.status = SUCCESSFUL_SESSION_STATUSES.has(\n sessionStatus.finalStatus,\n )\n ? 'complete'\n : 'failed';\n }\n });\n if (isTerminal) {\n this.#stopPolling();\n }\n return isTerminal;\n } catch {\n // Keep polling on transient errors, preserving the last good status.\n // Stop only when a reset / new sub-flow superseded this loop.\n return this.#pollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop: bumps the polling token (so any\n * in-flight `tick` bows out) and clears any scheduled poll.\n */\n #stopPolling(): void {\n this.#pollToken += 1;\n if (this.#pollTimer !== null) {\n clearTimeout(this.#pollTimer);\n this.#pollTimer = null;\n }\n }\n\n /**\n * Resets the flow to idle, clearing session tokens and sub-flow state while\n * preserving persisted terms acceptance and the per-product cache.\n */\n reset(): void {\n this.#cancelPendingSession();\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.vendorDisclaimers = [];\n state.vendorError = null;\n state.sessionDisclaimers = null;\n state.credentialReusabilityConsentGiven = null;\n clearMoonPaySession(state);\n state.activeVendor = 'moonpay';\n state.activeProduct = null;\n state.sumsub = {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n };\n });\n }\n\n /**\n * Restores the controller to its default state, discarding everything\n * {@link reset} deliberately keeps: the session email, the persisted terms\n * acceptance, the per-product KYC-required cache and the user-keyed status.\n *\n * Intended for a full wallet reset, where no trace of the previous\n * customer may survive into the next wallet.\n */\n clearState(): void {\n this.#cancelPendingSession();\n this.#applyUpdate((state) => {\n Object.assign(state, getDefaultKycControllerState());\n });\n }\n\n /**\n * Tears down everything that lives outside state: drops the MoonPay frame\n * keypair and auth client token, stops both polling loops, and bumps the flow\n * generation so async steps started earlier discard their results instead\n * of writing them onto the controller. Shared by {@link reset} and\n * {@link clearState}.\n */\n #cancelPendingSession(): void {\n this.#moonPayFrames.clear();\n this.#stopPolling();\n this.#stopUserStatusPolling();\n this.#generation += 1;\n }\n\n /**\n * Applies a state update only when the flow has not been reset since\n * `generation` was captured. Prevents an in-flight async step from writing\n * stale results onto a controller that a concurrent {@link reset} has\n * returned to idle.\n *\n * @param generation - The flow generation captured before the async work.\n * @param updater - The state mutation to apply when still current.\n * @returns `true` if the update was applied, `false` if it was superseded.\n */\n #updateIfCurrent(\n generation: number,\n updater: (state: KycControllerState) => void,\n ): boolean {\n if (this.#generation !== generation) {\n return false;\n }\n this.#applyUpdate(updater);\n return true;\n }\n\n /**\n * The single state-update path for this controller. All mutations go through\n * here (rather than calling `this.update` directly) so the mechanism stays\n * consistent and one subtlety is handled in a single place:\n *\n * `sumsub.result` is typed as the recursive `Json`, and expanding\n * `Draft<Json>` (which happens whenever an updater touches `sumsub.result`)\n * can trip TypeScript's \"type instantiation is excessively deep\" guard. By\n * typing the callback parameter as the plain {@link KycControllerState}\n * instead of Immer's `Draft`, we avoid expanding the draft type while keeping\n * the same mutate-in-place semantics (the underlying value is still the Immer\n * draft at runtime).\n *\n * @param updater - The state mutation to apply.\n */\n #applyUpdate(updater: (state: KycControllerState) => void): void {\n this.update((state) => {\n // @ts-expect-error Avoid \"type instantiation is excessively deep\".\n updater(state);\n });\n }\n\n /**\n * Confirms that an encryption schema's `serverPublicKey.x` matches the\n * `sessionServerPublicKeyX` attested inside its verified `jwtChain`. Rejects\n * a key that was swapped out-of-band after the chain was signed.\n *\n * @param keys - The issuer JWKS used to verify the chain (idOS enclave for\n * `encryptionDataKey`, idOS relay for `ukycCapabilityToken`).\n * @param schema - The encryption schema returned by session creation.\n */\n #assertAttestedServerPublicKey(keys: Jwk[], schema: EncryptionSchema): void {\n const jwtChainPayload = verifyJwtChain(keys, schema.jwtChain);\n if (jwtChainPayload.sessionServerPublicKeyX !== schema.serverPublicKey.x) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n }\n\n /**\n * Transitions to the error phase with a message.\n *\n * @param message - The error message.\n */\n #fail(message: string): void {\n this.#applyUpdate((state) => {\n state.error = message;\n state.phase = 'error';\n });\n }\n}\n"]}
1
+ {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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","sourcesContent":["import 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 {\n UserStorageControllerPerformGetStorageAction,\n UserStorageControllerPerformSetStorageAction,\n} from '@metamask/profile-sync-controller/user-storage';\nimport type { Json } from '@metamask/utils';\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 CreateUkycSessionParams,\n EncryptionSchema,\n} from './KycService.js';\nimport { controllerLog } from './logger.js';\nimport type {\n KycConsentDocument,\n KycConsentRecord,\n KycCustomerIdentity,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycPhase,\n KycProduct,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubSdkStatus,\n KycSumSubStatus,\n KycUserStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport type { Jwk } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n clearVendorDisclaimerAcceptance,\n hasVendorDisclaimerAcceptance,\n ironDisclaimerIds,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimerAcceptance.js';\nimport {\n clearMoonPaySession,\n MoonPayFrameHandler,\n} from './vendors/MoonPayFrameHandler.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\n// Placeholder credentials for the SumSub sub-flow. These are demo values that\n// must be replaced with real UKYC-issued material before production use.\nconst MOCK_JWT_TOKEN = 'mock-jwt-token';\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 = 4 * 60 * 60 * 1000;\n\n// SumSub statuses that mean the applicant submitted (see `KycSumSubSdkStatus`\n// for what each one reports). `Completed` covers launchers that normalize the\n// platform status before forwarding it. Review decisions (`Approved`,\n// `FinallyRejected`, `TemporarilyDeclined`) are post-submission outcomes: the\n// applicant finished the SDK, so UKYC is polled for the authoritative\n// decision. Pre-submission statuses (`Ready`, `Initial`, `Incomplete`) must\n// not be recorded as a completed verification.\nconst SUMSUB_COMPLETED_STATUSES: ReadonlySet<string> =\n new Set<KycSumSubSdkStatus>([\n 'Completed',\n 'Pending',\n 'Approved',\n 'ActionCompleted',\n 'FinallyRejected',\n 'TemporarilyDeclined',\n ]);\n\n// The only status meaning the SDK could not run, rather than reporting how far\n// the applicant got before closing it.\nconst SUMSUB_FAILED_STATUS: KycSumSubSdkStatus = 'Failed';\n\nconst SUMSUB_ABANDONED_MESSAGE =\n 'Identity verification was not finished — accept the terms to try again.';\n\n/**\n * Checks whether a SumSub status means the applicant submitted the flow.\n *\n * @param status - Status from a launcher callback or launch result.\n * @returns Whether the applicant submitted, including a review decision.\n */\nfunction isSumSubFlowCompleted(status: unknown): boolean {\n return typeof status === 'string' && SUMSUB_COMPLETED_STATUSES.has(status);\n}\n\n/**\n * Checks whether the SDK failed to run, as opposed to the applicant closing it\n * early. Only the former is worth reporting as an error.\n *\n * @param result - The result the launcher resolved with.\n * @returns Whether the SDK failed to run.\n */\nfunction isSumSubLaunchFailure(result: Record<string, unknown>): boolean {\n return (\n result.status === SUMSUB_FAILED_STATUS || typeof result.error === 'string'\n );\n}\n\n// Phases that represent an active vendor-session flow (tokens issued and/or\n// Check/Auth frames in progress). A repeat `initialize` while in one of these\n// must not restart the session and disrupt the in-flight flow.\nconst IN_PROGRESS_PHASES: KycPhase[] = [\n 'session',\n 'check',\n 'auth',\n 'form',\n 'submit',\n];\n\n// How often to poll the UKYC session status after the SumSub SDK completes,\n// until a terminal status is reached. Overridable via the constructor.\nconst DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// UKYC status values. `kycStatus` (the relay-side decision) and `finalStatus`\n// (the vendor-side outcome) draw from the same vocabulary, so they are defined\n// once here and composed into the sets/checks below rather than repeated as\n// literals.\nconst KYC_STATUSES = {\n approved: 'approved',\n completed: 'completed',\n rejected: 'rejected',\n failed: 'failed',\n blocked: 'blocked',\n pending: 'pending',\n} as const;\n\n// `finalStatus` values that end the polling loop. Anything else (e.g.\n// `KYC_STATUSES.pending`) keeps polling.\nconst TERMINAL_SESSION_STATUSES: ReadonlySet<string> = new Set([\n KYC_STATUSES.approved,\n KYC_STATUSES.completed,\n KYC_STATUSES.rejected,\n KYC_STATUSES.failed,\n KYC_STATUSES.blocked,\n]);\n\n// Terminal `finalStatus` values that represent a successful verification. Any\n// other terminal status resolves the sub-flow to `failed`.\nconst SUCCESSFUL_SESSION_STATUSES: ReadonlySet<string> = new Set([\n KYC_STATUSES.approved,\n KYC_STATUSES.completed,\n]);\n\n// Session creation can report that the applicant is already approved on the\n// relay (`kycStatus === KYC_STATUSES.approved`) while the vendor is still\n// finalizing its decision (`finalStatus === KYC_STATUSES.pending`, a\n// non-terminal status). In that case there is nothing left for the applicant\n// to do, so the sub-flow stops before launching the SDK and surfaces this\n// message.\nconst VENDOR_PROCESSING_MESSAGE =\n 'Your KYC has been submitted and is being processed by the vendor.';\n\n// UKYC / relay error indicating the applicant already finished KYC. Mapped to\n// the simplified `completed` user status for the Money toast surface.\nconst SESSION_NOT_IN_VALID_STATE = 'session_not_in_valid_state';\n\n// How often to refresh the user-keyed `GET /kyc/status` while the simplified\n// status is still `pending`. Overridable via the constructor.\nconst DEFAULT_USER_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Current phase of the identity flow. */\n phase: KycPhase;\n /** Human-readable status message for the current phase. */\n statusMessage: string;\n /** The current error message, or `null`. */\n error: string | null;\n\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\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 /** Vendor disclaimers fetched for the current country. */\n vendorDisclaimers: KycDisclaimer[];\n /** Error encountered while loading vendor disclaimers, or `null`. */\n vendorError: string | null;\n /**\n * idOS / KYC-provider disclaimer catalog from `GET /disclaimers` or\n * `GET /sessions/{sessionId}/disclaimers`. `null` until the catalog has\n * been fetched (typically after a UKYC session exists).\n */\n sessionDisclaimers: KycSessionDisclaimers | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** MoonPay session token (not persisted, not logged). */\n moonpaySessionToken: string | null;\n /** MoonPay access token (not persisted, not logged). */\n moonpayAccessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\n\n /**\n * The identity vendor driving the current flow. Captured at `initialize`.\n * Defaults to `moonpay` when omitted so existing ramps/card callers keep\n * the Check/Auth frame path. Non-MoonPay vendors skip those frames.\n */\n activeVendor: KycVendor;\n\n /**\n * The product the current flow is running for. Captured at `initialize`\n * (or `acceptTermsAndStartSession`) and used to automatically run the\n * KYC-required check once authentication completes. `null` outside a\n * product-scoped flow (in which case the flow stops at `form` and the\n * consumer drives the check manually).\n */\n activeProduct: KycProduct | null;\n\n /** Cached \"is KYC required\" result per product (persisted). */\n kycRequiredByProduct: Partial<Record<KycProduct, boolean>>;\n /** ISO-8601 timestamp of the last KYC-required check (persisted). */\n lastCheckedAt: string | null;\n\n /**\n * User-keyed simplified KYC status from `GET /kyc/status` (persisted so the\n * Money toast can render across cold starts). `null` until the first\n * successful `refreshKycStatus`.\n */\n userStatus: KycUserStatus | null;\n /** Optional SumSub session id for the retryable error path. */\n userStatusSumsubSessionId: string | null;\n /** Optional machine-readable error code for terminal / EDD UX. */\n userStatusErrorCode: string | null;\n\n /** SumSub document-verification sub-flow state. */\n sumsub: {\n status: KycSumSubStatus;\n result: Json | null;\n sessionId: string | null;\n applicantAccessToken: string | null;\n /**\n * The latest UKYC session status, populated while polling after the SDK\n * completes. `null` until the first successful poll.\n */\n sessionStatus: KycSessionStatus | null;\n };\n};\n\nconst kycControllerMetadata = {\n phase: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n statusMessage: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n error: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\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: false,\n usedInUi: false,\n },\n vendorDisclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n vendorError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionDisclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n moonpaySessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n moonpayAccessToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n moonpayCustomerId: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n activeVendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n activeProduct: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n kycRequiredByProduct: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n lastCheckedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n userStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n userStatusSumsubSessionId: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: true,\n },\n userStatusErrorCode: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sumsub: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\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\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 phase: 'idle',\n statusMessage: '',\n error: null,\n email: null,\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n vendorDisclaimers: [],\n vendorError: null,\n sessionDisclaimers: null,\n geoCountry: null,\n moonpaySessionToken: null,\n moonpayAccessToken: null,\n moonpayCustomerId: null,\n activeVendor: 'moonpay',\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n userStatus: null,\n userStatusSumsubSessionId: null,\n userStatusErrorCode: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n/**\n * Whether an error indicates the applicant already finished KYC — the UKYC /\n * relay `session_not_in_valid_state` signal — which the controller maps to the\n * simplified `completed` user status.\n *\n * @param error - The caught error.\n * @returns `true` when the error carries the `session_not_in_valid_state`\n * marker.\n */\nfunction isSessionAlreadyCompletedError(error: unknown): boolean {\n return String(error).includes(SESSION_NOT_IN_VALID_STATE);\n}\n\n/**\n * Whether recording session disclaimers failed because those document\n * versions were already consented for the session (`409 Conflict`).\n *\n * @param error - The caught error.\n * @returns `true` when the error is an HTTP 409.\n */\nfunction isConsentConflictError(error: unknown): boolean {\n return (\n typeof error === 'object' &&\n error !== null &&\n typeof (error as { httpStatus?: unknown }).httpStatus === 'number' &&\n (error as { httpStatus: number }).httpStatus === 409\n );\n}\n\n/**\n *\n * @param value - The value to validate.\n * @returns `true` when `value` is a valid consent record list.\n */\nfunction isValidConsentRecordList(value: unknown): value is KycConsentRecord[] {\n return (\n Array.isArray(value) &&\n value.every(\n (item) =>\n typeof item === 'object' &&\n item !== null &&\n typeof (item as KycConsentRecord).key === 'string' &&\n typeof (item as KycConsentRecord).version === 'string',\n )\n );\n}\n\n/**\n * Maps accepted disclaimer records onto unconsented catalog documents.\n *\n * @param documents - Catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns Consent records to POST, omitting already-consented documents.\n */\nfunction consentRecordsFromAcceptedList(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): KycConsentRecord[] {\n if (accepted.length === 0) {\n return [];\n }\n const acceptedKeys = new Set(\n accepted.map((record) => `${record.key}:${record.version}`),\n );\n return documents\n .filter(\n (document) =>\n !document.consented &&\n acceptedKeys.has(`${document.key}:${document.version}`),\n )\n .map(({ key, version }) => ({ key, version }));\n}\n\n/**\n * Whether accepted disclaimers reference a missing catalog category.\n *\n * @param documents - Catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns `true` when the caller accepted docs but the catalog is empty.\n */\nfunction isAcceptedCategoryEmpty(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): boolean {\n return accepted.length > 0 && documents.length === 0;\n}\n\n/**\n * Whether accepted disclaimers are still missing consent after a 409 re-GET:\n * empty catalog or any accepted document still unconsented.\n *\n * @param documents - Latest catalog documents for one consent category.\n * @param accepted - Accepted `{ key, version }` records from the caller.\n * @returns `true` when accepted documents are not fully consented.\n */\nfunction acceptedCategoryStillMissing(\n documents: KycConsentDocument[],\n accepted: KycConsentRecord[],\n): boolean {\n if (accepted.length === 0) {\n return false;\n }\n if (documents.length === 0) {\n return true;\n }\n const acceptedKeys = new Set(\n accepted.map((record) => `${record.key}:${record.version}`),\n );\n const relevant = documents.filter((document) =>\n acceptedKeys.has(`${document.key}:${document.version}`),\n );\n return (\n relevant.length === 0 || relevant.some((document) => !document.consented)\n );\n}\n\n/**\n * Vendors other than MoonPay skip Check/Auth frames and use the empty-shell\n * customer + consents path instead.\n *\n * @param vendor - The identity vendor for the current flow.\n * @returns `true` when the vendor uses the consents session path.\n */\nfunction usesConsentsFlow(vendor: KycVendor): boolean {\n return vendor !== 'moonpay';\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 'initialize',\n 'loadDisclaimers',\n 'fetchSessionDisclaimers',\n 'acceptTermsAndStartSession',\n 'createVendorCustomer',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'getCustomerIdentity',\n 'refreshKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\n 'clearState',\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\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\n/**\n * Published when the user-keyed simplified KYC status changes (Money toast).\n */\nexport type KycControllerStatusChangedEvent = {\n type: `${typeof controllerName}:statusChanged`;\n payload: [\n {\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n },\n ];\n};\n\nexport type KycControllerEvents =\n | KycControllerStateChangeEvent\n | KycControllerStatusChangedEvent;\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 * How often, in milliseconds, to poll the UKYC session status after the\n * SumSub SDK completes. Defaults to\n * {@link DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS}.\n */\n sessionStatusPollIntervalMs?: number;\n /**\n * How often, in milliseconds, to refresh `GET /kyc/status` while the\n * simplified user status is `pending`. Defaults to\n * {@link DEFAULT_USER_STATUS_POLL_INTERVAL_MS}.\n */\n userStatusPollIntervalMs?: number;\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 /** MoonPay-specific frame protocol and non-persisted credentials. */\n readonly #moonPayFrames: MoonPayFrameHandler;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} and\n * {@link clearState} so in-flight async work (e.g. the KYC-required check)\n * can detect that it was superseded and avoid writing stale results onto a\n * reset controller.\n */\n #generation = 0;\n\n /** Interval, in milliseconds, between session-status polls. */\n readonly #sessionStatusPollIntervalMs: number;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #pollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped by {@link #stopPolling} (called on reset, a\n * new sub-flow, and once a terminal status is reached) so an in-flight poll\n * `tick` can detect it was superseded and neither write state nor schedule a\n * follow-up. This closes the gap where clearing the timer alone would still\n * let an already-awaiting request finish and reschedule.\n */\n #pollToken = 0;\n\n /** Interval, in milliseconds, between user-keyed status polls. */\n readonly #userStatusPollIntervalMs: number;\n\n /** Handle for the scheduled next user-status poll, or `null`. */\n #userStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Whether a user-status poll loop is currently active. Tracked separately\n * from {@link #userStatusPollTimer} because a scheduled tick clears the timer\n * handle before awaiting `fetchKycStatus`; relying on the handle alone would\n * let a concurrent {@link refreshKycStatus} start a second loop on the same\n * token during that in-flight window.\n */\n #userStatusPolling = false;\n\n /** Monotonic token for the user-status poll loop (see `#pollToken`). */\n #userStatusPollToken = 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 * @param options.sessionStatusPollIntervalMs - How often to poll the UKYC\n * session status after the SumSub SDK completes.\n * @param options.userStatusPollIntervalMs - How often to refresh the\n * user-keyed KYC status while it is still `pending`.\n */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_STATUS_POLL_INTERVAL_MS,\n userStatusPollIntervalMs = DEFAULT_USER_STATUS_POLL_INTERVAL_MS,\n }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#sessionStatusPollIntervalMs = sessionStatusPollIntervalMs;\n this.#userStatusPollIntervalMs = userStatusPollIntervalMs;\n this.#moonPayFrames = new MoonPayFrameHandler({\n getState: (): KycControllerState => this.state,\n update: (updater): void => this.#applyUpdate(updater),\n fail: (message): void => this.#fail(message),\n onAuthenticated: async (): Promise<void> =>\n this.#continueAfterAuthentication(),\n requireTermsReacceptance: (): void => this.#requireTermsReacceptance(),\n });\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Builds an adapter over `UserStorageController` that the platform-agnostic\n * `getOrCreateLocalUserSecret` helper uses to persist/load the UKYC\n * `local_user_secret`.\n *\n * @returns The Encrypted User Storage adapter.\n */\n #localUserSecretStore(): UkycLocalUserSecretStore {\n return {\n get: async (\n path: string,\n entropySourceId?: string,\n ): Promise<string | null> =>\n this.messenger.call(\n 'UserStorageController:performGetStorage',\n path as `${string}.${string}`,\n entropySourceId,\n ),\n set: async (\n path: string,\n value: string,\n entropySourceId?: string,\n ): Promise<void> =>\n this.messenger.call(\n 'UserStorageController:performSetStorage',\n path as `${string}.${string}`,\n value,\n entropySourceId,\n ),\n };\n }\n\n /**\n * Resolves persisted terms + geolocation, and auto-creates a session when\n * terms are already accepted and an email is available.\n *\n * @param params - Optional parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. When\n * provided, the controller automatically runs the KYC-required check once\n * authentication completes (and chains into document verification when KYC\n * is required). When omitted, the flow stops at `form` and the consumer must\n * call `checkKycRequired` manually.\n * @param params.vendor - Identity vendor for this flow. Non-MoonPay vendors\n * skip Check/Auth frames and use the consents path. Defaults to `moonpay`.\n */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\n vendor?: KycVendor;\n }): Promise<void> {\n // A repeat `initialize` while a session flow is already in progress must\n // not tear it down: creating a new vendor session clears the tokens and\n // forces `phase` back through `session`/`check`, breaking an in-flight\n // Check/Auth frame flow. Leave the active flow untouched and let the\n // consumer drive it (or call `reset` first to start over).\n const vendor = params?.vendor ?? 'moonpay';\n\n if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n if (vendor === 'moonpay') {\n this.#moonPayFrames.ensureKeypair();\n }\n return;\n }\n\n if (vendor === 'moonpay') {\n this.#moonPayFrames.startFlow();\n } else {\n this.#moonPayFrames.clear();\n }\n\n // `initialize` starts a fresh flow, so `activeProduct` is always reset to\n // this call's product (or `null`). Otherwise a prior run's product could\n // linger and cause `#continueAfterAuthentication` to auto-run the check /\n // sub-flow when the caller intended the manual (product-less) flow.\n this.#applyUpdate((state) => {\n if (params?.email) {\n state.email = params.email;\n }\n state.activeVendor = vendor;\n // MoonPay Check/Auth artifacts must not survive a switch to another vendor\n if (vendor !== 'moonpay') {\n clearMoonPaySession(state);\n }\n state.activeProduct = params?.product ?? null;\n });\n\n // Capture the flow generation so a `reset()` landing while the async\n // geolocation / session steps below are in flight cannot write results\n // onto an idle controller.\n const generation = this.#generation;\n\n // Resolve country for display; non-blocking.\n try {\n const country = await this.messenger.call('KycService:getGeoCountry');\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = country;\n });\n } catch {\n // Ignore; disclaimers loading will surface a country error if needed.\n }\n\n // A `reset()` / `clearState()` that landed while the geolocation request\n // was in flight supersedes this flow. Stop here rather than driving the\n // controller on into `terms` (or a new session): the steps below write\n // unconditionally, and `loadDisclaimers` captures the post-reset\n // generation, so its own guard would not catch this.\n if (this.#generation !== generation) {\n return;\n }\n\n if (usesConsentsFlow(vendor) && this.state.email) {\n try {\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor,\n email: this.state.email,\n });\n } catch (error) {\n if (this.#generation !== generation) {\n return;\n }\n this.#fail(`Vendor customer creation failed: ${String(error)}`);\n return;\n }\n }\n\n // Drop another vendor's persisted acceptance only after this flow has\n // committed (customer creation succeeded, or there was none to wait for).\n // Clearing earlier would permanently lose ramps/card terms if Iron\n // customer creation failed or a reset landed while it was in flight.\n if (this.#generation !== generation) {\n return;\n }\n const hasTerms = hasVendorDisclaimerAcceptance(\n this.state.vendorDisclaimersAccepted,\n vendor,\n );\n\n if (hasTerms && this.state.email) {\n if (usesConsentsFlow(vendor)) {\n // Consents-path vendors require T&C2 flags; if they weren't persisted\n // (i.e. null from pre-migration state), require reacceptance.\n const { providerDisclaimersAccepted, idosDisclaimersAccepted } =\n this.state;\n if (\n providerDisclaimersAccepted.sumsub === null ||\n idosDisclaimersAccepted === null\n ) {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n return;\n }\n await this.#startConsentsSession({\n providerDisclaimersAccepted: providerDisclaimersAccepted.sumsub,\n idosDisclaimersAccepted,\n credentialReusabilityConsentGiven:\n this.state.credentialReusabilityConsentGiven ?? false,\n });\n } else {\n // TODO: should this be here? or should it exist at all?\n if (vendor === 'moonpay' && this.state.vendorDisclaimers.length === 0) {\n await this.loadDisclaimers();\n if (this.#generation !== generation) {\n return;\n }\n }\n await this.#createSession();\n }\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n }\n\n /**\n * Creates (or resumes) an empty-shell customer for the given identity\n * vendor. Exposed so a consumer can ensure the customer exists before\n * showing T&C screens independently of {@link initialize}.\n *\n * A call while a session flow is already in progress is a no-op — matching\n * {@link initialize} — so a vendor switch cannot leave Check/Auth frames\n * attached to the wrong vendor. Call {@link reset} first to start over.\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor for the customer.\n * @param params.email - Email for the vendor customer.\n */\n async createVendorCustomer(params: {\n vendor: KycVendor;\n email: string;\n }): Promise<void> {\n if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\n }\n\n this.#applyUpdate((state) => {\n state.email = params.email;\n // MoonPay Check/Auth artifacts must not survive a switch to another\n // vendor — see `initialize`. Terms for another vendor are dropped only\n // after this request succeeds.\n state.activeVendor = params.vendor;\n if (params.vendor !== 'moonpay') {\n this.#moonPayFrames.clear();\n clearMoonPaySession(state);\n }\n });\n const generation = this.#generation;\n try {\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n email: params.email,\n });\n } catch (error) {\n if (this.#generation !== generation) {\n return;\n }\n this.#fail(`Vendor customer creation failed: ${String(error)}`);\n }\n }\n\n /**\n * Loads the disclaimers for the resolved (or provided) country.\n *\n * @param params - Optional parameters.\n * @param params.country - ISO 3166-1 alpha-3 country code override.\n */\n async loadDisclaimers(params?: { country?: string }): Promise<void> {\n // Capture the flow generation so a `reset()` landing while the geo /\n // disclaimers requests are in flight cannot write results onto an idle\n // controller.\n const generation = this.#generation;\n try {\n const country =\n params?.country ??\n this.state.geoCountry ??\n (await this.messenger.call('KycService:getGeoCountry'));\n if (country !== this.state.geoCountry) {\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = country;\n });\n }\n const disclaimers = await this.messenger.call(\n 'KycService:fetchVendorDisclaimers',\n {\n vendor: this.state.activeVendor,\n country,\n },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.vendorDisclaimers = disclaimers;\n state.vendorError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.vendorError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\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 const generation = this.#generation;\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 this.#updateIfCurrent(generation, (state) => {\n state.sessionDisclaimers = catalog;\n });\n return catalog;\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\n *\n * @param params - The parameters.\n * @param params.email - The account email to associate with the session.\n * @param params.product - The consuming feature the flow runs for. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n * @param params.providerDisclaimersAccepted - Sumsub disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.idosDisclaimersAccepted - idOS disclaimer documents the\n * customer accepted (`{ key, version }` records). Required for every vendor\n * so callers explicitly declare acceptance.\n * @param params.credentialReusabilityConsentGiven - Whether the customer\n * consented to reuse existing idOS credentials. Used when recording\n * session-scoped disclaimers on the consents path. Defaults to `false`.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven?: boolean;\n }): Promise<void> {\n const providerDisclaimersAccepted = params?.providerDisclaimersAccepted;\n const idosDisclaimersAccepted = params?.idosDisclaimersAccepted;\n if (\n !isValidConsentRecordList(providerDisclaimersAccepted) ||\n !isValidConsentRecordList(idosDisclaimersAccepted)\n ) {\n this.#fail('Missing T&C2 acceptance flags.');\n return;\n }\n const credentialReusabilityConsentGiven =\n params?.credentialReusabilityConsentGiven ?? false;\n\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.vendorDisclaimers.map(\n (disclaimer) => disclaimer.id,\n );\n this.#applyUpdate((state) => {\n if (params?.email) {\n state.email = params.email;\n }\n if (params?.product) {\n state.activeProduct = params.product;\n }\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n state.activeVendor,\n { termsAcceptedAt, disclaimerIds },\n );\n state.providerDisclaimersAccepted = {\n ...state.providerDisclaimersAccepted,\n sumsub: providerDisclaimersAccepted,\n };\n state.idosDisclaimersAccepted = idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n credentialReusabilityConsentGiven;\n });\n if (usesConsentsFlow(this.state.activeVendor)) {\n await this.#startConsentsSession({\n providerDisclaimersAccepted,\n idosDisclaimersAccepted,\n credentialReusabilityConsentGiven,\n });\n return;\n }\n await this.#createSession();\n }\n\n /**\n * Consents-path vendors: record vendor T&Cs, create a UKYC session,\n * record session-scoped idOS / KYC-provider disclaimers, then launch\n * SumSub — skipping MoonPay Check/Auth frames.\n *\n * @param consents - T&C2 flags mapped onto the session disclaimer catalog.\n * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param consents.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\n async #startConsentsSession(consents: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n const { email } = this.state;\n const acceptedDisclaimerIds = ironDisclaimerIds(\n this.state.vendorDisclaimersAccepted,\n );\n if (!email) {\n this.#fail('Missing email for consents session.');\n return;\n }\n if (acceptedDisclaimerIds.length === 0) {\n this.#fail('Missing disclaimer acceptance.');\n return;\n }\n\n const generation = this.#generation;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Submitting consents...';\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n // Consents-path vendors have no MoonPay session/access tokens.\n clearMoonPaySession(state);\n });\n\n try {\n await this.messenger.call('KycService:submitVendorDisclaimers', {\n vendor: this.state.activeVendor,\n disclaimerIds: acceptedDisclaimerIds,\n });\n if (this.#generation !== generation) {\n return;\n }\n\n this.#updateIfCurrent(generation, (state) => {\n state.statusMessage = 'Creating session...';\n });\n\n const created = await this.#createUkycSession(generation);\n if (!created) {\n return;\n }\n\n await this.#recordSessionDisclaimers(\n created.sessionId,\n consents,\n generation,\n );\n if (this.#generation !== generation) {\n return;\n }\n\n if (created.vendorProcessing) {\n try {\n await this.refreshKycStatus();\n } catch (statusError) {\n controllerLog('KYC status refresh failed:', statusError);\n }\n this.#updateIfCurrent(generation, (state) => {\n state.phase = 'done';\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return;\n }\n this.#applyUpdate((state) => {\n state.phase = 'submit';\n state.statusMessage = 'Starting document verification...';\n });\n const sumsubResult = await this.startSumSub();\n if (this.#generation !== generation) {\n return;\n }\n // The applicant closed the SDK without submitting. Nothing failed, so\n // rewind with `error` unset and let consumers offer a retry.\n if (this.state.sumsub.status === 'abandoned') {\n await this.#rewindConsentsFlow({\n error: null,\n statusMessage: SUMSUB_ABANDONED_MESSAGE,\n keepSumSubStatus: 'abandoned',\n });\n return;\n }\n // `startSumSub` records `failed` for thrown steps, an SDK that could not\n // run, *and* a terminal UKYC rejection after a submission. Only the first\n // two rewind. A rejection writes `sessionStatus` and is a finished flow:\n // refresh user status and land on `done`.\n if (\n this.state.sumsub.status === 'failed' &&\n this.state.sumsub.sessionStatus === null\n ) {\n const sumsubError = sumsubResult?.error;\n throw new Error(\n typeof sumsubError === 'string'\n ? sumsubError\n : 'SumSub verification could not run.',\n );\n }\n // After SumSub, refresh user-keyed status for the Money toast and start\n // polling while still pending. Soft-fail: toast refresh must not rewind\n // the consent / SumSub outcome.\n try {\n await this.refreshKycStatus();\n } catch (statusError) {\n controllerLog('KYC status refresh failed:', statusError);\n }\n this.#updateIfCurrent(generation, (state) => {\n if (state.phase !== 'error' && state.phase !== 'done') {\n state.phase = 'done';\n state.statusMessage = 'KYC submitted.';\n }\n });\n } catch (error) {\n if (isSessionAlreadyCompletedError(error)) {\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUserStatus({\n status: 'completed',\n sumsubSessionId: null,\n errorCode: null,\n });\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n state.sumsub.result = { alreadyCompleted: true };\n state.statusMessage = 'KYC already completed.';\n state.phase = 'done';\n state.error = null;\n });\n return;\n }\n controllerLog('Consents session failed:', error);\n if (this.#generation !== generation) {\n return;\n }\n await this.#rewindConsentsFlow({\n error: `Consents session failed: ${String(error)}`,\n statusMessage:\n 'Consent / verification failed — accept the terms to try again.',\n });\n }\n }\n\n /**\n * Returns the consents path to the terms phase after a SumSub sub-flow that\n * produced no verification decision, and reloads the disclaimers the next\n * attempt has to re-accept.\n *\n * @param options - Rewind options.\n * @param options.error - Message for `error`, or `null` when the rewind is a\n * normal outcome rather than a failure.\n * @param options.statusMessage - Message for `statusMessage`.\n * @param options.keepSumSubStatus - Sub-flow status to survive the rewind,\n * for an outcome consumers still need once the call resolves. Defaults to the\n * reset `idle`.\n */\n async #rewindConsentsFlow({\n error,\n statusMessage,\n keepSumSubStatus,\n }: {\n error: string | null;\n statusMessage: string;\n keepSumSubStatus?: KycSumSubStatus;\n }): Promise<void> {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.activeProduct = null;\n state.sessionDisclaimers = null;\n // Session create ran before recording disclaimers. Drop the leftover\n // UKYC session so a later `startSumSub` cannot skip consent recording.\n state.sumsub = { ...getDefaultKycControllerState().sumsub };\n if (keepSumSubStatus) {\n state.sumsub.status = keepSumSubStatus;\n }\n state.error = error;\n state.statusMessage = statusMessage;\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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 sessionId - The UKYC session id.\n * @param consents - T&C2 flags mapped onto catalog documents.\n * @param consents.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param consents.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param consents.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n * @param generation - Flow generation captured by the caller.\n */\n async #recordSessionDisclaimers(\n sessionId: string,\n consents: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n },\n generation: number,\n ): Promise<void> {\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUpdate((state) => {\n state.sessionDisclaimers = catalog;\n state.statusMessage = 'Submitting consents...';\n });\n\n if (\n isAcceptedCategoryEmpty(catalog.idOS, consents.idosDisclaimersAccepted) ||\n isAcceptedCategoryEmpty(\n catalog.kycProvider,\n consents.providerDisclaimersAccepted,\n )\n ) {\n throw new Error(\n 'Session disclaimer catalog is missing documents for an accepted category.',\n );\n }\n\n const idOS = consentRecordsFromAcceptedList(\n catalog.idOS,\n consents.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n catalog.kycProvider,\n consents.providerDisclaimersAccepted,\n );\n const reuseUnchanged =\n catalog.credentialReusabilityConsentGiven ===\n consents.credentialReusabilityConsentGiven;\n if (idOS.length === 0 && kycProvider.length === 0 && reuseUnchanged) {\n return;\n }\n\n try {\n const recorded = await this.messenger.call(\n 'KycService:submitSessionDisclaimers',\n {\n sessionId,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n consents.credentialReusabilityConsentGiven,\n },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.sessionDisclaimers = recorded;\n });\n } catch (error) {\n if (!isConsentConflictError(error)) {\n throw error;\n }\n // 409 means some document version was already recorded. Re-fetch and\n // continue only when every document the user accepted is now consented;\n // otherwise fail closed so a version bump cannot skip new docs.\n const latest = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n if (this.#generation !== generation) {\n return;\n }\n this.#applyUpdate((state) => {\n state.sessionDisclaimers = latest;\n });\n // TODO: Should we really be doing client side validation of these?\n const stillMissingIdos = acceptedCategoryStillMissing(\n latest.idOS,\n consents.idosDisclaimersAccepted,\n );\n const stillMissingProvider = acceptedCategoryStillMissing(\n latest.kycProvider,\n consents.providerDisclaimersAccepted,\n );\n const stillMissingReuse =\n consents.credentialReusabilityConsentGiven &&\n !latest.credentialReusabilityConsentGiven;\n if (stillMissingIdos || stillMissingProvider || stillMissingReuse) {\n throw error;\n }\n }\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email } = this.state;\n const termsAcceptedAt =\n this.state.vendorDisclaimersAccepted.moonpay?.termsAcceptedAt;\n const acceptedDisclaimerIds = this.state.vendorDisclaimers.map(\n (disclaimer) => disclaimer.id,\n );\n if (!email) {\n this.#fail('Missing email for session creation.');\n return;\n }\n if (!termsAcceptedAt || acceptedDisclaimerIds.length === 0) {\n this.#fail('Missing terms acceptance for session creation.');\n return;\n }\n\n // A new session invalidates any authentication carried over from a prior\n // session. Clear the stale session token, access token, and auth-frame\n // client token so `buildCheckFrameUrl` cannot return a URL bound to an old\n // (or, on failure, invalid) session token, `buildAuthFrameUrl` cannot\n // return a URL tied to an old client token, and `checkKycRequired` cannot\n // run with an access token from an earlier authentication. The Check/Auth\n // frames re-populate these for the new session. Because `moonpaySessionToken` is\n // cleared here and only re-set on success, a failed creation leaves it\n // `null` rather than resurrecting the previous session.\n // Capture the flow generation so a `reset()` landing while the create\n // request is in flight cannot resurrect a session (success) or overwrite\n // the now-idle controller (failure). The synchronous update below runs\n // before any `await`, so it needs no guard.\n const generation = this.#generation;\n this.#moonPayFrames.clearAuthentication();\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.moonpaySessionToken = null;\n state.moonpayAccessToken = null;\n });\n\n try {\n const { sessionToken } = await this.messenger.call(\n 'KycService:createSession',\n { email, termsAcceptedAt, disclaimerIds: acceptedDisclaimerIds },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.moonpaySessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n controllerLog('Session creation failed:', error);\n // A reset() superseded this flow while the request was in flight; leave\n // the idle controller alone rather than forcing it back to `terms`.\n if (this.#generation !== generation) {\n return;\n }\n // Invalidate the stored acceptance so the customer can retry. Also clear\n // `activeProduct` so a later `acceptTermsAndStartSession` that omits a\n // product cannot auto-run the KYC check / SumSub chain for this failed\n // flow's product — matching how `initialize` starts from a clean product.\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.activeProduct = null;\n state.error = `Session creation failed: ${String(error)}`;\n state.statusMessage =\n 'Session creation failed — accept the terms to try again.';\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\n }\n }\n\n /**\n * Clears the persisted terms acceptance.\n */\n clearSavedTerms(): void {\n this.#applyUpdate((state) => {\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Clears the stored terms acceptance on the given draft state. Shared by the\n * paths that must invalidate acceptance — explicit clear, vendor terms\n * update, and session-creation failure — so they stay in sync. This is a\n * targeted invalidation and, unlike {@link reset}, deliberately leaves the\n * rest of the flow (geolocation, disclaimers, phase) untouched.\n *\n * @param state - The state to mutate.\n * @param vendor - Vendor whose acceptance to clear. Defaults to\n * `state.activeVendor`.\n */\n #clearAcceptedTerms(state: KycControllerState, vendor?: KycVendor): void {\n const targetVendor = vendor ?? state.activeVendor;\n state.vendorDisclaimersAccepted = clearVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n targetVendor,\n );\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n }\n\n /**\n * Handles a message posted by a Check/Auth frame and advances the flow.\n *\n * The transport-agnostic caller (WebView on mobile, iframe on web) forwards\n * the raw message and injects the returned `reply` back into the frame.\n *\n * @param params - The parameters.\n * @param params.message - The raw message posted by the frame.\n * @returns An object whose optional `reply` should be posted back.\n */\n async handleFrameMessage(params: {\n message: unknown;\n }): Promise<{ reply?: unknown }> {\n return await this.#moonPayFrames.handleMessage(params.message);\n }\n\n /**\n * Continues the flow once authentication has completed (phase `form`).\n *\n * When the flow is scoped to a product (see {@link initialize}), the\n * KYC-required check runs automatically, and — when KYC is required — the\n * document-verification sub-flow is launched. When no product is set, this is\n * a no-op and the flow stays at `form` for the consumer to drive manually.\n *\n * Errors are already recorded on state by `checkKycRequired` (`error`\n * phase) and `startSumSub` (`sumsub.status = 'failed'`); this method swallows\n * them so it can be awaited safely from the frame-message handler.\n */\n async #continueAfterAuthentication(): Promise<void> {\n const product = this.state.activeProduct;\n if (!product) {\n return;\n }\n\n // Re-entry protection lives at the frame boundary: `handleFrameMessage`\n // only honors a Check/Auth `complete` while `phase` matches and\n // `activeVendor` is MoonPay, and both outcome handlers move `phase` to\n // `form` before awaiting this method. A duplicate, late, or cross-vendor\n // `complete` therefore lands after the phase moved on (or on the wrong\n // vendor) and is dropped before it can start a second continuation. Any\n // writes here are additionally guarded by `#generation` (see\n // `checkKycRequired` / `startSumSub`) so a `reset()` mid-continuation\n // cannot corrupt state.\n const kycRequired = await this.checkKycRequired({ product });\n if (!kycRequired) {\n return;\n }\n\n try {\n await this.startSumSub();\n } catch {\n // `startSumSub` already records `sumsub.status = 'failed'`; swallow the\n // rethrown error (e.g. SDK unavailable) so the awaited continuation\n // resolves cleanly rather than surfacing as an unhandled rejection.\n }\n }\n\n /**\n * Invalidates stored terms and returns to the terms phase.\n */\n #requireTermsReacceptance(): void {\n this.#applyUpdate((state) => {\n this.#clearAcceptedTerms(state);\n state.phase = 'terms';\n state.statusMessage =\n 'The vendor updated its Terms of Use — please re-accept.';\n });\n }\n\n /**\n * Builds the Check-frame URL, or `null` when no session exists yet.\n *\n * @returns The Check-frame URL or `null`.\n */\n buildCheckFrameUrl(): string | null {\n return this.#moonPayFrames.buildCheckFrameUrl();\n }\n\n /**\n * Builds the Auth-frame URL, or `null` when no client token is available.\n *\n * @returns The Auth-frame URL or `null`.\n */\n buildAuthFrameUrl(): string | null {\n return this.#moonPayFrames.buildAuthFrameUrl();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n return this.#moonPayFrames.buildResetFrameUrl();\n }\n\n /**\n * Checks whether KYC is required for a product and caches the result.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @param params.country - Optional alpha-3 country override.\n * @returns Whether KYC is required.\n */\n async checkKycRequired(params: {\n product: KycProduct;\n country?: string;\n }): Promise<boolean> {\n const { moonpayAccessToken } = this.state;\n if (!moonpayAccessToken) {\n this.#fail(\n 'Missing moonpayAccessToken — repeat the authentication step.',\n );\n return false;\n }\n const country = params.country ?? this.state.geoCountry;\n if (!country) {\n this.#fail('Missing country for KYC-required check.');\n return false;\n }\n\n // Capture the flow generation so we can detect a `reset()` that happens\n // while the HTTP call is in flight and avoid writing stale results.\n const generation = this.#generation;\n\n this.#applyUpdate((state) => {\n state.phase = 'submit';\n state.statusMessage = 'Checking KYC status...';\n });\n\n try {\n const { kycRequired } = await this.messenger.call(\n 'KycService:checkKycRequired',\n {\n accessToken: moonpayAccessToken,\n country,\n capabilities: [{ product: params.product }],\n },\n );\n // The flow was reset while the check was in flight; discard the result\n // rather than resurrecting a done/cached state on an idle controller.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.kycRequiredByProduct[params.product] = kycRequired;\n state.lastCheckedAt = new Date().toISOString();\n state.phase = 'done';\n state.statusMessage = 'KYC check complete.';\n });\n if (!applied) {\n return false;\n }\n return kycRequired;\n } catch (error) {\n if (this.#generation !== generation) {\n return false;\n }\n this.#fail(`KYC check failed: ${String(error)}`);\n return false;\n }\n }\n\n /**\n * Reads the cached \"is KYC required\" result for a product.\n *\n * @param params - The parameters.\n * @param params.product - The consuming feature.\n * @returns The cached value, or `undefined` if not yet checked.\n */\n getKycStatus(params: { product: KycProduct }): boolean | undefined {\n return this.state.kycRequiredByProduct[params.product];\n }\n\n /**\n * Returns the vendor-scoped identity for the currently authenticated\n * customer, or `null` when the flow has not yet captured a vendor customer\n * id (before authentication or after {@link reset}), or when a MoonPay id\n * is present under a different `activeVendor`.\n *\n * Exposed so consumers (e.g. ramps autoramp creation) can attach the vendor\n * customer id to downstream calls without reading the full KYC state, which\n * also holds session/access tokens. The id is session-scoped and never\n * persisted.\n *\n * @returns The current {@link KycCustomerIdentity}, or `null`.\n */\n getCustomerIdentity(): KycCustomerIdentity | null {\n const { moonpayCustomerId, activeVendor } = this.state;\n // `moonpayCustomerId` is issued only by MoonPay Check/Auth frames. Never\n // pair it with another vendor, even if a switch left the fields out of\n // sync, so consumers cannot attach a MoonPay id to an Iron (or other)\n // downstream call.\n if (!moonpayCustomerId || activeVendor !== 'moonpay') {\n return null;\n }\n return { vendor: 'moonpay', id: moonpayCustomerId };\n }\n\n /**\n * Builds the vendor-specific fields spread into a\n * `KycService:createUkycSession` call, derived from the active vendor and the\n * currently captured auth state.\n *\n * MoonPay sessions must carry the access token and customer id in\n * `vendorMetadata`; other vendors carry no vendor metadata.\n *\n * @returns The vendor-specific subset of the `createUkycSession` params.\n */\n #buildUkycSessionVendorFields(): Pick<\n CreateUkycSessionParams,\n 'vendor' | 'vendorMetadata'\n > {\n if (this.state.activeVendor === 'moonpay') {\n return {\n vendor: 'moonpay',\n vendorMetadata: {\n moonPayAccessToken: this.state.moonpayAccessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n };\n }\n\n return { vendor: this.state.activeVendor };\n }\n\n /**\n * Creates 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 `sumsub.sessionId`. Returns `null`\n * when a `reset()` superseded the flow.\n *\n * @param generation - Flow generation captured by the caller.\n * @returns The created session, or `null` if superseded.\n */\n async #createUkycSession(generation: number): Promise<{\n sessionId: string;\n kycStatus?: string;\n finalStatus?: string;\n vendorProcessing: boolean;\n } | null> {\n const jwtToken = MOCK_JWT_TOKEN;\n\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 residenceCountry =\n this.state.geoCountry ??\n (await this.messenger.call('KycService:getGeoCountry'));\n if (this.#generation !== generation) {\n return null;\n }\n if (residenceCountry !== this.state.geoCountry) {\n this.#updateIfCurrent(generation, (state) => {\n state.geoCountry = residenceCountry;\n });\n }\n\n const {\n sessionId,\n encryptionDataKey,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n jwtToken,\n sessionClientPublicKey,\n residenceCountry,\n ...this.#buildUkycSessionVendorFields(),\n });\n if (this.#generation !== generation) {\n return null;\n }\n\n // Verify each schema's jwtChain against the matching issuer JWKS, then\n // confirm 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` by the\n // idOS relay.\n const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] =\n await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n this.#assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n this.#assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n\n // Derive the data_encryption_key from the local_user_secret, mint a\n // read-only capability token, and wrap both for the session server. Only\n // the wrapped (encrypted) material ever leaves the device.\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 // Only the client holds the signing key derived from `local_user_secret`,\n // so only the client can mint the token; scoping it to `read` means it\n // authorizes later storage reads without granting write or delete access.\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 if (this.#generation !== generation) {\n return null;\n }\n\n const { kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n const vendorProcessing =\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending;\n\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.sessionId = sessionId;\n if (vendorProcessing) {\n state.sumsub.status = 'vendorProcessing';\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n }\n });\n if (!stillCurrent) {\n return null;\n }\n return { sessionId, kycStatus, finalStatus, vendorProcessing };\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\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 SDK result.\n */\n async startSumSub(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<Record<string, unknown>> {\n // A new sub-flow supersedes any polling still running from a prior run.\n this.#stopPolling();\n // Paused for the whole sub-flow: a tick landing while the SDK is on screen\n // publishes `statusChanged`, pulling consumers (and their signing prompts)\n // in front of a flow the applicant has not finished. Resumed in `finally`\n // so abandonment, SDK failure, and callers that do not run\n // `refreshKycStatus` (MoonPay post-auth) still restore the loop.\n this.#stopUserStatusPolling();\n\n // Capture the flow generation so each async step can detect a `reset()`\n // that lands mid-flight and avoid writing stale sub-flow state (or, worse,\n // presenting the SDK) on a controller that is now idle.\n const generation = this.#generation;\n\n try {\n if (!this.#sumsubLauncher.isAvailable()) {\n const error = 'SumSub SDK is not available in this runtime.';\n this.#applyUpdate((state) => {\n state.sumsub.status = 'failed';\n state.sumsub.result = { error };\n });\n throw new Error(error);\n }\n\n try {\n if (!this.state.sumsub.sessionId) {\n this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const created = await this.#createUkycSession(generation);\n if (!created) {\n return {};\n }\n\n // A user who already finished the journey can return to a session the\n // relay has already approved (`kycStatus`) while the vendor is still\n // finalizing its own decision (`finalStatus`). There is nothing left to\n // verify, so stop here and surface a message rather than launching the\n // SDK again.\n if (created.vendorProcessing) {\n return {\n kycStatus: created.kycStatus,\n finalStatus: created.finalStatus,\n };\n }\n }\n\n // Empty string is a valid \"no id to poll\" session id used by tests and\n // must not be coalesced away as missing.\n // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing\n const sessionId = this.state.sumsub.sessionId || '';\n\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'fetchingToken';\n state.sumsub.sessionId = sessionId;\n });\n\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n\n // A reset() may have landed while the session/token was being prepared.\n // Gate the `launching` write and the decision to open the SDK behind a\n // single generation check: `#updateIfCurrent` only writes when still\n // current and reports whether it did. Since there is no `await` between\n // this check and `launch` below, a successful result guarantees the SDK\n // is never presented on a flow that a concurrent reset() returned to idle.\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'launching';\n state.sumsub.applicantAccessToken = applicantAccessToken;\n });\n if (!stillCurrent) {\n return {};\n }\n\n // Track whether the SDK ever reported a successful completion. A resolved\n // `launch` alone does not imply success — the applicant may have\n // abandoned the flow or the SDK may have reported a non-success outcome.\n let reachedCompletion = false;\n\n const result = await this.#sumsubLauncher.launch({\n applicantAccessToken,\n onTokenExpiration: async () => {\n // A reset() may have superseded this flow while the SDK stayed open.\n // Refuse to refresh against the now-stale UKYC session rather than\n // silently keeping an orphaned SDK alive.\n if (this.#generation !== generation) {\n throw new Error(\n 'KYC flow was reset; SumSub session is no longer active.',\n );\n }\n const refreshed = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return refreshed.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = isSumSubFlowCompleted(next)\n ? 'complete'\n : 'inProgress';\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\n // A resolved `launch` alone is not the final outcome: only a submission\n // is worth polling for a decision. Without one, the SDK status is the\n // only way to tell a failure from an applicant who closed the SDK early\n // — the UKYC session leaves its initial state as soon as the journey is\n // created, so it cannot stand in for \"the applicant finished\".\n let settledStatus: KycSumSubStatus = 'abandoned';\n if (reachedCompletion) {\n settledStatus = 'polling';\n } else if (isSumSubLaunchFailure(result)) {\n settledStatus = 'failed';\n }\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = settledStatus;\n state.sumsub.result = result as Json;\n });\n\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result. Poll the session status\n // until it reaches a terminal decision. Guard on `applied` so a `reset()`\n // that landed during `launch` cannot start polling on an idle flow.\n if (applied && reachedCompletion) {\n if (sessionId) {\n await this.#startSessionStatusPolling(sessionId);\n } else {\n // No session id to poll against; fall back to treating the SDK\n // completion as the final outcome.\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n });\n }\n }\n return result;\n } catch (error) {\n // Applicant already finished KYC — treat as completed for Money toast.\n if (isSessionAlreadyCompletedError(error)) {\n // A reset() may have landed while `launch` was in flight; forcing\n // `completed` (and publishing `statusChanged`) on an idle controller\n // would resurrect a flow the consumer already tore down.\n if (this.#generation !== generation) {\n return { alreadyCompleted: true };\n }\n this.#applyUserStatus({\n status: 'completed',\n sumsubSessionId: null,\n errorCode: null,\n });\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'complete';\n state.sumsub.result = { alreadyCompleted: true };\n state.statusMessage = 'KYC already completed.';\n state.phase = 'done';\n state.error = null;\n });\n return { alreadyCompleted: true };\n }\n const result = { error: String(error) };\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'failed';\n state.sumsub.result = result;\n });\n return result;\n }\n } finally {\n if (this.#generation === generation) {\n try {\n await this.refreshKycStatus();\n } catch (error) {\n controllerLog('KYC status refresh failed:', error);\n }\n }\n }\n }\n\n /**\n * Refreshes the user-keyed simplified KYC status from `GET /kyc/status`,\n * stores it on state, publishes {@link KycControllerStatusChangedEvent}, and\n * schedules short-interval polling while the status is `pending`.\n *\n * Skipped when `userStatus` is already `completed`: a follow-up\n * `GET /kyc/status` can still read a stale `pending` (for example after\n * `session_not_in_valid_state`) and must not undo that decision.\n *\n * @returns The latest status payload.\n */\n async refreshKycStatus(): Promise<{\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }> {\n if (this.state.userStatus === 'completed') {\n return {\n status: 'completed',\n sumsubSessionId: this.state.userStatusSumsubSessionId,\n errorCode: this.state.userStatusErrorCode,\n };\n }\n\n const generation = this.#generation;\n const payload = await this.#fetchAndApplyUserStatus();\n // A `reset()` landing while the request was in flight already stopped\n // polling and left the flow idle, and the payload above is the pre-reset\n // cached status. Starting a loop from it would poll — and publish\n // `statusChanged` — on a torn-down flow.\n if (this.#generation !== generation) {\n return payload;\n }\n if (payload.status === 'pending') {\n this.#ensureUserStatusPolling();\n } else {\n this.#stopUserStatusPolling();\n }\n return payload;\n }\n\n /**\n * Fetches `GET /kyc/status` and applies it to state without managing the\n * poll loop (used by both {@link refreshKycStatus} and the poll tick).\n *\n * @returns The latest status payload.\n */\n async #fetchAndApplyUserStatus(): Promise<{\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }> {\n const generation = this.#generation;\n const response = await this.messenger.call('KycService:fetchKycStatus');\n if (this.#generation !== generation) {\n return {\n status: this.state.userStatus ?? 'not-started',\n sumsubSessionId: this.state.userStatusSumsubSessionId,\n errorCode: this.state.userStatusErrorCode,\n };\n }\n const payload = {\n status: response.status,\n sumsubSessionId: response.sumsubSessionId ?? null,\n errorCode: response.errorCode ?? null,\n };\n this.#applyUserStatus(payload);\n return payload;\n }\n\n /**\n * Writes user-keyed status onto state and publishes `statusChanged` when the\n * value actually changes.\n *\n * @param payload - The status payload to apply.\n * @param payload.status - User-keyed KYC status from `GET /kyc/status`.\n * @param payload.sumsubSessionId - Optional SumSub session id from status.\n * @param payload.errorCode - Optional error code from status.\n */\n #applyUserStatus(payload: {\n status: KycUserStatus;\n sumsubSessionId: string | null;\n errorCode: string | null;\n }): void {\n const previous = this.state.userStatus;\n this.#applyUpdate((state) => {\n state.userStatus = payload.status;\n state.userStatusSumsubSessionId = payload.sumsubSessionId;\n state.userStatusErrorCode = payload.errorCode;\n });\n if (previous !== payload.status) {\n this.messenger.publish(`${controllerName}:statusChanged`, payload);\n }\n }\n\n /**\n * Starts the user-status poll loop when not already running and status is\n * still `pending`.\n */\n #ensureUserStatusPolling(): void {\n if (this.#userStatusPolling) {\n return;\n }\n this.#userStatusPolling = true;\n const token = this.#userStatusPollToken;\n const tick = async (): Promise<void> => {\n try {\n const payload = await this.#fetchAndApplyUserStatus();\n // Race with `reset()` / `#stopUserStatusPolling` while the request was\n // in flight — do not reschedule onto an idle controller.\n /* istanbul ignore next */\n if (this.#userStatusPollToken !== token) {\n return;\n }\n if (payload.status !== 'pending') {\n this.#stopUserStatusPolling();\n return;\n }\n } catch {\n // Keep polling on transient errors, unless the loop was superseded.\n /* istanbul ignore next */\n if (this.#userStatusPollToken !== token) {\n return;\n }\n }\n this.#userStatusPollTimer = setTimeout(() => {\n this.#userStatusPollTimer = null;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#userStatusPollIntervalMs);\n // Allow the process to exit while a pending-status poll is scheduled.\n // React Native / browser timers are numbers with no `unref`, hence the\n // optional call.\n this.#userStatusPollTimer.unref?.();\n };\n this.#userStatusPollTimer = setTimeout(() => {\n this.#userStatusPollTimer = null;\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#userStatusPollIntervalMs);\n this.#userStatusPollTimer.unref?.();\n }\n\n /**\n * Stops the user-keyed status poll loop.\n */\n #stopUserStatusPolling(): void {\n this.#userStatusPollToken += 1;\n this.#userStatusPolling = false;\n if (this.#userStatusPollTimer !== null) {\n clearTimeout(this.#userStatusPollTimer);\n this.#userStatusPollTimer = null;\n }\n }\n\n /**\n * Fetches the current UKYC session status for the active sub-flow and records\n * it on state. Useful for a one-off refresh outside the automatic polling\n * loop that {@link startSumSub} runs.\n *\n * @returns The fetched session status.\n * @throws If there is no active SumSub session to query.\n */\n async getSessionStatus(): Promise<KycSessionStatus> {\n const { sessionId } = this.state.sumsub;\n if (!sessionId) {\n throw new Error('Cannot fetch session status: no active SumSub session.');\n }\n\n // Capture the flow generation so a `reset()` landing while the request is\n // in flight cannot write the result onto an idle controller.\n const generation = this.#generation;\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n /**\n * Begins polling the UKYC session status until a terminal decision is\n * reached. The first poll runs immediately (and is awaited by\n * {@link startSumSub}); subsequent polls are scheduled every\n * `#sessionStatusPollIntervalMs`.\n *\n * @param sessionId - The UKYC session id to poll.\n * @returns A promise that resolves once the first poll settles.\n */\n async #startSessionStatusPolling(sessionId: string): Promise<void> {\n // Supersede any prior loop and claim a fresh token for this one. Because\n // `#stopPolling` bumps the token, any in-flight poll from a previous loop\n // sees a mismatch and neither writes state nor reschedules.\n this.#stopPolling();\n const token = this.#pollToken;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n this.#pollTimer = setTimeout(() => {\n this.#pollTimer = null;\n // `tick` swallows its own errors (see `#pollSessionStatusOnce`) and\n // therefore never rejects, so this fire-and-forget scheduled poll\n // cannot surface as an unhandled rejection.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, this.#sessionStatusPollIntervalMs);\n };\n\n await tick();\n }\n\n /**\n * Performs a single session-status poll: fetches the status, records it, and\n * resolves the sub-flow when the status is terminal.\n *\n * Transient errors are swallowed so the loop keeps polling; the last good\n * `sessionStatus` is deliberately preserved rather than being overwritten\n * with the error.\n *\n * @param sessionId - The UKYC session id to poll.\n * @param token - The polling token captured when the loop started.\n * @returns `true` when the loop should stop (terminal status or superseded\n * by a reset / new sub-flow), `false` when it should keep polling.\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 // Superseded while the request was in flight — drop the result.\n if (this.#pollToken !== token) {\n return true;\n }\n const isTerminal = TERMINAL_SESSION_STATUSES.has(\n sessionStatus.finalStatus,\n );\n this.#applyUpdate((state) => {\n state.sumsub.sessionStatus = sessionStatus;\n if (isTerminal) {\n state.sumsub.status = SUCCESSFUL_SESSION_STATUSES.has(\n sessionStatus.finalStatus,\n )\n ? 'complete'\n : 'failed';\n }\n });\n if (isTerminal) {\n this.#stopPolling();\n }\n return isTerminal;\n } catch {\n // Keep polling on transient errors, preserving the last good status.\n // Stop only when a reset / new sub-flow superseded this loop.\n return this.#pollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop: bumps the polling token (so any\n * in-flight `tick` bows out) and clears any scheduled poll.\n */\n #stopPolling(): void {\n this.#pollToken += 1;\n if (this.#pollTimer !== null) {\n clearTimeout(this.#pollTimer);\n this.#pollTimer = null;\n }\n }\n\n /**\n * Resets the flow to idle, clearing session tokens and sub-flow state while\n * preserving persisted terms acceptance and the per-product cache.\n */\n reset(): void {\n this.#cancelPendingSession();\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.vendorDisclaimers = [];\n state.vendorError = null;\n state.sessionDisclaimers = null;\n state.credentialReusabilityConsentGiven = null;\n clearMoonPaySession(state);\n state.activeVendor = 'moonpay';\n state.activeProduct = null;\n state.sumsub = {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n };\n });\n }\n\n /**\n * Restores the controller to its default state, discarding everything\n * {@link reset} deliberately keeps: the session email, the persisted terms\n * acceptance, the per-product KYC-required cache and the user-keyed status.\n *\n * Intended for a full wallet reset, where no trace of the previous\n * customer may survive into the next wallet.\n */\n clearState(): void {\n this.#cancelPendingSession();\n this.#applyUpdate((state) => {\n Object.assign(state, getDefaultKycControllerState());\n });\n }\n\n /**\n * Tears down everything that lives outside state: drops the MoonPay frame\n * keypair and auth client token, stops both polling loops, and bumps the flow\n * generation so async steps started earlier discard their results instead\n * of writing them onto the controller. Shared by {@link reset} and\n * {@link clearState}.\n */\n #cancelPendingSession(): void {\n this.#moonPayFrames.clear();\n this.#stopPolling();\n this.#stopUserStatusPolling();\n this.#generation += 1;\n }\n\n /**\n * Applies a state update only when the flow has not been reset since\n * `generation` was captured. Prevents an in-flight async step from writing\n * stale results onto a controller that a concurrent {@link reset} has\n * returned to idle.\n *\n * @param generation - The flow generation captured before the async work.\n * @param updater - The state mutation to apply when still current.\n * @returns `true` if the update was applied, `false` if it was superseded.\n */\n #updateIfCurrent(\n generation: number,\n updater: (state: KycControllerState) => void,\n ): boolean {\n if (this.#generation !== generation) {\n return false;\n }\n this.#applyUpdate(updater);\n return true;\n }\n\n /**\n * The single state-update path for this controller. All mutations go through\n * here (rather than calling `this.update` directly) so the mechanism stays\n * consistent and one subtlety is handled in a single place:\n *\n * `sumsub.result` is typed as the recursive `Json`, and expanding\n * `Draft<Json>` (which happens whenever an updater touches `sumsub.result`)\n * can trip TypeScript's \"type instantiation is excessively deep\" guard. By\n * typing the callback parameter as the plain {@link KycControllerState}\n * instead of Immer's `Draft`, we avoid expanding the draft type while keeping\n * the same mutate-in-place semantics (the underlying value is still the Immer\n * draft at runtime).\n *\n * @param updater - The state mutation to apply.\n */\n #applyUpdate(updater: (state: KycControllerState) => void): void {\n this.update((state) => {\n // @ts-expect-error Avoid \"type instantiation is excessively deep\".\n updater(state);\n });\n }\n\n /**\n * Confirms that an encryption schema's `serverPublicKey.x` matches the\n * `sessionServerPublicKeyX` attested inside its verified `jwtChain`. Rejects\n * a key that was swapped out-of-band after the chain was signed.\n *\n * @param keys - The issuer JWKS used to verify the chain (idOS enclave for\n * `encryptionDataKey`, idOS relay for `ukycCapabilityToken`).\n * @param schema - The encryption schema returned by session creation.\n */\n #assertAttestedServerPublicKey(keys: Jwk[], schema: EncryptionSchema): void {\n const jwtChainPayload = verifyJwtChain(keys, schema.jwtChain);\n if (jwtChainPayload.sessionServerPublicKeyX !== schema.serverPublicKey.x) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n }\n\n /**\n * Transitions to the error phase with a message.\n *\n * @param message - The error message.\n */\n #fail(message: string): void {\n this.#applyUpdate((state) => {\n state.error = message;\n state.phase = 'error';\n });\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/kyc-controller",
3
- "version": "0.3.0-preview-0a8ce9948",
3
+ "version": "0.3.0-preview-95a403d7b",
4
4
  "description": "Shared KYC / identity verification controller used across MetaMask clients",
5
5
  "keywords": [
6
6
  "Ethereum",