Neobank demo - #9853
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>
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>
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-previews |
|
KYC + Iron status on this demo branch: For mobile demo consumers: after #9855 merges, comment |
## 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>
|
@metamaskbot publish-preview |
The constant was annotated with the full RampsService/TransakService/ NeoBankService action unions, so spreading it into a messenger delegation widened the element type to every service action. Hosts that only delegate the actions RampsController actually calls (mobile) failed to typecheck once NeoBankService grew Pix and quote methods. Use `as const satisfies` so the type is the literal members while still being checked against the service action unions. Also record the kyc-controller dependency in the tsconfig project references so the package builds. Co-authored-by: Cursor <cursoragent@cursor.com>
…demo Keeps both sides of the KYC surface: the demo's `getCustomerIdentity` action and the incoming Money Account wallet registration APIs. Adds the missing `keyring-controller` project reference to the kyc-controller tsconfigs, which the incoming ownership-message signing imports but did not declare. Co-authored-by: Cursor <cursoragent@cursor.com>
Add an address-only KycController action that resolves the MoonPay customer, signs a Monad ownership proof, and registers the wallet through the MetaMask proxy.
Retarget Money Account self-hosted wallet registration from kyc-api /vendors/moonpay/* to onramp-api neobank-proxy /neobank/... so Core matches Money Movement ownership and transparent proxy semantics.
Prefer KycController identity when present, otherwise map the Profile Sync id through NeoBankService.getCustomerByExternalId so autoramp creation works before KYC has cached a MoonPay customer id. Co-authored-by: Cursor <cursoragent@cursor.com>
Reconciles the independently pushed wallet-registration commits with the local merge of feat/moonpay-wallet-registration-stacked. Co-authored-by: Cursor <cursoragent@cursor.com>
…r to ramps-controller (#9858) ## Summary Money Account self-hosted wallet registration (proving wallet ownership to MoonPay Iron via the neobank-proxy) lived in `@metamask/kyc-controller`. This PR moves it to `@metamask/ramps-controller`, which is the correct Money Movement owner, and removes the ramps→kyc package dependency that broke the monorepo TypeScript project-reference build. - Moved `wallet-registration-service.ts`, `wallet-registration-machine.ts`, `ownership-message.ts` (and tests) from `packages/kyc-controller/src` to `packages/ramps-controller/src`. - Moved `registerMoneyAccountWallet` from `KycController` to `RampsController` (resolves customer id via `resolveAutorampCustomerId`, signs via `KeyringController:signPersonalMessage`, submits via `NeoBankService`). - Moved the three wallet HTTP methods from `KycService` to `NeoBankService` (`getMoonpayCustomerId`, `getWalletRegistrationStatus`, `registerSelfHostedWallet`), built lazily so an invalid environment only throws at request time. Removed the `neobankBaseUrl` KycService option. - Removed the `@metamask/kyc-controller` dependency (package.json + both tsconfigs) from `ramps-controller`, and the unused `@metamask/keyring-controller` dependency from `kyc-controller`. `RampsController` now declares local structural types for the two type-only messenger actions it needs, so the packages are decoupled in the build graph. - Regenerated messenger action types for both packages, updated both `index.ts` export surfaces, moved/ported wallet-registration tests into ramps, and updated both CHANGELOGs. ## Why 1. **Architectural ownership** — wallet ownership signing is a Money Movement / neobank-proxy concern, not KYC identity. 2. **Unblocks monorepo build / preview publish** — the ramps→kyc package dependency caused TS6059 / TS6307 with project references and blocked `@metamaskbot publish-preview` on core PR #9853. ## Test plan - [x] `yarn build` (full monorepo, with project references) — exit 0; kyc-controller and ramps-controller build cleanly - [x] `yarn workspace @metamask/kyc-controller test` — passing, 100% coverage - [x] `yarn workspace @metamask/ramps-controller test:verbose` — 842/842 tests, 18/18 suites (coverage thresholds for pre-existing untested areas like `autoramp-syncing/controller-integration.ts` are pre-existing on `neobank-demo`, not introduced here) - [x] `yarn workspace @metamask/kyc-controller messenger-action-types:check` — up to date - [x] `yarn workspace @metamask/ramps-controller messenger-action-types:check` — up to date - [x] `yarn eslint packages/kyc-controller/src` — clean - [ ] Confirm CI build / typecheck / tests are green on this PR before merge Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
#9859) ## Summary - `RampsController.resolveAutorampCustomerId()` no longer calls `KycController:getCustomerIdentity`. Autoramp / Money Account wallet registration always resolve the MoonPay customer id via Profile Sync (`AuthenticationController:getSessionProfile`) → `NeoBankService:getCustomerByExternalId`, preferring `canonicalProfileId` then `profileId` (same pattern as `NeoBankService.#getCanonicalExternalId`). - Removed the local `KycControllerGetCustomerIdentityAction` type, its `AllowedActions` union entry, index export, and the action from `RAMPS_CONTROLLER_REQUIRED_CONTROLLER_ACTIONS`. - Updated createAutoramp / registerMoneyAccountWallet tests and CHANGELOG Unreleased. ## Residual risk Iron / MoonPay customers must already be mapped by external id for `createAutoramp` and `registerMoneyAccountWallet` to succeed. There is no longer a KYC-session identity shortcut. ## Test plan - [x] `yarn workspace @metamask/ramps-controller test --coverage=false --reporters=default` → 18 suites / 843+ tests passed - [x] Focused createAutoramp / registerMoneyAccountWallet cases pass - [ ] Host apps: confirm they no longer need to delegate `KycController:getCustomerIdentity` to the RampsController messenger for autoramp / wallet registration - [ ] Manual: autoramp create + Money Account wallet registration with a profile that has a neo-bank external-id mapping Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary - Fix eslint/oxfmt issues blocking lint on the neobank-demo stack (NeoBankService naming, test titles, return types, JSDoc, MethodActions export) - Add `#9853` Unreleased changelog PR links for kyc/ramps/profile-sync/transaction-pay - Fix transaction-pay jest `resolves` matchers restricted by eslint ## Test plan - [x] `yarn eslint` on ramps-controller + fixed transaction-pay test - [x] `yarn lint:misc --check` on touched packages - [x] `yarn workspace @metamask/ramps-controller messenger-action-types:check` - [ ] CI lint jobs on this PR / #9853 after merge Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
|
@metamaskbot publish-preview |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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 c6b9443. Configure here.
…9861) ## Summary Fixes the three real CI failures on [#9853](#9853) and resolves the outstanding Cursor/Bugbot findings. ### CI failures fixed | Failing check | Root cause | Fix | | --- | --- | --- | | `Build (24.x)` | `TS2345`/`TS2739` in `RampsController.addAutoramp` — the inline union check did not narrow `AutorampAccount` | Extracted an `isFullAutorampAccount` type guard | | `Lint (messenger-action-types:check)` | `TransactionPayController-method-action-types.ts` was stale after a JSDoc update to `vaultIronPayout` | Regenerated via `messenger-action-types:generate` | | `Test (18/20/22.x) (@metamask/ramps-controller)` | Coverage below thresholds (statements 96.94%, branches 93.50%, functions 97.04%, lines 96.96%) | Added tests; now 100% statements/functions/lines and 98.41% branches | ### Cursor/Bugbot findings - **Unsafe timer unref call** (high) — `#ensureUserStatusPolling` called `.unref()` directly, which throws in React Native/browser where timers are numbers. Now `unref?.()`. - **Unguarded status write after reset** (medium) — the `session_not_in_valid_state` path called `#applyUserStatus` with no generation check, so a `reset()` mid-flight could force `userStatus: completed` and publish `statusChanged` on an idle controller. Added the generation guard. - **Wrong vendor on customer identity** (medium) — `moonpayCustomerId` survived a switch to another vendor, so `getCustomerIdentity` could report a MoonPay id under `iron`. It is now cleared in `initialize` (non-MoonPay vendor) and `createIronCustomer`. - **Empty remote fields wipe local** (medium) — the `??` merge introduced for lint let an empty-string remote `customerId`/`walletAddress` overwrite valid local values. Restored explicit non-empty checks in `applyAutorampRemoteStatus` and `mapNeoBankAutorampToRemoteSnapshot`. ## Notes - The three defensive guards marked `/* istanbul ignore next */` in `controller-integration.ts` are unreachable through the public surface (every caller filters on `isSyncableAutoramp` or a non-empty storage key). The unused default parameter on the private `saveAutorampsToUserStorage` was dropped instead. ## Test plan - [x] `yarn workspace @metamask/ramps-controller run test` — pass, thresholds met - [x] `yarn workspace @metamask/kyc-controller run test` — pass, 100% coverage - [x] `yarn workspace @metamask/transaction-pay-controller run test` — pass - [x] `yarn build` — pass - [x] `yarn lint:tsc` — pass - [x] `yarn messenger-action-types:check` — pass - [x] `eslint` + `oxfmt --check` on all changed files — pass - [x] `changelog:validate` for the three packages — pass Made with [Cursor](https://cursor.com)
|
@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. |
A single autoramp creation attempt fired the same request four times because the service policy retried MoonPay's 403 "Customer is not active", which is a statement about account state and never resolves by re-issuing the request. Filter retries to 429, 5xx, and non-HTTP errors, matching the existing chomp-api-service and subscription-controller policies. Also surface the upstream response body in HttpError. The neobank proxy mirrors MoonPay's body verbatim and it is usually the only explanation of a 4xx, so dropping it left failures undiagnosable. Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary - Replaces `file:../core/packages/...` linking for `@metamask/kyc-controller` and `@metamask/ramps-controller` with published MetaMask core preview packages so the `demo/vba-kyc` branch can be shared without a sibling core build. - Pins from MetaMask/core#9853 preview publish (`-preview-c34a16a37`), comment: MetaMask/core#9853 (comment) ### Exact version pins | Package | Version | | --- | --- | | `@metamask/kyc-controller` | `npm:@metamask-previews/kyc-controller@0.0.0-preview-c34a16a37` | | `@metamask/ramps-controller` | `npm:@metamask-previews/ramps-controller@20.0.0-preview-c34a16a37` | Updated in both `dependencies` and `resolutions`. **Note:** Re-bump these pins when a new `@metamaskbot publish-preview` lands on core#9853 (or a follow-up PR). ## Test plan - [ ] `yarn install` resolves the preview packages (no `file:../core` links) - [ ] `yarn start:ios` (run `yarn pod:install` if native deps need refresh) - [ ] Smoke NeoBank / VBA KYC entry and Money Account wallet registration flows that depend on these controllers Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>

Explanation
References
Checklist
Note
High Risk
New identity/KYC orchestration touches auth tokens, encrypted frame credentials, UKYC crypto, and cross-vendor state; incorrect async/reset handling could leak stale customer ids or completion status (mitigated by extensive tests in the diff).
Overview
Introduces
@metamask/kyc-controller, a platform-agnostic package that centralizes identity/KYC across clients:KycController(phase machine, MoonPay Check/Auth frames + X25519 decrypt, UKYC/SumSub via injected launcher) andKycService(UKYC + vendor HTTP via messenger auth/geolocation).Iron / Money (VBA) is added as a second vendor: no MoonPay frames; Iron customer creation, Iron disclaimers,
POST /consents,GET /kyc/status,refreshKycStatus+statusChanged, and user-status polling.getCustomerIdentity()exposes a session-scoped vendor customer id for downstream calls (e.g. ramps).Wallet registration (MoonPay customer id, self-hosted wallet) is removed from KYC and documented as moving to
@metamask/ramps-controller/NeoBankService. README dependency graph addskyc_controllerandtransaction_pay_controller→ money_account_utils.Repo hygiene: Universal KYC CODEOWNERS, ESLint relaxations for
kyc-controller/scripts,build:watch,mint:ukyc-tokendev CLI, and a largeARCHITECTURE.md. Changelog also notes fixes for vendor id clearing on vendor switch, safe pollunref()outside Node, and ignoring latesession_not_in_valid_stateafterreset().Reviewed by Cursor Bugbot for commit 8bc742f. Bugbot is set up for automated code reviews on this repo. Configure here.