@metamask-previews/kyc-controller 0.7.0-preview-131e5e6ee → 0.8.0-preview-2750df1dc
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 +20 -1
- package/dist/KycController-method-action-types.d.ts +13 -9
- package/dist/KycController-method-action-types.d.ts.map +1 -1
- package/dist/KycController-method-action-types.js.map +1 -1
- package/dist/KycController.d.ts +13 -9
- package/dist/KycController.d.ts.map +1 -1
- package/dist/KycController.js +121 -48
- package/dist/KycController.js.map +1 -1
- package/dist/KycService-method-action-types.d.ts +21 -1
- package/dist/KycService-method-action-types.d.ts.map +1 -1
- package/dist/KycService-method-action-types.js.map +1 -1
- package/dist/KycService.d.ts +27 -0
- package/dist/KycService.d.ts.map +1 -1
- package/dist/KycService.js +28 -0
- package/dist/KycService.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/sessionDisclaimers.d.ts +1 -9
- package/dist/sessionDisclaimers.d.ts.map +1 -1
- package/dist/sessionDisclaimers.js +0 -12
- package/dist/sessionDisclaimers.js.map +1 -1
- package/dist/types.d.ts +48 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +53 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,8 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `KycService.resetWrappingKeys`, which posts `POST /sessions/{sessionId}/wrapping-keys` with `sessionClientPublicKey` and returns `UkycSessionResponse` ([#10692](https://github.com/MetaMask/core/pull/10692))
|
|
13
|
+
- Export `CAPABILITY_AUTHORIZATION_STATUSES`, `CAPABILITY_AUTHORIZATION_STATUSES_TO_REFRESH`, `FINAL_STATUSES_TO_SKIP_AUTH_REFRESH`, `needsCapabilityAuthorizationRefresh`, `KYC_STATUSES`, and `FINAL_STATUSES_TO_STOP_POLLING` ([#10692](https://github.com/MetaMask/core/pull/10692))
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Refresh and resubmit the UKYC capability authorization when `capabilityAuthorizationStatus` is `new` or `expired` while resuming a session in `startSession` (skipped when `finalStatus` is `approved` or `rejected`) ([#10692](https://github.com/MetaMask/core/pull/10692))
|
|
18
|
+
- Space `KycController` session-status polls with a linear backoff. The first poll is immediate, the next waits 10 seconds, and each later wait grows by 10 seconds. Starting polling again resets the delay ([#10764](https://github.com/MetaMask/core/pull/10764))
|
|
19
|
+
|
|
20
|
+
## [0.8.0]
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Added exported `KYC_STATUSES` and `TERMINAL_SESSION_STATUSES`, so consumers can reuse the KYC status vocabulary and the terminal session-status set (`approved`, `rejected`, `retry`) from the package entry point instead of redefining them locally ([#10771](https://github.com/MetaMask/core/pull/10771))
|
|
25
|
+
|
|
10
26
|
### Changed
|
|
11
27
|
|
|
28
|
+
- `KycController.hasCompletedSessionDisclaimers` now reports completion from session `consentStatus === 'given'` instead of fetching the session disclaimer catalog ([#10760](https://github.com/MetaMask/core/pull/10760))
|
|
29
|
+
- This no longer throws a 409 when the session is already in a terminal state
|
|
12
30
|
- Bump `@metamask/profile-sync-controller` from `^34.0.2` to `^34.0.3` ([#10761](https://github.com/MetaMask/core/pull/10761))
|
|
13
31
|
|
|
14
32
|
## [0.7.0]
|
|
@@ -130,7 +148,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
130
148
|
|
|
131
149
|
- Initial Release ([#10145](https://github.com/MetaMask/core/pull/10145))
|
|
132
150
|
|
|
133
|
-
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.
|
|
151
|
+
[Unreleased]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.8.0...HEAD
|
|
152
|
+
[0.8.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.7.0...@metamask/kyc-controller@0.8.0
|
|
134
153
|
[0.7.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.6.1...@metamask/kyc-controller@0.7.0
|
|
135
154
|
[0.6.1]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.6.0...@metamask/kyc-controller@0.6.1
|
|
136
155
|
[0.6.0]: https://github.com/MetaMask/core/compare/@metamask/kyc-controller@0.5.0...@metamask/kyc-controller@0.6.0
|
|
@@ -53,10 +53,13 @@ export type KycControllerGetProviderFlowStatusAction = {
|
|
|
53
53
|
handler: KycController['getProviderFlowStatus'];
|
|
54
54
|
};
|
|
55
55
|
/**
|
|
56
|
-
* Returns the
|
|
57
|
-
* terminal.
|
|
56
|
+
* Returns the session already stored on state.
|
|
58
57
|
*
|
|
59
|
-
*
|
|
58
|
+
* Starts session-status polling when `finalStatus` is not `approved`,
|
|
59
|
+
* `rejected`, or `retry`. Does not fetch status or refresh capability
|
|
60
|
+
* authorization.
|
|
61
|
+
*
|
|
62
|
+
* @returns The session status stored at call time.
|
|
60
63
|
* @throws If there is no session on state.
|
|
61
64
|
*/
|
|
62
65
|
export type KycControllerRefreshSessionStatusAction = {
|
|
@@ -89,9 +92,11 @@ export type KycControllerFetchSessionStatusOnceAction = {
|
|
|
89
92
|
/**
|
|
90
93
|
* Starts polling `GET /sessions/{id}/status` for
|
|
91
94
|
* {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes
|
|
92
|
-
* the result onto state only when the payload changed. The
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
+
* the result onto state only when the payload changed. The first poll runs
|
|
96
|
+
* immediately. Each later wait starts at 10 seconds and grows by 10 seconds
|
|
97
|
+
* after every poll, including a failed one. Starting the loop again resets
|
|
98
|
+
* that delay. The loop stops once `finalStatus` is `approved`, `rejected`,
|
|
99
|
+
* or `retry`, or when {@link reset} / {@link clearState} runs.
|
|
95
100
|
*
|
|
96
101
|
* @throws If there is no current session id to poll.
|
|
97
102
|
*/
|
|
@@ -138,10 +143,9 @@ export type KycControllerRecordSessionDisclaimersAction = {
|
|
|
138
143
|
handler: KycController['recordSessionDisclaimers'];
|
|
139
144
|
};
|
|
140
145
|
/**
|
|
141
|
-
* Fetches session
|
|
142
|
-
* consented and credential reuse was accepted.
|
|
146
|
+
* Fetches the current session status and reports whether consent was given.
|
|
143
147
|
*
|
|
144
|
-
* @returns Whether
|
|
148
|
+
* @returns Whether `consentStatus` is `given`.
|
|
145
149
|
* @throws If there is no session on state.
|
|
146
150
|
*/
|
|
147
151
|
export type KycControllerHasCompletedSessionDisclaimersAction = {
|
|
@@ -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;;;;;;;;;;;GAWG;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;;;;GAIG;AACH,MAAM,MAAM,wCAAwC,GAAG;IACrD,IAAI,EAAE,qCAAqC,CAAC;IAC5C,OAAO,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;CACjD,CAAC;AAEF
|
|
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 * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\nexport type KycControllerGetProviderFlowStatusAction = {\n type: `KycController:getProviderFlowStatus`;\n handler: KycController['getProviderFlowStatus'];\n};\n\n/**\n * Returns the
|
|
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 * @param params.aal2Token - AAL2 authentication token. Required only when a\n * UKYC session must be created, where it is sent as the Authorization bearer\n * value. Omit it when reusing an existing session.\n * @returns The current or newly created session status.\n */\nexport type KycControllerStartSessionAction = {\n type: `KycController:startSession`;\n handler: KycController['startSession'];\n};\n\n/**\n * Stops session-status polling and restores default controller state.\n */\nexport type KycControllerResetAction = {\n type: `KycController:reset`;\n handler: KycController['reset'];\n};\n\n/**\n * Restores the controller to its default state.\n */\nexport type KycControllerClearStateAction = {\n type: `KycController:clearState`;\n handler: KycController['clearState'];\n};\n\n/**\n * Fetches the latest UKYC session status for a vendor.\n *\n * @param vendor - Identity vendor whose latest session should be queried.\n * @returns The session status, or `null` when none exists.\n */\nexport type KycControllerGetSessionStatusForVendorAction = {\n type: `KycController:getSessionStatusForVendor`;\n handler: KycController['getSessionStatusForVendor'];\n};\n\n/**\n * Returns the durable outcome of the identity-provider flow.\n *\n * @returns The latest provider-flow status.\n */\nexport type KycControllerGetProviderFlowStatusAction = {\n type: `KycController:getProviderFlowStatus`;\n handler: KycController['getProviderFlowStatus'];\n};\n\n/**\n * Returns the session already stored on state.\n *\n * Starts session-status polling when `finalStatus` is not `approved`,\n * `rejected`, or `retry`. Does not fetch status or refresh capability\n * authorization.\n *\n * @returns The session status stored at call time.\n * @throws If there is no session on state.\n */\nexport type KycControllerRefreshSessionStatusAction = {\n type: `KycController:refreshSessionStatus`;\n handler: KycController['refreshSessionStatus'];\n};\n\n/**\n * Returns the persisted session status.\n *\n * Does not call the network and does not start session-status polling.\n *\n * @returns The session on state, or `null` when none is stored.\n */\nexport type KycControllerReadSessionStatusAction = {\n type: `KycController:readSessionStatus`;\n handler: KycController['readSessionStatus'];\n};\n\n/**\n * Fetches `GET /sessions/{id}/status` once and writes the result onto state.\n *\n * Does not start the session-status polling timer.\n *\n * @param sessionId - UKYC session id.\n * @returns The fetched session status.\n */\nexport type KycControllerFetchSessionStatusOnceAction = {\n type: `KycController:fetchSessionStatusOnce`;\n handler: KycController['fetchSessionStatusOnce'];\n};\n\n/**\n * Starts polling `GET /sessions/{id}/status` for\n * {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes\n * the result onto state only when the payload changed. The first poll runs\n * immediately. Each later wait starts at 10 seconds and grows by 10 seconds\n * after every poll, including a failed one. Starting the loop again resets\n * that delay. The loop stops once `finalStatus` is `approved`, `rejected`,\n * or `retry`, or when {@link reset} / {@link clearState} runs.\n *\n * @throws If there is no current session id to poll.\n */\nexport type KycControllerStartSessionStatusPollingAction = {\n type: `KycController:startSessionStatusPolling`;\n handler: KycController['startSessionStatusPolling'];\n};\n\n/**\n * Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of\n * `sessionId` or `country`:\n *\n * - `{ sessionId }` → {@link KycService.fetchSessionDisclaimersBySessionId}\n * (`GET /sessions/{sessionId}/disclaimers`)\n * - `{ country }` → {@link KycService.fetchSessionDisclaimersByCountry}\n * (`GET /disclaimers?country=`)\n *\n * A session-id fetch also writes the catalog to `sessionDisclaimers`.\n *\n * @param params - The parameters. Provide exactly one of `sessionId` or\n * `country`.\n * @param params.sessionId - The UKYC session id.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The catalog. Session fetches include consent state; country\n * fetches do not.\n */\nexport type KycControllerFetchSessionDisclaimersAction = {\n type: `KycController:fetchSessionDisclaimers`;\n handler: KycController['fetchSessionDisclaimers'];\n};\n\n/**\n * Fetches the session-scoped disclaimer catalog and records consents\n * derived from the T&C2 flags. Already-consented catalog rows are omitted\n * from the POST. A 409 is re-checked with a GET: continue only when every\n * accepted document is now consented, otherwise fail closed.\n *\n * @param params - Accepted session-disclaimer records.\n * @param params.providerDisclaimersAccepted - Accepted Sumsub disclaimer records.\n * @param params.idosDisclaimersAccepted - Accepted idOS disclaimer records.\n * @param params.credentialReusabilityConsentGiven - Whether credential\n * reuse was accepted.\n */\nexport type KycControllerRecordSessionDisclaimersAction = {\n type: `KycController:recordSessionDisclaimers`;\n handler: KycController['recordSessionDisclaimers'];\n};\n\n/**\n * Fetches the current session status and reports whether consent was given.\n *\n * @returns Whether `consentStatus` is `given`.\n * @throws If there is no session on state.\n */\nexport type KycControllerHasCompletedSessionDisclaimersAction = {\n type: `KycController:hasCompletedSessionDisclaimers`;\n handler: KycController['hasCompletedSessionDisclaimers'];\n};\n\n/**\n * Fetches the vendor T&Cs the customer must accept before a session is\n * created (`GET /vendors/{vendor}/disclaimers?country=`).\n *\n * @param params - The parameters.\n * @param params.vendor - Identity vendor. Defaults to `moonpay`.\n * @param params.country - ISO 3166-1 alpha-3 country code.\n * @returns The disclaimers.\n */\nexport type KycControllerFetchVendorDisclaimersAction = {\n type: `KycController:fetchVendorDisclaimers`;\n handler: KycController['fetchVendorDisclaimers'];\n};\n\n/**\n * Records vendor T&C acceptance via {@link KycService.submitVendorDisclaimers}\n * and persists the accepted ids on state.\n *\n * @param params - The parameters.\n * @param params.disclaimerIds - Accepted vendor T&C ids.\n * @returns The vendor signing records.\n * @throws If `vendor` is missing from state.\n */\nexport type KycControllerRecordVendorDisclaimersAction = {\n type: `KycController:recordVendorDisclaimers`;\n handler: KycController['recordVendorDisclaimers'];\n};\n\n/**\n * Fetches the current vendor T&C catalog and returns whether every document\n * is already recorded in {@link KycControllerState.vendorDisclaimersAccepted}.\n *\n * @returns Whether persisted acceptance covers the fetched catalog.\n * @throws If `vendor` or `geoCountry` is missing from state.\n */\nexport type KycControllerHasCompletedVendorDisclaimersAction = {\n type: `KycController:hasCompletedVendorDisclaimers`;\n handler: KycController['hasCompletedVendorDisclaimers'];\n};\n\n/**\n * Presents the identity-provider verification UI. Currently launches SumSub.\n *\n * @param params - Optional SDK presentation options.\n * @param params.locale - BCP-47 locale for the SDK UI.\n * @param params.debug - Enables SDK debug logging.\n * @returns The durable provider-flow outcome.\n */\nexport type KycControllerLaunchProviderFlowAction = {\n type: `KycController:launchProviderFlow`;\n handler: KycController['launchProviderFlow'];\n};\n\n/**\n * Union of all KycController action types.\n */\nexport type KycControllerMethodActions =\n | KycControllerStartSessionAction\n | KycControllerResetAction\n | KycControllerClearStateAction\n | KycControllerGetSessionStatusForVendorAction\n | KycControllerGetProviderFlowStatusAction\n | KycControllerRefreshSessionStatusAction\n | KycControllerReadSessionStatusAction\n | KycControllerFetchSessionStatusOnceAction\n | KycControllerStartSessionStatusPollingAction\n | KycControllerFetchSessionDisclaimersAction\n | KycControllerRecordSessionDisclaimersAction\n | KycControllerHasCompletedSessionDisclaimersAction\n | KycControllerFetchVendorDisclaimersAction\n | KycControllerRecordVendorDisclaimersAction\n | KycControllerHasCompletedVendorDisclaimersAction\n | KycControllerLaunchProviderFlowAction;\n"]}
|
package/dist/KycController.d.ts
CHANGED
|
@@ -164,10 +164,13 @@ export declare class KycController extends BaseController<typeof controllerName,
|
|
|
164
164
|
*/
|
|
165
165
|
getProviderFlowStatus(): KycProviderFlowStatus;
|
|
166
166
|
/**
|
|
167
|
-
* Returns the
|
|
168
|
-
* terminal.
|
|
167
|
+
* Returns the session already stored on state.
|
|
169
168
|
*
|
|
170
|
-
*
|
|
169
|
+
* Starts session-status polling when `finalStatus` is not `approved`,
|
|
170
|
+
* `rejected`, or `retry`. Does not fetch status or refresh capability
|
|
171
|
+
* authorization.
|
|
172
|
+
*
|
|
173
|
+
* @returns The session status stored at call time.
|
|
171
174
|
* @throws If there is no session on state.
|
|
172
175
|
*/
|
|
173
176
|
refreshSessionStatus(): KycSessionStatus;
|
|
@@ -191,9 +194,11 @@ export declare class KycController extends BaseController<typeof controllerName,
|
|
|
191
194
|
/**
|
|
192
195
|
* Starts polling `GET /sessions/{id}/status` for
|
|
193
196
|
* {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes
|
|
194
|
-
* the result onto state only when the payload changed. The
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
+
* the result onto state only when the payload changed. The first poll runs
|
|
198
|
+
* immediately. Each later wait starts at 10 seconds and grows by 10 seconds
|
|
199
|
+
* after every poll, including a failed one. Starting the loop again resets
|
|
200
|
+
* that delay. The loop stops once `finalStatus` is `approved`, `rejected`,
|
|
201
|
+
* or `retry`, or when {@link reset} / {@link clearState} runs.
|
|
197
202
|
*
|
|
198
203
|
* @throws If there is no current session id to poll.
|
|
199
204
|
*/
|
|
@@ -235,10 +240,9 @@ export declare class KycController extends BaseController<typeof controllerName,
|
|
|
235
240
|
credentialReusabilityConsentGiven: boolean;
|
|
236
241
|
}): Promise<void>;
|
|
237
242
|
/**
|
|
238
|
-
* Fetches session
|
|
239
|
-
* consented and credential reuse was accepted.
|
|
243
|
+
* Fetches the current session status and reports whether consent was given.
|
|
240
244
|
*
|
|
241
|
-
* @returns Whether
|
|
245
|
+
* @returns Whether `consentStatus` is `given`.
|
|
242
246
|
* @throws If there is no session on state.
|
|
243
247
|
*/
|
|
244
248
|
hasCompletedSessionDisclaimers(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAE3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EACV,4CAA4C,EAC5C,4CAA4C,EAC7C,MAAM,gDAAgD,CAAC;AAKxD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAC;AACzF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AASnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM/D,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,8BAA8B,EAC9B,qBAAqB,EACrB,gBAAgB,EAChB,SAAS,EACT,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAmBpB,eAAO,MAAM,cAAc,kBAAkB,CAAC;AAE9C,eAAO,MAAM,0BAA0B,YACrC,aAAa,EACb,WAAW,EACX,WAAW,EACX,QAAQ,CACA,CAAC;AAEX;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"KycController.d.ts","sourceRoot":"","sources":["../src/KycController.ts"],"names":[],"mappings":"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"}
|
package/dist/KycController.js
CHANGED
|
@@ -3,8 +3,8 @@ import { stringToBytes } from '@metamask/utils';
|
|
|
3
3
|
import { x25519 } from '@noble/curves/ed25519';
|
|
4
4
|
import { toBase64Url } from './encoding.js';
|
|
5
5
|
import { isSumSubFlowCompleted, isSumSubFlowFailed, } from './providers/sumsub.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { consentRecordsFromAcceptedList } from './sessionDisclaimers.js';
|
|
7
|
+
import { needsCapabilityAuthorizationRefresh, FINAL_STATUSES_TO_STOP_POLLING, } from './types.js';
|
|
8
8
|
import { deriveClientMaterial } from './ukyc/deriveClientMaterial.js';
|
|
9
9
|
import { assertAttestedServerPublicKey } from './ukyc/jwtChain.js';
|
|
10
10
|
import { getOrCreateLocalUserSecret, UkycLocalUserSecretStore, } from './ukyc/localUserSecret.js';
|
|
@@ -24,8 +24,9 @@ export const KYC_PROVIDER_FLOW_STATUSES = [
|
|
|
24
24
|
// cover the KYC session's expected lifetime — including the provider journey —
|
|
25
25
|
// rather than a fixed short window, so this is a session-scoped window.
|
|
26
26
|
const UKYC_CAPABILITY_TOKEN_TTL_MS = 72 * 60 * 60 * 1000;
|
|
27
|
-
//
|
|
28
|
-
|
|
27
|
+
// First wait between UKYC session-status polls. Each later wait grows by this
|
|
28
|
+
// step, so the delays are 10s, 20s, 30s, and so on.
|
|
29
|
+
const SESSION_STATUS_POLL_INTERVAL_MS = 10_000;
|
|
29
30
|
const kycControllerMetadata = {
|
|
30
31
|
email: {
|
|
31
32
|
includeInDebugSnapshot: false,
|
|
@@ -210,7 +211,7 @@ export class KycController extends BaseController {
|
|
|
210
211
|
this.update((state) => {
|
|
211
212
|
state.sessionStatus = sessionStatus;
|
|
212
213
|
});
|
|
213
|
-
return
|
|
214
|
+
return this.#refreshAuthorizationsIfNeeded();
|
|
214
215
|
}
|
|
215
216
|
// TODO: Probably move this into it's own method? Feels like startSession is a little overloaded.
|
|
216
217
|
// It's assumed that if the session does not exist, the customer does not exist either
|
|
@@ -227,9 +228,12 @@ export class KycController extends BaseController {
|
|
|
227
228
|
aal2Token: params.aal2Token,
|
|
228
229
|
});
|
|
229
230
|
}
|
|
230
|
-
|
|
231
|
-
|
|
231
|
+
const sessionStatus = await this.messenger.call('KycService:getSessionStatus', { sessionId: this.state.sessionStatus.id });
|
|
232
|
+
this.update((state) => {
|
|
233
|
+
state.sessionStatus = sessionStatus;
|
|
234
|
+
});
|
|
232
235
|
// TODO: Should we resume polling here?
|
|
236
|
+
return this.#refreshAuthorizationsIfNeeded();
|
|
233
237
|
}
|
|
234
238
|
/**
|
|
235
239
|
* Stops session-status polling and restores default controller state.
|
|
@@ -274,18 +278,22 @@ export class KycController extends BaseController {
|
|
|
274
278
|
getProviderFlowStatus() {
|
|
275
279
|
return this.state.providerFlowStatus;
|
|
276
280
|
}
|
|
281
|
+
// TODO: Perhaps this should be renamed to resumeSession()?
|
|
277
282
|
/**
|
|
278
|
-
* Returns the
|
|
279
|
-
*
|
|
283
|
+
* Returns the session already stored on state.
|
|
284
|
+
*
|
|
285
|
+
* Starts session-status polling when `finalStatus` is not `approved`,
|
|
286
|
+
* `rejected`, or `retry`. Does not fetch status or refresh capability
|
|
287
|
+
* authorization.
|
|
280
288
|
*
|
|
281
|
-
* @returns The
|
|
289
|
+
* @returns The session status stored at call time.
|
|
282
290
|
* @throws If there is no session on state.
|
|
283
291
|
*/
|
|
284
292
|
refreshSessionStatus() {
|
|
285
293
|
if (!this.state.sessionStatus) {
|
|
286
294
|
throw new Error('No session was found');
|
|
287
295
|
}
|
|
288
|
-
if (!
|
|
296
|
+
if (!FINAL_STATUSES_TO_STOP_POLLING.has(this.state.sessionStatus.finalStatus)) {
|
|
289
297
|
this.startSessionStatusPolling();
|
|
290
298
|
}
|
|
291
299
|
return this.state.sessionStatus;
|
|
@@ -318,9 +326,11 @@ export class KycController extends BaseController {
|
|
|
318
326
|
/**
|
|
319
327
|
* Starts polling `GET /sessions/{id}/status` for
|
|
320
328
|
* {@link KycControllerState.sessionStatus}'s current `id`. Each tick writes
|
|
321
|
-
* the result onto state only when the payload changed. The
|
|
322
|
-
*
|
|
323
|
-
*
|
|
329
|
+
* the result onto state only when the payload changed. The first poll runs
|
|
330
|
+
* immediately. Each later wait starts at 10 seconds and grows by 10 seconds
|
|
331
|
+
* after every poll, including a failed one. Starting the loop again resets
|
|
332
|
+
* that delay. The loop stops once `finalStatus` is `approved`, `rejected`,
|
|
333
|
+
* or `retry`, or when {@link reset} / {@link clearState} runs.
|
|
324
334
|
*
|
|
325
335
|
* @throws If there is no current session id to poll.
|
|
326
336
|
*/
|
|
@@ -331,17 +341,19 @@ export class KycController extends BaseController {
|
|
|
331
341
|
}
|
|
332
342
|
this.#stopSessionStatusPolling();
|
|
333
343
|
const token = this.#sessionStatusPollToken;
|
|
344
|
+
let completedPolls = 0;
|
|
334
345
|
const tick = async () => {
|
|
335
346
|
const shouldStop = await this.#pollSessionStatusOnce(sessionId, token);
|
|
336
347
|
if (shouldStop) {
|
|
337
348
|
return;
|
|
338
349
|
}
|
|
350
|
+
completedPolls += 1;
|
|
339
351
|
this.#sessionStatusPollTimer = setTimeout(() => {
|
|
340
352
|
this.#sessionStatusPollTimer = null;
|
|
341
353
|
// `tick` swallows its own errors and therefore never rejects.
|
|
342
354
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
343
355
|
tick();
|
|
344
|
-
}, SESSION_STATUS_POLL_INTERVAL_MS);
|
|
356
|
+
}, SESSION_STATUS_POLL_INTERVAL_MS * completedPolls);
|
|
345
357
|
this.#sessionStatusPollTimer.unref?.();
|
|
346
358
|
};
|
|
347
359
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
@@ -368,7 +380,7 @@ export class KycController extends BaseController {
|
|
|
368
380
|
state.sessionStatus = sessionStatus;
|
|
369
381
|
});
|
|
370
382
|
}
|
|
371
|
-
if (
|
|
383
|
+
if (FINAL_STATUSES_TO_STOP_POLLING.has(sessionStatus.finalStatus)) {
|
|
372
384
|
this.#stopSessionStatusPolling();
|
|
373
385
|
return true;
|
|
374
386
|
}
|
|
@@ -389,17 +401,18 @@ export class KycController extends BaseController {
|
|
|
389
401
|
}
|
|
390
402
|
}
|
|
391
403
|
/**
|
|
392
|
-
* Creates a UKYC session, wraps the `data_encryption_key` and
|
|
404
|
+
* Creates or reuses a UKYC session, wraps the `data_encryption_key` and
|
|
393
405
|
* `ukyc_capability_token` against the returned encryption schemas, and
|
|
394
|
-
* submits both via authorizations. Stores
|
|
395
|
-
* kyc-api returns the existing session if one with the same vendor and
|
|
406
|
+
* submits both via authorizations. Stores the resulting session status.
|
|
407
|
+
* kyc-api returns the existing session if one with the same vendor and
|
|
408
|
+
* canonicalUserId already exists.
|
|
396
409
|
*
|
|
397
410
|
* @param params - Vendor, country, and AAL2 token used to create the session.
|
|
398
411
|
* @param params.vendor - Identity vendor for the UKYC session.
|
|
399
412
|
* @param params.geoCountry - ISO 3166-1 alpha-3 country of residence.
|
|
400
413
|
* @param params.aal2Token - AAL2 authentication token sent as the
|
|
401
414
|
* Authorization bearer value for session creation.
|
|
402
|
-
* @returns The created session.
|
|
415
|
+
* @returns The created or refreshed session status.
|
|
403
416
|
*/
|
|
404
417
|
async #createUkycSession(params) {
|
|
405
418
|
// Establish a per-session X25519 keypair used to seal both secrets. The
|
|
@@ -411,14 +424,41 @@ export class KycController extends BaseController {
|
|
|
411
424
|
// Residence is the ISO 3166-1 alpha-3 country already resolved for
|
|
412
425
|
// disclaimers / KYC-required; fetch it if this sub-flow started without
|
|
413
426
|
// that earlier step.
|
|
414
|
-
const { sessionId, encryptionDataKey, ukycCapabilityToken: capabilityTokenSchema, } = await this.messenger.call('KycService:createUkycSession', {
|
|
427
|
+
const { sessionId, encryptionDataKey: encryptionDataKeySchema, ukycCapabilityToken: capabilityTokenSchema, } = await this.messenger.call('KycService:createUkycSession', {
|
|
415
428
|
sessionClientPublicKey,
|
|
416
429
|
residenceCountry: params.geoCountry,
|
|
417
430
|
vendor: params.vendor,
|
|
418
431
|
aal2Token: params.aal2Token,
|
|
419
432
|
});
|
|
420
|
-
|
|
421
|
-
|
|
433
|
+
return this.#setAuthorizations({
|
|
434
|
+
sessionId,
|
|
435
|
+
sessionClientPrivateKey,
|
|
436
|
+
sessionClientPublicKey,
|
|
437
|
+
encryptionDataKeySchema,
|
|
438
|
+
capabilityTokenSchema,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Verifies encryption schemas, wraps the `data_encryption_key` and
|
|
443
|
+
* `ukyc_capability_token`, and submits both via
|
|
444
|
+
* {@link KycService.setAuthorizations}. Stores the resulting session status.
|
|
445
|
+
*
|
|
446
|
+
* @param params - Session key material and encryption schemas.
|
|
447
|
+
* @param params.sessionId - UKYC session id to authorize.
|
|
448
|
+
* @param params.sessionClientPrivateKey - Per-session X25519 private key
|
|
449
|
+
* used to seal both secrets.
|
|
450
|
+
* @param params.sessionClientPublicKey - Matching public key registered on
|
|
451
|
+
* the session (must correspond to `sessionClientPrivateKey`).
|
|
452
|
+
* @param params.encryptionDataKeySchema - Encryption schema for the data
|
|
453
|
+
* encryption key.
|
|
454
|
+
* @param params.capabilityTokenSchema - Encryption schema for the capability
|
|
455
|
+
* token.
|
|
456
|
+
* @returns The session status after authorizations are applied.
|
|
457
|
+
*/
|
|
458
|
+
async #setAuthorizations(params) {
|
|
459
|
+
const { sessionId, sessionClientPrivateKey, encryptionDataKeySchema, capabilityTokenSchema, } = params;
|
|
460
|
+
await this.#verifyWrappingKeys(encryptionDataKeySchema, capabilityTokenSchema);
|
|
461
|
+
const { wrappedEncryptionDataKey, wrappedUkycCapabilityToken } = await this.#generateWrappedAuthorizations(sessionClientPrivateKey, encryptionDataKeySchema, capabilityTokenSchema);
|
|
422
462
|
const sessionStatus = await this.messenger.call('KycService:setAuthorizations', {
|
|
423
463
|
sessionId,
|
|
424
464
|
wrappedEncryptionDataKey,
|
|
@@ -429,6 +469,52 @@ export class KycController extends BaseController {
|
|
|
429
469
|
});
|
|
430
470
|
return sessionStatus;
|
|
431
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* Mints a new per-session X25519 keypair, reissues wrapping keys for the
|
|
474
|
+
* current session, and submits wrapped authorizations.
|
|
475
|
+
*
|
|
476
|
+
* @returns The session status after authorizations are applied.
|
|
477
|
+
* @throws If there is no session on state.
|
|
478
|
+
*/
|
|
479
|
+
async #refreshAuthorizations() {
|
|
480
|
+
const sessionId = this.state.sessionStatus?.id;
|
|
481
|
+
if (!sessionId) {
|
|
482
|
+
throw new Error('No session was found');
|
|
483
|
+
}
|
|
484
|
+
const sessionClientPrivateKey = x25519.utils.randomSecretKey();
|
|
485
|
+
const sessionClientPublicKey = toBase64Url(x25519.getPublicKey(sessionClientPrivateKey));
|
|
486
|
+
const { encryptionDataKey: encryptionDataKeySchema, ukycCapabilityToken: capabilityTokenSchema, } = await this.messenger.call('KycService:resetWrappingKeys', {
|
|
487
|
+
sessionId,
|
|
488
|
+
sessionClientPublicKey,
|
|
489
|
+
});
|
|
490
|
+
return this.#setAuthorizations({
|
|
491
|
+
sessionId,
|
|
492
|
+
sessionClientPrivateKey,
|
|
493
|
+
sessionClientPublicKey,
|
|
494
|
+
encryptionDataKeySchema,
|
|
495
|
+
capabilityTokenSchema,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Refreshes and resubmits the UKYC capability authorization when the current
|
|
500
|
+
* session reports it as `new` or `expired`. Uses the `sessionStatus` already
|
|
501
|
+
* on state (callers are responsible for refreshing status when needed).
|
|
502
|
+
* No-ops when KYC has already finished (`finalStatus` is `approved` or
|
|
503
|
+
* `rejected`) or the capability token is `pending`, `stored`, or `wiped`.
|
|
504
|
+
*
|
|
505
|
+
* @returns The current or refreshed session status.
|
|
506
|
+
* @throws If there is no session on state when a refresh is required.
|
|
507
|
+
*/
|
|
508
|
+
async #refreshAuthorizationsIfNeeded() {
|
|
509
|
+
const { sessionStatus } = this.state;
|
|
510
|
+
if (!sessionStatus) {
|
|
511
|
+
throw new Error('No session was found');
|
|
512
|
+
}
|
|
513
|
+
if (!needsCapabilityAuthorizationRefresh(sessionStatus)) {
|
|
514
|
+
return sessionStatus;
|
|
515
|
+
}
|
|
516
|
+
return this.#refreshAuthorizations();
|
|
517
|
+
}
|
|
432
518
|
/**
|
|
433
519
|
* Fetches the idOS + KYC-provider disclaimer catalog. Pass exactly one of
|
|
434
520
|
* `sessionId` or `country`:
|
|
@@ -502,20 +588,20 @@ export class KycController extends BaseController {
|
|
|
502
588
|
});
|
|
503
589
|
}
|
|
504
590
|
/**
|
|
505
|
-
* Fetches session
|
|
506
|
-
* consented and credential reuse was accepted.
|
|
591
|
+
* Fetches the current session status and reports whether consent was given.
|
|
507
592
|
*
|
|
508
|
-
* @returns Whether
|
|
593
|
+
* @returns Whether `consentStatus` is `given`.
|
|
509
594
|
* @throws If there is no session on state.
|
|
510
595
|
*/
|
|
511
596
|
async hasCompletedSessionDisclaimers() {
|
|
512
597
|
if (!this.state.sessionStatus) {
|
|
513
598
|
throw new Error('No session was found');
|
|
514
599
|
}
|
|
515
|
-
// TODO:
|
|
516
|
-
//
|
|
517
|
-
|
|
518
|
-
|
|
600
|
+
// TODO: remove this explicit call to the service and use the state directly
|
|
601
|
+
// after we have established the pattern for resuming a session after wallet
|
|
602
|
+
// restart more concretely
|
|
603
|
+
const sessionStatus = await this.messenger.call('KycService:getSessionStatus', { sessionId: this.state.sessionStatus.id });
|
|
604
|
+
return sessionStatus.consentStatus === 'given';
|
|
519
605
|
}
|
|
520
606
|
/**
|
|
521
607
|
* Fetches the vendor T&Cs the customer must accept before a session is
|
|
@@ -594,25 +680,12 @@ export class KycController extends BaseController {
|
|
|
594
680
|
/**
|
|
595
681
|
* Runs the SumSub document-verification sub-flow end to end:
|
|
596
682
|
*
|
|
597
|
-
* 1.
|
|
598
|
-
* 2.
|
|
599
|
-
* idOS enclave JWKS and the `ukycCapabilityToken` schema's `jwtChain` against
|
|
600
|
-
* the idOS relay JWKS, then confirms each attested session server public
|
|
601
|
-
* key;
|
|
602
|
-
* 3. derives the `data_encryption_key` from the wallet's UKYC
|
|
603
|
-
* `local_user_secret` and wraps it for the session server;
|
|
604
|
-
* 4. mints a client-signed, read-only `ukyc_capability_token`, wraps it the
|
|
605
|
-
* same way as the encryption key, and submits both via authorizations;
|
|
606
|
-
* 5. fetches the SumSub applicant access token; and
|
|
607
|
-
* 6. presents the SDK via the injected launcher.
|
|
608
|
-
*
|
|
609
|
-
* If a UKYC session already exists (the consents path creates it before
|
|
610
|
-
* recording session disclaimers), steps 1–4 are skipped.
|
|
683
|
+
* 1. fetches the SumSub applicant access token; and
|
|
684
|
+
* 2. presents the SDK via the injected launcher.
|
|
611
685
|
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
* `vendorProcessing` status and a message rather than launching the SDK.
|
|
686
|
+
* Capability authorization must already be valid on
|
|
687
|
+
* {@link KycControllerState.sessionStatus} (see
|
|
688
|
+
* {@link KycController.#refreshAuthorizationsIfNeeded}).
|
|
616
689
|
*
|
|
617
690
|
* @param params - Optional parameters.
|
|
618
691
|
* @param params.locale - BCP-47 locale for the SDK UI.
|