Neobank demo - #9853
Draft
georgeweiler wants to merge 79 commits into
Draft
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>
Contributor
|
@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>
Merged
7 tasks
…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>
4 tasks
## 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>
Contributor
|
@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.
8 tasks
…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)
Contributor
|
@metamaskbot publish-preview |
Contributor
|
Preview builds have been published. Learn how to use preview builds in other projects. Expand for full list of packages and versions. |
3 tasks
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>
amitabh94
added a commit
to MetaMask/metamask-mobile
that referenced
this pull request
Aug 13, 2026
## 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>
georgeweiler
marked this pull request as draft
August 17, 2026 13:01
dan437
removed their request for review
August 18, 2026 09:39
4 tasks
| } | ||
|
|
||
| this.update((state) => { | ||
| delete state.ensEntries[chainId][normalizedEnsName]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

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.