@metamask-previews/kyc-controller 0.0.0-preview-e81fe8853 → 0.0.0-preview-3c77cf4
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/dist/KycController.cjs
CHANGED
|
@@ -1071,9 +1071,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
|
|
|
1071
1071
|
return true;
|
|
1072
1072
|
}, _KycController_applyUpdate = function _KycController_applyUpdate(updater) {
|
|
1073
1073
|
this.update((state) => {
|
|
1074
|
-
//
|
|
1075
|
-
// TS2589, so the directive is unused and fails the build.
|
|
1076
|
-
// type issue only happens at the IDE level.
|
|
1074
|
+
// @ts-expect-error Avoid "type instantiation is excessively deep".
|
|
1077
1075
|
updater(state);
|
|
1078
1076
|
});
|
|
1079
1077
|
}, _KycController_fail = function _KycController_fail(message) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KycController.cjs","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 { x25519 } from '@noble/curves/ed25519';\n\nimport { decryptCredentials, generateKeyPair } from './crypto.js';\nimport type { EncryptedCredentialsEnvelope, X25519KeyPair } from './crypto.js';\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 KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubStatus,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport { signStorageAccessToken } from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nconst FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';\nconst CHANNEL_CHECK = 'ch_1';\nconst CHANNEL_AUTH = 'ch_2';\nconst CHANNEL_RESET = 'ch_reset';\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// The SumSub SDK status that signals the applicant finished the flow\n// successfully. Any other resolution (abandonment, failure, or a non-success\n// outcome) must not be recorded as `complete`.\nconst SUMSUB_COMPLETED_STATUS = 'Completed';\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// === 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 /** ISO-8601 timestamp of the customer's terms acceptance (persisted). */\n termsAcceptedAt: string | null;\n /** IDs of the disclaimers the customer accepted (persisted). */\n acceptedDisclaimerIds: string[];\n\n /** Disclaimers fetched for the current country. */\n disclaimers: KycDisclaimer[];\n /** Error encountered while loading disclaimers, or `null`. */\n disclaimersError: string | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Vendor session token (not persisted, not logged). */\n sessionToken: string | null;\n /** Vendor access token (not persisted, not logged). */\n accessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\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 /** 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 termsAcceptedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n acceptedDisclaimerIds: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n disclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n disclaimersError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n accessToken: {\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 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 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 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 termsAcceptedAt: null,\n acceptedDisclaimerIds: [],\n disclaimers: [],\n disclaimersError: null,\n geoCountry: null,\n sessionToken: null,\n accessToken: null,\n moonpayCustomerId: null,\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'initialize',\n 'loadDisclaimers',\n 'acceptTermsAndStartSession',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\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\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n /**\n * 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\n/**\n * The shape of a message posted by a Check/Auth frame.\n */\ntype FrameMessage = {\n meta?: { channelId?: string };\n kind?: string;\n payload?: {\n status?:\n | 'active'\n | 'connectionRequired'\n | 'termsAcceptanceRequired'\n | 'pending'\n | 'unavailable'\n | 'failed';\n credentials?: EncryptedCredentialsEnvelope | string;\n customer?: { id?: string };\n };\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, HTTP\n * orchestration (via `KycService`), crypto, and the frame message protocol;\n * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n /** Ephemeral X25519 keypair for the frame key exchange (never persisted). */\n readonly #keypair: X25519KeyPair;\n\n /** Auth-frame client token, kept out of state. */\n #authClientToken: string | null = null;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} so in-flight async\n * work (e.g. the KYC-required check) can detect that it was superseded and\n * avoid writing stale results onto a 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 /**\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 */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_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.#keypair = generateKeyPair();\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 */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\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 if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\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.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 const hasTerms =\n Boolean(this.state.termsAcceptedAt) &&\n this.state.acceptedDisclaimerIds.length > 0;\n\n if (hasTerms && this.state.email) {\n await this.#createSession();\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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:fetchDisclaimers',\n { country },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimers = disclaimers;\n state.disclaimersError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\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. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n }): Promise<void> {\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.disclaimers.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.termsAcceptedAt = termsAcceptedAt;\n state.acceptedDisclaimerIds = disclaimerIds;\n });\n await this.#createSession();\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;\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 `sessionToken` 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.#authClientToken = null;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.sessionToken = null;\n state.accessToken = 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.sessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n console.error('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 this.#clearAcceptedTerms(state);\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 */\n #clearAcceptedTerms(state: KycControllerState): void {\n state.termsAcceptedAt = null;\n state.acceptedDisclaimerIds = [];\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 const payload = params.message as FrameMessage | undefined;\n\n if (!payload) {\n return {};\n }\n\n if (payload.kind === 'handshake') {\n const channelId = payload.meta?.channelId;\n return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };\n }\n\n if (payload.kind !== 'complete') {\n return {};\n }\n\n const channelId = payload.meta?.channelId;\n\n // Only honor a Check/Auth `complete` for the frame the flow is currently\n // waiting on. This drops stale or duplicate messages — e.g. a late post\n // after `reset()` (phase `idle`) or after the flow already advanced past\n // this frame — so they cannot resurrect tokens or rewind `phase` on a\n // controller that has moved on. Frame messages are external input and,\n // unlike the async steps, are not covered by the `#generation` guard.\n let expectedPhase: KycPhase | null = null;\n if (channelId === CHANNEL_CHECK) {\n expectedPhase = 'check';\n } else if (channelId === CHANNEL_AUTH) {\n expectedPhase = 'auth';\n }\n if (!expectedPhase || this.state.phase !== expectedPhase) {\n return {};\n }\n\n const status = payload.payload?.status;\n const credsEnvelope = payload.payload?.credentials;\n\n const customerId = payload.payload?.customer?.id ?? null;\n if (customerId) {\n this.#applyUpdate((state) => {\n state.moonpayCustomerId = customerId;\n });\n }\n\n if (!status) {\n return {};\n }\n\n let accessToken: string | undefined;\n let clientToken: string | undefined;\n if (credsEnvelope) {\n try {\n const { credentials } = decryptCredentials(\n credsEnvelope,\n this.#keypair.privateKey,\n );\n accessToken = credentials.accessToken;\n clientToken = credentials.clientToken;\n } catch (error) {\n this.#fail(`Failed to decrypt frame credentials: ${String(error)}`);\n return {};\n }\n }\n\n if (channelId === CHANNEL_CHECK) {\n await this.#handleCheckOutcome(status, accessToken, clientToken);\n return {};\n }\n\n // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.\n await this.#handleAuthOutcome(status, accessToken);\n return {};\n }\n\n /**\n * Applies a Check-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n * @param clientToken - The decrypted client token, if any.\n */\n async #handleCheckOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n clientToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Already authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'connectionRequired' && clientToken) {\n this.#authClientToken = clientToken;\n this.#applyUpdate((state) => {\n state.phase = 'auth';\n state.statusMessage = 'Verify your email via OTP in the Auth frame.';\n });\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Check frame returned status: ${status}`);\n }\n\n /**\n * Applies an Auth-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n */\n async #handleAuthOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Auth frame returned status: ${status}`);\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 both\n // outcome handlers move `phase` to `form` before awaiting this method. A\n // duplicate or late `complete` therefore lands after the phase moved on and\n // is dropped before it can start a second continuation. Any writes here are\n // additionally guarded by `#generation` (see `checkKycRequired` /\n // `startSumSub`) so a `reset()` mid-continuation 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 if (!this.state.sessionToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/check-connection`);\n url.searchParams.set('sessionToken', this.state.sessionToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_CHECK);\n url.searchParams.set('skipKyc', 'true');\n return url.toString();\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 if (!this.#authClientToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/auth`);\n url.searchParams.set('clientToken', this.#authClientToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_AUTH);\n return url.toString();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n const url = new URL(`${FRAMES_BASE_URL}/reset`);\n url.searchParams.set('channelId', CHANNEL_RESET);\n return url.toString();\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 { accessToken } = this.state;\n if (!accessToken) {\n this.#fail('Missing accessToken — repeat the authentication step.');\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 { accessToken, country, capabilities: [{ product: params.product }] },\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 * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. requests a per-session wrapping key from the UKYC backend;\n * 2. verifies its `jwtChain` against the Fractal JWKS and confirms the\n * attested session server public 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` and creates\n * the UKYC session (handing over the wrapped key and the token);\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If session creation reports 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\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 // 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 this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const jwtToken = MOCK_JWT_TOKEN;\n\n // Establish a per-session X25519 keypair and exchange our public half for\n // the server's wrapping key. The private half stays on the device and is\n // used to derive the shared secret that seals the data_encryption_key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = x25519.getPublicKey(\n sessionClientPrivateKey,\n );\n const wrappingKey = await this.messenger.call(\n 'KycService:getWrappingKey',\n { sessionClientPublicKey: toBase64Url(sessionClientPublicKey) },\n );\n\n // Verify the jwtChain against Fractal's JWKS, then confirm the returned\n // sessionServerPublicKey matches the value attested inside the verified\n // JWT payload before trusting it for key wrapping.\n const { keys } = await this.messenger.call('KycService:fetchJwks');\n const jwtChainPayload = verifyJwtChain(keys, wrappingKey.jwtChain);\n if (\n jwtChainPayload.sessionServerPublicKeyX !==\n wrappingKey.sessionServerPublicKey.x\n ) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n\n // Derive the data_encryption_key from the local_user_secret and wrap it\n // for the session server. Only the wrapped (encrypted) key ever leaves\n // the device.\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore(),\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionKey = {\n sessionId: wrappingKey.id,\n ...wrapEncryptionKey(\n sessionClientPrivateKey,\n wrappingKey.sessionServerPublicKey.x,\n clientMaterial.dataEncryptionKey,\n ),\n };\n\n // Mint a read-only `ukyc_capability_token` for the session. Only the\n // client holds the signing key derived from `local_user_secret`, so only\n // the client can mint it; scoping it to `read` means it authorizes later\n // storage reads without granting write or delete access.\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n operations: ['read'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n\n const { sessionId, kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:createUkycSession',\n {\n jwtToken,\n vendorMetadata: {\n moonPayAccessToken: this.state.accessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n wrappedEncryptionKey,\n ukycCapabilityToken,\n },\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 (\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending\n ) {\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'vendorProcessing';\n state.sumsub.sessionId = sessionId;\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return stillCurrent ? { kycStatus, finalStatus } : {};\n }\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 (next === SUMSUB_COMPLETED_STATUS) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status =\n next === SUMSUB_COMPLETED_STATUS ? 'complete' : 'inProgress';\n });\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // A resolved `launch` alone is not the final outcome: only a SDK-reported\n // completion is worth polling for a verification decision. Anything else\n // (abandonment, non-success) is `failed` and must not be polled.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = reachedCompletion ? 'polling' : 'failed';\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 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 }\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.#authClientToken = null;\n // Stop any session-status polling so a late poll cannot write onto the\n // now-idle controller.\n this.#stopPolling();\n // Invalidate any in-flight async work started before this reset so its\n // results are discarded rather than written onto the now-idle controller.\n this.#generation += 1;\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.disclaimers = [];\n state.disclaimersError = null;\n state.sessionToken = null;\n state.accessToken = null;\n state.moonpayCustomerId = null;\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 * 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` cannot be used: ts-bridge does not surface\n // TS2589, so the directive is unused and fails the build.\n // type issue only happens at the IDE level.\n updater(state);\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.cjs","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 { x25519 } from '@noble/curves/ed25519';\n\nimport { decryptCredentials, generateKeyPair } from './crypto.js';\nimport type { EncryptedCredentialsEnvelope, X25519KeyPair } from './crypto.js';\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 KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubStatus,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport { signStorageAccessToken } from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nconst FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';\nconst CHANNEL_CHECK = 'ch_1';\nconst CHANNEL_AUTH = 'ch_2';\nconst CHANNEL_RESET = 'ch_reset';\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// The SumSub SDK status that signals the applicant finished the flow\n// successfully. Any other resolution (abandonment, failure, or a non-success\n// outcome) must not be recorded as `complete`.\nconst SUMSUB_COMPLETED_STATUS = 'Completed';\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// === 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 /** ISO-8601 timestamp of the customer's terms acceptance (persisted). */\n termsAcceptedAt: string | null;\n /** IDs of the disclaimers the customer accepted (persisted). */\n acceptedDisclaimerIds: string[];\n\n /** Disclaimers fetched for the current country. */\n disclaimers: KycDisclaimer[];\n /** Error encountered while loading disclaimers, or `null`. */\n disclaimersError: string | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Vendor session token (not persisted, not logged). */\n sessionToken: string | null;\n /** Vendor access token (not persisted, not logged). */\n accessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\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 /** 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 termsAcceptedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n acceptedDisclaimerIds: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n disclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n disclaimersError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n accessToken: {\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 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 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 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 termsAcceptedAt: null,\n acceptedDisclaimerIds: [],\n disclaimers: [],\n disclaimersError: null,\n geoCountry: null,\n sessionToken: null,\n accessToken: null,\n moonpayCustomerId: null,\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'initialize',\n 'loadDisclaimers',\n 'acceptTermsAndStartSession',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\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\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n /**\n * 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\n/**\n * The shape of a message posted by a Check/Auth frame.\n */\ntype FrameMessage = {\n meta?: { channelId?: string };\n kind?: string;\n payload?: {\n status?:\n | 'active'\n | 'connectionRequired'\n | 'termsAcceptanceRequired'\n | 'pending'\n | 'unavailable'\n | 'failed';\n credentials?: EncryptedCredentialsEnvelope | string;\n customer?: { id?: string };\n };\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, HTTP\n * orchestration (via `KycService`), crypto, and the frame message protocol;\n * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n /** Ephemeral X25519 keypair for the frame key exchange (never persisted). */\n readonly #keypair: X25519KeyPair;\n\n /** Auth-frame client token, kept out of state. */\n #authClientToken: string | null = null;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} so in-flight async\n * work (e.g. the KYC-required check) can detect that it was superseded and\n * avoid writing stale results onto a 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 /**\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 */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_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.#keypair = generateKeyPair();\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 */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\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 if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\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.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 const hasTerms =\n Boolean(this.state.termsAcceptedAt) &&\n this.state.acceptedDisclaimerIds.length > 0;\n\n if (hasTerms && this.state.email) {\n await this.#createSession();\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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:fetchDisclaimers',\n { country },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimers = disclaimers;\n state.disclaimersError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\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. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n }): Promise<void> {\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.disclaimers.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.termsAcceptedAt = termsAcceptedAt;\n state.acceptedDisclaimerIds = disclaimerIds;\n });\n await this.#createSession();\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;\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 `sessionToken` 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.#authClientToken = null;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.sessionToken = null;\n state.accessToken = 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.sessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n console.error('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 this.#clearAcceptedTerms(state);\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 */\n #clearAcceptedTerms(state: KycControllerState): void {\n state.termsAcceptedAt = null;\n state.acceptedDisclaimerIds = [];\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 const payload = params.message as FrameMessage | undefined;\n\n if (!payload) {\n return {};\n }\n\n if (payload.kind === 'handshake') {\n const channelId = payload.meta?.channelId;\n return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };\n }\n\n if (payload.kind !== 'complete') {\n return {};\n }\n\n const channelId = payload.meta?.channelId;\n\n // Only honor a Check/Auth `complete` for the frame the flow is currently\n // waiting on. This drops stale or duplicate messages — e.g. a late post\n // after `reset()` (phase `idle`) or after the flow already advanced past\n // this frame — so they cannot resurrect tokens or rewind `phase` on a\n // controller that has moved on. Frame messages are external input and,\n // unlike the async steps, are not covered by the `#generation` guard.\n let expectedPhase: KycPhase | null = null;\n if (channelId === CHANNEL_CHECK) {\n expectedPhase = 'check';\n } else if (channelId === CHANNEL_AUTH) {\n expectedPhase = 'auth';\n }\n if (!expectedPhase || this.state.phase !== expectedPhase) {\n return {};\n }\n\n const status = payload.payload?.status;\n const credsEnvelope = payload.payload?.credentials;\n\n const customerId = payload.payload?.customer?.id ?? null;\n if (customerId) {\n this.#applyUpdate((state) => {\n state.moonpayCustomerId = customerId;\n });\n }\n\n if (!status) {\n return {};\n }\n\n let accessToken: string | undefined;\n let clientToken: string | undefined;\n if (credsEnvelope) {\n try {\n const { credentials } = decryptCredentials(\n credsEnvelope,\n this.#keypair.privateKey,\n );\n accessToken = credentials.accessToken;\n clientToken = credentials.clientToken;\n } catch (error) {\n this.#fail(`Failed to decrypt frame credentials: ${String(error)}`);\n return {};\n }\n }\n\n if (channelId === CHANNEL_CHECK) {\n await this.#handleCheckOutcome(status, accessToken, clientToken);\n return {};\n }\n\n // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.\n await this.#handleAuthOutcome(status, accessToken);\n return {};\n }\n\n /**\n * Applies a Check-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n * @param clientToken - The decrypted client token, if any.\n */\n async #handleCheckOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n clientToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Already authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'connectionRequired' && clientToken) {\n this.#authClientToken = clientToken;\n this.#applyUpdate((state) => {\n state.phase = 'auth';\n state.statusMessage = 'Verify your email via OTP in the Auth frame.';\n });\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Check frame returned status: ${status}`);\n }\n\n /**\n * Applies an Auth-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n */\n async #handleAuthOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Auth frame returned status: ${status}`);\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 both\n // outcome handlers move `phase` to `form` before awaiting this method. A\n // duplicate or late `complete` therefore lands after the phase moved on and\n // is dropped before it can start a second continuation. Any writes here are\n // additionally guarded by `#generation` (see `checkKycRequired` /\n // `startSumSub`) so a `reset()` mid-continuation 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 if (!this.state.sessionToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/check-connection`);\n url.searchParams.set('sessionToken', this.state.sessionToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_CHECK);\n url.searchParams.set('skipKyc', 'true');\n return url.toString();\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 if (!this.#authClientToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/auth`);\n url.searchParams.set('clientToken', this.#authClientToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_AUTH);\n return url.toString();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n const url = new URL(`${FRAMES_BASE_URL}/reset`);\n url.searchParams.set('channelId', CHANNEL_RESET);\n return url.toString();\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 { accessToken } = this.state;\n if (!accessToken) {\n this.#fail('Missing accessToken — repeat the authentication step.');\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 { accessToken, country, capabilities: [{ product: params.product }] },\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 * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. requests a per-session wrapping key from the UKYC backend;\n * 2. verifies its `jwtChain` against the Fractal JWKS and confirms the\n * attested session server public 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` and creates\n * the UKYC session (handing over the wrapped key and the token);\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If session creation reports 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\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 // 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 this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const jwtToken = MOCK_JWT_TOKEN;\n\n // Establish a per-session X25519 keypair and exchange our public half for\n // the server's wrapping key. The private half stays on the device and is\n // used to derive the shared secret that seals the data_encryption_key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = x25519.getPublicKey(\n sessionClientPrivateKey,\n );\n const wrappingKey = await this.messenger.call(\n 'KycService:getWrappingKey',\n { sessionClientPublicKey: toBase64Url(sessionClientPublicKey) },\n );\n\n // Verify the jwtChain against Fractal's JWKS, then confirm the returned\n // sessionServerPublicKey matches the value attested inside the verified\n // JWT payload before trusting it for key wrapping.\n const { keys } = await this.messenger.call('KycService:fetchJwks');\n const jwtChainPayload = verifyJwtChain(keys, wrappingKey.jwtChain);\n if (\n jwtChainPayload.sessionServerPublicKeyX !==\n wrappingKey.sessionServerPublicKey.x\n ) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n\n // Derive the data_encryption_key from the local_user_secret and wrap it\n // for the session server. Only the wrapped (encrypted) key ever leaves\n // the device.\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore(),\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionKey = {\n sessionId: wrappingKey.id,\n ...wrapEncryptionKey(\n sessionClientPrivateKey,\n wrappingKey.sessionServerPublicKey.x,\n clientMaterial.dataEncryptionKey,\n ),\n };\n\n // Mint a read-only `ukyc_capability_token` for the session. Only the\n // client holds the signing key derived from `local_user_secret`, so only\n // the client can mint it; scoping it to `read` means it authorizes later\n // storage reads without granting write or delete access.\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n operations: ['read'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n\n const { sessionId, kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:createUkycSession',\n {\n jwtToken,\n vendorMetadata: {\n moonPayAccessToken: this.state.accessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n wrappedEncryptionKey,\n ukycCapabilityToken,\n },\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 (\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending\n ) {\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'vendorProcessing';\n state.sumsub.sessionId = sessionId;\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return stillCurrent ? { kycStatus, finalStatus } : {};\n }\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 (next === SUMSUB_COMPLETED_STATUS) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status =\n next === SUMSUB_COMPLETED_STATUS ? 'complete' : 'inProgress';\n });\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // A resolved `launch` alone is not the final outcome: only a SDK-reported\n // completion is worth polling for a verification decision. Anything else\n // (abandonment, non-success) is `failed` and must not be polled.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = reachedCompletion ? 'polling' : 'failed';\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 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 }\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.#authClientToken = null;\n // Stop any session-status polling so a late poll cannot write onto the\n // now-idle controller.\n this.#stopPolling();\n // Invalidate any in-flight async work started before this reset so its\n // results are discarded rather than written onto the now-idle controller.\n this.#generation += 1;\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.disclaimers = [];\n state.disclaimersError = null;\n state.sessionToken = null;\n state.accessToken = null;\n state.moonpayCustomerId = null;\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 * 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 * 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KycController.d.cts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"KycController.d.cts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KycController.d.mts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"KycController.d.mts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
|
package/dist/KycController.mjs
CHANGED
|
@@ -1066,9 +1066,7 @@ async function _KycController_pollSessionStatusOnce(sessionId, token) {
|
|
|
1066
1066
|
return true;
|
|
1067
1067
|
}, _KycController_applyUpdate = function _KycController_applyUpdate(updater) {
|
|
1068
1068
|
this.update((state) => {
|
|
1069
|
-
//
|
|
1070
|
-
// TS2589, so the directive is unused and fails the build.
|
|
1071
|
-
// type issue only happens at the IDE level.
|
|
1069
|
+
// @ts-expect-error Avoid "type instantiation is excessively deep".
|
|
1072
1070
|
updater(state);
|
|
1073
1071
|
});
|
|
1074
1072
|
}, _KycController_fail = function _KycController_fail(message) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KycController.mjs","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 { x25519 } from '@noble/curves/ed25519';\n\nimport { decryptCredentials, generateKeyPair } from './crypto.js';\nimport type { EncryptedCredentialsEnvelope, X25519KeyPair } from './crypto.js';\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 KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubStatus,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport { signStorageAccessToken } from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nconst FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';\nconst CHANNEL_CHECK = 'ch_1';\nconst CHANNEL_AUTH = 'ch_2';\nconst CHANNEL_RESET = 'ch_reset';\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// The SumSub SDK status that signals the applicant finished the flow\n// successfully. Any other resolution (abandonment, failure, or a non-success\n// outcome) must not be recorded as `complete`.\nconst SUMSUB_COMPLETED_STATUS = 'Completed';\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// === 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 /** ISO-8601 timestamp of the customer's terms acceptance (persisted). */\n termsAcceptedAt: string | null;\n /** IDs of the disclaimers the customer accepted (persisted). */\n acceptedDisclaimerIds: string[];\n\n /** Disclaimers fetched for the current country. */\n disclaimers: KycDisclaimer[];\n /** Error encountered while loading disclaimers, or `null`. */\n disclaimersError: string | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Vendor session token (not persisted, not logged). */\n sessionToken: string | null;\n /** Vendor access token (not persisted, not logged). */\n accessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\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 /** 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 termsAcceptedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n acceptedDisclaimerIds: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n disclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n disclaimersError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n accessToken: {\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 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 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 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 termsAcceptedAt: null,\n acceptedDisclaimerIds: [],\n disclaimers: [],\n disclaimersError: null,\n geoCountry: null,\n sessionToken: null,\n accessToken: null,\n moonpayCustomerId: null,\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'initialize',\n 'loadDisclaimers',\n 'acceptTermsAndStartSession',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\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\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n /**\n * 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\n/**\n * The shape of a message posted by a Check/Auth frame.\n */\ntype FrameMessage = {\n meta?: { channelId?: string };\n kind?: string;\n payload?: {\n status?:\n | 'active'\n | 'connectionRequired'\n | 'termsAcceptanceRequired'\n | 'pending'\n | 'unavailable'\n | 'failed';\n credentials?: EncryptedCredentialsEnvelope | string;\n customer?: { id?: string };\n };\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, HTTP\n * orchestration (via `KycService`), crypto, and the frame message protocol;\n * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n /** Ephemeral X25519 keypair for the frame key exchange (never persisted). */\n readonly #keypair: X25519KeyPair;\n\n /** Auth-frame client token, kept out of state. */\n #authClientToken: string | null = null;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} so in-flight async\n * work (e.g. the KYC-required check) can detect that it was superseded and\n * avoid writing stale results onto a 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 /**\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 */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_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.#keypair = generateKeyPair();\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 */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\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 if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\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.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 const hasTerms =\n Boolean(this.state.termsAcceptedAt) &&\n this.state.acceptedDisclaimerIds.length > 0;\n\n if (hasTerms && this.state.email) {\n await this.#createSession();\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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:fetchDisclaimers',\n { country },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimers = disclaimers;\n state.disclaimersError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\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. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n }): Promise<void> {\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.disclaimers.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.termsAcceptedAt = termsAcceptedAt;\n state.acceptedDisclaimerIds = disclaimerIds;\n });\n await this.#createSession();\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;\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 `sessionToken` 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.#authClientToken = null;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.sessionToken = null;\n state.accessToken = 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.sessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n console.error('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 this.#clearAcceptedTerms(state);\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 */\n #clearAcceptedTerms(state: KycControllerState): void {\n state.termsAcceptedAt = null;\n state.acceptedDisclaimerIds = [];\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 const payload = params.message as FrameMessage | undefined;\n\n if (!payload) {\n return {};\n }\n\n if (payload.kind === 'handshake') {\n const channelId = payload.meta?.channelId;\n return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };\n }\n\n if (payload.kind !== 'complete') {\n return {};\n }\n\n const channelId = payload.meta?.channelId;\n\n // Only honor a Check/Auth `complete` for the frame the flow is currently\n // waiting on. This drops stale or duplicate messages — e.g. a late post\n // after `reset()` (phase `idle`) or after the flow already advanced past\n // this frame — so they cannot resurrect tokens or rewind `phase` on a\n // controller that has moved on. Frame messages are external input and,\n // unlike the async steps, are not covered by the `#generation` guard.\n let expectedPhase: KycPhase | null = null;\n if (channelId === CHANNEL_CHECK) {\n expectedPhase = 'check';\n } else if (channelId === CHANNEL_AUTH) {\n expectedPhase = 'auth';\n }\n if (!expectedPhase || this.state.phase !== expectedPhase) {\n return {};\n }\n\n const status = payload.payload?.status;\n const credsEnvelope = payload.payload?.credentials;\n\n const customerId = payload.payload?.customer?.id ?? null;\n if (customerId) {\n this.#applyUpdate((state) => {\n state.moonpayCustomerId = customerId;\n });\n }\n\n if (!status) {\n return {};\n }\n\n let accessToken: string | undefined;\n let clientToken: string | undefined;\n if (credsEnvelope) {\n try {\n const { credentials } = decryptCredentials(\n credsEnvelope,\n this.#keypair.privateKey,\n );\n accessToken = credentials.accessToken;\n clientToken = credentials.clientToken;\n } catch (error) {\n this.#fail(`Failed to decrypt frame credentials: ${String(error)}`);\n return {};\n }\n }\n\n if (channelId === CHANNEL_CHECK) {\n await this.#handleCheckOutcome(status, accessToken, clientToken);\n return {};\n }\n\n // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.\n await this.#handleAuthOutcome(status, accessToken);\n return {};\n }\n\n /**\n * Applies a Check-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n * @param clientToken - The decrypted client token, if any.\n */\n async #handleCheckOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n clientToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Already authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'connectionRequired' && clientToken) {\n this.#authClientToken = clientToken;\n this.#applyUpdate((state) => {\n state.phase = 'auth';\n state.statusMessage = 'Verify your email via OTP in the Auth frame.';\n });\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Check frame returned status: ${status}`);\n }\n\n /**\n * Applies an Auth-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n */\n async #handleAuthOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Auth frame returned status: ${status}`);\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 both\n // outcome handlers move `phase` to `form` before awaiting this method. A\n // duplicate or late `complete` therefore lands after the phase moved on and\n // is dropped before it can start a second continuation. Any writes here are\n // additionally guarded by `#generation` (see `checkKycRequired` /\n // `startSumSub`) so a `reset()` mid-continuation 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 if (!this.state.sessionToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/check-connection`);\n url.searchParams.set('sessionToken', this.state.sessionToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_CHECK);\n url.searchParams.set('skipKyc', 'true');\n return url.toString();\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 if (!this.#authClientToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/auth`);\n url.searchParams.set('clientToken', this.#authClientToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_AUTH);\n return url.toString();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n const url = new URL(`${FRAMES_BASE_URL}/reset`);\n url.searchParams.set('channelId', CHANNEL_RESET);\n return url.toString();\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 { accessToken } = this.state;\n if (!accessToken) {\n this.#fail('Missing accessToken — repeat the authentication step.');\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 { accessToken, country, capabilities: [{ product: params.product }] },\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 * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. requests a per-session wrapping key from the UKYC backend;\n * 2. verifies its `jwtChain` against the Fractal JWKS and confirms the\n * attested session server public 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` and creates\n * the UKYC session (handing over the wrapped key and the token);\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If session creation reports 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\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 // 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 this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const jwtToken = MOCK_JWT_TOKEN;\n\n // Establish a per-session X25519 keypair and exchange our public half for\n // the server's wrapping key. The private half stays on the device and is\n // used to derive the shared secret that seals the data_encryption_key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = x25519.getPublicKey(\n sessionClientPrivateKey,\n );\n const wrappingKey = await this.messenger.call(\n 'KycService:getWrappingKey',\n { sessionClientPublicKey: toBase64Url(sessionClientPublicKey) },\n );\n\n // Verify the jwtChain against Fractal's JWKS, then confirm the returned\n // sessionServerPublicKey matches the value attested inside the verified\n // JWT payload before trusting it for key wrapping.\n const { keys } = await this.messenger.call('KycService:fetchJwks');\n const jwtChainPayload = verifyJwtChain(keys, wrappingKey.jwtChain);\n if (\n jwtChainPayload.sessionServerPublicKeyX !==\n wrappingKey.sessionServerPublicKey.x\n ) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n\n // Derive the data_encryption_key from the local_user_secret and wrap it\n // for the session server. Only the wrapped (encrypted) key ever leaves\n // the device.\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore(),\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionKey = {\n sessionId: wrappingKey.id,\n ...wrapEncryptionKey(\n sessionClientPrivateKey,\n wrappingKey.sessionServerPublicKey.x,\n clientMaterial.dataEncryptionKey,\n ),\n };\n\n // Mint a read-only `ukyc_capability_token` for the session. Only the\n // client holds the signing key derived from `local_user_secret`, so only\n // the client can mint it; scoping it to `read` means it authorizes later\n // storage reads without granting write or delete access.\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n operations: ['read'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n\n const { sessionId, kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:createUkycSession',\n {\n jwtToken,\n vendorMetadata: {\n moonPayAccessToken: this.state.accessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n wrappedEncryptionKey,\n ukycCapabilityToken,\n },\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 (\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending\n ) {\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'vendorProcessing';\n state.sumsub.sessionId = sessionId;\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return stillCurrent ? { kycStatus, finalStatus } : {};\n }\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 (next === SUMSUB_COMPLETED_STATUS) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status =\n next === SUMSUB_COMPLETED_STATUS ? 'complete' : 'inProgress';\n });\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // A resolved `launch` alone is not the final outcome: only a SDK-reported\n // completion is worth polling for a verification decision. Anything else\n // (abandonment, non-success) is `failed` and must not be polled.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = reachedCompletion ? 'polling' : 'failed';\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 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 }\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.#authClientToken = null;\n // Stop any session-status polling so a late poll cannot write onto the\n // now-idle controller.\n this.#stopPolling();\n // Invalidate any in-flight async work started before this reset so its\n // results are discarded rather than written onto the now-idle controller.\n this.#generation += 1;\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.disclaimers = [];\n state.disclaimersError = null;\n state.sessionToken = null;\n state.accessToken = null;\n state.moonpayCustomerId = null;\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 * 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` cannot be used: ts-bridge does not surface\n // TS2589, so the directive is unused and fails the build.\n // type issue only happens at the IDE level.\n updater(state);\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.mjs","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAKA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAO3D,OAAO,EAAE,MAAM,EAAE,8BAA8B;AAE/C,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,qBAAoB;AAElE,OAAO,EAAE,WAAW,EAAE,uBAAsB;AAW5C,OAAO,EAAE,oBAAoB,EAAE,wCAAuC;AACtE,OAAO,EAAE,cAAc,EAAE,4BAA2B;AACpD,OAAO,EAAE,0BAA0B,EAAE,mCAAkC;AAEvE,OAAO,EAAE,sBAAsB,EAAE,sCAAqC;AACtE,OAAO,EAAE,iBAAiB,EAAE,qCAAoC;AAEhE,kBAAkB;AAElB,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC;AAE9C,MAAM,eAAe,GAAG,wCAAwC,CAAC;AACjE,MAAM,aAAa,GAAG,MAAM,CAAC;AAC7B,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,MAAM,aAAa,GAAG,UAAU,CAAC;AAEjC,8EAA8E;AAC9E,yEAAyE;AACzE,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAExC,2EAA2E;AAC3E,+EAA+E;AAC/E,+EAA+E;AAC/E,wEAAwE;AACxE,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExD,qEAAqE;AACrE,6EAA6E;AAC7E,+CAA+C;AAC/C,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAE5C,4EAA4E;AAC5E,8EAA8E;AAC9E,+DAA+D;AAC/D,MAAM,kBAAkB,GAAe;IACrC,SAAS;IACT,OAAO;IACP,MAAM;IACN,MAAM;IACN,QAAQ;CACT,CAAC;AAEF,4EAA4E;AAC5E,uEAAuE;AACvE,MAAM,uCAAuC,GAAG,KAAM,CAAC;AAEvD,8EAA8E;AAC9E,+EAA+E;AAC/E,4EAA4E;AAC5E,YAAY;AACZ,MAAM,YAAY,GAAG;IACnB,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAEX,sEAAsE;AACtE,yCAAyC;AACzC,MAAM,yBAAyB,GAAwB,IAAI,GAAG,CAAC;IAC7D,YAAY,CAAC,QAAQ;IACrB,YAAY,CAAC,SAAS;IACtB,YAAY,CAAC,QAAQ;IACrB,YAAY,CAAC,MAAM;IACnB,YAAY,CAAC,OAAO;CACrB,CAAC,CAAC;AAEH,8EAA8E;AAC9E,2DAA2D;AAC3D,MAAM,2BAA2B,GAAwB,IAAI,GAAG,CAAC;IAC/D,YAAY,CAAC,QAAQ;IACrB,YAAY,CAAC,SAAS;CACvB,CAAC,CAAC;AAEH,4EAA4E;AAC5E,0EAA0E;AAC1E,qEAAqE;AACrE,6EAA6E;AAC7E,0EAA0E;AAC1E,WAAW;AACX,MAAM,yBAAyB,GAC7B,mEAAmE,CAAC;AAkEtE,MAAM,qBAAqB,GAAG;IAC5B,KAAK,EAAE;QACL,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,aAAa,EAAE;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,KAAK,EAAE;QACL,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,KAAK,EAAE;QACL,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;IACD,eAAe,EAAE;QACf,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,qBAAqB,EAAE;QACrB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,WAAW,EAAE;QACX,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,gBAAgB,EAAE;QAChB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,UAAU,EAAE;QACV,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,YAAY,EAAE;QACZ,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;IACD,WAAW,EAAE;QACX,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;IACD,iBAAiB,EAAE;QACjB,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK;KAChB;IACD,aAAa,EAAE;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;IACD,oBAAoB,EAAE;QACpB,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,IAAI;KACf;IACD,aAAa,EAAE;QACb,sBAAsB,EAAE,IAAI;QAC5B,kBAAkB,EAAE,IAAI;QACxB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,KAAK;KAChB;IACD,MAAM,EAAE;QACN,sBAAsB,EAAE,KAAK;QAC7B,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,IAAI;KACf;CAC0C,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,KAAK,EAAE,MAAM;QACb,aAAa,EAAE,EAAE;QACjB,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;QACX,eAAe,EAAE,IAAI;QACrB,qBAAqB,EAAE,EAAE;QACzB,WAAW,EAAE,EAAE;QACf,gBAAgB,EAAE,IAAI;QACtB,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,IAAI;QACjB,iBAAiB,EAAE,IAAI;QACvB,aAAa,EAAE,IAAI;QACnB,oBAAoB,EAAE,EAAE;QACxB,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE;YACN,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,IAAI;YACf,oBAAoB,EAAE,IAAI;YAC1B,aAAa,EAAE,IAAI;SACpB;KACF,CAAC;AACJ,CAAC;AAED,oBAAoB;AAEpB,MAAM,yBAAyB,GAAG;IAChC,YAAY;IACZ,iBAAiB;IACjB,4BAA4B;IAC5B,iBAAiB;IACjB,oBAAoB;IACpB,oBAAoB;IACpB,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,OAAO;CACC,CAAC;AAqEX,gCAAgC;AAEhC;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,cAIlC;IA+BC;;;;;;;;;OASG;IACH,YAAY,EACV,SAAS,EACT,KAAK,EACL,cAAc,EACd,2BAA2B,GAAG,uCAAuC,GAChD;QACrB,KAAK,CAAC;YACJ,SAAS;YACT,QAAQ,EAAE,qBAAqB;YAC/B,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,EAAE,GAAG,4BAA4B,EAAE,EAAE,GAAG,KAAK,EAAE;SACvD,CAAC,CAAC;;QAnDI,gDAAmC;QAE5C,6EAA6E;QACpE,yCAAwB;QAEjC,kDAAkD;QAClD,yCAAkC,IAAI,EAAC;QAEvC;;;;WAIG;QACH,oCAAc,CAAC,EAAC;QAEhB,+DAA+D;QACtD,6DAAqC;QAE9C,oEAAoE;QACpE,mCAAmD,IAAI,EAAC;QAExD;;;;;;WAMG;QACH,mCAAa,CAAC,EAAC;QAyBb,uBAAA,IAAI,iCAAmB,cAAc,MAAA,CAAC;QACtC,uBAAA,IAAI,8CAAgC,2BAA2B,MAAA,CAAC;QAChE,uBAAA,IAAI,0BAAY,eAAe,EAAE,MAAA,CAAC;QAElC,IAAI,CAAC,SAAS,CAAC,4BAA4B,CACzC,IAAI,EACJ,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAkCD;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,UAAU,CAAC,MAGhB;QACC,yEAAyE;QACzE,wEAAwE;QACxE,uEAAuE;QACvE,qEAAqE;QACrE,2DAA2D;QAC3D,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO;QACT,CAAC;QAED,0EAA0E;QAC1E,yEAAyE;QACzE,0EAA0E;QAC1E,oEAAoE;QACpE,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;gBAClB,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC7B,CAAC;YACD,KAAK,CAAC,aAAa,GAAG,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,qEAAqE;QACrE,uEAAuE;QACvE,2BAA2B;QAC3B,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;QAEpC,6CAA6C;QAC7C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YACtE,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1C,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,sEAAsE;QACxE,CAAC;QAED,MAAM,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,CAAC;QAE9C,IAAI,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,uBAAA,IAAI,8DAAe,MAAnB,IAAI,CAAiB,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,eAAe,CAAC,MAA6B;QACjD,qEAAqE;QACrE,uEAAuE;QACvE,cAAc;QACd,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,OAAO,GACX,MAAM,EAAE,OAAO;gBACf,IAAI,CAAC,KAAK,CAAC,UAAU;gBACrB,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC;YAC1D,IAAI,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;gBACtC,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;oBAC1C,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC;gBAC7B,CAAC,CAAC,CAAC;YACL,CAAC;YACD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC3C,6BAA6B,EAC7B,EAAE,OAAO,EAAE,CACZ,CAAC;YACF,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1C,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;gBAChC,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAChC,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1C,KAAK,CAAC,gBAAgB,GAAG,+BAA+B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1E,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,0BAA0B,CAAC,MAGhC;QACC,MAAM,eAAe,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAC9C,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAC9B,CAAC;QACF,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;gBAClB,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC7B,CAAC;YACD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;gBACpB,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC;YACvC,CAAC;YACD,KAAK,CAAC,eAAe,GAAG,eAAe,CAAC;YACxC,KAAK,CAAC,qBAAqB,GAAG,aAAa,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,MAAM,uBAAA,IAAI,8DAAe,MAAnB,IAAI,CAAiB,CAAC;IAC9B,CAAC;IAwED;;OAEG;IACH,eAAe;QACb,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,uBAAA,IAAI,mEAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAgBD;;;;;;;;;OASG;IACH,KAAK,CAAC,kBAAkB,CAAC,MAExB;QACC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAmC,CAAC;QAE3D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;YAC1C,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC;QAE1C,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,sEAAsE;QACtE,uEAAuE;QACvE,sEAAsE;QACtE,IAAI,aAAa,GAAoB,IAAI,CAAC;QAC1C,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;YAChC,aAAa,GAAG,OAAO,CAAC;QAC1B,CAAC;aAAM,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;YACtC,aAAa,GAAG,MAAM,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;YACzD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC;QACvC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC;QAEnD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,IAAI,CAAC;QACzD,IAAI,UAAU,EAAE,CAAC;YACf,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;gBAC1B,KAAK,CAAC,iBAAiB,GAAG,UAAU,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,WAA+B,CAAC;QACpC,IAAI,WAA+B,CAAC;QACpC,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,MAAM,EAAE,WAAW,EAAE,GAAG,kBAAkB,CACxC,aAAa,EACb,uBAAA,IAAI,8BAAS,CAAC,UAAU,CACzB,CAAC;gBACF,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC;gBACtC,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC;YACxC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,wCAAwC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpE,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;YAChC,MAAM,uBAAA,IAAI,mEAAoB,MAAxB,IAAI,EAAqB,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;YACjE,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,2EAA2E;QAC3E,MAAM,uBAAA,IAAI,kEAAmB,MAAvB,IAAI,EAAoB,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,OAAO,EAAE,CAAC;IACZ,CAAC;IAmHD;;;;OAIG;IACH,kBAAkB;QAChB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,eAAe,mBAAmB,CAAC,CAAC;QAC3D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC9D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,uBAAA,IAAI,8BAAS,CAAC,YAAY,CAAC,CAAC;QAC9D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACjD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,iBAAiB;QACf,IAAI,CAAC,uBAAA,IAAI,sCAAiB,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,eAAe,OAAO,CAAC,CAAC;QAC/C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,aAAa,EAAE,uBAAA,IAAI,sCAAiB,CAAC,CAAC;QAC3D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,uBAAA,IAAI,8BAAS,CAAC,YAAY,CAAC,CAAC;QAC9D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAChD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,kBAAkB;QAChB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,eAAe,QAAQ,CAAC,CAAC;QAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACjD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB,CAAC,MAGtB;QACC,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACnC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,uDAAuD,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QACxD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,yCAAyC,CAAC,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wEAAwE;QACxE,oEAAoE;QACpE,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;QAEpC,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC;YACvB,KAAK,CAAC,aAAa,GAAG,wBAAwB,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,6BAA6B,EAC7B,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,EAAE,CACtE,CAAC;YACF,uEAAuE;YACvE,sEAAsE;YACtE,MAAM,OAAO,GAAG,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1D,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC;gBACzD,KAAK,CAAC,aAAa,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC/C,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;gBACrB,KAAK,CAAC,aAAa,GAAG,qBAAqB,CAAC;YAC9C,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,uBAAA,IAAI,iCAAY,KAAK,UAAU,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC;YACf,CAAC;YACD,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,qBAAqB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,YAAY,CAAC,MAA+B;QAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,KAAK,CAAC,WAAW,CAAC,MAGjB;QACC,wEAAwE;QACxE,uBAAA,IAAI,4DAAa,MAAjB,IAAI,CAAe,CAAC;QAEpB,IAAI,CAAC,uBAAA,IAAI,qCAAgB,CAAC,WAAW,EAAE,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,8CAA8C,CAAC;YAC7D,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;gBAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;gBAC/B,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QAED,wEAAwE;QACxE,2EAA2E;QAC3E,wDAAwD;QACxD,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;QAEpC,IAAI,CAAC;YACH,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;gBAC1B,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,iBAAiB,CAAC;gBACxC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;gBAC3B,KAAK,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC;YACpC,CAAC,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,cAAc,CAAC;YAEhC,0EAA0E;YAC1E,yEAAyE;YACzE,uEAAuE;YACvE,MAAM,uBAAuB,GAAG,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC;YAC/D,MAAM,sBAAsB,GAAG,MAAM,CAAC,YAAY,CAChD,uBAAuB,CACxB,CAAC;YACF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC3C,2BAA2B,EAC3B,EAAE,sBAAsB,EAAE,WAAW,CAAC,sBAAsB,CAAC,EAAE,CAChE,CAAC;YAEF,wEAAwE;YACxE,wEAAwE;YACxE,mDAAmD;YACnD,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACnE,MAAM,eAAe,GAAG,cAAc,CAAC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YACnE,IACE,eAAe,CAAC,uBAAuB;gBACvC,WAAW,CAAC,sBAAsB,CAAC,CAAC,EACpC,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;YACJ,CAAC;YAED,wEAAwE;YACxE,uEAAuE;YACvE,cAAc;YACd,MAAM,eAAe,GAAG,MAAM,0BAA0B,CACtD,uBAAA,IAAI,qEAAsB,MAA1B,IAAI,CAAwB,CAC7B,CAAC;YACF,MAAM,cAAc,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;YAC7D,MAAM,oBAAoB,GAAG;gBAC3B,SAAS,EAAE,WAAW,CAAC,EAAE;gBACzB,GAAG,iBAAiB,CAClB,uBAAuB,EACvB,WAAW,CAAC,sBAAsB,CAAC,CAAC,EACpC,cAAc,CAAC,iBAAiB,CACjC;aACF,CAAC;YAEF,qEAAqE;YACrE,yEAAyE;YACzE,yEAAyE;YACzE,yDAAyD;YACzD,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;gBACjD,QAAQ,EAAE,cAAc;gBACxB,UAAU,EAAE,CAAC,MAAM,CAAC;gBACpB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,4BAA4B,CAAC;aAC/D,CAAC,CAAC;YAEH,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACrE,8BAA8B,EAC9B;gBACE,QAAQ;gBACR,cAAc,EAAE;oBACd,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;oBAC1C,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB;iBAC5C;gBACD,oBAAoB;gBACpB,mBAAmB;aACpB,CACF,CAAC;YAEF,sEAAsE;YACtE,qEAAqE;YACrE,wEAAwE;YACxE,uEAAuE;YACvE,aAAa;YACb,IACE,SAAS,KAAK,YAAY,CAAC,QAAQ;gBACnC,WAAW,KAAK,YAAY,CAAC,OAAO,EACpC,CAAC;gBACD,MAAM,YAAY,GAAG,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;oBAC/D,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,kBAAkB,CAAC;oBACzC,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;oBACnC,KAAK,CAAC,aAAa,GAAG,yBAAyB,CAAC;gBAClD,CAAC,CAAC,CAAC;gBACH,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,CAAC;YAED,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1C,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC;gBACtC,KAAK,CAAC,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;YACrC,CAAC,CAAC,CAAC;YAEH,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACxD,0BAA0B,EAC1B,SAAS,CACV,CAAC;YAEF,wEAAwE;YACxE,uEAAuE;YACvE,qEAAqE;YACrE,wEAAwE;YACxE,wEAAwE;YACxE,2EAA2E;YAC3E,MAAM,YAAY,GAAG,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/D,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC;gBAClC,KAAK,CAAC,MAAM,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;YAC3D,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,0EAA0E;YAC1E,iEAAiE;YACjE,yEAAyE;YACzE,IAAI,iBAAiB,GAAG,KAAK,CAAC;YAE9B,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,qCAAgB,CAAC,MAAM,CAAC;gBAC/C,oBAAoB;gBACpB,iBAAiB,EAAE,KAAK,IAAI,EAAE;oBAC5B,qEAAqE;oBACrE,mEAAmE;oBACnE,0CAA0C;oBAC1C,IAAI,uBAAA,IAAI,iCAAY,KAAK,UAAU,EAAE,CAAC;wBACpC,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;oBACJ,CAAC;oBACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,0BAA0B,EAC1B,SAAS,CACV,CAAC;oBACF,OAAO,SAAS,CAAC,oBAAoB,CAAC;gBACxC,CAAC;gBACD,cAAc,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;oBAC9B,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;wBACrC,iBAAiB,GAAG,IAAI,CAAC;oBAC3B,CAAC;oBACD,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;wBAC1C,KAAK,CAAC,MAAM,CAAC,MAAM;4BACjB,IAAI,KAAK,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;oBACjE,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,EAAE,MAAM,EAAE,MAAM,IAAI,IAAI;gBAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK;aAC9B,CAAC,CAAC;YAEH,0EAA0E;YAC1E,yEAAyE;YACzE,iEAAiE;YACjE,MAAM,OAAO,GAAG,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1D,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAC/D,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,MAAc,CAAC;YACvC,CAAC,CAAC,CAAC;YAEH,wEAAwE;YACxE,qEAAqE;YACrE,0EAA0E;YAC1E,oEAAoE;YACpE,IAAI,OAAO,IAAI,iBAAiB,EAAE,CAAC;gBACjC,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,uBAAA,IAAI,0EAA2B,MAA/B,IAAI,EAA4B,SAAS,CAAC,CAAC;gBACnD,CAAC;qBAAM,CAAC;oBACN,+DAA+D;oBAC/D,mCAAmC;oBACnC,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;wBAC1C,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,UAAU,CAAC;oBACnC,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACxC,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1C,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;gBAC/B,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YAC/B,CAAC,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;QACpC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,CACd,CAAC;QACF,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1C,KAAK,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC;QAC7C,CAAC,CAAC,CAAC;QACH,OAAO,aAAa,CAAC;IACvB,CAAC;IAkGD;;;OAGG;IACH,KAAK;QACH,uBAAA,IAAI,kCAAoB,IAAI,MAAA,CAAC;QAC7B,uEAAuE;QACvE,uBAAuB;QACvB,uBAAA,IAAI,4DAAa,MAAjB,IAAI,CAAe,CAAC;QACpB,uEAAuE;QACvE,0EAA0E;QAC1E,uHAAoB,CAAC,MAAA,CAAC;QACtB,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;YACrB,KAAK,CAAC,aAAa,GAAG,EAAE,CAAC;YACzB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;YACnB,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;YACvB,KAAK,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC9B,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;YAC1B,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YACzB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC/B,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,MAAM,GAAG;gBACb,MAAM,EAAE,MAAM;gBACd,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI;gBACf,oBAAoB,EAAE,IAAI;gBAC1B,aAAa,EAAE,IAAI;aACpB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;CAwDF;;IAv+BG,OAAO;QACL,GAAG,EAAE,KAAK,EACR,IAAY,EACZ,eAAwB,EACA,EAAE,CAC1B,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,yCAAyC,EACzC,IAA6B,EAC7B,eAAe,CAChB;QACH,GAAG,EAAE,KAAK,EACR,IAAY,EACZ,KAAa,EACb,eAAwB,EACT,EAAE,CACjB,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,yCAAyC,EACzC,IAA6B,EAC7B,KAAK,EACL,eAAe,CAChB;KACJ,CAAC;AACJ,CAAC;AAuID;;GAEG;AACH,KAAK;IACH,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;IACrE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,qCAAqC,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,eAAe,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,gDAAgD,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,yEAAyE;IACzE,uEAAuE;IACvE,2EAA2E;IAC3E,sEAAsE;IACtE,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,wDAAwD;IACxD,sEAAsE;IACtE,yEAAyE;IACzE,uEAAuE;IACvE,4CAA4C;IAC5C,MAAM,UAAU,GAAG,uBAAA,IAAI,iCAAY,CAAC;IACpC,uBAAA,IAAI,kCAAoB,IAAI,MAAA,CAAC;IAC7B,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;QAC1B,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;QACnB,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,KAAK,CAAC,aAAa,GAAG,qBAAqB,CAAC;QAC5C,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAChD,0BAA0B,EAC1B,EAAE,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,qBAAqB,EAAE,CACjE,CAAC;QACF,uBAAA,IAAI,gEAAiB,MAArB,IAAI,EAAkB,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1C,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;YAClC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;YACtB,KAAK,CAAC,aAAa,GAAG,mCAAmC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC;QACjD,wEAAwE;QACxE,oEAAoE;QACpE,IAAI,uBAAA,IAAI,iCAAY,KAAK,UAAU,EAAE,CAAC;YACpC,OAAO;QACT,CAAC;QACD,yEAAyE;QACzE,uEAAuE;QACvE,uEAAuE;QACvE,0EAA0E;QAC1E,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,uBAAA,IAAI,mEAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,CAAC;YAChC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC3B,KAAK,CAAC,KAAK,GAAG,4BAA4B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,KAAK,CAAC,aAAa;gBACjB,0DAA0D,CAAC;YAC7D,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC,iFAoBmB,KAAyB;IAC3C,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC;AACnC,CAAC;AAwFD;;;;;;GAMG;AACH,KAAK,4CACH,MAAsD,EACtD,WAAoB,EACpB,WAAoB;IAEpB,IAAI,MAAM,KAAK,QAAQ,IAAI,WAAW,EAAE,CAAC;QACvC,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;YAChC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;YACrB,KAAK,CAAC,aAAa,GAAG,0CAA0C,CAAC;QACnE,CAAC,CAAC,CAAC;QACH,MAAM,uBAAA,IAAI,4EAA6B,MAAjC,IAAI,CAA+B,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,IAAI,MAAM,KAAK,oBAAoB,IAAI,WAAW,EAAE,CAAC;QACnD,uBAAA,IAAI,kCAAoB,WAAW,MAAA,CAAC;QACpC,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;YACrB,KAAK,CAAC,aAAa,GAAG,8CAA8C,CAAC;QACvE,CAAC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,IAAI,MAAM,KAAK,yBAAyB,EAAE,CAAC;QACzC,uBAAA,IAAI,yEAA0B,MAA9B,IAAI,CAA4B,CAAC;QACjC,OAAO;IACT,CAAC;IACD,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,gCAAgC,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,KAAK,2CACH,MAAsD,EACtD,WAAoB;IAEpB,IAAI,MAAM,KAAK,QAAQ,IAAI,WAAW,EAAE,CAAC;QACvC,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;YAChC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC;YACrB,KAAK,CAAC,aAAa,GAAG,kCAAkC,CAAC;QAC3D,CAAC,CAAC,CAAC;QACH,MAAM,uBAAA,IAAI,4EAA6B,MAAjC,IAAI,CAA+B,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,IAAI,MAAM,KAAK,yBAAyB,EAAE,CAAC;QACzC,uBAAA,IAAI,yEAA0B,MAA9B,IAAI,CAA4B,CAAC;QACjC,OAAO;IACT,CAAC;IACD,uBAAA,IAAI,qDAAM,MAAV,IAAI,EAAO,+BAA+B,MAAM,EAAE,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,KAAK;IACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IACzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IAED,wEAAwE;IACxE,sEAAsE;IACtE,yEAAyE;IACzE,4EAA4E;IAC5E,4EAA4E;IAC5E,kEAAkE;IAClE,uEAAuE;IACvE,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,oEAAoE;QACpE,oEAAoE;IACtE,CAAC;AACH,CAAC;IAMC,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;QAC1B,uBAAA,IAAI,mEAAoB,MAAxB,IAAI,EAAqB,KAAK,CAAC,CAAC;QAChC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QACtB,KAAK,CAAC,aAAa;YACjB,yDAAyD,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC;AAkXD;;;;;;;;GAQG;AACH,KAAK,mDAA4B,SAAiB;IAChD,yEAAyE;IACzE,0EAA0E;IAC1E,4DAA4D;IAC5D,uBAAA,IAAI,4DAAa,MAAjB,IAAI,CAAe,CAAC;IACpB,MAAM,KAAK,GAAG,uBAAA,IAAI,gCAAW,CAAC;IAE9B,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;QACrC,MAAM,UAAU,GAAG,MAAM,uBAAA,IAAI,sEAAuB,MAA3B,IAAI,EAAwB,SAAS,EAAE,KAAK,CAAC,CAAC;QACvE,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QACD,uBAAA,IAAI,4BAAc,UAAU,CAAC,GAAG,EAAE;YAChC,uBAAA,IAAI,4BAAc,IAAI,MAAA,CAAC;YACvB,oEAAoE;YACpE,kEAAkE;YAClE,4CAA4C;YAC5C,mEAAmE;YACnE,IAAI,EAAE,CAAC;QACT,CAAC,EAAE,uBAAA,IAAI,kDAA6B,CAAC,MAAA,CAAC;IACxC,CAAC,CAAC;IAEF,MAAM,IAAI,EAAE,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,KAAK,+CACH,SAAiB,EACjB,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,6BAA6B,EAC7B,EAAE,SAAS,EAAE,CACd,CAAC;QACF,gEAAgE;QAChE,IAAI,uBAAA,IAAI,gCAAW,KAAK,KAAK,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAC9C,aAAa,CAAC,WAAW,CAC1B,CAAC;QACF,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,CAAC,MAAM,CAAC,aAAa,GAAG,aAAa,CAAC;YAC3C,IAAI,UAAU,EAAE,CAAC;gBACf,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,2BAA2B,CAAC,GAAG,CACnD,aAAa,CAAC,WAAW,CAC1B;oBACC,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,QAAQ,CAAC;YACf,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,UAAU,EAAE,CAAC;YACf,uBAAA,IAAI,4DAAa,MAAjB,IAAI,CAAe,CAAC;QACtB,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;QACrE,8DAA8D;QAC9D,OAAO,uBAAA,IAAI,gCAAW,KAAK,KAAK,CAAC;IACnC,CAAC;AACH,CAAC;IAOC,qHAAmB,CAAC,MAAA,CAAC;IACrB,IAAI,uBAAA,IAAI,gCAAW,KAAK,IAAI,EAAE,CAAC;QAC7B,YAAY,CAAC,uBAAA,IAAI,gCAAW,CAAC,CAAC;QAC9B,uBAAA,IAAI,4BAAc,IAAI,MAAA,CAAC;IACzB,CAAC;AACH,CAAC,2EA6CC,UAAkB,EAClB,OAA4C;IAE5C,IAAI,uBAAA,IAAI,iCAAY,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,OAAO,CAAC,CAAC;IAC3B,OAAO,IAAI,CAAC;AACd,CAAC,mEAiBY,OAA4C;IACvD,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACpB,mEAAmE;QACnE,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC,qDAOK,OAAe;IACnB,uBAAA,IAAI,4DAAa,MAAjB,IAAI,EAAc,CAAC,KAAK,EAAE,EAAE;QAC1B,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QACtB,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC","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 { x25519 } from '@noble/curves/ed25519';\n\nimport { decryptCredentials, generateKeyPair } from './crypto.js';\nimport type { EncryptedCredentialsEnvelope, X25519KeyPair } from './crypto.js';\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 KycDisclaimer,\n KycPhase,\n KycProduct,\n KycSessionStatus,\n KycSumSubLauncher,\n KycSumSubStatus,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { verifyJwtChain } from './ukyc/jwtChain.js';\nimport { getOrCreateLocalUserSecret } from './ukyc/localUserSecret.js';\nimport type { UkycLocalUserSecretStore } from './ukyc/localUserSecret.js';\nimport { signStorageAccessToken } from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nconst FRAMES_BASE_URL = 'https://blocks.moonpay.com/platform/v1';\nconst CHANNEL_CHECK = 'ch_1';\nconst CHANNEL_AUTH = 'ch_2';\nconst CHANNEL_RESET = 'ch_reset';\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// The SumSub SDK status that signals the applicant finished the flow\n// successfully. Any other resolution (abandonment, failure, or a non-success\n// outcome) must not be recorded as `complete`.\nconst SUMSUB_COMPLETED_STATUS = 'Completed';\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// === 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 /** ISO-8601 timestamp of the customer's terms acceptance (persisted). */\n termsAcceptedAt: string | null;\n /** IDs of the disclaimers the customer accepted (persisted). */\n acceptedDisclaimerIds: string[];\n\n /** Disclaimers fetched for the current country. */\n disclaimers: KycDisclaimer[];\n /** Error encountered while loading disclaimers, or `null`. */\n disclaimersError: string | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Vendor session token (not persisted, not logged). */\n sessionToken: string | null;\n /** Vendor access token (not persisted, not logged). */\n accessToken: string | null;\n /** Vendor customer id, used for the SumSub hand-off. */\n moonpayCustomerId: string | null;\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 /** 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 termsAcceptedAt: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n acceptedDisclaimerIds: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n disclaimers: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: true,\n },\n disclaimersError: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: false,\n usedInUi: true,\n },\n sessionToken: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: false,\n usedInUi: false,\n },\n accessToken: {\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 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 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 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 termsAcceptedAt: null,\n acceptedDisclaimerIds: [],\n disclaimers: [],\n disclaimersError: null,\n geoCountry: null,\n sessionToken: null,\n accessToken: null,\n moonpayCustomerId: null,\n activeProduct: null,\n kycRequiredByProduct: {},\n lastCheckedAt: null,\n sumsub: {\n status: 'idle',\n result: null,\n sessionId: null,\n applicantAccessToken: null,\n sessionStatus: null,\n },\n };\n}\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'initialize',\n 'loadDisclaimers',\n 'acceptTermsAndStartSession',\n 'clearSavedTerms',\n 'handleFrameMessage',\n 'buildCheckFrameUrl',\n 'buildAuthFrameUrl',\n 'buildResetFrameUrl',\n 'checkKycRequired',\n 'getKycStatus',\n 'startSumSub',\n 'getSessionStatus',\n 'reset',\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\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n /**\n * 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\n/**\n * The shape of a message posted by a Check/Auth frame.\n */\ntype FrameMessage = {\n meta?: { channelId?: string };\n kind?: string;\n payload?: {\n status?:\n | 'active'\n | 'connectionRequired'\n | 'termsAcceptanceRequired'\n | 'pending'\n | 'unavailable'\n | 'failed';\n credentials?: EncryptedCredentialsEnvelope | string;\n customer?: { id?: string };\n };\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, HTTP\n * orchestration (via `KycService`), crypto, and the frame message protocol;\n * platform-specific presentation (WebView/iframe, SumSub SDK) is injected.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n /** Ephemeral X25519 keypair for the frame key exchange (never persisted). */\n readonly #keypair: X25519KeyPair;\n\n /** Auth-frame client token, kept out of state. */\n #authClientToken: string | null = null;\n\n /**\n * Monotonic flow generation. Incremented by {@link reset} so in-flight async\n * work (e.g. the KYC-required check) can detect that it was superseded and\n * avoid writing stale results onto a 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 /**\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 */\n constructor({\n messenger,\n state,\n sumsubLauncher,\n sessionStatusPollIntervalMs = DEFAULT_SESSION_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.#keypair = generateKeyPair();\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 */\n async initialize(params?: {\n email?: string;\n product?: KycProduct;\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 if (IN_PROGRESS_PHASES.includes(this.state.phase)) {\n return;\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.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 const hasTerms =\n Boolean(this.state.termsAcceptedAt) &&\n this.state.acceptedDisclaimerIds.length > 0;\n\n if (hasTerms && this.state.email) {\n await this.#createSession();\n return;\n }\n\n this.#applyUpdate((state) => {\n state.phase = 'terms';\n });\n await this.loadDisclaimers();\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:fetchDisclaimers',\n { country },\n );\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimers = disclaimers;\n state.disclaimersError = null;\n });\n } catch (error) {\n this.#updateIfCurrent(generation, (state) => {\n state.disclaimersError = `Failed to load disclaimers: ${String(error)}`;\n });\n }\n }\n\n /**\n * Captures terms acceptance for the currently loaded disclaimers and creates\n * a session.\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. See\n * {@link initialize} for how the product drives the automatic post\n * authentication continuation.\n */\n async acceptTermsAndStartSession(params?: {\n email?: string;\n product?: KycProduct;\n }): Promise<void> {\n const termsAcceptedAt = new Date().toISOString();\n const disclaimerIds = this.state.disclaimers.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.termsAcceptedAt = termsAcceptedAt;\n state.acceptedDisclaimerIds = disclaimerIds;\n });\n await this.#createSession();\n }\n\n /**\n * Creates a vendor session from the currently stored terms + email.\n */\n async #createSession(): Promise<void> {\n const { email, termsAcceptedAt, acceptedDisclaimerIds } = this.state;\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 `sessionToken` 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.#authClientToken = null;\n this.#applyUpdate((state) => {\n state.error = null;\n state.phase = 'session';\n state.statusMessage = 'Creating session...';\n state.sessionToken = null;\n state.accessToken = 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.sessionToken = sessionToken;\n state.phase = 'check';\n state.statusMessage = 'Authenticating via Check frame...';\n });\n } catch (error) {\n console.error('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 this.#clearAcceptedTerms(state);\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 */\n #clearAcceptedTerms(state: KycControllerState): void {\n state.termsAcceptedAt = null;\n state.acceptedDisclaimerIds = [];\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 const payload = params.message as FrameMessage | undefined;\n\n if (!payload) {\n return {};\n }\n\n if (payload.kind === 'handshake') {\n const channelId = payload.meta?.channelId;\n return { reply: { version: 2, meta: { channelId }, kind: 'ack' } };\n }\n\n if (payload.kind !== 'complete') {\n return {};\n }\n\n const channelId = payload.meta?.channelId;\n\n // Only honor a Check/Auth `complete` for the frame the flow is currently\n // waiting on. This drops stale or duplicate messages — e.g. a late post\n // after `reset()` (phase `idle`) or after the flow already advanced past\n // this frame — so they cannot resurrect tokens or rewind `phase` on a\n // controller that has moved on. Frame messages are external input and,\n // unlike the async steps, are not covered by the `#generation` guard.\n let expectedPhase: KycPhase | null = null;\n if (channelId === CHANNEL_CHECK) {\n expectedPhase = 'check';\n } else if (channelId === CHANNEL_AUTH) {\n expectedPhase = 'auth';\n }\n if (!expectedPhase || this.state.phase !== expectedPhase) {\n return {};\n }\n\n const status = payload.payload?.status;\n const credsEnvelope = payload.payload?.credentials;\n\n const customerId = payload.payload?.customer?.id ?? null;\n if (customerId) {\n this.#applyUpdate((state) => {\n state.moonpayCustomerId = customerId;\n });\n }\n\n if (!status) {\n return {};\n }\n\n let accessToken: string | undefined;\n let clientToken: string | undefined;\n if (credsEnvelope) {\n try {\n const { credentials } = decryptCredentials(\n credsEnvelope,\n this.#keypair.privateKey,\n );\n accessToken = credentials.accessToken;\n clientToken = credentials.clientToken;\n } catch (error) {\n this.#fail(`Failed to decrypt frame credentials: ${String(error)}`);\n return {};\n }\n }\n\n if (channelId === CHANNEL_CHECK) {\n await this.#handleCheckOutcome(status, accessToken, clientToken);\n return {};\n }\n\n // channelId === CHANNEL_AUTH, guaranteed by the expectedPhase guard above.\n await this.#handleAuthOutcome(status, accessToken);\n return {};\n }\n\n /**\n * Applies a Check-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n * @param clientToken - The decrypted client token, if any.\n */\n async #handleCheckOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n clientToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Already authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'connectionRequired' && clientToken) {\n this.#authClientToken = clientToken;\n this.#applyUpdate((state) => {\n state.phase = 'auth';\n state.statusMessage = 'Verify your email via OTP in the Auth frame.';\n });\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Check frame returned status: ${status}`);\n }\n\n /**\n * Applies an Auth-frame outcome.\n *\n * @param status - The frame status.\n * @param accessToken - The decrypted access token, if any.\n */\n async #handleAuthOutcome(\n status: NonNullable<FrameMessage['payload']>['status'],\n accessToken?: string,\n ): Promise<void> {\n if (status === 'active' && accessToken) {\n this.#applyUpdate((state) => {\n state.accessToken = accessToken;\n state.phase = 'form';\n state.statusMessage = 'Authenticated. Review to submit.';\n });\n await this.#continueAfterAuthentication();\n return;\n }\n if (status === 'termsAcceptanceRequired') {\n this.#requireTermsReacceptance();\n return;\n }\n this.#fail(`Auth frame returned status: ${status}`);\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 both\n // outcome handlers move `phase` to `form` before awaiting this method. A\n // duplicate or late `complete` therefore lands after the phase moved on and\n // is dropped before it can start a second continuation. Any writes here are\n // additionally guarded by `#generation` (see `checkKycRequired` /\n // `startSumSub`) so a `reset()` mid-continuation 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 if (!this.state.sessionToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/check-connection`);\n url.searchParams.set('sessionToken', this.state.sessionToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_CHECK);\n url.searchParams.set('skipKyc', 'true');\n return url.toString();\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 if (!this.#authClientToken) {\n return null;\n }\n const url = new URL(`${FRAMES_BASE_URL}/auth`);\n url.searchParams.set('clientToken', this.#authClientToken);\n url.searchParams.set('publicKey', this.#keypair.publicKeyHex);\n url.searchParams.set('channelId', CHANNEL_AUTH);\n return url.toString();\n }\n\n /**\n * Builds the Reset-frame URL.\n *\n * @returns The Reset-frame URL.\n */\n buildResetFrameUrl(): string {\n const url = new URL(`${FRAMES_BASE_URL}/reset`);\n url.searchParams.set('channelId', CHANNEL_RESET);\n return url.toString();\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 { accessToken } = this.state;\n if (!accessToken) {\n this.#fail('Missing accessToken — repeat the authentication step.');\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 { accessToken, country, capabilities: [{ product: params.product }] },\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 * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. requests a per-session wrapping key from the UKYC backend;\n * 2. verifies its `jwtChain` against the Fractal JWKS and confirms the\n * attested session server public 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` and creates\n * the UKYC session (handing over the wrapped key and the token);\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If session creation reports 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\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 // 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 this.#applyUpdate((state) => {\n state.sumsub.status = 'creatingSession';\n state.sumsub.result = null;\n state.sumsub.sessionStatus = null;\n });\n\n const jwtToken = MOCK_JWT_TOKEN;\n\n // Establish a per-session X25519 keypair and exchange our public half for\n // the server's wrapping key. The private half stays on the device and is\n // used to derive the shared secret that seals the data_encryption_key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = x25519.getPublicKey(\n sessionClientPrivateKey,\n );\n const wrappingKey = await this.messenger.call(\n 'KycService:getWrappingKey',\n { sessionClientPublicKey: toBase64Url(sessionClientPublicKey) },\n );\n\n // Verify the jwtChain against Fractal's JWKS, then confirm the returned\n // sessionServerPublicKey matches the value attested inside the verified\n // JWT payload before trusting it for key wrapping.\n const { keys } = await this.messenger.call('KycService:fetchJwks');\n const jwtChainPayload = verifyJwtChain(keys, wrappingKey.jwtChain);\n if (\n jwtChainPayload.sessionServerPublicKeyX !==\n wrappingKey.sessionServerPublicKey.x\n ) {\n throw new Error(\n 'sessionServerPublicKey does not match the verified jwtChain payload (sessionServerPublicKeyX).',\n );\n }\n\n // Derive the data_encryption_key from the local_user_secret and wrap it\n // for the session server. Only the wrapped (encrypted) key ever leaves\n // the device.\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore(),\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionKey = {\n sessionId: wrappingKey.id,\n ...wrapEncryptionKey(\n sessionClientPrivateKey,\n wrappingKey.sessionServerPublicKey.x,\n clientMaterial.dataEncryptionKey,\n ),\n };\n\n // Mint a read-only `ukyc_capability_token` for the session. Only the\n // client holds the signing key derived from `local_user_secret`, so only\n // the client can mint it; scoping it to `read` means it authorizes later\n // storage reads without granting write or delete access.\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n operations: ['read'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n\n const { sessionId, kycStatus, finalStatus } = await this.messenger.call(\n 'KycService:createUkycSession',\n {\n jwtToken,\n vendorMetadata: {\n moonPayAccessToken: this.state.accessToken,\n moonPayUserId: this.state.moonpayCustomerId,\n },\n wrappedEncryptionKey,\n ukycCapabilityToken,\n },\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 (\n kycStatus === KYC_STATUSES.approved &&\n finalStatus === KYC_STATUSES.pending\n ) {\n const stillCurrent = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = 'vendorProcessing';\n state.sumsub.sessionId = sessionId;\n state.statusMessage = VENDOR_PROCESSING_MESSAGE;\n });\n return stillCurrent ? { kycStatus, finalStatus } : {};\n }\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 (next === SUMSUB_COMPLETED_STATUS) {\n reachedCompletion = true;\n }\n this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status =\n next === SUMSUB_COMPLETED_STATUS ? 'complete' : 'inProgress';\n });\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // A resolved `launch` alone is not the final outcome: only a SDK-reported\n // completion is worth polling for a verification decision. Anything else\n // (abandonment, non-success) is `failed` and must not be polled.\n const applied = this.#updateIfCurrent(generation, (state) => {\n state.sumsub.status = reachedCompletion ? 'polling' : 'failed';\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 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 }\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.#authClientToken = null;\n // Stop any session-status polling so a late poll cannot write onto the\n // now-idle controller.\n this.#stopPolling();\n // Invalidate any in-flight async work started before this reset so its\n // results are discarded rather than written onto the now-idle controller.\n this.#generation += 1;\n this.#applyUpdate((state) => {\n state.phase = 'idle';\n state.statusMessage = '';\n state.error = null;\n state.disclaimers = [];\n state.disclaimersError = null;\n state.sessionToken = null;\n state.accessToken = null;\n state.moonpayCustomerId = null;\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 * 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 * 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