[pull] main from MetaMask:main#622
Merged
Merged
Conversation
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
Fixes flaky component view test **TrendingTokensFullView › user can
search on trending tokens full view** (`TrendingView.view.test.tsx`).
### Root cause
- `setupTrendingApiFetchMock` only intercepted
**`/v3/tokens/trending`**. Full-view search also calls
**`searchTokens`**, which hits **`/tokens/search`** on
`token.api.cx.metamask.io`.
- With **`nock.disableNetConnect()`**, that request was unmatched, so
search completion and loading state were **slow or variable** while
`useTrendingSearch` stayed in a loading path.
- Assertions used a **2s** `waitFor`, so the test could time out before
`trending-token-row-item-*` appeared—especially with debounced search
and typing.
### Changes
- **`tests/component-view/api-mocking/trending.ts`** — Persistent nock
for **`GET /tokens/search`** returning `{ count: 0, data: [] }` so
search resolves immediately; filtered rows still come from mocked
trending data (e.g. “Ethereum” via local name match).
- **`TrendingView.view.test.tsx`** — `assertTrendingTokenRowsVisibility`
timeout increased to **5s**; full-view search test **waits for the
Ethereum row** after opening the full view **before** toggling search to
avoid racing the initial trending fetch.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I've included tests if applicable
- [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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.
## **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.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to component-view test code and nock
mocks, with no production logic impact; main risk is inadvertently
masking real network behavior in tests by broadly mocking `GET
/tokens/search`.
>
> **Overview**
> Fixes flakiness in the `TrendingTokensFullView` search test by
ensuring all network calls are deterministically mocked and by reducing
timing races.
>
> The trending API mock now also persists a `GET /tokens/search`
interceptor (returning an empty result set) so search requests don’t
hang when net connect is disabled. The test helper
`assertTrendingTokenRowsVisibility` uses a longer `waitFor` timeout
(5s), and the full-view search test now waits for the initial Ethereum
row to render before toggling search.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3db3c8c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…71.0 (#27709) ## **Description** Integration PR to validate **MetaMask/core** changes in mobile CI/E2E by resolving `@metamask/ramps-controller` from a **preview** npm package (`previewBuilds` in `package.json` + updated `yarn.lock`). No application code changes. **Core PR:** MetaMask/core#8251 After core merges and a **released** version is published, this PR should be updated to remove `previewBuilds` and bump `dependencies` to the real version before merge. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: N/A (validation / dependency preview only) ## **Manual testing steps** ```gherkin Feature: ramps-controller preview validation Scenario: app resolves preview package Given a clean install from this branch When the app bundles and runs Then @metamask/ramps-controller resolves to the preview version from previewBuilds Scenario: ramps flows still work Given the app is built from this branch When user exercises on-ramp flows that use ramps-controller Then no regressions vs main (same UX; underlying package is preview) ``` ## **Screenshots/Recordings** N/A — dependency-only change. ## **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 - [ ] I've included tests if applicable - [ ] 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. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. --- <!-- Optional: paste below into GitHub if you use Cursor Bugbot summary --> > [!NOTE] > **Low Risk** > Low risk because this is a dependency source/version switch for `@metamask/ramps-controller` with no application code changes; main risk is behavior changes introduced by the preview package at runtime. > > **Overview** > Switches `@metamask/ramps-controller` to a **preview build** via `previewBuilds` in `package.json` and `yarn.lock` (e.g. `@metamask-previews/ramps-controller@12.0.0-preview-434bd0c`). Update the preview version string if the bot publishes a newer build for core#8251. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk patch-level dependency update; main risk is any runtime behavior changes in `@metamask/ramps-controller` affecting ramp flows, plus potential test fixture mismatches if state shape changes again. > > **Overview** > Updates `@metamask/ramps-controller` from `12.0.0` to `12.0.1` (including lockfile resolution changes). > > Aligns the default E2E/unit fixture (`default-fixture.json`) with the newer `RampsController` state shape by adding persisted sub-state for countries, providers/payment methods/tokens, native provider (Transak) auth/kyc/user details, requests, and orders. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0b2fc2f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: adds "Paid by MetaMask" on Activity "Total gas fee" row when the tx was a gas-sponsored swap. ## **Related issues** Fixes: #27246 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` 1. Select Monad or SEI network (or any gas-sponsored network). 2. Select the in-app Swap feature (or "buy/sell") selecting tokens from the same network. 3. Perform the swap - "Paid by MetaMask". 4. Once completed, click on the transaction item in the Activity tab. 5. Observe content of the Transaction Detail view. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** Showing a `MON` gas fee amount (zero). <img width="200" alt="image" src="https://github.com/user-attachments/assets/291bf9da-82a9-4569-be0b-69722bc46dec" /> ### **After** <!-- [screenshots/recordings] --> Showing the "Paid by MetaMask" label. <img width="200" alt="image" src="https://github.com/user-attachments/assets/566855ab-a0de-4c68-86cd-2a865a9b520a" /> ## **Pre-merge author checklist** - [ ] 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). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Small UI-only change gated by existing `isGasFeeSponsored` flag; low risk aside from potential styling/layout regressions in the transaction details view. > > **Overview** > Updates the Bridge/Swap transaction details screen to display a green `Paid by MetaMask` tag in the *Total gas fee* row when `evmTxMeta.isGasFeeSponsored` is true, instead of showing a (typically zero) native gas amount. > > Introduces a small reusable `PaidByMetaMask` component using `TagColored` (with `testID: paid-by-metamask`) and keeps the prior fee amount rendering for non-sponsored transactions. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 12125cd. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
… useAnalytics (#27748) ## **Description** Part of the analytics cleanup effort (#26686). This PR migrates network, accounts, and permissions files from the deprecated `useMetrics` hook and `MetricsEventBuilder` to the new `useAnalytics` hook and `AnalyticsEventBuilder`. Renames applied across 24 files: - `useMetrics` → `useAnalytics` - `MetricsEventBuilder` → `AnalyticsEventBuilder` - `addTraitsToUser` → `identify` - `getMetaMetricsId` → `getAnalyticsId` Test mocks updated to match the new API shape (adds `identify` mock, uses `jest.mocked()` pattern). ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: #26686 ## **Manual testing steps** N/A — purely mechanical rename with no behavior change. Existing unit tests updated and passing. ## **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. ## **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 --> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Mostly mechanical analytics API migration; primary risk is missed hook import or mismatched method names causing analytics calls (or tests) to break at runtime. > > **Overview** > Migrates several network, accounts, and permissions UI surfaces from deprecated `useMetrics`/`MetricsEventBuilder` to the newer `useAnalytics`/`AnalyticsEventBuilder`, keeping the same event tracking behavior. > > Updates places that previously set user traits during network add/update flows to call `identify` instead of `addTraitsToUser`, and refactors Jest mocks to the new hook shape using `createMockUseAnalyticsHook`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 861220b. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->
## **Description**
source_branch and ref are doing the same thing in build.yml so we can
consolidate them.
## **Changelog**
<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`
If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`
(This helps the Release Engineer do their job more quickly and
accurately)
-->
CHANGELOG entry:null
## **Related issues**
Fixes:
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user [verb for user action]
Given [describe expected initial app state]
When user [verb for user action]
Then [describe expected outcome]
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **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.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] 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.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk CI-only change that primarily renames/rewires workflow
inputs; risk is limited to mis-checkout of the intended commit/branch in
GitHub Actions builds.
>
> **Overview**
> Simplifies the reusable `build.yml` workflow by consolidating checkout
control into a single `source_branch` input, and clarifies its semantics
for version-bump vs. skip-version-bump runs.
>
> Updates checkout conditionals to use `source_branch` wherever `ref`
was previously used, and adjusts `nightly-build.yml` to pass the bumped
commit hash via `source_branch` for both exp and RC builds.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
30daf6c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** Split from #26651 to reduce CODEOWNERS fanout. Batch: assets Source branch: \`origin/remove-static-hex-from-tests\` When \`@metamask/design-tokens\` upgrades change color values, tests that hardcode hex literals (e.g. \`'#ffffff'\`, \`'#457a39'\`) break because the component renders the new token value while the test still asserts the old one — even though nothing is actually wrong. This PR fixes that brittleness across the assets scope. **Two strategies are applied:** 1. **Replace hardcoded hex theme mocks with \`mockTheme\`** — test mocks that hand-rolled partial theme objects (e.g. \`{ colors: { primary: { default: '#0376C9' } } }\`) are replaced with \`jest.requireActual\` to pull the real \`mockTheme\`. Test assertions that checked against hex literals (e.g. \`expect(color).toBe('#457a39')\`) now reference \`mockTheme.colors.success.default\`, so both the component and the test always resolve the same value regardless of token package version. 2. **Add targeted \`eslint-disable\` comments** — strings like \`'#113'\` or \`'#6904'\` are NFT token IDs, not CSS colors. The \`color-no-hex\` rule can't distinguish them, so inline suppressions are added to allow these legitimate domain strings without weakening the rule elsewhere. Together these changes make the \`@metamask/design-tokens/color-no-hex\` lint rule enforceable across this scope, so future hex literals won't accidentally creep back in and cause brittle tests. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** \`\`\`gherkin Feature: color-no-hex lint compliance (assets batch) Scenario: user runs lint and tests Given the asset test files have been updated When user runs lint and test checks Then no color-no-hex violations are reported And all tests pass \`\`\` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are confined to ESLint configuration and test mocks/assertions to avoid hardcoded hex values, with no runtime logic impact. > > **Overview** > **Enables `@metamask/design-tokens/color-no-hex` enforcement for the Assets-owned UI/hooks surface** by expanding the ESLint override to treat hex literals as errors in those directories. > > Updates multiple Assets-related tests to remove hardcoded hex color mocks and assertions by sourcing colors from the real `mockTheme` via `jest.requireActual`, and adds targeted inline disables where strings like `#113`/`#6904` are NFT identifiers (not color literals). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 02aaba1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…kflow (#27750) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** Add an optional job to upload sourcemap to Sentry <img width="314" height="430" alt="Screenshot 2026-03-20 at 4 23 50 PM" src="https://github.com/user-attachments/assets/1680945f-268f-4c93-a04f-bb2e373b820c" /> Sentry: https://metamask.sentry.io/settings/projects/metamask-mobile/source-maps/?query=4123 ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: Added a checkbox to upload sourcemap on build mobile workflow ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **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. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches the mobile build/release pipeline and version numbering across Android/iOS/Bitrise, which can affect artifact reproducibility and release ordering if misconfigured. The Sentry upload toggle is opt-in but relies on correct environment auth and build scripts honoring `SENTRY_DISABLE_AUTO_UPLOAD`. > > **Overview** > Adds a new `upload_to_sentry` input to the GitHub Actions `build.yml` workflow and wires it to a `Configure Sentry upload` step that toggles `SENTRY_DISABLE_AUTO_UPLOAD` for the subsequent platform build. > > Updates build/version numbers used by the native projects and CI (`android/app/build.gradle`, `ios/MetaMask.xcodeproj/project.pbxproj`, and `bitrise.yml`) to align on `4138` (and adjusts Android `versionName`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0230a9c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…27804) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> Fixes the external-browser return flow for unified ramps by moving callback resolution out of Build Quote and into Order Details. The bug was that external-browser returns were resolved too early in BuildQuote. If callback parsing or order lookup failed there, users could get bounced around or end up on a broken Order Details screen. This change fixes that by moving callback resolution into Order Details itself. BuildQuote now only hands off the callback context, and Order Details fetches the real order itself. That makes the flow more reliable: bailed callbacks return to Build Quote, and real fetch failures show a retryable error instead of a broken redirect. **What changed** - **Build Quote -> Order Details callback handoff** After a successful external-browser return, Build Quote now navigates to Order Details with the full `callbackUrl`, `providerCode`, and `walletAddress` instead of trying to resolve the order immediately. - **Order Details callback bootstrap** Order Details now supports loading from callback params, fetching the real order on first render, and updating route params once the order has been resolved. - **Bailed / invalid callback handling** If the callback resolves to a bailed order state or no usable order, the user is sent back to Build Quote instead of landing on a blank or broken Order Details screen. - **Retryable callback error state** If fetching the order from the callback URL fails, Order Details now shows a retryable error screen rather than silently resetting away. This makes transient backend/network failures recoverable. - **Navigation tests updated** Tests were updated to reflect the callback-based route shape and the new Order Details retry behavior. **What stays untouched** This PR does not change Order Content amount rendering, list display formatting, or duplicate placeholder cleanup. It is scoped only to fixing the external-browser redirection and callback-resolution path. ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> Paypal Order going to build quote page first: Uploading Screen Recording 2026-03-23 at 1.00.39 PM.mov… ### **After** <!-- [screenshots/recordings] --> Native Transak Redirection https://github.com/user-attachments/assets/32d1a7f9-23c7-4df1-aba8-f639338d7a6f Bailed Paypal order (return to build quote page): https://github.com/user-attachments/assets/8ed07fa3-e7df-4b69-b2f0-9318799c8249 Paypal order going to order details page: https://github.com/user-attachments/assets/5a2e8489-a4b0-488d-8aca-7982df63c45c ## **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 - [ ] 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. ## **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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes the unified ramps external-browser return flow and navigation params, which can impact users reaching the correct order state after checkout; failures may surface as new retry/error behaviors. > > **Overview** > Fixes unified ramps external-browser return handling by **moving callback URL resolution out of `BuildQuote` and into `OrderDetails`**. > > `BuildQuote` no longer calls `getOrderFromCallback`/`addOrder` on InAppBrowser success; it now resets navigation to `OrderDetails` with `callbackUrl`, `providerCode`, and `walletAddress`. `OrderDetails` bootstraps from these callback params, fetches the real order (bailing back to `BuildQuote` for invalid/bailed statuses), updates route params to the resolved `orderId`, and shows a retryable error state if the callback fetch fails. > > Updates `rampsNavigation` to support an `OrderDetails` route shaped around callback params (and makes `orderId` optional), and adjusts/adds tests to cover the new handoff and retry behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0eabfd6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )