feat: KYC controller - #9615
Conversation
ac34b99 to
a61e704
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning MetaMask internal reviewing guidelines:
Ignoring alerts on:
|
| * (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
|
@SocketSecurity ignore npm/yargs@17.7.3 |
|
@metamaskbot publish-preview |
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>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
… been reset 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>
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>
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>
|
@metamaskbot publish-preview |
Signed-off-by: Sébastien Van Eyck <sebastien.vaneyck@consensys.net>
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
|
@metamaskbot publish-preview |
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
## Summary - `neobank-demo` already includes Sébastien’s `feat/kyc-controller` stack and the Iron feature commit from #9852 (`a40fa2fc3f`, merged by George). - This PR cherry-picks the remaining #9852 CI fixes (`lint` / changelog PR link / `oxfmt`) so the demo branch matches the Iron tip for package publish/preview and mobile consumption. - Keeps #9852 targeting `feat/kyc-controller` for the eventual mainline path via #9615. Does **not** merge to `main`. ## Context (demo topology) - Integration branch: `neobank-demo` (owner: @georgeweiler) — umbrella PR #9853 → `main` - Iron feature PR (mainline stack): #9852 → `feat/kyc-controller` - KYC controller PR: #9615 → `main` ## Test plan - [ ] Confirm diff is formatting/lint/changelog only (no Iron behavior change) - [ ] CI green on this PR - [ ] After merge, `@metamaskbot publish-preview` on #9853 (or this PR) if mobile needs a preview pin of `@metamask/kyc-controller` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes the failing lint:misc:check CI job by applying formatter fixes (import ordering, line wrapping, trailing newline). Co-authored-by: Cursor <cursoragent@cursor.com>
mcmire
left a comment
There was a problem hiding this comment.
One nitpick, but it can be addressed later. LGTM.
|
|
||
| ### Added | ||
|
|
||
| - Add `KycController.getCustomerIdentity()` method and the `KycController:getCustomerIdentity` messenger action (plus the exported `KycControllerGetCustomerIdentityAction` and `KycCustomerIdentity` types). Returns the vendor-scoped `{ vendor, id }` for the currently authenticated customer, or `null` before authentication and after `reset()`. Lets consumers (e.g. ramps autoramp creation) attach the vendor customer id to downstream calls without reading the full KYC state, which also holds session/access tokens. The id is session-scoped and never persisted. ([#9852](https://github.com/MetaMask/core/pull/9852)) |
There was a problem hiding this comment.
Has kyc-controller been released yet? We tend to treat the changelog like release notes, so each section lists differences from the previous version. For the first version of a package there isn't a previous version — everything is new — so it's often enough to have a single bullet point in ### Added that says something like "Initial release of the @metamask/kyc-controller" and maybe lists some highlights of the controller (interesting features, etc.) below it.
This isn't something you have to change now but make sure to change it when you make a release.
@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 surface handling access tokens, encryption keys, JWT attestation, and user storage; incorrect flow guards or crypto could block verification or mishandle secrets, and mock JWT remains for production.
Overview
Adds
@metamask/kyc-controller, a new shared package that orchestrates vendor-neutral KYC forrampsandcard:KycControllerruns the phase machine (terms → MoonPay Check/Auth frames → KYC-required → SumSub), decrypts frame credentials (X25519/AES-GCM), andKycServicecalls the Universal KYC API with bearer auth, geolocation, retries, and superstruct validation.Product-scoped flows store
activeProductand, after authentication, automatically run the KYC-required check and chain into document verification when needed;reset()and generation/phase guards prevent stale async work and late frame messages from corrupting state. The SumSub path adds UKYC wrapping-key verification (JWKSjwtChain),local_user_secretvia User Storage, read-onlyukyc_capability_token, SDK launch through an injectedKycSumSubLauncher, and post-SDK session-status polling.Monorepo updates assign Universal KYC ownership, wire the package into the dependency graph, relax ESLint for the dev
mint:ukyc-tokenscript, and document architecture inARCHITECTURE.md. Note:startSumSubstill uses aMOCK_JWT_TOKENplaceholder until real UKYC credentials are wired.Reviewed by Cursor Bugbot for commit 5a29cbb. Bugbot is set up for automated code reviews on this repo. Configure here.