[pull] main from MetaMask:main#591
Merged
Merged
Conversation
- Simplified the network controller setup by removing the nested
providerConfig object in multiple test files.
- Updated tests across various modules to directly set chainId, rpcUrl,
type, nickname, and ticker properties.
- Ensured consistency in the network configuration for local RPC and
other custom networks.
<!--
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?
-->
## Summary
- **Creates `tests/framework/fixtures/types.ts`** — single source of
truth for all fixture-related TypeScript types. Imports
`NetworkState`, `AccountsControllerState`, `PreferencesState`, and
`AccountTreeControllerState` from MetaMask packages; writes
minimal hand-crafted interfaces for the remaining controllers. Exports
the composed `Fixture → FixtureState →
EngineBackgroundState` hierarchy plus `ProviderConfig`,
`UserKeyringState`, `UserSnapState`, `UserPermissionState`, and
`DeepPartial<T>`.
- **Replaces `private fixture: any` with `private fixture!: Fixture`**
in `FixtureBuilder.ts` — TypeScript now catches invalid
fixture modifications at compile time.
- **Changes `withNetworkController()` signature** from
`withNetworkController({ providerConfig: {...} })` to
`withNetworkController(providerConfig: ProviderConfig)` (flat, no
wrapper). Updates all 53 call sites across `tests/smoke/` and
`tests/regression/`.
- **Types 8 previously-`any` methods:** `withPermissionController`,
`withPreferencesController`, `withAccountTreeController`,
`withSnapController`, `withUserProfileKeyRing`,
`withUserProfileSnapUnencryptedState`, `withUserProfileSnapPermissions`,
`withTokensForAllPopularNetworks`. Removes all 8 `eslint-disable
@typescript-eslint/no-explicit-any` suppressions that guarded
them.
- **Removes `withState()`** callers should use the typed builder methods
instead.
- **Additional type-accuracy fixes** surfaced by the stricter typing:
`BrowserTab.isArchived` added to interface, `withAsyncState`
parameter tightened to `Record<string, string>`,
`RpcEndpointType.Custom` enum used in all `rpcEndpoints` type fields
(was plain
string `'custom'`), `networkConfigurationsByChainId` index assignments
cast correctly.
- **JSDoc cleanup:** removed redundant `{type}` from all `@param` and
`@returns` tags (26 + 34 occurrences) — types are declared
in TypeScript signatures, not JSDoc.
## Breaking change
`withNetworkController()` call sites must be updated. Before:
`.withNetworkController({ providerConfig: { chainId, rpcUrl, type }
})`. After: `.withNetletworkController({ chainId, rpcUrl, type })`. All
existing call sites in this repo are already updated.
## **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**
- [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]
> **Medium Risk**
> Primarily test-infrastructure refactors, but changes the
fixture/network configuration API and fixture loading types across many
tests, which could cause widespread E2E failures if any state shape
assumptions are wrong.
>
> **Overview**
> E2E fixture construction is made **type-safe** by introducing
`tests/framework/fixtures/types.ts` and converting `FixtureBuilder`’s
internal state from `any` to a strongly typed `Fixture`, plus tightening
several builder APIs (e.g., `withPermissionController`,
`withPreferencesController`, `withAccountTreeController`, token helpers)
and removing the generic `withState()` escape hatch.
>
> `withNetworkController()` is simplified to accept a flat
`ProviderConfig` (no nested `{ providerConfig: ... }` wrapper), and
fixture/network endpoint typing is aligned to controller enums (e.g.,
`RpcEndpointType.Custom`). The fixture loading pipeline
(`FixtureHelper`, `FixtureServer`, and `WithFixturesOptions`) is updated
to accept either a `FixtureBuilder` or a pre-built `Fixture`, and a
broad set of smoke/regression tests are updated accordingly.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
51b142a. 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** Removes fixed `width` and `height` from the AI icon SVG so it scales correctly with the icon component (e.g. at different sizes). 1. **Reason for the change:** The AI icon had `width="24"` and `height="24"` on the root `<svg>`, which can prevent proper scaling when the icon is used at other sizes; the icon component typically controls dimensions. 2. **Improvement:** Removed `width` and `height` from the SVG; kept `viewBox="0 0 24 24"` so aspect ratio is preserved and the icon scales with its container. ## **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: https://consensyssoftware.atlassian.net/browse/DSYS-553 ## **Manual testing steps** ```gherkin Feature: AI icon scaling Scenario: AI icon scales with container Given the app is open When user navigates to a screen that displays the AI icon (e.g. Predict, or component library / Storybook) Then the AI icon is displayed with correct aspect ratio And the icon scales correctly at different sizes (e.g. small and large) ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/ab9f9755-d420-453a-b7c5-21bfc4855454 <!-- [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** > Single-asset SVG attribute change with minimal blast radius; risk is limited to potential visual sizing differences for the `ai` icon. > > **Overview** > Updates the `ai` icon asset to drop hardcoded `width` and `height` on the root `<svg>`, relying on `viewBox="0 0 24 24"` for correct scaling at different rendered sizes. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c068b52. 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** increase touchable area of select quotes entry <!-- 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: increase touchable area of select quotes entry ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4246 ## **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** - [ ] 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 UI behavior change confined to the Bridge quote details card; main risk is unintentionally preventing users from opening the price impact modal if thresholds/feature flags are misconfigured. > > **Overview** > Improves the Bridge `QuoteDetailsCard` interaction by making the *entire rate value + arrow* area tappable (larger touch target) to open the quote selector. > > Adds a `priceImpactIsSafe` check (using `selectBridgeFeatureFlags.priceImpactThreshold.warning` with a fallback to `AppConstants`) so pressing the price impact value only navigates to the price impact modal when impact is at/above the warning threshold; tests and snapshots are updated and a new test asserts no navigation below the threshold. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7666e16. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…sitions (#27164) ## **Description** `PredictClaimFooter` was internally reading the selected account address via `selectSelectedInternalAccountAddress` selector, which could be stale or mismatched with the actual transaction address. This change: 1. Accepts `address` as a prop so the parent passes the address directly from the transaction context, ensuring consistency. 2. Adds an `onError` callback prop that fires when the component encounters no won positions to claim, allowing the parent to handle the error appropriately instead of silently rendering nothing. 3. Removes the internal `selectSelectedInternalAccountAddress` selector dependency and the `?? '0x0'` fallback. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: MetaMask/MetaMask-planning#7093 ## **Manual testing steps** ```gherkin Feature: Predict claim confirmation Scenario: user claims winning prediction positions Given user has winning prediction positions for their account When user opens the claim confirmation Then the claim footer displays the correct positions and claim button Scenario: user attempts to claim with no winning positions Given user has no winning prediction positions for the given address When user opens the claim confirmation Then the onError callback is invoked with an error message ``` ## **Screenshots/Recordings** ### **Before** N/A - logic-only change ### **After** N/A - logic-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 - [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] > **Medium Risk** > Touches confirmation flow for `predictClaim` by changing how the claim footer derives the address and how errors trigger rejection, which could affect whether a user can confirm or gets auto-rejected in edge cases. > > **Overview** > Updates the `predictClaim` confirmation footer to derive the wallet address from the current transaction (`txParams.from`) instead of the selected account, avoiding mismatches when the selected account is stale. > > Adds an `onError` callback to `PredictClaimFooter` and triggers it (while rendering `null`) when there is no transaction address or no won/claimable positions; the parent `Footer` wires this to `onReject` so empty claims are handled explicitly. Tests are updated to cover the new `onError` behavior and the no-positions path. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 76bc72f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…able modal (#27277) ## **Description** Fixes the "Token not available with provider" modal so that pressing the close (`X`) button navigates the user back to the token selection screen instead of leaving them in a stuck state. Previously, closing the modal did nothing — the bottom sheet dismissed but no navigation occurred, leaving the user on a blank/unresponsive input screen. Now the close button behaves the same as the "Change token" button, sending the user back to the token list. ## **Changelog** CHANGELOG entry: Fixed a bug where closing the "Token not available" modal left the user in a stuck state instead of navigating back to the token selection screen. ## **Related issues** Refs: [TRAM-3329](https://consensyssoftware.atlassian.net/browse/TRAM-3329) ## **Manual testing steps** ```gherkin Feature: Token not available modal close behavior Scenario: Close button navigates back to token selection Given the user is in the Buy flow with a region set to US (e.g. Texas) And a provider is selected that does not support the chosen token (e.g. Ramp Network + UNI) When the "Not available" modal appears And the user presses the close (X) button Then the user is navigated back to the token selection screen And the token list is displayed correctly Scenario: Change token button still works Given the "Not available" modal is displayed When the user presses the "Change token" button Then the user is navigated back to the token selection screen Scenario: Change provider button still works Given the "Not available" modal is displayed When the user presses the "Change provider" button Then the provider selection modal is displayed ``` ## **Screenshots/Recordings** ### **Before** <!-- Video/screenshot showing the stuck state after closing the modal --> https://github.com/user-attachments/assets/ff13e927-65e8-424f-9124-fbcd6a25e9a9 ### **After** <!-- Video/screenshot showing navigation back to token selection after closing --> https://github.com/user-attachments/assets/33d6767b-2596-461f-afa1-d8d3f7c8c357 https://github.com/user-attachments/assets/c4325a29-920e-4a12-9c8d-a3840505accd https://github.com/user-attachments/assets/64a6d24e-26f9-4612-9b89-edd78fb7c488 ## **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 - [ ] 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** > Small UI navigation change scoped to a single modal, with updated test coverage and no sensitive data/auth logic involved. > > **Overview** > Fixes the `TokenNotAvailableModal` close (X) behavior so it now triggers the same flow as *Change token*: the bottom sheet closes and navigation returns to `Routes.RAMP.TOKEN_SELECTION` instead of simply dismissing. > > Updates the unit test to assert navigation to token selection on close, preventing regressions of the previously “stuck” state. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 89ca0e9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
Replace manual `useState`/`useEffect`/`useRef` data-fetching in
`usePredictMarket` with React Query's `useQuery`, backed by a new
`predictMarketOptions` query factory.
**Why:** The existing implementation manually manages loading, error,
and mounted-ref state which is error-prone and duplicates logic that
React Query handles out of the box (caching, deduplication,
stale-while-revalidate, automatic cleanup on unmount).
**What changed:**
- New `queries/market.ts` — query key factory and `queryOptions` for
fetching a single market
- `queries/index.ts` — registered `market` entry in the `predictQueries`
object
- `usePredictMarket.tsx` — replaced ~100 lines of manual state
management with a single `useQuery` call
- `usePredictMarket.test.tsx` — updated tests to use
`QueryClientProvider` wrapper and `@testing-library/react-native` APIs
(`waitFor` instead of `waitForNextUpdate`)
## **Changelog**
## **Related issues**
## **Manual testing steps**
```gherkin
Feature: Predict market detail loading
Scenario: user navigates to a market detail screen
Given user is on the Predict markets list
When user taps on a market card
Then market detail screen loads with market data
And loading indicator is shown while fetching
And error state is shown if the fetch fails
```
## **Screenshots/Recordings**
N/A — no UI changes, internal refactor only.
### **Before**
### **After**
## **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
- [ ] 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**
> Changes the data-fetching mechanism and hook return shape for market
details, which can affect loading/error states and caching behavior
across Predict screens despite being largely a refactor with updated
test coverage.
>
> **Overview**
> Migrates `usePredictMarket` from manual `useState`/`useEffect`
fetching to React Query’s `useQuery`, introducing a new
`predictQueries.market` query factory (`queries/market.ts`) with stable
keys and a 10s `staleTime`.
>
> Updates Predict UI consumers (`PredictMarketSportCardWrapper`,
`PredictMarketDetails`, and `PredictMarketDetailsActions`) and related
tests to use React Query return fields (`data`, `isLoading`, `error`)
and adjust loading/skeleton conditions accordingly, including minor test
expectation tweaks (e.g., date formatting and async waits).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c42adc2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description** The "Select Network" bottom sheet in the Bridge token selector was not scrollable on Android. Tested on both iOS and Android. ## **Changelog** CHANGELOG entry: Fixed the Bridge "Select Network" bottom sheet not being scrollable when many networks are available on Android. ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-4252 Fixes: #27290 ## **Manual testing steps** ``` Feature: Bridge token selector network filter Scenario: user scrolls the network list in the Select Network bottom sheet Given the user is on the Bridge screen And many networks are available When user taps the network filter pill above the token list Then the Select Network bottom sheet opens When user attempts to scroll the network list Then the list scrolls smoothly without dismissing the sheet When user taps a network Then the sheet closes and the token list is filtered to that network ``` ## **Screenshots/Recordings** ### **Before** <!-- List clipped, vertical pan dismissed the sheet instead of scrolling --> ### **After** https://github.com/user-attachments/assets/006154c0-b0a3-482d-8c23-be4cfbb37085 <!-- Full network list scrollable --> ## **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 gesture-handling change limited to the Bridge network selector; no auth, security, or data-flow logic is modified. > > **Overview** > Fixes the Bridge token selector "Select Network" bottom sheet not scrolling on Android by switching the network list container to `ScrollView` from `react-native-gesture-handler`, which correctly handles scroll gestures inside the bottom sheet. > > Removes the unused `BridgeNetworkSelectorBase` component that previously wrapped children in a bottom sheet + `react-native` `ScrollView`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit d3b24db. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Fixes the "Change provider" link in the payment selection modal so it remains clickable while payment methods are loading. Previously, the "Change provider" text was rendered as plain, non-interactive text during the loading state (same grey color as surrounding text, no `onPress` handler). Now it stays styled as a tappable link and navigates to the provider selection screen even while payment methods are still loading. The link is still disabled when there is a payment method error. ## **Changelog** CHANGELOG entry: Fixed a bug where the "Change provider" link in the payment selection modal was not clickable while payment methods were loading. ## **Related issues** Refs: [TRAM-3291](https://consensyssoftware.atlassian.net/browse/TRAM-3291) ## **Manual testing steps** ```gherkin Feature: Change provider link clickable during loading Scenario: Change provider link is clickable while payment methods are loading Given the user is in the Buy flow And the user opens the "Pay with" payment selection modal And payment methods are still loading (skeleton placeholders visible) When the user taps the "Change provider" link at the bottom Then the provider selection modal is displayed Scenario: Change provider link is still clickable after payment methods load Given the payment selection modal is displayed And payment methods have finished loading When the user taps the "Change provider" link Then the provider selection modal is displayed Scenario: Change provider link is disabled on payment method error Given the payment selection modal is displayed And payment methods failed to load with an error When the user views the "Change provider" text Then it appears as non-interactive grey text ``` ## **Screenshots/Recordings** ### **Before** <!-- Screenshot showing "Change provider" as plain grey text during loading --> https://github.com/user-attachments/assets/34a72fca-3899-4b94-a489-b214aa0233c9 ### **After** <!-- Screenshot showing "Change provider" as a clickable blue link during loading --> https://github.com/user-attachments/assets/6aca24e1-351f-45ed-8d8e-3c736d0ae00a ## **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 - [ ] 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** > Small UI behavior change gated to a modal link; limited impact and covered by an updated unit test. > > **Overview** > Fixes the `PaymentSelectionModal` footer so **"Change provider" remains a tappable link while payment methods are loading**, and is only disabled/styled as non-interactive when `paymentMethodsError` is present. > > Updates the modal test to expect navigation to `RampProviderSelectionModal` even during the loading state (and ensures route `amount` is provided in that scenario). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 84a1450. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Fixes the "Token not available with provider" modal so that pressing the close (`X`) button navigates the user back to the token selection screen instead of leaving them in a stuck state. Previously, closing the modal did nothing — the bottom sheet dismissed but no navigation occurred, leaving the user on a blank/unresponsive input screen. Now the close button behaves the same as the "Change token" button, sending the user back to the token list. ## **Changelog** CHANGELOG entry: Fixed a bug where closing the "Token not available" modal left the user in a stuck state instead of navigating back to the token selection screen. ## **Related issues** Refs: [TRAM-3329](https://consensyssoftware.atlassian.net/browse/TRAM-3329) ## **Manual testing steps** ```gherkin Feature: Token not available modal close behavior Scenario: Dismiss provider selection returns to token selection Given the "Not available" modal is displayed And the user pressed "Change provider" When the user taps the deposit screen behind the provider selection modal Then the token selection screen is displayed Scenario: Dismiss token not available modal returns to token selection Given the "Not available" modal is displayed When the user taps the deposit screen behind the modal Then the token selection screen is displayed ``` ## **Screenshots/Recordings** ### **Before** <!-- Video/screenshot showing the stuck state after closing the modal --> https://github.com/user-attachments/assets/ff13e927-65e8-424f-9124-fbcd6a25e9a9 ### **After** <!-- Video/screenshot showing navigation back to token selection after closing --> https://github.com/user-attachments/assets/199f4980-ce25-4873-ac68-e547c8d5950c ## **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 - [ ] 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** > Small, isolated navigation change on modal dismissal with added test coverage; minimal impact outside the ramp modal flow. > > **Overview** > Fixes `ProviderSelectionModal` so dismissing the bottom sheet (e.g., tapping outside/close) triggers navigation back to `Routes.RAMP.TOKEN_SELECTION` when the modal is shown in `skipQuotes` mode (i.e., no pending post-action). > > Updates tests to mock `navigate`, capture the `BottomSheet` `onClose` callback, and assert navigation occurs only for `skipQuotes: true` and not for the normal quotes flow. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 69669e2. 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? --> Fix branch deeplinks not working with the X (Twitter) app by adding a `$deeplink_path` param in branch.io and consuming it in MetaMask Mobile. ### Context - Platform: happens only on iOS. Android behaves differently (no Deepview in our flow). - User taps a t.co link in X (Twitter) → redirects to https://metamask.app.link/1WkF6GmE40b (which is a link generated by X/Branch.io on Tweet posting) → Branch Deepview is shown → user taps “Get the app” → opens MetaMask via Universal Link: https://metamask-alternate.app.link/1WkF6GmE40b?__branch_flow_type=viewapp&__branch_flow_id=...&__branch_mobile_deepview_type=1. - Issue: The app opens correctly, but in-app we show a “page not found” (404). So the OS and Branch open the app, but we don’t know which in-app route corresponds to link ID 1WkF6GmE40b. ### What we found 1. No resolved URI from the SDK - The Branch iOS SDK (and react-native-branch) give us: - The raw URL that opened the app (e.g. https://metamask-alternate.app.link/1WkF6GmE40b?...), and - The params from the session (e.g. from getLatestReferringParams() / subscribe callback). - The SDK does not build a custom deeplink URI (e.g. metamask://swap) from link data; it only returns the params. So we have to do routing ourselves. 2. Implemented fix: - Added a $deeplink_path in Branch deeplinks (this must be added to every existing and future deeplinks that we want to post on X) - Read it from the params and build our deeplink ourselves (e.g. metamask://${params.$deeplink_path}) and then route inside the app. ## **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: Fixed a bug that was causing deeplinks opened from X app to fail ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/GE-139 Fixes: #27140 ## **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] > **Medium Risk** > Touches deeplink routing/host allowlists and Branch handling on app start, which can affect navigation from external links, but the change is narrowly scoped and covered by new unit tests. > > **Overview** > Fixes Branch short-link universal links (notably from X on iOS) by introducing `rewriteBranchUri`, which converts `metamask-alternate.app.link/<id>` URLs into `https://link.metamask.io/<$deeplink_path>` while preserving query params. > > `DeeplinkManager.start()` now applies this rewrite for both cold-start Branch params (`~referring_link`) and `branch.subscribe` events, replacing the prior `getLatestReferringParams` fallback logic. > > Adds `MM_UNIVERSAL_LINK_HOST_ALTERNATE` (`metamask-alternate.app.link`) and includes it in universal-link host validation (`handleUniversalLink`) and MetaMask-host detection (`util/deeplinks`), with new tests covering rewrite and routing behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit de4e3dc. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Adds analytics tracking for all user interactions with the `TokenNotAvailableModal` — the bottom sheet shown in Unified Buy v2 when the selected token is not supported by the selected provider. Previously only the "Change Provider" button was tracked. This PR adds: - `Ramps Screen Viewed` on modal mount (`location: 'Token Unavailable Modal'`) - `Ramps Change Token Button Clicked` (new event) when user taps "Change Token" - `Ramps Close Button Clicked` when user taps X to dismiss This gives full funnel visibility into what users do when they hit a token-unavailability state. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-3311 ## **Manual testing steps** ```gherkin Feature: Token unavailable modal analytics Scenario: user sees the modal and taps Change Token Given the user is on the Amount Input screen with a provider selected And the selected token is not supported by that provider When the token unavailable modal appears Then a "Ramps Screen Viewed" event fires with location "Token Unavailable Modal" When user taps "Change Token" Then a "Ramps Change Token Button Clicked" event fires with current_provider set Scenario: user dismisses the modal Given the token unavailable modal is visible When user taps the X close button Then a "Ramps Close Button Clicked" event fires with location "Token Unavailable Modal" Scenario: user taps Change Provider (no regression) Given the token unavailable modal is visible When user taps "Change Provider" Then a "Ramps Change Provider Button Clicked" event fires (unchanged behaviour) ``` ## **Screenshots/Recordings** ### **Before** Only `Ramps Change Provider Button Clicked` fired from this modal. ### **After** All four interaction surfaces tracked. Verify via Segment debugger or analytics logs. ## **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** > Analytics-only changes plus a small close-button behavior tweak (close vs navigate) confined to a single modal and covered by updated tests. > > **Overview** > Adds MetaMetrics tracking to the Unified Buy v2 `TokenNotAvailableModal`, firing `RAMPS_SCREEN_VIEWED` on mount and logging button interactions for **Change token** and the modal **close (X)**. > > Introduces a new analytics event constant `RAMPS_CHANGE_TOKEN_BUTTON_CLICKED` in `MetaMetrics.events.ts`, wires the close button to a new `handleClose` (close only, no navigation), and updates/extends tests to mock `useAnalytics` and assert the new event payloads. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit cb0455f. 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 : )