@metamask-previews/kyc-controller 0.5.0-preview-ff2ab0583 → 0.6.0-preview-c4789fdf4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0]
11
+
12
+ ### Added
13
+
14
+ - Add the persisted `providerFlowStatus` state field and `KycController:getProviderFlowStatus` messenger action to distinguish provider flows that were submitted, abandoned, or failed ([#10457](https://github.com/MetaMask/core/pull/10457))
15
+
16
+ ### Changed
17
+
18
+ - **BREAKING:** `KycController.launchProviderFlow` and its messenger action now return the durable provider-flow outcome instead of `void` ([#10457](https://github.com/MetaMask/core/pull/10457))
19
+ - Treat a SumSub SDK `Failed` status as `failed` instead of `abandoned` ([#10457](https://github.com/MetaMask/core/pull/10457))
20
+ - Bump `deepmerge` from `^4.2.2` to `^4.3.1` ([#10437](https://github.com/MetaMask/core/pull/10437))
21
+
10
22
  ## [0.5.0]
11
23
 
12
24
  ### Changed
@@ -88,7 +100,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
100
 
89
101
  - Initial Release ([#10145](https://github.com/MetaMask/core/pull/10145))
90
102
 
91
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.5.0...HEAD
103
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.6.0...HEAD
104
+ [0.6.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.5.0...@metamask/kyc-controller@0.6.0
92
105
  [0.5.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.4.0...@metamask/kyc-controller@0.5.0
93
106
  [0.4.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.3.0...@metamask/kyc-controller@0.4.0
94
107
  [0.3.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.2.0...@metamask/kyc-controller@0.3.0
@@ -40,6 +40,15 @@ export type KycControllerGetSessionStatusForVendorAction = {
40
40
  type: `KycController:getSessionStatusForVendor`;
41
41
  handler: KycController['getSessionStatusForVendor'];
42
42
  };
43
+ /**
44
+ * Returns the durable outcome of the identity-provider flow.
45
+ *
46
+ * @returns The latest provider-flow status.
47
+ */
48
+ export type KycControllerGetProviderFlowStatusAction = {
49
+ type: `KycController:getProviderFlowStatus`;
50
+ handler: KycController['getProviderFlowStatus'];
51
+ };
43
52
  /**
44
53
  * Returns the current session status and starts polling when it is not yet
45
54
  * terminal.
@@ -156,7 +165,7 @@ export type KycControllerHasCompletedVendorDisclaimersAction = {
156
165
  * @param params - Optional SDK presentation options.
157
166
  * @param params.locale - BCP-47 locale for the SDK UI.
158
167
  * @param params.debug - Enables SDK debug logging.
159
- * @returns A promise that settles when the provider flow finishes.
168
+ * @returns The durable provider-flow outcome.
160
169
  */
161
170
  export type KycControllerLaunchProviderFlowAction = {
162
171
  type: `KycController:launchProviderFlow`;
@@ -165,5 +174,5 @@ export type KycControllerLaunchProviderFlowAction = {
165
174
  /**
166
175
  * Union of all KycController action types.
167
176
  */
168
- export type KycControllerMethodActions = KycControllerStartSessionAction | KycControllerResetAction | KycControllerClearStateAction | KycControllerGetSessionStatusForVendorAction | KycControllerRefreshSessionStatusAction | KycControllerStartSessionStatusPollingAction | KycControllerFetchSessionDisclaimersAction | KycControllerRecordSessionDisclaimersAction | KycControllerHasCompletedSessionDisclaimersAction | KycControllerFetchVendorDisclaimersAction | KycControllerRecordVendorDisclaimersAction | KycControllerHasCompletedVendorDisclaimersAction | KycControllerLaunchProviderFlowAction;
177
+ export type KycControllerMethodActions = KycControllerStartSessionAction | KycControllerResetAction | KycControllerClearStateAction | KycControllerGetSessionStatusForVendorAction | KycControllerGetProviderFlowStatusAction | KycControllerRefreshSessionStatusAction | KycControllerStartSessionStatusPollingAction | KycControllerFetchSessionDisclaimersAction | KycControllerRecordSessionDisclaimersAction | KycControllerHasCompletedSessionDisclaimersAction | KycControllerFetchVendorDisclaimersAction | KycControllerRecordVendorDisclaimersAction | KycControllerHasCompletedVendorDisclaimersAction | KycControllerLaunchProviderFlowAction;
169
178
  //# sourceMappingURL=KycController-method-action-types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"KycController-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,IAAI,EAAE,4BAA4B,CAAC;IACnC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAC;CACxC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG;IAC1C,IAAI,EAAE,0BAA0B,CAAC;IACjC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACtC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,aAAa,CAAC,2BAA2B,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,uCAAuC,GAAG;IACpD,IAAI,EAAE,oCAAoC,CAAC;IAC3C,OAAO,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;CAChD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,4CAA4C,GAAG;IACzD,IAAI,EAAE,yCAAyC,CAAC;IAChD,OAAO,EAAE,aAAa,CAAC,2BAA2B,CAAC,CAAC;CACrD,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;CACnD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,2CAA2C,GAAG;IACxD,IAAI,EAAE,wCAAwC,CAAC;IAC/C,OAAO,EAAE,aAAa,CAAC,0BAA0B,CAAC,CAAC;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,iDAAiD,GAAG;IAC9D,IAAI,EAAE,8CAA8C,CAAC;IACrD,OAAO,EAAE,aAAa,CAAC,gCAAgC,CAAC,CAAC;CAC1D,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,yCAAyC,GAAG;IACtD,IAAI,EAAE,sCAAsC,CAAC;IAC7C,OAAO,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;CAClD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,0CAA0C,GAAG;IACvD,IAAI,EAAE,uCAAuC,CAAC;IAC9C,OAAO,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;CACnD,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,gDAAgD,GAAG;IAC7D,IAAI,EAAE,6CAA6C,CAAC;IACpD,OAAO,EAAE,aAAa,CAAC,+BAA+B,CAAC,CAAC;CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,kCAAkC,CAAC;IACzC,OAAO,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC9C,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAClC,+BAA+B,GAC/B,wBAAwB,GACxB,6BAA6B,GAC7B,4CAA4C,GAC5C,uCAAuC,GACvC,4CAA4C,GAC5C,0CAA0C,GAC1C,2CAA2C,GAC3C,iDAAiD,GACjD,yCAAyC,GACzC,0CAA0C,GAC1C,gDAAgD,GAChD,qCAAqC,CAAC"}
1
+ {"version":3,"file":"KycController-method-action-types.d.ts","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"KycController-method-action-types.js","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycController } from './KycController.js';\n\n/**\n * Starts a KYC session for the given vendor and email. Reuses a latest\n * vendor session when one exists; otherwise creates a UKYC session.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.email - Account email associated with the session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the current session status and starts polling when it is not yet\n * terminal.\n *\n * @returns The current session status.\n * @throws If there is no session on state.\n */\nexport type KycControllerRefreshSessionStatusAction = {\n type: `KycController:refreshSessionStatus`;\n handler: KycController['refreshSessionStatus'];\n};\n\n/**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The loop stops once\n * `finalStatus` is `approved`, `rejected`, or `retry`, or when\n * {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\nexport type KycControllerStartSessionStatusPollingAction = {\n type: `KycController:startSessionStatusPolling`;\n handler: KycController['startSessionStatusPolling'];\n};\n\n/**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\nexport type KycControllerFetchSessionDisclaimersAction = {\n type: `KycController:fetchSessionDisclaimers`;\n handler: KycController['fetchSessionDisclaimers'];\n};\n\n/**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\nexport type KycControllerRecordSessionDisclaimersAction = {\n type: `KycController:recordSessionDisclaimers`;\n handler: KycController['recordSessionDisclaimers'];\n};\n\n/**\n * Fetches session-scoped disclaimers and reports whether every document is\n * consented and credential reuse was accepted.\n *\n * @returns Whether session disclaimers are complete.\n * @throws If there is no session on state.\n */\nexport type KycControllerHasCompletedSessionDisclaimersAction = {\n type: `KycController:hasCompletedSessionDisclaimers`;\n handler: KycController['hasCompletedSessionDisclaimers'];\n};\n\n/**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\nexport type KycControllerFetchVendorDisclaimersAction = {\n type: `KycController:fetchVendorDisclaimers`;\n handler: KycController['fetchVendorDisclaimers'];\n};\n\n/**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\nexport type KycControllerRecordVendorDisclaimersAction = {\n type: `KycController:recordVendorDisclaimers`;\n handler: KycController['recordVendorDisclaimers'];\n};\n\n/**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\nexport type KycControllerHasCompletedVendorDisclaimersAction = {\n type: `KycController:hasCompletedVendorDisclaimers`;\n handler: KycController['hasCompletedVendorDisclaimers'];\n};\n\n/**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns A promise that settles when the provider flow finishes.\n */\nexport type KycControllerLaunchProviderFlowAction = {\n type: `KycController:launchProviderFlow`;\n handler: KycController['launchProviderFlow'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerStartSessionAction\n | KycControllerResetAction\n | KycControllerClearStateAction\n | KycControllerGetSessionStatusForVendorAction\n | KycControllerRefreshSessionStatusAction\n | KycControllerStartSessionStatusPollingAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerRecordSessionDisclaimersAction\n | KycControllerHasCompletedSessionDisclaimersAction\n | KycControllerFetchVendorDisclaimersAction\n | KycControllerRecordVendorDisclaimersAction\n | KycControllerHasCompletedVendorDisclaimersAction\n | KycControllerLaunchProviderFlowAction;\n"]}
1
+ {"version":3,"file":"KycController-method-action-types.js","sourceRoot":"","sources":["../src/KycController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { KycController } from './KycController.js';\n\n/**\n * Starts a KYC session for the given vendor and email. Reuses a latest\n * vendor session when one exists; otherwise creates a UKYC session.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.email - Account email associated with the session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\nexport type KycControllerGetProviderFlowStatusAction = {\n type: `KycController:getProviderFlowStatus`;\n handler: KycController['getProviderFlowStatus'];\n};\n\n/**\n * Returns the current session status and starts polling when it is not yet\n * terminal.\n *\n * @returns The current session status.\n * @throws If there is no session on state.\n */\nexport type KycControllerRefreshSessionStatusAction = {\n type: `KycController:refreshSessionStatus`;\n handler: KycController['refreshSessionStatus'];\n};\n\n/**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The loop stops once\n * `finalStatus` is `approved`, `rejected`, or `retry`, or when\n * {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\nexport type KycControllerStartSessionStatusPollingAction = {\n type: `KycController:startSessionStatusPolling`;\n handler: KycController['startSessionStatusPolling'];\n};\n\n/**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\nexport type KycControllerFetchSessionDisclaimersAction = {\n type: `KycController:fetchSessionDisclaimers`;\n handler: KycController['fetchSessionDisclaimers'];\n};\n\n/**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\nexport type KycControllerRecordSessionDisclaimersAction = {\n type: `KycController:recordSessionDisclaimers`;\n handler: KycController['recordSessionDisclaimers'];\n};\n\n/**\n * Fetches session-scoped disclaimers and reports whether every document is\n * consented and credential reuse was accepted.\n *\n * @returns Whether session disclaimers are complete.\n * @throws If there is no session on state.\n */\nexport type KycControllerHasCompletedSessionDisclaimersAction = {\n type: `KycController:hasCompletedSessionDisclaimers`;\n handler: KycController['hasCompletedSessionDisclaimers'];\n};\n\n/**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\nexport type KycControllerFetchVendorDisclaimersAction = {\n type: `KycController:fetchVendorDisclaimers`;\n handler: KycController['fetchVendorDisclaimers'];\n};\n\n/**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\nexport type KycControllerRecordVendorDisclaimersAction = {\n type: `KycController:recordVendorDisclaimers`;\n handler: KycController['recordVendorDisclaimers'];\n};\n\n/**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\nexport type KycControllerHasCompletedVendorDisclaimersAction = {\n type: `KycController:hasCompletedVendorDisclaimers`;\n handler: KycController['hasCompletedVendorDisclaimers'];\n};\n\n/**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\nexport type KycControllerLaunchProviderFlowAction = {\n type: `KycController:launchProviderFlow`;\n handler: KycController['launchProviderFlow'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerStartSessionAction\n | KycControllerResetAction\n | KycControllerClearStateAction\n | KycControllerGetSessionStatusForVendorAction\n | KycControllerGetProviderFlowStatusAction\n | KycControllerRefreshSessionStatusAction\n | KycControllerStartSessionStatusPollingAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerRecordSessionDisclaimersAction\n | KycControllerHasCompletedSessionDisclaimersAction\n | KycControllerFetchVendorDisclaimersAction\n | KycControllerRecordVendorDisclaimersAction\n | KycControllerHasCompletedVendorDisclaimersAction\n | KycControllerLaunchProviderFlowAction;\n"]}
@@ -7,6 +7,14 @@ import type { KycServiceMethodActions } from './KycService-method-action-types.j
7
7
  import type { KycSumSubLauncher } from './providers/sumsub.js';
8
8
  import type { KycConsentRecord, KycDisclaimer, KycDisclaimersCatalog, KycProviderDisclaimersAccepted, KycSessionDisclaimers, KycSessionStatus, KycVendor, KycVendorDisclaimersAccepted, KycVendorSigning } from './types.js';
9
9
  export declare const controllerName = "KycController";
10
+ export declare const KYC_PROVIDER_FLOW_STATUSES: readonly ['not_started', 'submitted', 'abandoned', 'failed'];
11
+ /**
12
+ * Durable outcome of the identity-provider flow.
13
+ *
14
+ * Unlike the KYC session's `finalStatus`, this distinguishes a newly-created
15
+ * pending session from a provider flow that the customer actually submitted.
16
+ */
17
+ export type KycProviderFlowStatus = (typeof KYC_PROVIDER_FLOW_STATUSES)[number];
10
18
  /**
11
19
  * Describes the shape of the state object for {@link KycController}.
12
20
  */
@@ -18,6 +26,8 @@ export type KycControllerState = {
18
26
  geoCountry: string | null;
19
27
  /** Latest UKYC session status, or `null` when none has been fetched. */
20
28
  sessionStatus: KycSessionStatus | null;
29
+ /** Last durable identity-provider flow outcome for this session. */
30
+ providerFlowStatus: KycProviderFlowStatus;
21
31
  /**
22
32
  * Persisted vendor-disclaimer acceptance (T&C1) with fixed `moonpay` and
23
33
  * `iron` keys. MoonPay stores only `termsAcceptedAt`; Iron stores
@@ -143,6 +153,12 @@ export declare class KycController extends BaseController<typeof controllerName,
143
153
  * @returns The session status, or `null` when none exists.
144
154
  */
145
155
  getSessionStatusForVendor(vendor: KycVendor): Promise<KycSessionStatus | null>;
156
+ /**
157
+ * Returns the durable outcome of the identity-provider flow.
158
+ *
159
+ * @returns The latest provider-flow status.
160
+ */
161
+ getProviderFlowStatus(): KycProviderFlowStatus;
146
162
  /**
147
163
  * Returns the current session status and starts polling when it is not yet
148
164
  * terminal.
@@ -244,12 +260,12 @@ export declare class KycController extends BaseController<typeof controllerName,
244
260
  * @param params - Optional SDK presentation options.
245
261
  * @param params.locale - BCP-47 locale for the SDK UI.
246
262
  * @param params.debug - Enables SDK debug logging.
247
- * @returns A promise that settles when the provider flow finishes.
263
+ * @returns The durable provider-flow outcome.
248
264
  */
249
265
  launchProviderFlow({ locale, debug, }: {
250
266
  locale?: string;
251
267
  debug?: boolean;
252
- }): Promise<void>;
268
+ }): Promise<KycProviderFlowStatus>;
253
269
  }
254
270
  export {};
255
271
  //# sourceMappingURL=KycController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { BaseController } from '@metamask/base-controller';
2
2
  import { stringToBytes } from '@metamask/utils';
3
3
  import { x25519 } from '@noble/curves/ed25519';
4
4
  import { toBase64Url } from './encoding.js';
5
- import { isSumSubFlowCompleted } from './providers/sumsub.js';
5
+ import { isSumSubFlowCompleted, isSumSubFlowFailed, } from './providers/sumsub.js';
6
6
  import { areSessionDisclaimersCompleted, consentRecordsFromAcceptedList, } from './sessionDisclaimers.js';
7
7
  import { TERMINAL_SESSION_STATUSES } from './types.js';
8
8
  import { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';
@@ -13,6 +13,12 @@ import { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';
13
13
  import { areVendorDisclaimersCompleted, recordVendorDisclaimerAcceptance, } from './vendorDisclaimers.js';
14
14
  // === GENERAL ===
15
15
  export const controllerName = 'KycController';
16
+ export const KYC_PROVIDER_FLOW_STATUSES = [
17
+ 'not_started',
18
+ 'submitted',
19
+ 'abandoned',
20
+ 'failed',
21
+ ];
16
22
  // Lifetime of the read-only `ukyc_capability_token` minted when creating a
17
23
  // UKYC session. The storage-and-auth spec requires the token's `expires_at` to
18
24
  // cover the KYC session's expected lifetime — including the provider journey —
@@ -45,6 +51,12 @@ const kycControllerMetadata = {
45
51
  persist: true,
46
52
  usedInUi: true,
47
53
  },
54
+ providerFlowStatus: {
55
+ includeInDebugSnapshot: true,
56
+ includeInStateLogs: true,
57
+ persist: true,
58
+ usedInUi: true,
59
+ },
48
60
  vendorDisclaimersAccepted: {
49
61
  includeInDebugSnapshot: true,
50
62
  includeInStateLogs: true,
@@ -97,6 +109,7 @@ export function getDefaultKycControllerState() {
97
109
  vendor: null,
98
110
  geoCountry: null,
99
111
  sessionStatus: null,
112
+ providerFlowStatus: 'not_started',
100
113
  vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),
101
114
  providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),
102
115
  idosDisclaimersAccepted: null,
@@ -109,6 +122,7 @@ const MESSENGER_EXPOSED_METHODS = [
109
122
  'reset',
110
123
  'clearState',
111
124
  'getSessionStatusForVendor',
125
+ 'getProviderFlowStatus',
112
126
  'refreshSessionStatus',
113
127
  'startSessionStatusPolling',
114
128
  'fetchSessionDisclaimers',
@@ -181,6 +195,9 @@ export class KycController extends BaseController {
181
195
  state.email = params.email;
182
196
  state.vendor = params.vendor;
183
197
  state.geoCountry = geoCountry;
198
+ if (state.sessionStatus === null) {
199
+ state.providerFlowStatus = 'not_started';
200
+ }
184
201
  });
185
202
  if (this.state.sessionStatus === null) {
186
203
  const sessionStatus = await this.messenger.call('KycService:getSessionStatusForVendor', params.vendor);
@@ -219,6 +236,7 @@ export class KycController extends BaseController {
219
236
  state.vendor = null;
220
237
  state.geoCountry = null;
221
238
  state.sessionStatus = null;
239
+ state.providerFlowStatus = 'not_started';
222
240
  state.vendorDisclaimersAccepted =
223
241
  getDefaultKycVendorDisclaimersAccepted();
224
242
  state.providerDisclaimersAccepted =
@@ -236,6 +254,14 @@ export class KycController extends BaseController {
236
254
  getSessionStatusForVendor(vendor) {
237
255
  return this.messenger.call('KycService:getSessionStatusForVendor', vendor);
238
256
  }
257
+ /**
258
+ * Returns the durable outcome of the identity-provider flow.
259
+ *
260
+ * @returns The latest provider-flow status.
261
+ */
262
+ getProviderFlowStatus() {
263
+ return this.state.providerFlowStatus;
264
+ }
239
265
  /**
240
266
  * Returns the current session status and starts polling when it is not yet
241
267
  * terminal.
@@ -519,7 +545,7 @@ export class KycController extends BaseController {
519
545
  * @param params - Optional SDK presentation options.
520
546
  * @param params.locale - BCP-47 locale for the SDK UI.
521
547
  * @param params.debug - Enables SDK debug logging.
522
- * @returns A promise that settles when the provider flow finishes.
548
+ * @returns The durable provider-flow outcome.
523
549
  */
524
550
  launchProviderFlow({ locale, debug, }) {
525
551
  // Currently only sumsub is supported and must be used for Iron
@@ -551,61 +577,81 @@ export class KycController extends BaseController {
551
577
  * @param params - Optional parameters.
552
578
  * @param params.locale - BCP-47 locale for the SDK UI.
553
579
  * @param params.debug - Enables SDK debug logging.
554
- * @returns The SDK result.
580
+ * @returns The durable provider-flow outcome.
555
581
  */
556
582
  async #launchSumsubFlow(params) {
583
+ const sessionId = this.state.sessionStatus?.id;
584
+ if (!this.#sumsubLauncher.isAvailable() || !sessionId) {
585
+ this.update((state) => {
586
+ state.providerFlowStatus = 'failed';
587
+ });
588
+ return 'failed';
589
+ }
557
590
  try {
558
- if (!this.#sumsubLauncher.isAvailable()) {
559
- throw new Error('SumSub SDK is not available in this runtime.');
591
+ // TODO: check if the sumsub and idos disclaimers are accepted
592
+ const { applicantAccessToken } = await this.messenger.call('KycService:createJourney', sessionId);
593
+ // Track whether the SDK ever reported a successful completion or its own
594
+ // failure. A resolved `launch` alone does not imply success — the
595
+ // applicant may have abandoned the flow, or the SDK may have reported
596
+ // that it could not run.
597
+ let reachedCompletion = false;
598
+ let sdkFailed = false;
599
+ const result = await this.#sumsubLauncher.launch({
600
+ applicantAccessToken,
601
+ onTokenExpiration: async () => {
602
+ const journey = await this.messenger.call('KycService:createJourney', sessionId);
603
+ return journey.applicantAccessToken;
604
+ },
605
+ onStatusChange: (_prev, next) => {
606
+ if (isSumSubFlowCompleted(next)) {
607
+ reachedCompletion = true;
608
+ }
609
+ if (isSumSubFlowFailed(next)) {
610
+ sdkFailed = true;
611
+ }
612
+ },
613
+ locale: params?.locale ?? 'en',
614
+ debug: params?.debug ?? false,
615
+ });
616
+ // Some native SDKs resolve with their final status without first
617
+ // delivering the corresponding state-change callback.
618
+ reachedCompletion ||= isSumSubFlowCompleted(result.status);
619
+ sdkFailed ||= isSumSubFlowFailed(result.status);
620
+ const currentSessionStatus = this.state.sessionStatus;
621
+ if (currentSessionStatus?.id !== sessionId) {
622
+ return 'failed';
560
623
  }
561
- try {
562
- if (!this.state.sessionStatus) {
563
- throw new Error('no session was found');
564
- }
565
- const sessionId = this.state.sessionStatus.id;
566
- // TODO: check if the sumsub and idos disclaimers are accepted
567
- const { applicantAccessToken } = await this.messenger.call('KycService:createJourney', sessionId);
568
- // Track whether the SDK ever reported a successful completion. A resolved
569
- // `launch` alone does not imply success — the applicant may have
570
- // abandoned the flow or the SDK may have reported a non-success outcome.
571
- let reachedCompletion = false;
572
- const result = await this.#sumsubLauncher.launch({
573
- applicantAccessToken,
574
- onTokenExpiration: async () => {
575
- const journey = await this.messenger.call('KycService:createJourney', sessionId);
576
- return journey.applicantAccessToken;
577
- },
578
- onStatusChange: (_prev, next) => {
579
- if (isSumSubFlowCompleted(next)) {
580
- reachedCompletion = true;
581
- }
582
- },
583
- locale: params?.locale ?? 'en',
584
- debug: params?.debug ?? false,
624
+ if (sdkFailed) {
625
+ this.update((state) => {
626
+ state.providerFlowStatus = 'failed';
585
627
  });
586
- // Some native SDKs resolve with their final status without first
587
- // delivering the corresponding state-change callback.
588
- reachedCompletion ||= isSumSubFlowCompleted(result.status);
589
- // Once the SDK completes, the authoritative verification decision comes
590
- // from the UKYC backend, not the SDK result. Fetch session status once.
591
- const currentSessionStatus = this.state.sessionStatus;
592
- if (reachedCompletion && currentSessionStatus) {
593
- // TODO: is this too optimistic?
594
- this.update((state) => {
595
- state.sessionStatus = {
596
- ...currentSessionStatus,
597
- finalStatus: 'pending',
598
- };
599
- });
600
- this.startSessionStatusPolling();
601
- }
628
+ return 'failed';
602
629
  }
603
- catch {
604
- // TODO: Figure out if the sessionAlreadyCompletedError is still needed
630
+ if (reachedCompletion) {
631
+ // Once the SDK completes, the authoritative verification decision comes
632
+ // from the UKYC backend, not the SDK result.
633
+ this.update((state) => {
634
+ state.sessionStatus = {
635
+ ...currentSessionStatus,
636
+ finalStatus: 'pending',
637
+ };
638
+ state.providerFlowStatus = 'submitted';
639
+ });
640
+ this.startSessionStatusPolling();
641
+ return 'submitted';
605
642
  }
643
+ this.update((state) => {
644
+ state.providerFlowStatus = 'abandoned';
645
+ });
646
+ return 'abandoned';
606
647
  }
607
648
  catch {
608
- // Launcher unavailability and session errors currently fail closed.
649
+ if (this.state.sessionStatus?.id === sessionId) {
650
+ this.update((state) => {
651
+ state.providerFlowStatus = 'failed';
652
+ });
653
+ }
654
+ return 'failed';
609
655
  }
610
656
  }
611
657
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n UserStorageControllerPerformGetStorageAction,\n UserStorageControllerPerformSetStorageAction,\n} from '@metamask/profile-sync-controller/user-storage';\nimport { stringToBytes } from '@metamask/utils';\nimport { x25519 } from '@noble/curves/ed25519';\n\nimport { toBase64Url } from './encoding.js';\nimport type { KycControllerMethodActions } from './KycController-method-action-types.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n CapabilityAuthorization,\n EncryptionSchema,\n} from './KycService.js';\nimport { isSumSubFlowCompleted } from './providers/sumsub.js';\nimport type { KycSumSubLauncher } from './providers/sumsub.js';\nimport {\n areSessionDisclaimersCompleted,\n consentRecordsFromAcceptedList,\n} from './sessionDisclaimers.js';\nimport { TERMINAL_SESSION_STATUSES } from './types.js';\nimport type {\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { assertAttestedServerPublicKey } from './ukyc/jwtChain.js';\nimport {\n getOrCreateLocalUserSecret,\n UkycLocalUserSecretStore,\n} from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n areVendorDisclaimersCompleted,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimers.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\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// How often to poll UKYC session status until a terminal `finalStatus`.\nconst SESSION_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\n vendor: KycVendor | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Latest UKYC session status, or `null` when none has been fetched. */\n sessionStatus: KycSessionStatus | null;\n\n // TODO: Check if we need truly need to persist these accepted disclaimers\n /**\n * Persisted vendor-disclaimer acceptance (T&C1) with fixed `moonpay` and\n * `iron` keys. MoonPay stores only `termsAcceptedAt`; Iron stores\n * `disclaimerIds`.\n */\n vendorDisclaimersAccepted: KycVendorDisclaimersAccepted;\n /**\n * KYC-provider disclaimer documents the customer accepted during the last\n * terms acceptance (persisted `{ key, version }` records under `sumsub`).\n * Consents-path vendors require this when resuming a session. `null` for\n * acceptance recorded before this field existed (treated as requiring\n * reacceptance).\n */\n providerDisclaimersAccepted: KycProviderDisclaimersAccepted;\n /**\n * idOS disclaimer documents the customer accepted during the last terms\n * acceptance (persisted `{ key, version }` records). Consents-path vendors\n * require this when resuming a session. `null` for acceptance recorded\n * before this field existed (treated as requiring reacceptance).\n */\n idosDisclaimersAccepted: KycConsentRecord[] | null;\n /**\n * Whether the customer consented to reuse existing idOS credentials\n * during this session. Applied when recording session-scoped disclaimers.\n * Not persisted: a new UKYC session must collect reuse consent again.\n * `null` when never set (treated as `false`).\n */\n credentialReusabilityConsentGiven: boolean | null;\n};\n\nconst kycControllerMetadata = {\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: false,\n },\n vendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sessionStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n vendorDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n providerDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n idosDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n credentialReusabilityConsentGiven: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n} satisfies StateMetadata<KycControllerState>;\n\n/**\n * Constructs the default {@link KycVendorDisclaimersAccepted} value.\n *\n * @returns The default vendor-disclaimer acceptance map.\n */\nexport function getDefaultKycVendorDisclaimersAccepted(): KycVendorDisclaimersAccepted {\n return { moonpay: null, iron: null };\n}\n\n/**\n * Constructs the default {@link KycProviderDisclaimersAccepted} value.\n *\n * @returns The default provider-disclaimer acceptance map.\n */\nexport function getDefaultKycProviderDisclaimersAccepted(): KycProviderDisclaimersAccepted {\n return { sumsub: null };\n}\n\n/**\n * Constructs the default {@link KycController} state.\n *\n * @returns The default state.\n */\nexport function getDefaultKycControllerState(): KycControllerState {\n return {\n email: null,\n vendor: null,\n geoCountry: null,\n sessionStatus: null,\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n };\n}\n\n/**\n * Parameters for {@link KycController.fetchSessionDisclaimers}. Provide\n * exactly one of `sessionId` or `country`.\n */\nexport type FetchSessionDisclaimersParams =\n | {\n /** UKYC session id from `KycService.createUkycSession`. */\n sessionId: string;\n country?: never;\n }\n | {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n sessionId?: never;\n };\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'startSession',\n 'reset',\n 'clearState',\n 'getSessionStatusForVendor',\n 'refreshSessionStatus',\n 'startSessionStatusPolling',\n 'fetchSessionDisclaimers',\n 'recordSessionDisclaimers',\n 'hasCompletedSessionDisclaimers',\n 'fetchVendorDisclaimers',\n 'recordVendorDisclaimers',\n 'hasCompletedVendorDisclaimers',\n 'launchProviderFlow',\n] as const;\n\nexport type KycControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerActions =\n | KycControllerGetStateAction\n | KycControllerMethodActions;\n\ntype AllowedActions =\n | KycServiceMethodActions\n | UserStorageControllerPerformGetStorageAction\n | UserStorageControllerPerformSetStorageAction;\n\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n};\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * `KycController` orchestrates the vendor-backed KYC / identity-verification\n * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per\n * product surface used by ramps and card. It owns all state and HTTP\n * orchestration (via `KycService`), while vendor protocol handling and\n * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n readonly #localUserSecretStore: UkycLocalUserSecretStore;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #sessionStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped when the loop stops so an in-flight fetch\n * neither writes state nor schedules a follow-up.\n */\n #sessionStatusPollToken = 0;\n\n /**\n * Constructs a new {@link KycController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - Partial initial state; merged over defaults.\n * @param options.sumsubLauncher - The platform SumSub launcher adapter.\n */\n constructor({ messenger, state, sumsubLauncher }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#localUserSecretStore = new UkycLocalUserSecretStore(this.messenger);\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Starts a KYC session for the given vendor and email. Reuses a latest\n * vendor session when one exists; otherwise creates a UKYC session.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.email - Account email associated with the session.\n * @returns The current or newly created session status.\n */\n async startSession(params: {\n vendor: KycVendor;\n email: string; // TODO: This will be removed once partnerIdentityTokens are fully ready\n }): Promise<KycSessionStatus> {\n if (this.state.email !== null && this.state.email !== params.email) {\n throw new Error(\n 'KycController already initialized with a different email',\n );\n }\n if (this.state.vendor !== null && this.state.vendor !== params.vendor) {\n throw new Error(\n 'KycController already initialized with a different vendor',\n );\n }\n\n const geoCountry = await this.messenger.call('KycService:getGeoCountry');\n if (\n this.state.geoCountry !== null &&\n this.state.geoCountry !== geoCountry\n ) {\n throw new Error(\n 'KycController already initialized with a different geoCountry',\n );\n }\n\n this.update((state) => {\n state.email = params.email;\n state.vendor = params.vendor;\n state.geoCountry = geoCountry;\n });\n\n if (this.state.sessionStatus === null) {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatusForVendor',\n params.vendor,\n );\n if (sessionStatus !== null) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n // TODO: Probably move this into it's own method? Feels like startSession is a little overloaded.\n // It's assumed that if the session does not exist, the customer does not exist either\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n email: params.email,\n });\n\n return this.#createUkycSession({ vendor: params.vendor, geoCountry });\n }\n // TODO: Should this made a call to check if the session is up-to-date?\n return this.state.sessionStatus;\n // TODO: Should we resume polling here?\n }\n\n /**\n * Stops session-status polling and restores default controller state.\n */\n async reset(): Promise<void> {\n this.#stopSessionStatusPolling();\n this.clearState();\n }\n\n /**\n * Restores the controller to its default state.\n */\n clearState(): void {\n this.#stopSessionStatusPolling();\n this.update((state) => {\n state.email = null;\n state.vendor = null;\n state.geoCountry = null;\n state.sessionStatus = null;\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\n getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n return this.messenger.call('KycService:getSessionStatusForVendor', vendor);\n }\n\n /**\n * Returns the current session status and starts polling when it is not yet\n * terminal.\n *\n * @returns The current session status.\n * @throws If there is no session on state.\n */\n refreshSessionStatus(): KycSessionStatus {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n if (!TERMINAL_SESSION_STATUSES.has(this.state.sessionStatus.finalStatus)) {\n this.startSessionStatusPolling();\n }\n return this.state.sessionStatus;\n }\n\n /**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The loop stops once\n * `finalStatus` is `approved`, `rejected`, or `retry`, or when\n * {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\n startSessionStatusPolling(): void {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n this.#stopSessionStatusPolling();\n const token = this.#sessionStatusPollToken;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n this.#sessionStatusPollTimer = setTimeout(() => {\n this.#sessionStatusPollTimer = null;\n // `tick` swallows its own errors and therefore never rejects.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, SESSION_STATUS_POLL_INTERVAL_MS);\n this.#sessionStatusPollTimer.unref?.();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }\n\n /**\n * Fetches session status for the polled session and records it when it\n * differs from state.\n *\n * @param sessionId - Session the loop started for.\n * @param token - Polling token captured when the loop started.\n * @returns Whether the loop should stop.\n */\n async #pollSessionStatusOnce(\n sessionId: string,\n token: number,\n ): Promise<boolean> {\n try {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n if (this.#sessionStatusPollToken !== token) {\n return true;\n }\n\n // TODO: This check seems fragile\n if (\n JSON.stringify(this.state.sessionStatus) !==\n JSON.stringify(sessionStatus)\n ) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n }\n\n if (TERMINAL_SESSION_STATUSES.has(sessionStatus.finalStatus)) {\n this.#stopSessionStatusPolling();\n return true;\n }\n return false;\n } catch {\n return this.#sessionStatusPollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop.\n */\n #stopSessionStatusPolling(): void {\n this.#sessionStatusPollToken += 1;\n if (this.#sessionStatusPollTimer !== null) {\n clearTimeout(this.#sessionStatusPollTimer);\n this.#sessionStatusPollTimer = null;\n }\n }\n\n /**\n * Creates a UKYC session, wraps the `data_encryption_key` and\n * `ukyc_capability_token` against the returned encryption schemas, and\n * submits both via authorizations. Stores `sumsub.sessionId`.\n * kyc-api returns the existing session if one with the same vendor and canonicalUserId already exists.\n *\n * @param params - Vendor and country used to create the session.\n * @param params.vendor - Identity vendor for the UKYC session.\n * @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.\n * @returns The created session.\n */\n async #createUkycSession(params: {\n vendor: KycVendor;\n geoCountry: string;\n }): Promise<KycSessionStatus> {\n // Establish a per-session X25519 keypair used to seal both secrets. The\n // private half stays on the device; the public half is registered on the\n // session so the server can open later authorizations. Each encryption\n // schema from session creation supplies the matching server public key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n // Residence is the ISO 3166-1 alpha-3 country already resolved for\n // disclaimers / KYC-required; fetch it if this sub-flow started without\n // that earlier step.\n const {\n sessionId,\n encryptionDataKey,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n sessionClientPublicKey,\n residenceCountry: params.geoCountry,\n vendor: params.vendor,\n });\n\n await this.#verifyWrappingKeys(encryptionDataKey, capabilityTokenSchema);\n\n const { wrappedEncryptionDataKey, wrappedUkycCapabilityToken } =\n await this.#generateWrappedAuthorizations(\n sessionClientPrivateKey,\n encryptionDataKey,\n capabilityTokenSchema,\n );\n\n const sessionStatus = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n\n return sessionStatus;\n }\n\n /**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\n async fetchSessionDisclaimers(\n params: FetchSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers | KycDisclaimersCatalog> {\n const { sessionId, country } = params as {\n sessionId?: string;\n country?: string;\n };\n if (sessionId && country) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n if (country) {\n return this.messenger.call(\n 'KycService:fetchSessionDisclaimersByCountry',\n { country },\n );\n }\n\n if (!sessionId) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n return catalog;\n }\n\n /**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\n async recordSessionDisclaimers(params: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: Check if these can simply be mapped to `{key, version}` pairs instead\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n const idOS = consentRecordsFromAcceptedList(\n disclaimers.idOS,\n params.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n disclaimers.kycProvider,\n params.providerDisclaimersAccepted,\n );\n\n try {\n await this.messenger.call('KycService:submitSessionDisclaimers', {\n sessionId: this.state.sessionStatus.id,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n params.credentialReusabilityConsentGiven,\n });\n } catch {\n // A 409 means the session already recorded these consents.\n }\n this.update((state) => {\n // TODO: This shouldn't be hardcoded to sumsub\n state.providerDisclaimersAccepted.sumsub =\n params.providerDisclaimersAccepted;\n state.idosDisclaimersAccepted = params.idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n params.credentialReusabilityConsentGiven;\n });\n }\n\n /**\n * Fetches session-scoped disclaimers and reports whether every document is\n * consented and credential reuse was accepted.\n *\n * @returns Whether session disclaimers are complete.\n * @throws If there is no session on state.\n */\n async hasCompletedSessionDisclaimers(): Promise<boolean> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n // TODO: validate if this shorcut check is sufficient\n // return this.state.sessionStatus.consentStatus === 'given';\n\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n return areSessionDisclaimersCompleted(disclaimers);\n }\n\n /**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\n async fetchVendorDisclaimers(params: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n return this.messenger.call('KycService:fetchVendorDisclaimers', params);\n }\n\n /**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\n async recordVendorDisclaimers(params: {\n disclaimerIds: string[];\n }): Promise<KycVendorSigning[]> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n\n if (!this.state.email) {\n throw new Error('No email was found');\n }\n\n const { vendor } = this.state;\n\n const signings = await this.messenger.call(\n 'KycService:submitVendorDisclaimers',\n {\n vendor,\n disclaimerIds: params.disclaimerIds,\n },\n );\n\n // TODO: this only works for Iron right now\n this.update((state) => {\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n vendor,\n {\n disclaimerIds: params.disclaimerIds,\n },\n );\n });\n\n return signings;\n }\n\n /**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\n async hasCompletedVendorDisclaimers(): Promise<boolean> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n if (!this.state.geoCountry) {\n throw new Error('No geoCountry was found');\n }\n\n const fetched = await this.fetchVendorDisclaimers({\n vendor: this.state.vendor,\n country: this.state.geoCountry,\n });\n\n // TODO: this only works for Iron right now\n return areVendorDisclaimersCompleted(\n this.state.vendorDisclaimersAccepted,\n this.state.vendor,\n fetched,\n );\n }\n\n /**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns A promise that settles when the provider flow finishes.\n */\n launchProviderFlow({\n locale,\n debug,\n }: {\n locale?: string;\n debug?: boolean;\n }): Promise<void> {\n // Currently only sumsub is supported and must be used for Iron\n return this.#launchSumsubFlow({ locale, debug });\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\n *\n * @param params - Optional parameters.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The SDK result.\n */\n async #launchSumsubFlow(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<void> {\n try {\n if (!this.#sumsubLauncher.isAvailable()) {\n throw new Error('SumSub SDK is not available in this runtime.');\n }\n\n try {\n if (!this.state.sessionStatus) {\n throw new Error('no session was found');\n }\n\n const sessionId = this.state.sessionStatus.id;\n\n // TODO: check if the sumsub and idos disclaimers are accepted\n\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\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 const journey = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return journey.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // Some native SDKs resolve with their final status without first\n // delivering the corresponding state-change callback.\n reachedCompletion ||= isSumSubFlowCompleted(result.status);\n\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result. Fetch session status once.\n const currentSessionStatus = this.state.sessionStatus;\n if (reachedCompletion && currentSessionStatus) {\n // TODO: is this too optimistic?\n this.update((state) => {\n state.sessionStatus = {\n ...currentSessionStatus,\n finalStatus: 'pending',\n };\n });\n this.startSessionStatusPolling();\n }\n } catch {\n // TODO: Figure out if the sessionAlreadyCompletedError is still needed\n }\n } catch {\n // Launcher unavailability and session errors currently fail closed.\n }\n }\n\n /**\n * Verifies each schema's jwtChain against the matching issuer JWKS, then\n * confirms the returned server public key matches the value attested inside\n * the verified JWT payload before trusting it for wrapping.\n * `encryptionDataKey` is attested by the idOS enclave; `ukycCapabilityToken`\n * by the idOS relay.\n *\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n */\n async #verifyWrappingKeys(\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<void> {\n const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] =\n await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n }\n\n /**\n * Derives the `data_encryption_key` from the `local_user_secret`, mints a\n * capability token, and wraps both for the session server. Only the wrapped\n * (encrypted) material ever leaves the device.\n *\n * Only the client holds the signing key derived from `local_user_secret`, so\n * only the client can mint the token.\n *\n * @param sessionClientPrivateKey - Per-session X25519 private key used to\n * seal both secrets.\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n * @returns The wrapped encryption key and capability token.\n */\n async #generateWrappedAuthorizations(\n sessionClientPrivateKey: Uint8Array,\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<{\n wrappedEncryptionDataKey: CapabilityAuthorization;\n wrappedUkycCapabilityToken: CapabilityAuthorization;\n }> {\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore,\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionDataKey = wrapEncryptionKey(\n sessionClientPrivateKey,\n encryptionDataKey.serverPublicKey.x,\n clientMaterial.dataEncryptionKey,\n );\n\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write\n operations: ['read', 'write'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n const wrappedUkycCapabilityToken = wrapEncryptionKey(\n sessionClientPrivateKey,\n capabilityTokenSchema.serverPublicKey.x,\n stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)),\n );\n\n return { wrappedEncryptionDataKey, wrappedUkycCapabilityToken };\n }\n}\n"]}
1
+ {"version":3,"file":"KycController.js","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n 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 { stringToBytes } from '@metamask/utils';\nimport { x25519 } from '@noble/curves/ed25519';\n\nimport { toBase64Url } from './encoding.js';\nimport type { KycControllerMethodActions } from './KycController-method-action-types.js';\nimport type { KycServiceMethodActions } from './KycService-method-action-types.js';\nimport type {\n CapabilityAuthorization,\n EncryptionSchema,\n} from './KycService.js';\nimport {\n isSumSubFlowCompleted,\n isSumSubFlowFailed,\n} from './providers/sumsub.js';\nimport type { KycSumSubLauncher } from './providers/sumsub.js';\nimport {\n areSessionDisclaimersCompleted,\n consentRecordsFromAcceptedList,\n} from './sessionDisclaimers.js';\nimport { TERMINAL_SESSION_STATUSES } from './types.js';\nimport type {\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nimport { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';\nimport { assertAttestedServerPublicKey } from './ukyc/jwtChain.js';\nimport {\n getOrCreateLocalUserSecret,\n UkycLocalUserSecretStore,\n} from './ukyc/localUserSecret.js';\nimport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nimport { wrapEncryptionKey } from './ukyc/wrapEncryptionKey.js';\nimport {\n areVendorDisclaimersCompleted,\n recordVendorDisclaimerAcceptance,\n} from './vendorDisclaimers.js';\n\n// === GENERAL ===\n\nexport const controllerName = 'KycController';\n\nexport const KYC_PROVIDER_FLOW_STATUSES = [\n 'not_started',\n 'submitted',\n 'abandoned',\n 'failed',\n] as const;\n\n/**\n * Durable outcome of the identity-provider flow.\n *\n * Unlike the KYC session's `finalStatus`, this distinguishes a newly-created\n * pending session from a provider flow that the customer actually submitted.\n */\nexport type KycProviderFlowStatus = (typeof KYC_PROVIDER_FLOW_STATUSES)[number];\n\n// Lifetime of the read-only `ukyc_capability_token` minted when creating a\n// UKYC session. The storage-and-auth spec requires the token's `expires_at` to\n// cover the KYC session's expected lifetime — including the provider journey —\n// rather than a fixed short window, so this is a session-scoped window.\nconst UKYC_CAPABILITY_TOKEN_TTL_MS = 4 * 60 * 60 * 1000;\n\n// How often to poll UKYC session status until a terminal `finalStatus`.\nconst SESSION_STATUS_POLL_INTERVAL_MS = 15_000;\n\n// === STATE ===\n\n/**\n * Describes the shape of the state object for {@link KycController}.\n */\nexport type KycControllerState = {\n /** Email associated with the session (sourced from the account). */\n email: string | null;\n\n vendor: KycVendor | null;\n\n /** Resolved ISO 3166-1 alpha-3 country code. */\n geoCountry: string | null;\n\n /** Latest UKYC session status, or `null` when none has been fetched. */\n sessionStatus: KycSessionStatus | null;\n\n /** Last durable identity-provider flow outcome for this session. */\n providerFlowStatus: KycProviderFlowStatus;\n\n // TODO: Check if we need truly need to persist these accepted disclaimers\n /**\n * Persisted vendor-disclaimer acceptance (T&C1) with fixed `moonpay` and\n * `iron` keys. MoonPay stores only `termsAcceptedAt`; Iron stores\n * `disclaimerIds`.\n */\n vendorDisclaimersAccepted: KycVendorDisclaimersAccepted;\n /**\n * KYC-provider disclaimer documents the customer accepted during the last\n * terms acceptance (persisted `{ key, version }` records under `sumsub`).\n * Consents-path vendors require this when resuming a session. `null` for\n * acceptance recorded before this field existed (treated as requiring\n * reacceptance).\n */\n providerDisclaimersAccepted: KycProviderDisclaimersAccepted;\n /**\n * idOS disclaimer documents the customer accepted during the last terms\n * acceptance (persisted `{ key, version }` records). Consents-path vendors\n * require this when resuming a session. `null` for acceptance recorded\n * before this field existed (treated as requiring reacceptance).\n */\n idosDisclaimersAccepted: KycConsentRecord[] | null;\n /**\n * Whether the customer consented to reuse existing idOS credentials\n * during this session. Applied when recording session-scoped disclaimers.\n * Not persisted: a new UKYC session must collect reuse consent again.\n * `null` when never set (treated as `false`).\n */\n credentialReusabilityConsentGiven: boolean | null;\n};\n\nconst kycControllerMetadata = {\n email: {\n includeInDebugSnapshot: false,\n includeInStateLogs: false,\n persist: true,\n usedInUi: false,\n },\n vendor: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n geoCountry: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n sessionStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n providerFlowStatus: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: true,\n },\n vendorDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n providerDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n idosDisclaimersAccepted: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n credentialReusabilityConsentGiven: {\n includeInDebugSnapshot: true,\n includeInStateLogs: true,\n persist: true,\n usedInUi: false,\n },\n} satisfies StateMetadata<KycControllerState>;\n\n/**\n * Constructs the default {@link KycVendorDisclaimersAccepted} value.\n *\n * @returns The default vendor-disclaimer acceptance map.\n */\nexport function getDefaultKycVendorDisclaimersAccepted(): KycVendorDisclaimersAccepted {\n return { moonpay: null, iron: null };\n}\n\n/**\n * Constructs the default {@link KycProviderDisclaimersAccepted} value.\n *\n * @returns The default provider-disclaimer acceptance map.\n */\nexport function getDefaultKycProviderDisclaimersAccepted(): KycProviderDisclaimersAccepted {\n return { sumsub: null };\n}\n\n/**\n * Constructs the default {@link KycController} state.\n *\n * @returns The default state.\n */\nexport function getDefaultKycControllerState(): KycControllerState {\n return {\n email: null,\n vendor: null,\n geoCountry: null,\n sessionStatus: null,\n providerFlowStatus: 'not_started',\n vendorDisclaimersAccepted: getDefaultKycVendorDisclaimersAccepted(),\n providerDisclaimersAccepted: getDefaultKycProviderDisclaimersAccepted(),\n idosDisclaimersAccepted: null,\n credentialReusabilityConsentGiven: null,\n };\n}\n\n/**\n * Parameters for {@link KycController.fetchSessionDisclaimers}. Provide\n * exactly one of `sessionId` or `country`.\n */\nexport type FetchSessionDisclaimersParams =\n | {\n /** UKYC session id from `KycService.createUkycSession`. */\n sessionId: string;\n country?: never;\n }\n | {\n /** ISO 3166-1 alpha-3 country code for `GET /disclaimers?country=`. */\n country: string;\n sessionId?: never;\n };\n\n// === MESSENGER ===\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'startSession',\n 'reset',\n 'clearState',\n 'getSessionStatusForVendor',\n 'getProviderFlowStatus',\n 'refreshSessionStatus',\n 'startSessionStatusPolling',\n 'fetchSessionDisclaimers',\n 'recordSessionDisclaimers',\n 'hasCompletedSessionDisclaimers',\n 'fetchVendorDisclaimers',\n 'recordVendorDisclaimers',\n 'hasCompletedVendorDisclaimers',\n 'launchProviderFlow',\n] as const;\n\nexport type KycControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerActions =\n | KycControllerGetStateAction\n | KycControllerMethodActions;\n\ntype AllowedActions =\n | KycServiceMethodActions\n | UserStorageControllerPerformGetStorageAction\n | UserStorageControllerPerformSetStorageAction;\n\nexport type KycControllerStateChangeEvent = ControllerStateChangeEvent<\n typeof controllerName,\n KycControllerState\n>;\n\nexport type KycControllerEvents = KycControllerStateChangeEvent;\n\ntype AllowedEvents = never;\n\nexport type KycControllerMessenger = Messenger<\n typeof controllerName,\n KycControllerActions | AllowedActions,\n KycControllerEvents | AllowedEvents\n>;\n\n/**\n * Options for constructing a {@link KycController}.\n */\nexport type KycControllerOptions = {\n messenger: KycControllerMessenger;\n state?: Partial<KycControllerState>;\n /**\n * Platform adapter that presents the SumSub SDK. Injected by each client so\n * the controller stays platform-agnostic.\n */\n sumsubLauncher: KycSumSubLauncher;\n};\n\n// === CONTROLLER DEFINITION ===\n\n/**\n * `KycController` orchestrates the vendor-backed KYC / identity-verification\n * flow (MoonPay identity + SumSub documents) behind a vendor-neutral, per\n * product surface used by ramps and card. It owns all state and HTTP\n * orchestration (via `KycService`), while vendor protocol handling and\n * platform-specific presentation (WebView/iframe, SumSub SDK) are delegated.\n */\nexport class KycController extends BaseController<\n typeof controllerName,\n KycControllerState,\n KycControllerMessenger\n> {\n readonly #sumsubLauncher: KycSumSubLauncher;\n\n readonly #localUserSecretStore: UkycLocalUserSecretStore;\n\n /** Handle for the scheduled next session-status poll, or `null`. */\n #sessionStatusPollTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Monotonic polling token. Bumped when the loop stops so an in-flight fetch\n * neither writes state nor schedules a follow-up.\n */\n #sessionStatusPollToken = 0;\n\n /**\n * Constructs a new {@link KycController}.\n *\n * @param options - The constructor options.\n * @param options.messenger - The messenger suited for this controller.\n * @param options.state - Partial initial state; merged over defaults.\n * @param options.sumsubLauncher - The platform SumSub launcher adapter.\n */\n constructor({ messenger, state, sumsubLauncher }: KycControllerOptions) {\n super({\n messenger,\n metadata: kycControllerMetadata,\n name: controllerName,\n state: { ...getDefaultKycControllerState(), ...state },\n });\n\n this.#sumsubLauncher = sumsubLauncher;\n this.#localUserSecretStore = new UkycLocalUserSecretStore(this.messenger);\n\n this.messenger.registerMethodActionHandlers(\n this,\n MESSENGER_EXPOSED_METHODS,\n );\n }\n\n /**\n * Starts a KYC session for the given vendor and email. Reuses a latest\n * vendor session when one exists; otherwise creates a UKYC session.\n *\n * @param params - The session parameters.\n * @param params.vendor - Identity vendor for the session.\n * @param params.email - Account email associated with the session.\n * @returns The current or newly created session status.\n */\n async startSession(params: {\n vendor: KycVendor;\n email: string; // TODO: This will be removed once partnerIdentityTokens are fully ready\n }): Promise<KycSessionStatus> {\n if (this.state.email !== null && this.state.email !== params.email) {\n throw new Error(\n 'KycController already initialized with a different email',\n );\n }\n if (this.state.vendor !== null && this.state.vendor !== params.vendor) {\n throw new Error(\n 'KycController already initialized with a different vendor',\n );\n }\n\n const geoCountry = await this.messenger.call('KycService:getGeoCountry');\n if (\n this.state.geoCountry !== null &&\n this.state.geoCountry !== geoCountry\n ) {\n throw new Error(\n 'KycController already initialized with a different geoCountry',\n );\n }\n\n this.update((state) => {\n state.email = params.email;\n state.vendor = params.vendor;\n state.geoCountry = geoCountry;\n if (state.sessionStatus === null) {\n state.providerFlowStatus = 'not_started';\n }\n });\n\n if (this.state.sessionStatus === null) {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatusForVendor',\n params.vendor,\n );\n if (sessionStatus !== null) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n return sessionStatus;\n }\n\n // TODO: Probably move this into it's own method? Feels like startSession is a little overloaded.\n // It's assumed that if the session does not exist, the customer does not exist either\n await this.messenger.call('KycService:createVendorCustomer', {\n vendor: params.vendor,\n email: params.email,\n });\n\n return this.#createUkycSession({ vendor: params.vendor, geoCountry });\n }\n // TODO: Should this made a call to check if the session is up-to-date?\n return this.state.sessionStatus;\n // TODO: Should we resume polling here?\n }\n\n /**\n * Stops session-status polling and restores default controller state.\n */\n async reset(): Promise<void> {\n this.#stopSessionStatusPolling();\n this.clearState();\n }\n\n /**\n * Restores the controller to its default state.\n */\n clearState(): void {\n this.#stopSessionStatusPolling();\n this.update((state) => {\n state.email = null;\n state.vendor = null;\n state.geoCountry = null;\n state.sessionStatus = null;\n state.providerFlowStatus = 'not_started';\n state.vendorDisclaimersAccepted =\n getDefaultKycVendorDisclaimersAccepted();\n state.providerDisclaimersAccepted =\n getDefaultKycProviderDisclaimersAccepted();\n state.idosDisclaimersAccepted = null;\n state.credentialReusabilityConsentGiven = null;\n });\n }\n\n /**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\n getSessionStatusForVendor(\n vendor: KycVendor,\n ): Promise<KycSessionStatus | null> {\n return this.messenger.call('KycService:getSessionStatusForVendor', vendor);\n }\n\n /**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\n getProviderFlowStatus(): KycProviderFlowStatus {\n return this.state.providerFlowStatus;\n }\n\n /**\n * Returns the current session status and starts polling when it is not yet\n * terminal.\n *\n * @returns The current session status.\n * @throws If there is no session on state.\n */\n refreshSessionStatus(): KycSessionStatus {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n if (!TERMINAL_SESSION_STATUSES.has(this.state.sessionStatus.finalStatus)) {\n this.startSessionStatusPolling();\n }\n return this.state.sessionStatus;\n }\n\n /**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The loop stops once\n * `finalStatus` is `approved`, `rejected`, or `retry`, or when\n * {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\n startSessionStatusPolling(): void {\n const sessionId = this.state.sessionStatus?.id;\n if (!sessionId) {\n throw new Error('No session was found');\n }\n\n this.#stopSessionStatusPolling();\n const token = this.#sessionStatusPollToken;\n\n const tick = async (): Promise<void> => {\n const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);\n if (shouldStop) {\n return;\n }\n this.#sessionStatusPollTimer = setTimeout(() => {\n this.#sessionStatusPollTimer = null;\n // `tick` swallows its own errors and therefore never rejects.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }, SESSION_STATUS_POLL_INTERVAL_MS);\n this.#sessionStatusPollTimer.unref?.();\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n tick();\n }\n\n /**\n * Fetches session status for the polled session and records it when it\n * differs from state.\n *\n * @param sessionId - Session the loop started for.\n * @param token - Polling token captured when the loop started.\n * @returns Whether the loop should stop.\n */\n async #pollSessionStatusOnce(\n sessionId: string,\n token: number,\n ): Promise<boolean> {\n try {\n const sessionStatus = await this.messenger.call(\n 'KycService:getSessionStatus',\n { sessionId },\n );\n if (this.#sessionStatusPollToken !== token) {\n return true;\n }\n\n // TODO: This check seems fragile\n if (\n JSON.stringify(this.state.sessionStatus) !==\n JSON.stringify(sessionStatus)\n ) {\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n }\n\n if (TERMINAL_SESSION_STATUSES.has(sessionStatus.finalStatus)) {\n this.#stopSessionStatusPolling();\n return true;\n }\n return false;\n } catch {\n return this.#sessionStatusPollToken !== token;\n }\n }\n\n /**\n * Stops the session-status polling loop.\n */\n #stopSessionStatusPolling(): void {\n this.#sessionStatusPollToken += 1;\n if (this.#sessionStatusPollTimer !== null) {\n clearTimeout(this.#sessionStatusPollTimer);\n this.#sessionStatusPollTimer = null;\n }\n }\n\n /**\n * Creates a UKYC session, wraps the `data_encryption_key` and\n * `ukyc_capability_token` against the returned encryption schemas, and\n * submits both via authorizations. Stores `sumsub.sessionId`.\n * kyc-api returns the existing session if one with the same vendor and canonicalUserId already exists.\n *\n * @param params - Vendor and country used to create the session.\n * @param params.vendor - Identity vendor for the UKYC session.\n * @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.\n * @returns The created session.\n */\n async #createUkycSession(params: {\n vendor: KycVendor;\n geoCountry: string;\n }): Promise<KycSessionStatus> {\n // Establish a per-session X25519 keypair used to seal both secrets. The\n // private half stays on the device; the public half is registered on the\n // session so the server can open later authorizations. Each encryption\n // schema from session creation supplies the matching server public key.\n const sessionClientPrivateKey = x25519.utils.randomSecretKey();\n const sessionClientPublicKey = toBase64Url(\n x25519.getPublicKey(sessionClientPrivateKey),\n );\n // Residence is the ISO 3166-1 alpha-3 country already resolved for\n // disclaimers / KYC-required; fetch it if this sub-flow started without\n // that earlier step.\n const {\n sessionId,\n encryptionDataKey,\n ukycCapabilityToken: capabilityTokenSchema,\n } = await this.messenger.call('KycService:createUkycSession', {\n sessionClientPublicKey,\n residenceCountry: params.geoCountry,\n vendor: params.vendor,\n });\n\n await this.#verifyWrappingKeys(encryptionDataKey, capabilityTokenSchema);\n\n const { wrappedEncryptionDataKey, wrappedUkycCapabilityToken } =\n await this.#generateWrappedAuthorizations(\n sessionClientPrivateKey,\n encryptionDataKey,\n capabilityTokenSchema,\n );\n\n const sessionStatus = await this.messenger.call(\n 'KycService:setAuthorizations',\n {\n sessionId,\n wrappedEncryptionDataKey,\n wrappedUkycCapabilityToken,\n },\n );\n\n this.update((state) => {\n state.sessionStatus = sessionStatus;\n });\n\n return sessionStatus;\n }\n\n /**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\n async fetchSessionDisclaimers(\n params: FetchSessionDisclaimersParams,\n ): Promise<KycSessionDisclaimers | KycDisclaimersCatalog> {\n const { sessionId, country } = params as {\n sessionId?: string;\n country?: string;\n };\n if (sessionId && country) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n if (country) {\n return this.messenger.call(\n 'KycService:fetchSessionDisclaimersByCountry',\n { country },\n );\n }\n\n if (!sessionId) {\n throw new Error(\n 'KycController.fetchSessionDisclaimers: provide exactly one of sessionId or country.',\n );\n }\n\n const catalog = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId },\n );\n return catalog;\n }\n\n /**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\n async recordSessionDisclaimers(params: {\n providerDisclaimersAccepted: KycConsentRecord[];\n idosDisclaimersAccepted: KycConsentRecord[];\n credentialReusabilityConsentGiven: boolean;\n }): Promise<void> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n\n // TODO: Check if these can simply be mapped to `{key, version}` pairs instead\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n const idOS = consentRecordsFromAcceptedList(\n disclaimers.idOS,\n params.idosDisclaimersAccepted,\n );\n const kycProvider = consentRecordsFromAcceptedList(\n disclaimers.kycProvider,\n params.providerDisclaimersAccepted,\n );\n\n try {\n await this.messenger.call('KycService:submitSessionDisclaimers', {\n sessionId: this.state.sessionStatus.id,\n idOS,\n kycProvider,\n credentialReusabilityConsentGiven:\n params.credentialReusabilityConsentGiven,\n });\n } catch {\n // A 409 means the session already recorded these consents.\n }\n this.update((state) => {\n // TODO: This shouldn't be hardcoded to sumsub\n state.providerDisclaimersAccepted.sumsub =\n params.providerDisclaimersAccepted;\n state.idosDisclaimersAccepted = params.idosDisclaimersAccepted;\n state.credentialReusabilityConsentGiven =\n params.credentialReusabilityConsentGiven;\n });\n }\n\n /**\n * Fetches session-scoped disclaimers and reports whether every document is\n * consented and credential reuse was accepted.\n *\n * @returns Whether session disclaimers are complete.\n * @throws If there is no session on state.\n */\n async hasCompletedSessionDisclaimers(): Promise<boolean> {\n if (!this.state.sessionStatus) {\n throw new Error('No session was found');\n }\n // TODO: validate if this shorcut check is sufficient\n // return this.state.sessionStatus.consentStatus === 'given';\n\n const disclaimers = await this.messenger.call(\n 'KycService:fetchSessionDisclaimersBySessionId',\n { sessionId: this.state.sessionStatus.id },\n );\n\n return areSessionDisclaimersCompleted(disclaimers);\n }\n\n /**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\n async fetchVendorDisclaimers(params: {\n vendor?: KycVendor;\n country: string;\n }): Promise<KycDisclaimer[]> {\n return this.messenger.call('KycService:fetchVendorDisclaimers', params);\n }\n\n /**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\n async recordVendorDisclaimers(params: {\n disclaimerIds: string[];\n }): Promise<KycVendorSigning[]> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n\n if (!this.state.email) {\n throw new Error('No email was found');\n }\n\n const { vendor } = this.state;\n\n const signings = await this.messenger.call(\n 'KycService:submitVendorDisclaimers',\n {\n vendor,\n disclaimerIds: params.disclaimerIds,\n },\n );\n\n // TODO: this only works for Iron right now\n this.update((state) => {\n state.vendorDisclaimersAccepted = recordVendorDisclaimerAcceptance(\n state.vendorDisclaimersAccepted,\n vendor,\n {\n disclaimerIds: params.disclaimerIds,\n },\n );\n });\n\n return signings;\n }\n\n /**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\n async hasCompletedVendorDisclaimers(): Promise<boolean> {\n if (!this.state.vendor) {\n throw new Error('No vendor was found');\n }\n if (!this.state.geoCountry) {\n throw new Error('No geoCountry was found');\n }\n\n const fetched = await this.fetchVendorDisclaimers({\n vendor: this.state.vendor,\n country: this.state.geoCountry,\n });\n\n // TODO: this only works for Iron right now\n return areVendorDisclaimersCompleted(\n this.state.vendorDisclaimersAccepted,\n this.state.vendor,\n fetched,\n );\n }\n\n /**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n launchProviderFlow({\n locale,\n debug,\n }: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n // Currently only sumsub is supported and must be used for Iron\n return this.#launchSumsubFlow({ locale, debug });\n }\n\n /**\n * Runs the SumSub document-verification sub-flow end to end:\n *\n * 1. creates a UKYC session, receiving per-secret encryption schemas;\n * 2. verifies the `encryptionDataKey` schema's `jwtChain` against the\n * idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against\n * the idOS relay JWKS, then confirms each attested session server public\n * key;\n * 3. derives the `data_encryption_key` from the wallet's UKYC\n * `local_user_secret` and wraps it for the session server;\n * 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the\n * same way as the encryption key, and submits both via authorizations;\n * 5. fetches the SumSub applicant access token; and\n * 6. presents the SDK via the injected launcher.\n *\n * If a UKYC session already exists (the consents path creates it before\n * recording session disclaimers), steps 1–4 are skipped.\n *\n * If authorizations report the applicant is already approved on the relay\n * while the vendor is still finalizing (`kycStatus: approved`,\n * `finalStatus: pending`), the sub-flow stops at step 4 with a\n * `vendorProcessing` status and a message rather than launching the SDK.\n *\n * @param params - Optional parameters.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\n async #launchSumsubFlow(params?: {\n locale?: string;\n debug?: boolean;\n }): Promise<KycProviderFlowStatus> {\n const sessionId = this.state.sessionStatus?.id;\n if (!this.#sumsubLauncher.isAvailable() || !sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n try {\n // TODO: check if the sumsub and idos disclaimers are accepted\n const { applicantAccessToken } = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n\n // Track whether the SDK ever reported a successful completion or its own\n // failure. A resolved `launch` alone does not imply success — the\n // applicant may have abandoned the flow, or the SDK may have reported\n // that it could not run.\n let reachedCompletion = false;\n let sdkFailed = false;\n\n const result = await this.#sumsubLauncher.launch({\n applicantAccessToken,\n onTokenExpiration: async () => {\n const journey = await this.messenger.call(\n 'KycService:createJourney',\n sessionId,\n );\n return journey.applicantAccessToken;\n },\n onStatusChange: (_prev, next) => {\n if (isSumSubFlowCompleted(next)) {\n reachedCompletion = true;\n }\n if (isSumSubFlowFailed(next)) {\n sdkFailed = true;\n }\n },\n locale: params?.locale ?? 'en',\n debug: params?.debug ?? false,\n });\n\n // Some native SDKs resolve with their final status without first\n // delivering the corresponding state-change callback.\n reachedCompletion ||= isSumSubFlowCompleted(result.status);\n sdkFailed ||= isSumSubFlowFailed(result.status);\n\n const currentSessionStatus = this.state.sessionStatus;\n if (currentSessionStatus?.id !== sessionId) {\n return 'failed';\n }\n\n if (sdkFailed) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n return 'failed';\n }\n\n if (reachedCompletion) {\n // Once the SDK completes, the authoritative verification decision comes\n // from the UKYC backend, not the SDK result.\n this.update((state) => {\n state.sessionStatus = {\n ...currentSessionStatus,\n finalStatus: 'pending',\n };\n state.providerFlowStatus = 'submitted';\n });\n this.startSessionStatusPolling();\n return 'submitted';\n }\n\n this.update((state) => {\n state.providerFlowStatus = 'abandoned';\n });\n return 'abandoned';\n } catch {\n if (this.state.sessionStatus?.id === sessionId) {\n this.update((state) => {\n state.providerFlowStatus = 'failed';\n });\n }\n return 'failed';\n }\n }\n\n /**\n * Verifies each schema's jwtChain against the matching issuer JWKS, then\n * confirms the returned server public key matches the value attested inside\n * the verified JWT payload before trusting it for wrapping.\n * `encryptionDataKey` is attested by the idOS enclave; `ukycCapabilityToken`\n * by the idOS relay.\n *\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n */\n async #verifyWrappingKeys(\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<void> {\n const [{ keys: idosEnclaveKeys }, { keys: idosRelayKeys }] =\n await Promise.all([\n this.messenger.call('KycService:fetchIdosEnclaveJwks'),\n this.messenger.call('KycService:fetchIdosRelayJwks'),\n ]);\n assertAttestedServerPublicKey(idosEnclaveKeys, encryptionDataKey);\n assertAttestedServerPublicKey(idosRelayKeys, capabilityTokenSchema);\n }\n\n /**\n * Derives the `data_encryption_key` from the `local_user_secret`, mints a\n * capability token, and wraps both for the session server. Only the wrapped\n * (encrypted) material ever leaves the device.\n *\n * Only the client holds the signing key derived from `local_user_secret`, so\n * only the client can mint the token.\n *\n * @param sessionClientPrivateKey - Per-session X25519 private key used to\n * seal both secrets.\n * @param encryptionDataKey - Encryption schema for the data encryption key.\n * @param capabilityTokenSchema - Encryption schema for the capability token.\n * @returns The wrapped encryption key and capability token.\n */\n async #generateWrappedAuthorizations(\n sessionClientPrivateKey: Uint8Array,\n encryptionDataKey: EncryptionSchema,\n capabilityTokenSchema: EncryptionSchema,\n ): Promise<{\n wrappedEncryptionDataKey: CapabilityAuthorization;\n wrappedUkycCapabilityToken: CapabilityAuthorization;\n }> {\n const localUserSecret = await getOrCreateLocalUserSecret(\n this.#localUserSecretStore,\n );\n const clientMaterial = deriveClientMaterial(localUserSecret);\n const wrappedEncryptionDataKey = wrapEncryptionKey(\n sessionClientPrivateKey,\n encryptionDataKey.serverPublicKey.x,\n clientMaterial.dataEncryptionKey,\n );\n\n const ukycCapabilityToken = signStorageAccessToken({\n material: clientMaterial,\n // TODO: Confirm with idOS when this can be switched back to read and a separate token is sent for write\n operations: ['read', 'write'],\n expiresAt: new Date(Date.now() + UKYC_CAPABILITY_TOKEN_TTL_MS),\n });\n const wrappedUkycCapabilityToken = wrapEncryptionKey(\n sessionClientPrivateKey,\n capabilityTokenSchema.serverPublicKey.x,\n stringToBytes(encodeStorageAccessTokenForHeader(ukycCapabilityToken)),\n );\n\n return { wrappedEncryptionDataKey, wrappedUkycCapabilityToken };\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { KycController, getDefaultKycControllerState, getDefaultKycProviderDisclaimersAccepted, getDefaultKycVendorDisclaimersAccepted, controllerName, } from './KycController.js';
2
- export type { KycControllerActions, KycControllerEvents, KycControllerGetStateAction, KycControllerMessenger, KycControllerOptions, KycControllerState, KycControllerStateChangeEvent, FetchSessionDisclaimersParams, } from './KycController.js';
3
- export type { KycControllerClearStateAction, KycControllerFetchSessionDisclaimersAction, KycControllerFetchVendorDisclaimersAction, KycControllerGetSessionStatusForVendorAction, KycControllerHasCompletedSessionDisclaimersAction, KycControllerHasCompletedVendorDisclaimersAction, KycControllerLaunchProviderFlowAction, KycControllerRecordSessionDisclaimersAction, KycControllerRecordVendorDisclaimersAction, KycControllerRefreshSessionStatusAction, KycControllerResetAction, KycControllerStartSessionAction, KycControllerStartSessionStatusPollingAction, } from './KycController-method-action-types.js';
1
+ export { KycController, getDefaultKycControllerState, getDefaultKycProviderDisclaimersAccepted, getDefaultKycVendorDisclaimersAccepted, KYC_PROVIDER_FLOW_STATUSES, controllerName, } from './KycController.js';
2
+ export type { KycControllerActions, KycControllerEvents, KycControllerGetStateAction, KycControllerMessenger, KycControllerOptions, KycControllerState, KycControllerStateChangeEvent, FetchSessionDisclaimersParams, KycProviderFlowStatus, } from './KycController.js';
3
+ export type { KycControllerClearStateAction, KycControllerFetchSessionDisclaimersAction, KycControllerFetchVendorDisclaimersAction, KycControllerGetProviderFlowStatusAction, KycControllerGetSessionStatusForVendorAction, KycControllerHasCompletedSessionDisclaimersAction, KycControllerHasCompletedVendorDisclaimersAction, KycControllerLaunchProviderFlowAction, KycControllerRecordSessionDisclaimersAction, KycControllerRecordVendorDisclaimersAction, KycControllerRefreshSessionStatusAction, KycControllerResetAction, KycControllerStartSessionAction, KycControllerStartSessionStatusPollingAction, } from './KycController-method-action-types.js';
4
4
  export { KycService, serviceName } from './KycService.js';
5
5
  export type { ApplicantAccessTokenResponse, CapabilityAuthorization, CreateVendorCustomerParams, CreateMoonpaySessionParams, CreateUkycSessionParams, EncryptionSchema, FetchSessionDisclaimersByCountryParams, FetchSessionDisclaimersBySessionIdParams, GetSessionStatusParams, VendorCustomerResponse, JwksResponse, KycServiceActions, KycServiceCacheUpdatedEvent, KycServiceEvents, KycServiceGranularCacheUpdatedEvent, KycServiceInvalidateQueriesAction, KycServiceMessenger, KycServiceOptions, SetAuthorizationsParams, SubmitSessionDisclaimersParams, SubmitVendorDisclaimersParams, UkycSessionResponse, } from './KycService.js';
6
6
  export type { KycServiceCreateVendorCustomerAction, KycServiceCreateJourneyAction, KycServiceCreateMoonpaySessionAction, KycServiceCreateUkycSessionAction, KycServiceFetchIdosEnclaveJwksAction, KycServiceFetchIdosRelayJwksAction, KycServiceFetchSessionDisclaimersByCountryAction, KycServiceFetchSessionDisclaimersBySessionIdAction, KycServiceFetchVendorDisclaimersAction, KycServiceGetGeoCountryAction, KycServiceGetSessionStatusAction, KycServiceGetSessionStatusForVendorAction, KycServiceSetAuthorizationsAction, KycServiceSubmitSessionDisclaimersAction, KycServiceSubmitVendorDisclaimersAction, } from './KycService-method-action-types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { KycController, getDefaultKycControllerState, getDefaultKycProviderDisclaimersAccepted, getDefaultKycVendorDisclaimersAccepted, controllerName, } from './KycController.js';
1
+ export { KycController, getDefaultKycControllerState, getDefaultKycProviderDisclaimersAccepted, getDefaultKycVendorDisclaimersAccepted, KYC_PROVIDER_FLOW_STATUSES, controllerName, } from './KycController.js';
2
2
  export { KycService, serviceName } from './KycService.js';
3
3
  export { selectKycSessionStatus, selectKycVendor } from './selectors.js';
4
4
  export { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from './countryCodes.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,wCAAwC,EACxC,sCAAsC,EACtC,cAAc,GACf,MAAM,oBAAoB,CAAC;AA2B5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA2C1D,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgClE,iFAAiF;AACjF,gEAAgE;AAChE,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,kCAAkC,EAClC,mCAAmC,EACnC,iCAAiC,GAClC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAKxC,OAAO,EACL,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAQtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMxD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,kCAAkC,CAAC","sourcesContent":["export {\n KycController,\n getDefaultKycControllerState,\n getDefaultKycProviderDisclaimersAccepted,\n getDefaultKycVendorDisclaimersAccepted,\n controllerName,\n} from './KycController.js';\nexport type {\n KycControllerActions,\n KycControllerEvents,\n KycControllerGetStateAction,\n KycControllerMessenger,\n KycControllerOptions,\n KycControllerState,\n KycControllerStateChangeEvent,\n FetchSessionDisclaimersParams,\n} from './KycController.js';\nexport type {\n KycControllerClearStateAction,\n KycControllerFetchSessionDisclaimersAction,\n KycControllerFetchVendorDisclaimersAction,\n KycControllerGetSessionStatusForVendorAction,\n KycControllerHasCompletedSessionDisclaimersAction,\n KycControllerHasCompletedVendorDisclaimersAction,\n KycControllerLaunchProviderFlowAction,\n KycControllerRecordSessionDisclaimersAction,\n KycControllerRecordVendorDisclaimersAction,\n KycControllerRefreshSessionStatusAction,\n KycControllerResetAction,\n KycControllerStartSessionAction,\n KycControllerStartSessionStatusPollingAction,\n} from './KycController-method-action-types.js';\n\nexport { KycService, serviceName } from './KycService.js';\nexport type {\n ApplicantAccessTokenResponse,\n CapabilityAuthorization,\n CreateVendorCustomerParams,\n CreateMoonpaySessionParams,\n CreateUkycSessionParams,\n EncryptionSchema,\n FetchSessionDisclaimersByCountryParams,\n FetchSessionDisclaimersBySessionIdParams,\n GetSessionStatusParams,\n VendorCustomerResponse,\n JwksResponse,\n KycServiceActions,\n KycServiceCacheUpdatedEvent,\n KycServiceEvents,\n KycServiceGranularCacheUpdatedEvent,\n KycServiceInvalidateQueriesAction,\n KycServiceMessenger,\n KycServiceOptions,\n SetAuthorizationsParams,\n SubmitSessionDisclaimersParams,\n SubmitVendorDisclaimersParams,\n UkycSessionResponse,\n} from './KycService.js';\nexport type {\n KycServiceCreateVendorCustomerAction,\n KycServiceCreateJourneyAction,\n KycServiceCreateMoonpaySessionAction,\n KycServiceCreateUkycSessionAction,\n KycServiceFetchIdosEnclaveJwksAction,\n KycServiceFetchIdosRelayJwksAction,\n KycServiceFetchSessionDisclaimersByCountryAction,\n KycServiceFetchSessionDisclaimersBySessionIdAction,\n KycServiceFetchVendorDisclaimersAction,\n KycServiceGetGeoCountryAction,\n KycServiceGetSessionStatusAction,\n KycServiceGetSessionStatusForVendorAction,\n KycServiceSetAuthorizationsAction,\n KycServiceSubmitSessionDisclaimersAction,\n KycServiceSubmitVendorDisclaimersAction,\n} from './KycService-method-action-types.js';\n\nexport { selectKycSessionStatus, selectKycVendor } from './selectors.js';\n\nexport { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from './countryCodes.js';\nexport { decryptCredentials, generateKeyPair } from './crypto.js';\nexport type {\n DecryptedCredentials,\n DecryptResult,\n EncryptedCredentialsEnvelope,\n X25519KeyPair,\n} from './crypto.js';\n\nexport type {\n KycCatalogDocument,\n KycConsentDocument,\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycPhase,\n KycProduct,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycIronVendorDisclaimersAccepted,\n KycMoonpayVendorDisclaimersAccepted,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nexport type {\n KycSumSubLaunchParams,\n KycSumSubLauncher,\n KycSumSubSdkStatus,\n KycSumSubStatus,\n} from './providers/sumsub.js';\n\n// UKYC storage-access-token utilities. Exported so a signed capability token can\n// be minted for testing UKYC Storage (see `mintUkycTestToken`).\nexport {\n UKYC_CAPABILITY_AUTH_SCHEME,\n UKYC_KWIL_AUDIENCE,\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE,\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES,\n UKYC_STORAGE_ACCESS_TOKEN_VERSION,\n} from './ukyc/constants.js';\nexport {\n deriveClientMaterial,\n encodeClientMaterial,\n} from './ukyc/deriveClientMaterial.js';\nexport type {\n EncodedUkycClientMaterial,\n UkycClientMaterial,\n} from './ukyc/deriveClientMaterial.js';\nexport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nexport type {\n SignStorageAccessTokenParams,\n UkycStorageAccessToken,\n UkycStorageAccessTokenPayload,\n UkycStorageOperation,\n UkycTokenPresenter,\n} from './ukyc/storageAccessToken.js';\nexport { mintUkycTestToken } from './ukyc/testToken.js';\nexport type {\n MintedUkycTestToken,\n MintUkycTestTokenParams,\n} from './ukyc/testToken.js';\n\nexport {\n clearMoonPaySession,\n MoonPayFrameHandler,\n} from './vendors/MoonPayFrameHandler.js';\nexport type { MoonPayFrameHandlerOptions } from './vendors/MoonPayFrameHandler.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,4BAA4B,EAC5B,wCAAwC,EACxC,sCAAsC,EACtC,0BAA0B,EAC1B,cAAc,GACf,MAAM,oBAAoB,CAAC;AA6B5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AA2C1D,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgClE,iFAAiF;AACjF,gEAAgE;AAChE,OAAO,EACL,2BAA2B,EAC3B,kBAAkB,EAClB,kCAAkC,EAClC,mCAAmC,EACnC,iCAAiC,GAClC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AAKxC,OAAO,EACL,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAQtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMxD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,kCAAkC,CAAC","sourcesContent":["export {\n KycController,\n getDefaultKycControllerState,\n getDefaultKycProviderDisclaimersAccepted,\n getDefaultKycVendorDisclaimersAccepted,\n KYC_PROVIDER_FLOW_STATUSES,\n controllerName,\n} from './KycController.js';\nexport type {\n KycControllerActions,\n KycControllerEvents,\n KycControllerGetStateAction,\n KycControllerMessenger,\n KycControllerOptions,\n KycControllerState,\n KycControllerStateChangeEvent,\n FetchSessionDisclaimersParams,\n KycProviderFlowStatus,\n} from './KycController.js';\nexport type {\n KycControllerClearStateAction,\n KycControllerFetchSessionDisclaimersAction,\n KycControllerFetchVendorDisclaimersAction,\n KycControllerGetProviderFlowStatusAction,\n KycControllerGetSessionStatusForVendorAction,\n KycControllerHasCompletedSessionDisclaimersAction,\n KycControllerHasCompletedVendorDisclaimersAction,\n KycControllerLaunchProviderFlowAction,\n KycControllerRecordSessionDisclaimersAction,\n KycControllerRecordVendorDisclaimersAction,\n KycControllerRefreshSessionStatusAction,\n KycControllerResetAction,\n KycControllerStartSessionAction,\n KycControllerStartSessionStatusPollingAction,\n} from './KycController-method-action-types.js';\n\nexport { KycService, serviceName } from './KycService.js';\nexport type {\n ApplicantAccessTokenResponse,\n CapabilityAuthorization,\n CreateVendorCustomerParams,\n CreateMoonpaySessionParams,\n CreateUkycSessionParams,\n EncryptionSchema,\n FetchSessionDisclaimersByCountryParams,\n FetchSessionDisclaimersBySessionIdParams,\n GetSessionStatusParams,\n VendorCustomerResponse,\n JwksResponse,\n KycServiceActions,\n KycServiceCacheUpdatedEvent,\n KycServiceEvents,\n KycServiceGranularCacheUpdatedEvent,\n KycServiceInvalidateQueriesAction,\n KycServiceMessenger,\n KycServiceOptions,\n SetAuthorizationsParams,\n SubmitSessionDisclaimersParams,\n SubmitVendorDisclaimersParams,\n UkycSessionResponse,\n} from './KycService.js';\nexport type {\n KycServiceCreateVendorCustomerAction,\n KycServiceCreateJourneyAction,\n KycServiceCreateMoonpaySessionAction,\n KycServiceCreateUkycSessionAction,\n KycServiceFetchIdosEnclaveJwksAction,\n KycServiceFetchIdosRelayJwksAction,\n KycServiceFetchSessionDisclaimersByCountryAction,\n KycServiceFetchSessionDisclaimersBySessionIdAction,\n KycServiceFetchVendorDisclaimersAction,\n KycServiceGetGeoCountryAction,\n KycServiceGetSessionStatusAction,\n KycServiceGetSessionStatusForVendorAction,\n KycServiceSetAuthorizationsAction,\n KycServiceSubmitSessionDisclaimersAction,\n KycServiceSubmitVendorDisclaimersAction,\n} from './KycService-method-action-types.js';\n\nexport { selectKycSessionStatus, selectKycVendor } from './selectors.js';\n\nexport { alpha2ToAlpha3, ALPHA2_TO_ALPHA3 } from './countryCodes.js';\nexport { decryptCredentials, generateKeyPair } from './crypto.js';\nexport type {\n DecryptedCredentials,\n DecryptResult,\n EncryptedCredentialsEnvelope,\n X25519KeyPair,\n} from './crypto.js';\n\nexport type {\n KycCatalogDocument,\n KycConsentDocument,\n KycConsentRecord,\n KycDisclaimer,\n KycDisclaimersCatalog,\n KycPhase,\n KycProduct,\n KycProviderDisclaimersAccepted,\n KycSessionDisclaimers,\n KycSessionStatus,\n KycVendor,\n KycIronVendorDisclaimersAccepted,\n KycMoonpayVendorDisclaimersAccepted,\n KycVendorDisclaimersAccepted,\n KycVendorSigning,\n} from './types.js';\nexport type {\n KycSumSubLaunchParams,\n KycSumSubLauncher,\n KycSumSubSdkStatus,\n KycSumSubStatus,\n} from './providers/sumsub.js';\n\n// UKYC storage-access-token utilities. Exported so a signed capability token can\n// be minted for testing UKYC Storage (see `mintUkycTestToken`).\nexport {\n UKYC_CAPABILITY_AUTH_SCHEME,\n UKYC_KWIL_AUDIENCE,\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCE,\n UKYC_STORAGE_ACCESS_TOKEN_AUDIENCES,\n UKYC_STORAGE_ACCESS_TOKEN_VERSION,\n} from './ukyc/constants.js';\nexport {\n deriveClientMaterial,\n encodeClientMaterial,\n} from './ukyc/deriveClientMaterial.js';\nexport type {\n EncodedUkycClientMaterial,\n UkycClientMaterial,\n} from './ukyc/deriveClientMaterial.js';\nexport {\n encodeStorageAccessTokenForHeader,\n signStorageAccessToken,\n} from './ukyc/storageAccessToken.js';\nexport type {\n SignStorageAccessTokenParams,\n UkycStorageAccessToken,\n UkycStorageAccessTokenPayload,\n UkycStorageOperation,\n UkycTokenPresenter,\n} from './ukyc/storageAccessToken.js';\nexport { mintUkycTestToken } from './ukyc/testToken.js';\nexport type {\n MintedUkycTestToken,\n MintUkycTestTokenParams,\n} from './ukyc/testToken.js';\n\nexport {\n clearMoonPaySession,\n MoonPayFrameHandler,\n} from './vendors/MoonPayFrameHandler.js';\nexport type { MoonPayFrameHandlerOptions } from './vendors/MoonPayFrameHandler.js';\n"]}
@@ -87,4 +87,14 @@ export type KycSumSubLauncher = {
87
87
  * @returns Whether the applicant submitted, including a review decision.
88
88
  */
89
89
  export declare function isSumSubFlowCompleted(status: unknown): boolean;
90
+ /**
91
+ * Checks whether a SumSub status means the SDK itself could not run.
92
+ *
93
+ * Distinct from a user closing the flow before submitting (`Incomplete`,
94
+ * `Initial`, or `Ready`).
95
+ *
96
+ * @param status - Status from a launcher callback or launch result.
97
+ * @returns Whether the SDK failed to run.
98
+ */
99
+ export declare function isSumSubFlowFailed(status: unknown): boolean;
90
100
  //# sourceMappingURL=sumsub.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sumsub.d.ts","sourceRoot":"","sources":["../../src/providers/sumsub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,iBAAiB,GACjB,eAAe,GACf,WAAW,GACX,YAAY,GACZ,UAAU,GACV,WAAW,GACX,QAAQ,GACR,kBAAkB,CAAC;AAEvB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,SAAS,GACT,qBAAqB,GACrB,iBAAiB,GACjB,UAAU,GACV,iBAAiB,GACjB,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjE;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzE,CAAC;AAmBF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE9D"}
1
+ {"version":3,"file":"sumsub.d.ts","sourceRoot":"","sources":["../../src/providers/sumsub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,iBAAiB,GACjB,eAAe,GACf,WAAW,GACX,YAAY,GACZ,UAAU,GACV,WAAW,GACX,QAAQ,GACR,kBAAkB,CAAC;AAEvB;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,QAAQ,GACR,SAAS,GACT,YAAY,GACZ,SAAS,GACT,qBAAqB,GACrB,iBAAiB,GACjB,UAAU,GACV,iBAAiB,GACjB,WAAW,CAAC;AAEhB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzC;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAEjE;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzE,CAAC;AAmBF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAE3D"}
@@ -28,4 +28,16 @@ const SUMSUB_COMPLETED_STATUSES = new Set([
28
28
  export function isSumSubFlowCompleted(status) {
29
29
  return typeof status === 'string' && SUMSUB_COMPLETED_STATUSES.has(status);
30
30
  }
31
+ /**
32
+ * Checks whether a SumSub status means the SDK itself could not run.
33
+ *
34
+ * Distinct from a user closing the flow before submitting (`Incomplete`,
35
+ * `Initial`, or `Ready`).
36
+ *
37
+ * @param status - Status from a launcher callback or launch result.
38
+ * @returns Whether the SDK failed to run.
39
+ */
40
+ export function isSumSubFlowFailed(status) {
41
+ return status === 'Failed';
42
+ }
31
43
  //# sourceMappingURL=sumsub.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sumsub.js","sourceRoot":"","sources":["../../src/providers/sumsub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0GH,8EAA8E;AAC9E,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,uEAAuE;AACvE,4EAA4E;AAC5E,+CAA+C;AAC/C,MAAM,yBAAyB,GAC7B,IAAI,GAAG,CAAqB;IAC1B,WAAW;IACX,SAAS;IACT,UAAU;IACV,iBAAiB;IACjB,iBAAiB;IACjB,qBAAqB;CACtB,CAAC,CAAC;AAEL;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7E,CAAC","sourcesContent":["/**\n * SumSub document-verification types and SDK status helpers.\n *\n * The KYC controller is platform-agnostic and does not import any SDK; each\n * client (mobile / extension / web) injects a {@link KycSumSubLauncher}.\n */\n\n/**\n * Progress of the SumSub document-verification sub-flow.\n *\n * - `inProgress` — the SumSub SDK is on screen.\n * - `vendorProcessing` — session creation reported that the applicant is\n * already approved on the relay (`kycStatus`) while the vendor is still\n * finalizing its own decision (`finalStatus`). There is nothing left for the\n * applicant to do, so the SDK is not launched; see `statusMessage`.\n * - `abandoned` — the applicant closed the SDK before submitting. Unlike\n * `failed`, nothing went wrong, so `error` is left unset and consumers should\n * offer a retry rather than report a problem.\n */\nexport type KycSumSubStatus =\n | 'idle'\n | 'creatingSession'\n | 'fetchingToken'\n | 'launching'\n | 'inProgress'\n | 'complete'\n | 'abandoned'\n | 'failed'\n | 'vendorProcessing';\n\n/**\n * Status strings a SumSub SDK reports, through either the status-change\n * callback or the `launch` result. Distinct from {@link KycSumSubStatus},\n * which tracks the controller's own sub-flow.\n *\n * - `Ready` — initialized and presented; no step reported yet.\n * - `Failed` — the SDK itself could not run.\n * - `Initial` — no verification step has been passed.\n * - `Incomplete` — some but not all verification steps have been passed.\n * - `Pending` — the applicant submitted and review is pending.\n * - `TemporarilyDeclined` — the applicant was declined but may resubmit.\n * - `FinallyRejected` — the applicant was rejected for good.\n * - `Approved` — the applicant was approved.\n * - `ActionCompleted` — an applicant action (e.g. a liveness check) finished.\n * - `Completed` — normalized completion reported by non-native launchers.\n */\nexport type KycSumSubSdkStatus =\n | 'Ready'\n | 'Failed'\n | 'Initial'\n | 'Incomplete'\n | 'Pending'\n | 'TemporarilyDeclined'\n | 'FinallyRejected'\n | 'Approved'\n | 'ActionCompleted'\n | 'Completed';\n\n/**\n * Parameters passed to a platform SumSub launcher.\n */\nexport type KycSumSubLaunchParams = {\n /**\n * The applicant access token used to initialize the SumSub SDK.\n */\n applicantAccessToken: string;\n\n /**\n * Called by the SDK when the access token expires; must resolve with a fresh\n * applicant access token.\n */\n onTokenExpiration: () => Promise<string>;\n\n /**\n * Called when the SDK reports a status transition.\n */\n onStatusChange?: (prevStatus: string, newStatus: string) => void;\n\n /**\n * BCP-47 locale for the SDK UI.\n */\n locale?: string;\n\n /**\n * Enables SDK debug logging.\n */\n debug?: boolean;\n};\n\n/**\n * Platform adapter that launches the native/web SumSub SDK.\n *\n * The KYC controller is platform-agnostic and does not import any SDK; each\n * client (mobile / extension / web) injects an implementation of this\n * interface. The controller owns all orchestration (session creation, token\n * exchange, token refresh, state) and only delegates the actual SDK\n * presentation to `launch`.\n */\nexport type KycSumSubLauncher = {\n /**\n * Whether the underlying SDK is available in the current runtime (e.g. the\n * native module is linked). When `false`, `startSumSub` fails fast.\n */\n isAvailable(): boolean;\n\n /**\n * Presents the SumSub verification flow and resolves with the SDK result.\n */\n launch(params: KycSumSubLaunchParams): Promise<Record<string, unknown>>;\n};\n\n// SumSub statuses that mean the applicant submitted (see `KycSumSubSdkStatus`\n// for what each one reports). `Completed` covers launchers that normalize the\n// platform status before forwarding it. Review decisions (`Approved`,\n// `FinallyRejected`, `TemporarilyDeclined`) are post-submission outcomes: the\n// applicant finished the SDK, so UKYC is queried for the authoritative\n// decision. Pre-submission statuses (`Ready`, `Initial`, `Incomplete`) must\n// not be recorded as a completed verification.\nconst SUMSUB_COMPLETED_STATUSES: ReadonlySet<string> =\n new Set<KycSumSubSdkStatus>([\n 'Completed',\n 'Pending',\n 'Approved',\n 'ActionCompleted',\n 'FinallyRejected',\n 'TemporarilyDeclined',\n ]);\n\n/**\n * Checks whether a SumSub status means the applicant submitted the flow.\n *\n * @param status - Status from a launcher callback or launch result.\n * @returns Whether the applicant submitted, including a review decision.\n */\nexport function isSumSubFlowCompleted(status: unknown): boolean {\n return typeof status === 'string' && SUMSUB_COMPLETED_STATUSES.has(status);\n}\n"]}
1
+ {"version":3,"file":"sumsub.js","sourceRoot":"","sources":["../../src/providers/sumsub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0GH,8EAA8E;AAC9E,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAC9E,uEAAuE;AACvE,4EAA4E;AAC5E,+CAA+C;AAC/C,MAAM,yBAAyB,GAC7B,IAAI,GAAG,CAAqB;IAC1B,WAAW;IACX,SAAS;IACT,UAAU;IACV,iBAAiB;IACjB,iBAAiB;IACjB,qBAAqB;CACtB,CAAC,CAAC;AAEL;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAe;IAChD,OAAO,MAAM,KAAK,QAAQ,CAAC;AAC7B,CAAC","sourcesContent":["/**\n * SumSub document-verification types and SDK status helpers.\n *\n * The KYC controller is platform-agnostic and does not import any SDK; each\n * client (mobile / extension / web) injects a {@link KycSumSubLauncher}.\n */\n\n/**\n * Progress of the SumSub document-verification sub-flow.\n *\n * - `inProgress` — the SumSub SDK is on screen.\n * - `vendorProcessing` — session creation reported that the applicant is\n * already approved on the relay (`kycStatus`) while the vendor is still\n * finalizing its own decision (`finalStatus`). There is nothing left for the\n * applicant to do, so the SDK is not launched; see `statusMessage`.\n * - `abandoned` — the applicant closed the SDK before submitting. Unlike\n * `failed`, nothing went wrong, so `error` is left unset and consumers should\n * offer a retry rather than report a problem.\n */\nexport type KycSumSubStatus =\n | 'idle'\n | 'creatingSession'\n | 'fetchingToken'\n | 'launching'\n | 'inProgress'\n | 'complete'\n | 'abandoned'\n | 'failed'\n | 'vendorProcessing';\n\n/**\n * Status strings a SumSub SDK reports, through either the status-change\n * callback or the `launch` result. Distinct from {@link KycSumSubStatus},\n * which tracks the controller's own sub-flow.\n *\n * - `Ready` — initialized and presented; no step reported yet.\n * - `Failed` — the SDK itself could not run.\n * - `Initial` — no verification step has been passed.\n * - `Incomplete` — some but not all verification steps have been passed.\n * - `Pending` — the applicant submitted and review is pending.\n * - `TemporarilyDeclined` — the applicant was declined but may resubmit.\n * - `FinallyRejected` — the applicant was rejected for good.\n * - `Approved` — the applicant was approved.\n * - `ActionCompleted` — an applicant action (e.g. a liveness check) finished.\n * - `Completed` — normalized completion reported by non-native launchers.\n */\nexport type KycSumSubSdkStatus =\n | 'Ready'\n | 'Failed'\n | 'Initial'\n | 'Incomplete'\n | 'Pending'\n | 'TemporarilyDeclined'\n | 'FinallyRejected'\n | 'Approved'\n | 'ActionCompleted'\n | 'Completed';\n\n/**\n * Parameters passed to a platform SumSub launcher.\n */\nexport type KycSumSubLaunchParams = {\n /**\n * The applicant access token used to initialize the SumSub SDK.\n */\n applicantAccessToken: string;\n\n /**\n * Called by the SDK when the access token expires; must resolve with a fresh\n * applicant access token.\n */\n onTokenExpiration: () => Promise<string>;\n\n /**\n * Called when the SDK reports a status transition.\n */\n onStatusChange?: (prevStatus: string, newStatus: string) => void;\n\n /**\n * BCP-47 locale for the SDK UI.\n */\n locale?: string;\n\n /**\n * Enables SDK debug logging.\n */\n debug?: boolean;\n};\n\n/**\n * Platform adapter that launches the native/web SumSub SDK.\n *\n * The KYC controller is platform-agnostic and does not import any SDK; each\n * client (mobile / extension / web) injects an implementation of this\n * interface. The controller owns all orchestration (session creation, token\n * exchange, token refresh, state) and only delegates the actual SDK\n * presentation to `launch`.\n */\nexport type KycSumSubLauncher = {\n /**\n * Whether the underlying SDK is available in the current runtime (e.g. the\n * native module is linked). When `false`, `startSumSub` fails fast.\n */\n isAvailable(): boolean;\n\n /**\n * Presents the SumSub verification flow and resolves with the SDK result.\n */\n launch(params: KycSumSubLaunchParams): Promise<Record<string, unknown>>;\n};\n\n// SumSub statuses that mean the applicant submitted (see `KycSumSubSdkStatus`\n// for what each one reports). `Completed` covers launchers that normalize the\n// platform status before forwarding it. Review decisions (`Approved`,\n// `FinallyRejected`, `TemporarilyDeclined`) are post-submission outcomes: the\n// applicant finished the SDK, so UKYC is queried for the authoritative\n// decision. Pre-submission statuses (`Ready`, `Initial`, `Incomplete`) must\n// not be recorded as a completed verification.\nconst SUMSUB_COMPLETED_STATUSES: ReadonlySet<string> =\n new Set<KycSumSubSdkStatus>([\n 'Completed',\n 'Pending',\n 'Approved',\n 'ActionCompleted',\n 'FinallyRejected',\n 'TemporarilyDeclined',\n ]);\n\n/**\n * Checks whether a SumSub status means the applicant submitted the flow.\n *\n * @param status - Status from a launcher callback or launch result.\n * @returns Whether the applicant submitted, including a review decision.\n */\nexport function isSumSubFlowCompleted(status: unknown): boolean {\n return typeof status === 'string' && SUMSUB_COMPLETED_STATUSES.has(status);\n}\n\n/**\n * Checks whether a SumSub status means the SDK itself could not run.\n *\n * Distinct from a user closing the flow before submitting (`Incomplete`,\n * `Initial`, or `Ready`).\n *\n * @param status - Status from a launcher callback or launch result.\n * @returns Whether the SDK failed to run.\n */\nexport function isSumSubFlowFailed(status: unknown): boolean {\n return status === 'Failed';\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/kyc-controller",
3
- "version": "0.5.0-preview-ff2ab0583",
3
+ "version": "0.6.0-preview-c4789fdf4",
4
4
  "description": "Shared KYC / identity verification controller used across MetaMask clients",
5
5
  "keywords": [
6
6
  "Ethereum",