Repository navigation
feat(ramps-controller): diff autoramp transaction statuses - #11017
Merged
Merged
Conversation
Persist the last seen status per autoramp transaction and publish a change only after that record is written. The first successful fetch seeds the record. Co-authored-by: george.weiler <george.weiler@consensys.net>
Co-authored-by: george.weiler <george.weiler@consensys.net>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort 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 68becb2. Configure here.
matteyusys
reviewed
Oct 23, 2026
| * status pass 50. | ||
| * @returns Transaction summaries from the newest page. | ||
| */ | ||
| async listAutorampTransactions( |
Contributor
There was a problem hiding this comment.
Proxy has /autoramp-transactions/ids for targeted refresh. Do we have any plan to use it (e.g. after push) vs forever listing?
matteyusys
self-requested a review
October 26, 2026 20:00
matteyusys
previously approved these changes
Oct 26, 2026
…moval A fetch that returns after removeAutoramp, a cursor replace, or a foreign session discard no longer writes the cleared record or publishes a status change. Co-authored-by: george.weiler <george.weiler@consensys.net>
…gh a callback The status change is only consumed as analytics, so refresh reports it through an injected tracker after the record is written instead of a messenger event. Co-authored-by: Cursor <cursoragent@cursor.com>
…n-diff-b4a1 Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # packages/ramps-controller/CHANGELOG.md
Co-authored-by: Cursor <cursoragent@cursor.com>
`refreshAutorampTransactions` wrote the record and then called `trackAutorampTransactionStatusChanged` for each change with no guard, so a throwing host tracker both rejected the refresh and skipped every later change in the batch. The record already says those statuses were seen, so they would never be reported again. The callback is now wrapped per change, matching the `trackKycAnalytics` callbacks on `KycController` (#11041). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
wenfix
approved these changes
Oct 27, 2026
This was referenced Oct 27, 2026
Merged
gaohan1994
pushed a commit
to gaohan1994/core
that referenced
this pull request
Oct 28, 2026
## Explanation Scoped release so clients can pick up MetaMask#11017 and MetaMask#11041. - **`@metamask/ramps-controller` 27.2.0 → 28.0.0** (major). Persists autoramp transaction statuses and reports a new id or a changed status string through the optional `trackAutorampTransactionStatusChanged` callback. **BREAKING:** `RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS` now includes `NeoBankService:listAutorampTransactions`. Hosts that spread that list pick it up on the bump. Hosts that copy the action list by hand must delegate it. This version also includes the unpublished `@metamask/utils` range bump to `^12.0.1` from MetaMask#11107. - **`@metamask/kyc-controller` 0.12.1 → 0.13.0** (minor). Adds the optional `trackKycAnalytics` constructor callbacks (`verificationOutcome` and `statusChanged`) from MetaMask#11041. Nothing is added to `KycControllerEvents`. This version also includes the unpublished `@metamask/utils` range bump to `^12.0.1` from MetaMask#11107. - **`@metamask/transaction-pay-controller` 30.3.0 → 30.3.1** (patch). Published because `ramps-controller` is a major and this is its only workspace dependent. The range moves from `^27.2.0` to `^28.0.0`. Other packages with unreleased changes are deferred. ## References - Ships MetaMask#11017 - Ships MetaMask#11041 - Also publishes the unpublished utils range bump already on main: MetaMask#11107 ## 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) - [ ] 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 Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > The ramps-controller major adds a required messenger action for autoramp transaction polling; hosts that hand-maintain delegated actions must update or delegation fails at runtime. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2be3977. 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>
darkwing
pushed a commit
to darkwing/metamask-mobile
that referenced
this pull request
Oct 29, 2026
## Explanation When the VBA details screen loads an approved autoramp, it calls `RampsController.refreshAutorampTransactions`. The controller calls `trackAutorampTransactionStatusChanged` for a new transaction or a status change. Mobile passes that callback from `rampsControllerInit` and tracks **Money VBA Transaction Updated**. This matches the schema merged in Consensys/segment-schema#785 and the callback on MetaMask/core#11017: - `status` is `pending` for `FundsReviewInProgress`, `ConversionInProgress`, and `PayoutInProgress`; `completed` for `Completed`; `failed` for `Failed`, `RejectedAml`, `RejectedFraud`, and `RejectedMinAmount`. A vendor status outside that enum is not tracked, because `status` and `transaction_status` are required closed enums. - The raw vendor value stays on `transaction_status`. `previous_status` is omitted for a new id and when the previous value is outside the enum. - `failure_reason` is not sent. The schema's known quirk is that a failed transaction is `status: failed` plus the raw `transaction_status`. `failure_reason` is the onboarding failure enum. - `kyc_status` and `provider_flow_status` are always sent. Missing state uses `none` and `not_started`. - `entry_point` (`add_funds_bank_account`), `vendor` (`moonpay`), `autoramp_status` (`ready`), `currency_destination_symbol` (`mUSD`), and `token_chain_id` (`eip155:143`) are constants. `screen_name` is omitted because this fires from the fetch, not from a screen. - `region` is the lowercase alpha-2 country and is omitted while geolocation is unknown. The schema marks it required and has no unknown value, so an invented country is not sent. - `currency_source` is sent when the autoramp deposit rail has one. Amounts are numbers and are omitted when not numeric. `seconds_since_created` is computed when the callback runs and is never negative. `orderStatusChanged` stays a messenger subscription. It is still used for notifications and order analytics. There is no transaction-status messenger event. Production fetches transactions once per autoramp while the details screen is open. Debug builds keep refreshing on the existing details poll so the debug sheet can show the latest status. A failed transaction refresh does not hide deposit details. There is no new background poller. ## Package bump Depends on MetaMask/core#11017. This compiles against the published `@metamask/ramps-controller` by declaring `AutorampTransactionStatusChangedPayload` locally and attaching `trackAutorampTransactionStatusChanged` through a constructor-options intersection. After `@metamask/ramps-controller` includes `refreshAutorampTransactions` and `AutorampTransactionStatusChangedPayload`: - Bump `@metamask/ramps-controller`. - Import `AutorampTransactionStatusChangedPayload` from the package and delete the local copy in `vbaTransactionAnalytics.ts`. - Drop the intersection on the constructor options. Until that bump, `refreshAutorampTransactions` is optional on the controller, so an older package skips the refresh instead of crashing. The new `NeoBankService:listAutorampTransactions` action is already covered by spreading `RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS` once that list includes it. ## Checklist - [x] Unit tests for the property mapping and the details-screen refresh - [ ] Bump `@metamask/ramps-controller` once MetaMask/core#11017 is published <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches money/VBA deposit flows and analytics emission on transaction refresh; behavior is guarded when the ramps package lacks `refreshAutorampTransactions`, but incorrect mapping could skew funnel metrics. > > **Overview** > Adds **Money VBA Transaction Updated** analytics when autoramp deposit transaction statuses change, aligned with the Segment VBA schema. > > `rampsControllerInit` passes `trackAutorampTransactionStatusChanged` into `RampsController`, which maps vendor statuses to `pending` / `completed` / `failed`, enriches events from Redux (KYC, region, fiat source), and skips unknown statuses. A shared `toAnalyticsRegion` helper normalizes geolocation for `region`. > > **VBA details** now triggers `RampsController.refreshAutorampTransactions` (once per autoramp in production, on the existing poll in debug) instead of calling `NeoBankService.listAutorampTransactions`. Deposit instruction loading stays separate so a failed transaction refresh does not hide PIX details; debug UI still shows the latest deposit status from the refresh result. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 15246f7. 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 Agent <cursoragent@cursor.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
darkwing
pushed a commit
to darkwing/metamask-mobile
that referenced
this pull request
Oct 29, 2026
…ask#38322) ## **Description** Adopts the two controller releases that the VBA / KYC analytics work depends on, and nothing else. No app behaviour changes. - `@metamask/kyc-controller` `^0.12.0` → `^0.13.0` - `@metamask/ramps-controller` `^27.1.0` → `^28.0.0` This is deliberately split out from the three analytics PRs that consume these APIs ([MetaMask#38078](MetaMask#38078), [MetaMask#38160](MetaMask#38160), [MetaMask#38161](MetaMask#38161)) for four reasons: 1. **`ramps-controller` is a major bump** (27.1.0 → 28.0.0, also skipping 27.2.0). That is a Ramps/platform review, not an analytics review, and it should not be buried in a PR about Segment events. 2. **One lockfile change instead of three.** If each analytics PR bumped, whichever merged first would force the other two to re-resolve `yarn.lock`. 3. **It makes the analytics PRs verifiable.** All three currently reference APIs that did not exist in the installed versions, so none of them can produce a meaningful `lint:tsc` result until this lands. 4. **Revert safety.** If the bump regresses something unrelated, it reverts on its own. ### The breaking change is a no-op for us `ramps-controller@28.0.0` has one breaking change: > **BREAKING:** `RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS` now includes `NeoBankService:listAutorampTransactions`. Hosts must delegate that action to `RampsController`. No code change is needed here. [`ramps-controller-messenger.ts`](https://github.com/MetaMask/metamask-mobile/blob/main/app/core/Engine/messengers/ramps-controller-messenger/ramps-controller-messenger.ts#L47) already spreads the package-owned list rather than enumerating actions: ```ts actions: [ // Spread the package-owned required list so new service actions // (e.g. getDefaultRedirectCallbackUrl / NeoBankService) cannot be // forgotten at upgrade. ...RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS, ... ], ``` and `NeoBankService` is registered as a messenger client in `Engine.ts`, so the new action is delegated automatically. ### Reviewer note: `ramps-controller` is now duplicated in the tree `@metamask/transaction-pay-controller@30.2.0` depends on `@metamask/ramps-controller@^27.1.0`, so this bump un-dedupes it: ``` ├─ @metamask/transaction-pay-controller@npm:30.2.0 │ └─ @metamask/ramps-controller@npm:27.1.0 (via npm:^27.1.0) └─ metamask@workspace:. └─ @metamask/ramps-controller@npm:28.0.0 (via npm:^28.0.0) ``` TPC references ramps in its messenger types (`RampsControllerGetOrderAction`, `RampsControllerGetQuoteWithFeesAction`). Those action shapes are unchanged in 28.0.0 — the only breaking change was the constant above — and `lint:tsc` passes, so this is a bundle-size cost rather than a correctness one. Flagging it so it is a conscious decision: the clean fix is a TPC release that widens its range to `^28.0.0`, which can follow separately. ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: MetaMask/core#11017 Refs: MetaMask/core#11041 Refs: MetaMask/core#11141 ## **Manual testing steps** ```gherkin Feature: VBA and KYC flows still work on the bumped controllers Scenario: Autoramp transactions still load on the VBA details screen Given a Money account with an approved autoramp When the user opens the virtual bank account details screen Then the deposit instructions render And no "action not registered" error is raised for NeoBankService:listAutorampTransactions Scenario: KYC identity verification still launches Given a user part way through VBA onboarding When the user reaches the identity verification step Then the SumSub webview opens as before And the stored KYC status still updates when the decision arrives ``` ## **Screenshots/Recordings** N/A — dependency bump with no UI change. ### **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 — no new code, so no new tests. The existing ramps, KYC and ramps-messenger suites were run against the bumped packages (12 suites, 138 tests). - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable — N/A, no new code. - [ ] 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) - [ ] I've tested on Android - [ ] I've tested with a power user scenario - [ ] I've instrumented key operations with Sentry traces for production performance metrics Not applicable: no runtime code changes. The one performance-relevant consequence is the duplicated `ramps-controller` noted above, which is a bundle-size effect rather than a runtime one. ## **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 [Claude Code](https://claude.com/claude-code) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Major ramps-controller bump touches VBA/autoramp and KYC-adjacent flows; runtime wiring appears pre-covered, but regressions in money onboarding are still possible. > > **Overview** > Dependency-only PR that upgrades **`@metamask/kyc-controller`** (`^0.12.0` → `^0.13.0`) and **`@metamask/ramps-controller`** (`^27.1.0` → `^28.0.0`), with matching **`yarn.lock`** resolution. No application logic changes beyond keeping tests aligned with the new controller default state. > > The test background snapshot adds **`autorampTransactionRecords: {}`** under **`RampsController`**, matching new state shipped in ramps-controller 28. **`ramps-controller-messenger.ts`** already spreads **`RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS`**, so the 28.0 breaking requirement to delegate **`NeoBankService:listAutorampTransactions`** does not need a separate host change here. > > This bump is split ahead of VBA/KYC analytics PRs that depend on these package APIs. Note that **`transaction-pay-controller`** may still pull **`ramps-controller@27.x`**, so the tree can temporarily carry two versions until TPC widens its range. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 49c0f97. 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: Claude Opus 5 <noreply@anthropic.com>
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
The app needs to know when a virtual bank account transaction is new or has changed status, without storing amounts or bank details and without reporting the same change twice.
RampsControllerpersistsautorampTransactionRecords: for each autoramp, the epoch ms of the first successful fetch and the last seen status string per transaction id.diffAutorampTransactionsis pure. The first successful fetch (including an empty one) seeds the record and calls nothing. Later fetches report a new id or a different status string, including a status that moved backwards or skipped intermediate values. A transaction missing from the page stays in the record.refreshAutorampTransactionsloads the newest page (sort_order=desc,page_size50, no pagination), writes the next record, then calls the optionaltrackAutorampTransactionStatusChangedconstructor callback once per change.previousStatusis omitted for a new id. A failed fetch writes nothing. Concurrent calls for the same autoramp share one request. Removing an autoramp, replacing the autoramp cursor, or discarding a foreign VBA session clears the matching records. A fetch still in flight when that autoramp leaves the cursor does not write the record or call the callback.This is an analytics signal, so it is a callback rather than a
RampsControllermessenger event.orderStatusChangedandautorampStatusChangedstay messenger events because the client uses them for more than tracking.NeoBankService.listAutorampTransactionsaccepts an optionalpageSize. Omitting it keeps the previous query.References
Checklist
BREAKING:
RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONSnow includesNeoBankService:listAutorampTransactions. Hosts that spread that list pick it up on the package bump. Hosts that copy the action list by hand must delegate it.Note
Medium Risk
Introduces a breaking messenger delegation requirement and new persisted VBA transaction state with analytics callbacks; behavior is guarded but hosts must wire the NeoBank action and handle migration of persisted state.
Overview
Adds persisted autoramp transaction status tracking so hosts can learn when a VBA deposit transaction is new or its MoonPay status string changed, without storing amounts or firing duplicate analytics.
RampsControllergains persistedautorampTransactionRecords(per autoramp:syncedAtplus last-seen status per transaction id), the pure helperdiffAutorampTransactions, andrefreshAutorampTransactions, which loads the newest transaction page (page_size50), updates the record, then invokes optional constructor callbacktrackAutorampTransactionStatusChangedonce per new id or status change (previousStatusomitted for new ids). The first successful fetch only seeds the record; failed fetches leave it unchanged; concurrent refreshes per autoramp dedupe to one request; records are cleared when an autoramp is removed, the cursor is replaced, or a foreign VBA session is discarded, with in-flight fetches not re-writing removed autoramps.NeoBankService.listAutorampTransactionsaccepts optionalpageSize(page_sizequery). Breaking:RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONSnow requiresNeoBankService:listAutorampTransactionsdelegation. New messenger actionRampsController:refreshAutorampTransactionsand related types are exported from the package.Reviewed by Cursor Bugbot for commit 86c201b. Bugbot is set up for automated code reviews on this repo. Configure here.