feat: KYC controller#9615
Conversation
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
…b flow opening Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
ac34b99 to
a61e704
Compare
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning MetaMask internal reviewing guidelines:
Ignoring alerts on:
|
… been reset Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
| * (disclaimers, kyc-required) expect alpha-3 codes (e.g. "USA"). This map | ||
| * bridges the two. | ||
| */ | ||
| export const ALPHA2_TO_ALPHA3: Record<string, string> = { |
There was a problem hiding this comment.
thoughts on this living in a different package or in the client for now?
I think the KYC Controller interface should expect the country code to be in 3 character format
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
|
@SocketSecurity ignore npm/yargs@17.7.3 |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c1c5b57. Configure here.
| state.statusMessage = | ||
| 'Session creation failed — accept the terms to try again.'; | ||
| state.phase = 'terms'; | ||
| }); |
There was a problem hiding this comment.
Stale product after session failure
Medium Severity
When vendor session creation fails, the controller clears persisted terms and returns to the terms phase but leaves activeProduct unchanged. A later acceptTermsAndStartSession call that omits product can still auto-run the KYC check and SumSub chain for the old product, unlike initialize, which explicitly clears activeProduct when no product is passed.
Reviewed by Cursor Bugbot for commit c1c5b57. Configure here.
| state.phase = 'form'; | ||
| state.statusMessage = 'Already authenticated. Review to submit.'; | ||
| }); | ||
| await this.#continueAfterAuthentication(); |
There was a problem hiding this comment.
Duplicate complete retriggers auto flow
Medium Severity
Check and Auth frame handlers always call #continueAfterAuthentication on every active completion with an access token, with no guard for phase or an in-flight auto-continuation. A duplicate or late complete message can run checkKycRequired and startSumSub again while a prior run is still active.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit c1c5b57. Configure here.
| 'KycService:submitWrappedKey', | ||
| exchange, | ||
| ); | ||
| return refreshed.applicantAccessToken; |
There was a problem hiding this comment.
Token refresh ignores flow reset
Medium Severity
The SumSub onTokenExpiration callback always calls KycService:submitWrappedKey with the captured exchange object and never checks #generation or whether the flow was reset. After reset(), a still-open SDK can refresh tokens against a stale UKYC session.
Reviewed by Cursor Bugbot for commit c1c5b57. Configure here.
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>


@metamask/kyc-controllerOverview
@metamask/kyc-controlleris a shared, platform-agnostic KYC / identity-verification package for MetaMask clients (mobile, extension, web). It centralizes all KYC orchestration logic in thecoremonorepo so every client consumes one implementation instead of maintaining its own.What's included
Core modules
KycController(src/KycController.ts) — ABaseControllerthat owns the entire identity flow:idle → terms → session → check → auth → form → submit → done / error.blocks.moonpay.com) over dedicated channels (ch_1,ch_2,ch_reset).KycSumSubLauncheradapter, keeping the controller SDK-free while each client injects its own launcher.product(ramps|card) passed toinitialize/acceptTermsAndStartSessionis stored asactiveProduct. Once authentication reaches theformphase, the controller automatically runs the KYC-required check and, when KYC is required, chains into the SumSub sub-flow — with no extra consumer calls. Without aproduct, the flow stops atformfor manual control (checkKycRequired/startSumSub).KycService(src/KycService.ts) — A data service that performs the Universal KYC (UKYC) HTTP calls via an injectedfetch. It wraps requests withcreateServicePolicyfor resilience, validates responses withsuperstruct, and sources the auth bearer token (fromprofile-sync-controller) and geolocation (fromgeolocation-controller) through the messenger. It also accepts an optionalbaseUrlto override theenv-derived URL for local/staging APIs.Supporting modules
crypto.ts— X25519 key-pair generation and encrypted-credential decryption.countryCodes.ts— ISO 3166-1 alpha-2 → alpha-3 country-code mapping.selectors.ts— Memoized state selectors (selectKycPhase,selectKycSumSub,selectIsKycRequiredForProduct).types.ts— Shared vendor-neutral types (KycPhase,KycProduct,KycVendor,KycSumSubLauncher,KycDisclaimer, etc.).KycController-method-action-types.ts/KycService-method-action-types.ts— Messenger action type definitions for the controller and service.index.ts— Explicit (non-barrel) exports defining the package's public API.Tests
Comprehensive Jest test suites covering the controller, service, crypto, country codes, selectors, and the index/public API (
KycController.tsat 100% coverage, including the new auto-continuation paths).Package scaffolding & monorepo wiring
package.json,tsconfig.json,tsconfig.build.json,jest.config.js,typedoc.json,CHANGELOG.md,README.md, and theLICENSE,LICENSE.APACHE2, andLICENSE.MITfiles.tsconfig.json/tsconfig.build.jsonproject references, added to the rootREADME.mdpackage list, and reflected inyarn.lock.Public API
The package explicitly exports:
KycController,getDefaultKycControllerState,controllerName, plus its messenger, options, state, action, and event types.initialize/acceptTermsAndStartSessionaccept an optionalproductto enable the automatic post-authentication continuation.KycService,serviceName, plus its messenger, options, params, response, action, and event types.selectIsKycRequiredForProduct,selectKycPhase,selectKycSumSub.alpha2ToAlpha3,ALPHA2_TO_ALPHA3,decryptCredentials,generateKeyPair, and related crypto/domain types.Note
The SumSub sub-flow currently uses placeholders (
MOCK_JWT_TOKENand a hardcodedvendorUserId), which must be replaced with real UKYC-issued credentials before production use.Checklist
Note
High Risk
New identity/KYC orchestration handles auth tokens, frame crypto, and profile-sync bearer tokens; SumSub paths still rely on mock UKYC credentials until production wiring lands.
Overview
Introduces
@metamask/kyc-controller, a new monorepo package that centralizes KYC / identity verification for MetaMask clients behind a vendor-neutralramps/cardAPI.KycControllerorchestrates the full flow (terms → session → MoonPay Check/Auth frames → KYC-required check → SumSub via an injectedKycSumSubLauncher), including X25519/AES-GCM frame credential decryption, messenger-exposed actions, and persisted per-product KYC-required cache. Optionalproductoninitialize/acceptTermsAndStartSessionsetsactiveProductso that after authentication the controller can automatically runcheckKycRequiredand chain into document verification when needed; without a product, behavior stops atformfor manual control.KycServiceis a stateless UKYC HTTP client (superstruct validation, service policy, auth bearer token and geolocation via messenger) with an optionalbaseUrloverride for non-production APIs.The root
README,tsconfigproject references, package scaffolding, docs, and Jest suites (100% coverage target on the controller) are included. Note: SumSub UKYC integration still uses placeholder JWT / vendor user id values called out for replacement before production.Reviewed by Cursor Bugbot for commit 1ef2e8d. Bugbot is set up for automated code reviews on this repo. Configure here.