Repository navigation
feat(ramps-controller): return VBA onboarding facts instead of a screen stage - #10354
Conversation
…en stage Hosts should own funnel order. Hydrate now exposes KYC and activation facts, and drops the persisted VbaOnboardingStage enum. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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 8edab69. Configure here.
| return true; | ||
| } | ||
| return stage; | ||
| return session.externalUserId === canonicalId; |
There was a problem hiding this comment.
Hydrate throws on profile read failure
Medium Severity
#isVbaSessionOwnedByCurrentProfile lets a rejected AuthenticationController:getSessionProfile escape, so hydrateVbaOnboarding throws for a persisted session instead of keeping it and returning facts. A signed-out, locked, or expired Profile Sync session now fails resume before KYC approval, where this call was not previously required.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 8edab69. Configure here.
Co-authored-by: Cursor <cursoragent@cursor.com>
…A snapshot Drop relay/applicant status from hydrateVbaOnboarding. Hosts map overall KYC outcome and autoramp setup, while remaining session statuses stay on KycController. Co-authored-by: Cursor <cursoragent@cursor.com>
## Explanation Cut `@metamask/ramps-controller@25.0.0` so Mobile can consume the VBA onboarding snapshot from MetaMask#10354, plus a required patch of `@metamask/transaction-pay-controller@29.1.1` because it is a workspace dependent of that major bump. Ramps is a **major** because `RampsController:hydrateVbaOnboarding` now returns `VbaOnboardingSnapshot` instead of `VbaOnboardingStage`, and `RampsControllerMessenger` requires `KycController:clearState`. ## References - Core feature: MetaMask#10354 - Mobile consumer: MetaMask/metamask-mobile#36522 - Previous ramps release: MetaMask#10326 ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [x] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them ## Test plan - [ ] Changelog for `@metamask/ramps-controller` 25.0.0 looks correct (no Uncategorized) - [ ] Changelog for `@metamask/transaction-pay-controller` 29.1.1 looks correct (no Uncategorized) - [ ] Published packages: ramps-controller `24.0.0` → `25.0.0`, transaction-pay-controller `29.1.0` → `29.1.1` - [ ] After merge, confirm GitHub release tags and npm publish of both packages Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Introduces the Mobile-owned Virtual Bank Account onboarding model on top of the published `@metamask/ramps-controller@25.0.0` snapshot API. Core supplies independent backend facts. Mobile composes those facts with locally persisted pre-email Terms 1 acceptance, maps them to the first incomplete route, and exposes a hydration/resume hook for later entry and retry integrations. This foundation does not expose a new user entry point by itself. Stack: 1 of 4 for MetaMask#36522. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** N/A — this foundation is covered by focused unit tests for every routing state, local Terms 1 persistence, and hydration/error behavior. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) - [x] I've tested on Android - [x] I've tested with a power user scenario - [x] I've instrumented key operations with Sentry traces for production performance metrics ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- Generated with the help of the pr-description AI skill --> Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Stack position: 2 of 7. Depends on merged MetaMask#36707. Renames the Pix-specific activation screen and route to Virtual Bank Account terminology, applies the regional account activation design and copy, and updates navigation, analytics locations, test IDs, and translations. No onboarding sequencing behavior changes in this layer. ## **Changelog** CHANGELOG entry: Updated the Virtual Bank Account activation experience ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Virtual Bank Account activation screen Scenario: user opens account activation Given the user enters the VBA activation flow When the activation screen opens Then the regional account benefits and provider terms are displayed ``` ## **Screenshots/Recordings** N/A — draft stack layer verified with focused automated tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — pending full-stack manual validation. - [x] Power-user testing assessed — N/A for this screen rename. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches VBA KYC onboarding navigation and legal disclaimer presentation; a broken route or consent gate could block account activation, though flow logic is largely preserved. > > **Overview** > Replaces the **Get Pix Key** VBA step with **Create Virtual Bank Account**: the screen, route (`RampCreateVirtualBankAccount`), nav types, analytics location, and test IDs are renamed, and **`GetPixKey`** is removed in favor of a new activation UI. > > The activation experience is reframed for regional virtual bank accounts (hero, three benefit rows, **Activate Virtual Bank Account** CTA) instead of Pix branding. KYC disclaimer handling is unchanged in flow—still gated on loaded disclaimers, **accept** then navigate to verify identity—but the layout moves to footer inline agreement links (with prefix/separator strings) rather than a separate disclosures block with skeleton **`LegalLink`** rows. > > **Kyc email** still starts the KYC session and now navigates to the new route. Navigator registration and tests follow the same VBA screen group. English i18n keys and copy are updated under **`create_virtual_bank_account`**; other locale files mostly rename the key while keeping prior Pix-oriented strings. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5bbda92. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Cursor <cursoragent@cursor.com>
…mail (MetaMask#36763) ## **Description** Stack position: 1 of 5 remaining. Depends on merged MetaMask#36709. Persists the Terms 1 disclaimer IDs for the selected wallet, creates the vendor session from the submitted email, and records the accepted vendor disclaimers before the onboarding flow advances. ## **Changelog** CHANGELOG entry: Added Virtual Bank Account Terms 1 acceptance and email handoff ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Virtual Bank Account Terms 1 and email handoff Scenario: user accepts Terms 1 and submits an email Given the provider disclaimers are loaded for the selected wallet When the user accepts the terms and submits a valid email Then the acceptance is persisted and recorded on the created vendor session ``` ## **Screenshots/Recordings** N/A — behavior-only stack layer covered by focused automated tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — N/A for this behavior-only stack layer. - [x] Power-user testing assessed — N/A for this behavior-only stack layer. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes KYC consent timing and navigation in the VBA onboarding path; incorrect handoff could block users or fail to record vendor disclaimers, though behavior is covered by focused hook/screen tests. > > **Overview** > Reorders Virtual Bank Account KYC so **Terms 1** (MoonPay vendor disclaimers) can be accepted before email, while still recording consent with the vendor only after a session exists. > > On **Activate VBA**, agreeing now **persists accepted disclaimer IDs locally** for the selected wallet (via `saveVbaTermsOneAcceptance`) and navigates to **`VBA_KYC_EMAIL`** instead of identity verification. **`useKycDisclaimers`** no longer calls `recordVendorDisclaimers` on accept; it passes **geo `country`** into `fetchVendorDisclaimers` and adds **Logger** diagnostics when loads fail or return empty. > > On the **email step**, **`useKycEmailVerification`** starts the vendor session, then **reads stored Terms 1 ids**, calls **`recordVendorDisclaimers`** when present, or skips recording if **`hasCompletedVendorDisclaimers`** is already true; missing local acceptance without prior vendor completion surfaces a **user-facing error** and blocks navigation. Success routes to **`VBA_VERIFY_IDENTITY`** (Terms 2) rather than back to the activation screen. > > Tests are updated to match the new navigation and storage/handoff behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a4e5741. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Stack position: 4 of 8. Depends on merged MetaMask#36763. Renames the legacy “Terms 1” vocabulary to vendor terms across local acceptance storage, onboarding facts, hooks, and tests. This is a terminology-only refactor; the persisted storage key remains unchanged for compatibility. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: VBA vendor terms naming Scenario: existing vendor terms acceptance remains usable Given vendor terms acceptance is persisted for a wallet When VBA onboarding resumes Then the existing acceptance is read through the renamed vendor terms API ``` ## **Screenshots/Recordings** N/A — terminology-only refactor covered by focused tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I’ve followed MetaMask contributor and mobile coding standards. - [x] I’ve completed the PR template to the best of my ability. - [x] I’ve included tests if applicable. - [x] I’ve documented the code where applicable. - [x] I’ve applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — N/A for a terminology-only refactor. - [x] Power-user testing assessed — N/A. - [x] Performance tracing assessed — N/A; no runtime behavior was added. ## **Pre-merge reviewer checklist** - [ ] I’ve manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Terminology and symbol renames only; onboarding behavior and local storage keys are unchanged, with coverage updated in focused tests. > > **Overview** > Replaces legacy **“Terms 1”** wording with **vendor terms** across the Virtual Bank Account KYC flow: local acceptance storage APIs, onboarding snapshot/funnel fields, hooks, UI comments, and tests. **Provider terms** replaces **Terms 2** in docs and test names where the post-email step is described. > > The onboarding snapshot flag becomes `vendorTermsAcceptedLocally`, and the funnel step id becomes `vendorTerms`; completion logic is unchanged. Module and exports move from `vbaTermsOneStorage` to `vbaVendorTermsStorage` (`save` / `get` / `hasAccepted` helpers renamed accordingly). > > **Persisted storage keys are unchanged** (`@MetaMask:vbaTermsOneAccepted:v1:…`), so existing on-device acceptance data keeps working after the rename. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 5d6cfb2. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Stack position: 1 of 4 remaining VBA onboarding PRs. This PR has no UI. It is the coordinator that decides where a Virtual Bank Account user should be in onboarding. Previously, each screen knew what came next. Resume was guesswork, and inserting or reordering steps required changing every screen. Now one snapshot from `hydrateVbaOnboarding` is the source of truth. `getVbaDestinationForSnapshot` walks three client-owned modules — vendor terms, email, identity verification — and returns the first incomplete one. If all are complete, it maps controller status to pending, rejected, complete, or a provisioning error. Everything goes through `useOpenVbaOnboarding`: entry, retry, and module completion all re-read facts and open the first incomplete destination. VBA screens live behind one feature-local navigator. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Modular VBA onboarding coordination Scenario: onboarding resumes from persisted facts Given a hydrated VBA onboarding snapshot When the coordinator resolves the first incomplete module Then it selects the corresponding feature-local route ``` ## **Screenshots/Recordings** N/A — architecture-only stack layer covered by unit tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — N/A for this architecture-only stack layer. - [x] Power-user testing assessed — N/A for this architecture-only stack layer. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
… KYC (MetaMask#36765) ## **Description** Stack position: 1 of 4 remaining VBA onboarding PRs. Depends on merged MetaMask#36764. This PR adds the host: a feature-local VBA navigator and thin adapters that render the coordinator destinations. Vendor terms and email become callback-driven modules. Completing a module calls `useOpenVbaOnboarding` so the coordinator re-reads facts and opens the next destination. Identity verification is still a placeholder here. Status screens (pending, rejected, provisioning error, recoverable error) are stubs that retry through the same coordinator API. The platform-owned navigation change is isolated in this layer: one `Routes.RAMP.VBA_ONBOARDING` screen in the main navigator, with VBA screens living behind it. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Modular VBA onboarding host Scenario: a module completes Given the VBA onboarding host is displaying the current module When that module reports success Then the coordinator hydrates state and opens the next incomplete module ``` ## **Screenshots/Recordings** N/A — navigation architecture is covered by focused component and navigation tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — N/A for this navigation architecture layer. - [x] Power-user testing assessed — N/A for this navigation architecture layer. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Stack position: 2 of 4 remaining VBA onboarding PRs. Depends on MetaMask#36765. Replaces the temporary KYC email screen integration with a small, replaceable email-module contract. `EmailOtpStub` collects an email and reports it through `onSuccess`; `VbaEmailAdapter` owns session creation, vendor-terms persistence, errors, and advancing through the coordinator. The stub also exposes `onBack` and retains the standard header/top inset. The Accounts team can replace this UI with its shared email OTP flow without moving VBA business logic into that component. Legacy email files remain temporarily for stack compatibility and are removed in the final cleanup PR. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Replaceable VBA email module Scenario: email collection succeeds Given the user has accepted vendor terms When the email module reports an email Then the adapter starts the KYC session, records vendor terms, and resumes onboarding ``` ## **Screenshots/Recordings** N/A — temporary stub UI covered by focused tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — N/A for this module boundary refactor. - [x] Power-user testing assessed — N/A. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. Made with [Cursor](https://cursor.com) Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Third of four PRs splitting up Virtual Bank Account onboarding. Depends on MetaMask#36800. This one is about the identity check. It has two screens: 1. **Verify your identity** — explains what the user will be asked for, links the provider's terms, and has a Continue button. 2. **A loading screen** that opens the SumSub identity app on top of it. Before this change those two screens were registered separately in the app's main navigator, and each decided on its own where to go next. Now they sit in their own small navigator behind a single entry, and only the final step reports back to the rest of onboarding. If the user has already agreed to the provider's terms, they skip straight to step 2. The PR also covers what happens when SumSub closes: - **Documents submitted** — onboarding continues, and the next screen is chosen from what the wallet already knows about the user. - **User backed out early** — shows "More information needed" with a button to reopen SumSub, instead of treating it as a failure. - **Something went wrong** — shows an error with Try again, instead of silently bouncing back to the previous screen. Two smaller changes worth flagging for review: - The provider's terms are now accepted immediately before SumSub opens, not on the earlier screen. Doing it in two separate steps made the provider reject the request with "Failed to get applicant". - Deleted `useKycStartSession`, which used to start the verification session here. The session is already created when the user enters their email, so this was a second, redundant call. ## **Changelog** CHANGELOG entry: Added Virtual Bank Account identity verification outcome handling ## **Related issues** Refs: MetaMask/core#10354 Depends on: MetaMask/core#10457 ## **Manual testing steps** ```gherkin Feature: VBA identity verification Scenario: the user finishes identity verification Given the user has entered their email and reached identity verification When they accept the provider terms and submit their documents in SumSub Then onboarding continues to the next step Scenario: the user closes SumSub before submitting Given the user has opened SumSub When they close it without submitting documents Then they see "More information needed" and can reopen SumSub ``` ## **Screenshots/Recordings** N/A — covered by automated tests; screens are verified as part of the full-stack manual pass. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — pending full-stack manual validation. - [x] Power-user testing assessed — N/A. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes KYC consent timing, SumSub launch, and VBA resume routing in a regulated identity flow; mistakes could block verification or mis-route users, though behavior is heavily covered by new tests. > > **Overview** > **VBA identity verification** is folded into a single onboarding module with an internal two-step flow (provider terms → SumSub host), and the legacy top-level `VBA_VERIFY_IDENTITY` route is removed from the main navigator. > > **Verify Identity** no longer starts KYC on Continue; it only advances to the SumSub screen. **`useKycStartSession` is removed** in favor of **`useLaunchSumSub`**, which records session consents immediately before `launchProviderFlow` so consent and SDK launch stay atomic. **`VbaSumSubKyc`** handles outcomes: submission resumes onboarding via the coordinator, early exit shows “More information needed,” and failures show a retry UI instead of navigating back. > > **Onboarding funnel and resume** now use **`providerFlowStatus`** (with bumps to `@metamask/kyc-controller` and `@metamask/ramps-controller`) so abandoned or in-progress SumSub flows return to identity verification, while submitted flows route to KYC pending. **Email** can prefill/lock a bound KYC email, and vendor disclaimer recording is retried on resume without blocking advance when local terms are missing. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit a9937ef. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
## **Description** Stack position: 4 of 4 remaining VBA onboarding PRs. Depends on MetaMask#36710. Updates Add Money to open the modular VBA onboarding coordinator, allowing returning users to resume from controller state, and tracks the unified VBA onboarding event location. ## **Changelog** CHANGELOG entry: Added resumable Virtual Bank Account onboarding from Add Money ## **Related issues** Refs: MetaMask/core#10354 ## **Manual testing steps** ```gherkin Feature: Resume VBA onboarding from Add Money Scenario: returning user opens Virtual Bank Account onboarding Given the user has incomplete VBA onboarding state When the user selects Virtual Bank Account from Add Money Then onboarding resumes at the first incomplete module ``` ## **Screenshots/Recordings** N/A — entry-point integration is covered by focused automated tests. ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask contributor and mobile coding standards. - [x] I've completed the PR template to the best of my ability. - [x] I've included tests if applicable. - [x] I've documented the code where applicable. - [x] I've applied the appropriate labels. #### Performance checks (if applicable) - [x] Android testing assessed — pending full-stack manual validation. - [x] Power-user testing assessed — N/A for this entry-point layer. - [x] Performance tracing assessed — N/A; no performance-sensitive operation was added. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR. - [ ] I confirm that this PR addresses its stated scope and includes appropriate testing evidence. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes VBA entry routing and removes legacy routes/screens; incorrect coordinator behavior could block bank-account onboarding or break deep links still targeting removed route names. > > **Overview** > **Add Money** no longer deep-links to the legacy KYC email screen. Tapping **Bank account** closes the sheet and calls **`useOpenVbaOnboarding`**, which hydrates onboarding state and navigates to **`RampVbaOnboarding`** at the first incomplete module (fresh users vs. returning users). > > Navigation is simplified to a **single feature-level VBA route**: transitional stack screens (`VBA_KYC_EMAIL`, `CREATE_VIRTUAL_BANK_ACCOUNT`, adapters) and their route constants/types are removed from **`MainNavigator`**, **`Routes`**, and navigation types. The standalone **`KycEmail`** UI and **`useKycEmailVerification`** hook (and tests) are deleted. > > Money analytics now report **`vba_onboarding`** instead of separate VBA KYC / create-account screen names; tests assert the coordinator is invoked rather than **`navigate('RampVbaKycEmail')`**. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 9e6d848. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>


Explanation
RampsController:hydrateVbaOnboardingcurrently returns a linearVbaOnboardingStageand persists it. That encodes product funnel order in Core, so a design change such as putting vendor terms before email requires a controller release.This PR keeps Core responsible for backend onboarding facts and money-account activation while removing screen and route concepts:
hydrateVbaOnboardingreturns aVbaOnboardingSnapshotcontainingsessionExists, disclaimer completion flags,kycStatus,finalStatus, andactivation.vbaOnboardingStagestate field andVbaOnboardingStageenum are removed.finalStatus === 'approved', wallet registration and autoramp creation still run as a coalesced operation.activation: 'retryable_failure'instead of turning hydration into a fatal error.Mobile owns the funnel in MetaMask/metamask-mobile#36522. Its current sequence is MoonPay Terms 1 → Iron email → session Terms 2 → SumSub. Entry and resume points hydrate this snapshot, while successful local actions advance optimistically.
References
Testing
RampsControllerunit coverage for every snapshot branch, including empty, pending, approved, rejected, retryable activation failure, and foreign-session reset states.hydrateVbaOnboardingasPromise<VbaOnboardingSnapshot>with no remaining stage API references.Checklist
Made with Cursor