Skip to content

[pull] main from MetaMask:main#549

Merged
pull[bot] merged 17 commits into
Reality2byte:mainfrom
MetaMask:main
Feb 24, 2026
Merged

[pull] main from MetaMask:main#549
pull[bot] merged 17 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Feb 24, 2026

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 : )

tommasini and others added 17 commits February 24, 2026 18:05
<!--
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:

## **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**
> Config-only change limited to Yarn audit suppression/formatting, with
no runtime code impact; the main risk is reduced visibility into the
ignored security advisories.
> 
> **Overview**
> Updates `.yarnrc.yml` to **suppress additional `bn.js` infinite-loop
security advisories** by adding `1113441` and `1113442` to
`npmAuditIgnoreAdvisories` (alongside existing ignores) to unblock
audits/CI.
> 
> Also normalizes Yarn config quoting/formatting (e.g., `spec` and
`npmPreapprovedPackages` entries switched to single-quoted strings).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
931f78f. 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**

EDIT: the main fix was recently done in this:
#26108

This PR adds a migration to ensure old entries are normalised and use
the expected typed shape.

## **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: fix: migration to fix TokenController string decimals

## **Related issues**

Fixes: #24360
https://consensyssoftware.atlassian.net/browse/ASSETS-2241

## **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**

https://www.loom.com/share/8e4070c5143645b98cf1f65740ff73c8

## **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 the persisted migration pipeline and mutates stored token
metadata across all users, so mistakes could affect token balance
display/calculations. Logic is scoped to `decimals` type normalization
with guarded state checks and tests, limiting blast radius.
> 
> **Overview**
> Fixes persisted token data where `TokensController` tokens could have
`decimals` stored as strings, which can break downstream calculations.
> 
> Adds migration `122` to walk `TokensController.allTokens` and
`TokensController.allDetectedTokens`, converting string `decimals` to
numbers (falling back to `0` when parsing fails), and wires the
migration into the main `migrationList`. Includes a comprehensive unit
test suite covering no-op cases and successful normalization across
chains/accounts.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3dc5c4c. 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**

Implements Market Insights tracking end-to-end by emitting `Market
Insights Clicked`, `Viewed`, and `Interaction` events in the Token
Details and Market Insights flows, makes thumbs up/down actionable in
the Market Insights footer, and updates `Token Details Opened` to
include `market_insights_displayed` based on actual entry-card
visibility, with focused test updates for the new analytics and
interactions.

## **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**

- [ ] 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**
> Mainly adds analytics instrumentation and a few new callbacks/press
handlers; moderate risk of duplicate/missed events due to new effect/ref
gating and route-param change behavior, but minimal impact on core funds
flows.
> 
> **Overview**
> Adds end-to-end MetaMetrics coverage for Market Insights: emits
`MARKET_INSIGHTS_OPENED` from the token details entry card,
`MARKET_INSIGHTS_VIEWED` when a report is shown (re-fires on `caip19Id`
change), and `MARKET_INSIGHTS_INTERACTION` for trade, thumbs up/down,
and source clicks (including source URL).
> 
> Makes Market Insights source lists and footer feedback actionable by
wiring `onSourcePress`/`onThumbsUp`/`onThumbsDown` through
`MarketInsightsSourcesFooter` and
`MarketInsightsTrendSourcesBottomSheet`, and adds new testIDs for the
thumb buttons.
> 
> Updates `TOKEN_DETAILS_OPENED` tracking to include
`market_insights_displayed` based on actual entry-card visibility
(deferred in TokenDetails V2 via `onMarketInsightsDisplayResolved`,
immediate `false` for legacy view) and avoids double-tracking for the
same token via a per-token key; removes unused summary-highlighting
helper and adjusts tests accordingly.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9cc8520. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…prevent trust conflation (#25932)

## **Description**

We've identified that self-reported dapp metadata (`originatorInfo.url`,
`session.peer.metadata.url`) was being stored in variables named
`origin` and `hostname` — the same names used for browser-provided
trusted identifiers. This naming conflation made it easy for downstream
code to accidentally treat self-reported data as trusted.

This PR renames variables and adds JSDoc documentation across all SDK
(v1, v2) and WalletConnect code paths to clearly distinguish
**self-reported** dapp metadata from **browser-provided trusted
origins**. No behavioral changes — all logic, validation, and permission
checks remain identical.

Addresses: https://consensyssoftware.atlassian.net/browse/WAPI-1081

### Changes by file

| File | Change |
|------|--------|
| `SDKConnect/handlers/setupBridge.ts` | Extract `selfReportedUrl`,
`selfReportedTitle`, `selfReportedIcon` from `originatorInfo`; add JSDoc
warning |
| `SDKConnect/handlers/handleConnectionReady.ts` | Rename `dappUrl` →
`selfReportedDappUrl` |
| `SDKConnect/SDKDeeplinkProtocol/DeeplinkProtocolService.ts` | Add
class-level security JSDoc; extract
`selfReportedUrl`/`selfReportedTitle` in `setupBridge()`; rename
`params.url` usage → `selfReportedRequestUrl` in
`processDappRpcRequest()` |
| `WalletConnect/WalletConnect2Session.ts` | Rename `origin` getter →
`selfReportedUrl`; `hostname` getter → `selfReportedHostname`; local
`origin` → `unverifiedOrigin` throughout `handleRequest()`,
`switchToChain()`, `handleSendTransaction()` |
| `WalletConnect/wc-utils.ts` | Rename `getRequestOrigin()` →
`getUnverifiedRequestOrigin()` with comprehensive JSDoc |
| `SDKConnectV2/adapters/rpc-bridge-adapter.ts` | Extract
`selfReportedDappUrl`/`selfReportedDappName`/`selfReportedDappIcon`; add
JSDoc to `createClient()` |

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: <!-- link Jira ticket here -->

## **Manual testing steps**

```gherkin
Feature: SDK and WalletConnect connections

  Scenario: user connects via SDK v1 socket relay
    Given the user has a dapp using SDK v1

    When user initiates a connection and sends a transaction
    Then the connection succeeds, confirmation UI shows dapp metadata, and the transaction can be approved or rejected as before

  Scenario: user connects via SDK v1 deeplink protocol (iOS)
    Given the user has an iOS dapp using SDK v1 deeplink transport

    When user initiates a connection and sends a transaction
    Then the connection succeeds and transactions are processed normally

  Scenario: user connects via SDK v2 / MWP
    Given the user has a dapp using MetaMask Connect (SDK v2)

    When user scans QR or taps deeplink to connect and sends a request
    Then the connection succeeds and requests are handled normally

  Scenario: user connects via WalletConnect v2
    Given the user has a dapp using WalletConnect v2

    When user pairs via QR code and sends a transaction
    Then the session is established, confirmation UI shows dapp metadata, and the transaction can be approved or rejected as before

  Scenario: INTERNAL_ORIGINS and ORIGIN_METAMASK checks still block
    Given a malicious dapp claims an internal origin via SDK or WC

    When the dapp attempts to send a transaction
    Then the request is rejected with "External transactions cannot use internal origins"
```

## **Screenshots/Recordings**

Not applicable — no UI changes. This is a variable renaming and
documentation-only refactor.

### **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
- [ ] 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**

- [ ] 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**
> Primarily a documentation and naming refactor; behavior should be
unchanged, but touches connection/middleware plumbing so regressions
would manifest as mis-attributed metadata or broken origin checks in
SDK/WC flows.
> 
> **Overview**
> Adds explicit *security warnings* and renames variables across SDK
Connect v1 (including iOS deeplink transport), SDK Connect v2 (MWP), and
WalletConnect v2 so dapp-provided metadata is consistently treated as
**self-reported/unverified** (e.g., `origin`/`hostname` ->
`selfReportedUrl`/`selfReportedHostname`, `getRequestOrigin` ->
`getUnverifiedRequestOrigin`).
> 
> Updates logs, bridge/middleware setup, and
`INTERNAL_ORIGINS`/`ORIGIN_METAMASK` checks to use the renamed variables
without changing the underlying behavior; adjusts the WC2 unit test
accordingly and adds JSDoc documenting spoofing/trust caveats for
displayed dapp URL/title/icon.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
38d710c. 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**

GH ACTIONS test proof -
https://github.com/MetaMask/metamask-mobile/actions/runs/22361836820/job/64717546937

CI builds currently fail late — after cloning, installing dependencies,
and starting the build — if a required secret is missing or not set in
the GitHub Environment. This PR adds a fast-fail validation step that
runs **before** secrets are injected, aborting the build immediately
with a clear, actionable error message.

### What changed

**`scripts/validate-secrets-from-config.js`** (new)

A CI-agnostic Node.js script that reads `CONFIG_SECRETS` (the `{
ENV_VAR_NAME: SECRET_NAME }` map defined in `builds.yml`, same format
used by `set-secrets-from-config.js`) and verifies every required secret
is present and non-empty before the build proceeds.

- Distinguishes two failure modes with separate error lists:
- **Absent** — secret is not in the source at all (e.g. missing from
`builds.yml` or not passed to the step)
- **Empty** — secret is present but has no value (e.g. not configured in
the GitHub Environment for this build)
- CI-agnostic by default: resolves secrets from `process.env`
individually, so it works on any CI platform (Bitrise, CircleCI, etc.)
without extra wiring
- Accepts an optional `SECRETS_JSON` env var (a JSON blob) as an
override, allowing callers to pass all secrets at once — used by the
GitHub Actions step via `toJSON(secrets)`

**`.github/workflows/build.yml`**

Adds a **"Validate secrets"** step between "Apply build config" and "Set
secrets":

```yaml
- name: Validate secrets
  env:
    CONFIG_SECRETS: ${{ needs.prepare.outputs.secrets_json }}
    SECRETS_JSON: ${{ toJSON(secrets) }}
  run: node scripts/validate-secrets-from-config.js
```

The GitHub-specific `toJSON(secrets)` wiring stays in the YAML; the
script itself has no GitHub-specific dependencies.

## **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**
> Adds a preflight CI validation step and a new script without changing
build outputs or secret injection logic; primary risk is only increased
CI failures when environments are misconfigured.
> 
> **Overview**
> CI now fails fast when a build’s required secrets (as defined in
`builds.yml`) are missing or empty, instead of failing later during the
build.
> 
> This adds a new `scripts/validate-secrets-from-config.js` validator
and wires it into `.github/workflows/build.yml` as a dedicated
**Validate secrets** step that runs before `set-secrets-from-config.js`,
emitting actionable errors for missing vs. empty secrets.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0ab10fb. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Adds the `corporate-fare` SVG icon to the Icon component library. This
icon is needed to unblock the Stocks feature while we wait for the
design system libraries upgrade in #26450.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: N/A
Related: #26450

## **Manual testing steps**

```gherkin
Feature: Corporate Fare Icon

  Scenario: Icon renders correctly
    Given the app is running

    When a component references the corporate-fare icon
    Then the icon should render as a building/corporate symbol
```

## **Screenshots/Recordings**

### **Before**

N/A - new icon asset

### **After**

N/A - SVG asset only, no UI 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]
> **Low Risk**
> Adds a new static SVG and enum entry with no behavioral changes beyond
making an additional icon available.
> 
> **Overview**
> Adds a new `corporate-fare.svg` asset and exposes it through the Icon
component library by extending `IconName` with `CorporateFare` and
registering the asset in `Icon.assets.ts`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c78eb70. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

As per Polymarket's team guidance, the event's `description` field is
not guaranteed to be accurate. Instead, we should use the first market's
description (`event.markets[0].description`), which is what Polymarket
does on their own website.

This PR updates `parsePolymarketEvents` to use
`event.markets?.[0]?.description` with a fallback to `event.description`
when unavailable.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-693

## **Manual testing steps**

```gherkin
Feature: Predict About Tab Description

  Scenario: user views event description in about tab
    Given user is on the Predict tab with a Polymarket event

    When user opens an event and views the About tab
    Then the description should show the first market's description instead of the event description
```

## **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]
> **Low Risk**
> Small, localized data-mapping change affecting only displayed
description text; logic includes a safe fallback and is covered by
updated tests.
> 
> **Overview**
> Adjusts `parsePolymarketEvents` to set a parsed Polymarket event’s
`description` from `event.markets?.[0]?.description`, falling back to
`event.description` when missing, to better match Polymarket’s canonical
descriptions.
> 
> Updates the associated unit test fixture/expectations in
`utils.test.ts` to reflect the new source of truth for the event and
outcome descriptions.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f1eb86a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…26443)

## **Description**

Implements the missing states for the Tokens section of the homepage
redesign

1. **Error state**: when the popular tokens price API fails for
zero-balance accounts, surfaces a catch-all `ErrorState` at section
level. `PopularTokensList` reports errors upward via an `onError`
callback so `TokensSection` owns the error UI

2. **Pull-to-refresh**: For zero-balance accounts, delegates to
PopularTokensList's ref. For funded accounts
CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-417
Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-424

## **Manual testing steps**

```gherkin
Feature: Homepage Tokens Section — Error and Refresh States

  Scenario: user sees error state when popular tokens fail to load
    Given the device has no internet connection
    And the selected account has zero balance

    When user opens the homepage
    Then the Tokens section shows a wifi-off icon and "Unable to load tokens"
    And a Retry button is visible

  Scenario: user retries after error
    Given the Tokens section is showing the error state
    And the device is back online

    When user presses Retry
    Then the Tokens section shows the popular token list again

  Scenario: user pulls to refresh on a funded account
    Given the selected account has token balances

    When user pulls to refresh on the homepage
    Then the Tokens section token balances refresh

  Scenario: user pulls to refresh on a zero-balance account
    Given the selected account has zero balance
    And popular tokens are displayed

    When user pulls to refresh on the homepage
    Then the popular token prices refresh
```

## **Screenshots/Recordings**

Refresh


https://github.com/user-attachments/assets/aa8596ca-6604-47a4-b97d-3ab5b9fa4005

Error state for empty state list

<img width="350" alt="empty_list_error_state"
src="https://github.com/user-attachments/assets/17009042-bbf4-43f1-9592-c04b19d3d808"
/>

Error state for list state

<img width="350" alt="has_assets_error_state"
src="https://github.com/user-attachments/assets/7450d72c-a429-4a2c-86d3-2e6774f40d31"
/>

### **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
- [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).
- [ ] 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 homepage token refresh and error-handling logic, so
regressions could hide token lists or show spurious errors; changes are
UI/state-oriented and covered by added tests.
> 
> **Overview**
> Adds a section-level **catch-all `ErrorState`** to the homepage
`TokensSection`, shown when popular tokens’ initial load fails
(zero-balance path), when an explicit refresh fails, or when balance
indicates funds but the token selector returns empty (with a `null`
balance guard to avoid cold-start false positives).
> 
> Implements **pull-to-refresh for funded accounts** by wiring
`TokensSection.refresh()` to `refreshTokens(...)` (with network/account
context), resets error state on account change, and adds an `onError`
callback in `PopularTokensList` so the section can own error UI and
retry behavior. Tests are expanded to cover error rendering, retry
clearing, the balance-based heuristic, and refresh invocation/args.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ab22af3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…exports (#26503)

<!--
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**

Part "3.5" of the hardware wallet connection & error management
overhaul. This does not introduce user facing changes.

Final implementation will look like this ([Figma
designs](https://www.figma.com/design/1F3yNWYLOVPFpTPeJugH20/SWAP?node-id=11110-19571&t=tPMZNNiwCgbDfegd-0)):
<img width="1404" height="631" alt="image"
src="https://github.com/user-attachments/assets/68850711-f53b-4060-8b47-6faceb67f82f"
/>

Reference feature branch:
#25519

## **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**

no manual testing steps

## **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**
> Moderate risk due to an interface change affecting all adapter
implementations and downstream imports/exports; runtime behavior change
is limited to additional transport metadata on Ledger.
> 
> **Overview**
> Extends the `HardwareWalletAdapter` interface with
`getTransportDisabledErrorCode()` and `getConnectionTips()` so callers
can surface transport-specific errors and UX guidance; implements these
for `LedgerBluetoothAdapter` (BLE tips + `BluetoothDisabled`) and no-ops
for `NonHardwareAdapter`, with tests updated accordingly.
> 
> Removes the `requiresBluetooth` helper and tightens module exports by
dropping default exports for
`useDeviceEventHandlers`/`useHardwareWalletStateManager` and narrowing
context exports, plus adds a top-level `app/core/HardwareWallet` index
exporting `useHardwareWallet` and `isUserCancellation`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
010da70. 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**

Aligns mobile ramps with controller changes that remove quotes, quote
polling, and widget URLs from shared state. Quote and widget data are
now fetched on demand, and the provider selection flow has been
refactored so each modal fetches its own data and ProviderPickerModal
has been removed.

## Context: Controller State Changes

Quotes, quote polling, and widget URLs have been removed from ramps
controller state and must be fetched on demand. The mobile app no longer
relies on shared quote state or polling.

## Changes

### On-Demand Quote & Widget Fetching

**BuildQuote**
- Fetches quote and widget URL on demand when amount, payment method,
provider, and token are selected
- Uses local component state for loading and error (instead of shared
controller state)
- No longer subscribes to shared quote state from the controller

### Modal Decoupling & Provider Selection Refactor

**PaymentSelectionModal**
- No longer embeds ProviderSelection or manages `activeView` state
- “Change provider” now navigates to a separate modal via routing
(instead of in-place view switching)
- Fetches its own quotes for its payment selection flow

**ProviderSelectionModal**
- Standalone modal with its own `useRampsController` and quote fetching
- Added to navigation stack as its own screen (Option A: separate modal,
stack push)
- Supports two flows:
1. **Change provider (with quotes)** – from PaymentSelectionModal,
fetches quotes and displays them in the list
2. **Provider picker (without quotes)** – from BuildQuote or
TokenNotAvailableModal via `skipQuotes: true`; filters by `assetId`,
shows provider list only

**ProviderSelection (shared content component)**
- Extracted as reusable component with optional `providers` and
`showQuotes` props
- When `showQuotes: false`, hides quote column and shows a different
empty-state message

**ProviderPickerModal removed**
- ProviderPickerModal and its route removed entirely
- Its use cases are handled by ProviderSelectionModal with `skipQuotes:
true` and `assetId`

### Provider Picker Trigger Removed from BuildQuote

- Removed the “powered by {provider}” touchable from BuildQuote
- Provider changes from BuildQuote are only available via
PaymentSelectionModal (through the payment method pill flow)
- Removed `handleProviderPress` and the `poweredByText` style

## Navigation Changes

- Added `PROVIDER_SELECTION` route and wired into `routes.tsx`
- Removed ProviderPickerModal route
- “Change provider” uses
`navigation.navigate(Routes.RAMP.MODALS.PROVIDER_SELECTION, { amount })`

<!--
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: 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] -->


Quote loading state and componentry for payment and provider selection
is now independent:


https://github.com/user-attachments/assets/f72f82f7-4b3d-4af4-a987-74c358d016d0





## **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 Ramp purchase flow state/validation and navigation, so
regressions could block quote selection or checkout despite being
largely a refactor with updated tests.
> 
> **Overview**
> Refactors Ramp V2 quote handling to be **on-demand via
`useRampsQuotes`** instead of relying on controller-held
`quotes`/polling state. `BuildQuote` now fetches quotes only when
amount/provider/payment method/token/wallet are set, shows a new
quote-fetch error banner, validates quote provider match before
continuing, and ensures the continue loading state always clears.
> 
> Simplifies provider selection: `PaymentSelectionModal` no longer
embeds the animated provider selection panel; “Change provider” now
navigates to `Routes.RAMP.MODALS.PROVIDER_SELECTION` and the modal
fetches its own quotes for per-payment-method quote display. UI
messaging is tweaked with a new `QuoteDisplay` “quote unavailable”
state, and tests/snapshots are updated accordingly (including removing
ProviderPicker/quote polling mocks).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d83fae3. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…`HighlightedAction` (#26480)

<!--
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?
-->

This PR replaces separate `HighlightedAction` and `HighlightedAsset`
with one unified `HighlightedItem`.

- Adds a single `HighlightedItem` component used both above the search
bar and inside the asset list.
- Uses explicit placement via position: 'outside_of_asset_list' |
'in_asset_list'.
- Keeps shared row behavior (action on row press), icon resolution
(IconName or URL), selected state, fiat display, and optional action
buttons.
- Preserves loading behavior with spinner (isLoading) for actionable
items.
- Updates related types, guards, call sites, and tests to the unified
model.
- Removes old highlighted-action and highlighted-asset components.

## **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**



https://github.com/user-attachments/assets/6465c37d-8b1b-457c-913e-f40b9f836286



## **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**
> Moderate UI/data-shape refactor in the token selection flow; risk is
mainly regressions in highlighted-row rendering/interaction and
modal-close callback wrapping (row press vs button press).
> 
> **Overview**
> Replaces the separate highlighted-row components (`HighlightedAsset`
in-list and `HighlightedAction` above-list) with a single
`HighlightedItem` that can render either a fiat-value row or a row with
right-side action buttons/spinner.
> 
> Updates the confirmations asset picker (`Asset`, `TokenList`, and
`PayWithModal`) to use the new `HighlightedItem` model, splitting
highlighted rows by `position` and ensuring modal close behavior wraps
both row presses and optional action-button presses. Types and type
guards in `types/token.ts` are consolidated accordingly, and tests are
rewritten to cover the unified component and updated call sites.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d73816f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

Adds a new `/create-bug` Claude skill that standardises GitHub bug issue
creation for the MetaMask Mobile repository. Without this skill, bug
issues created via Claude were inconsistently formatted, missing
required fields, and risked creating duplicate issues.

This skill:
- Searches for existing issues matching the bug description before
creating a new one, to prevent duplicates
- Guides Claude to interactively collect all required and optional
fields before creating an issue
- Formats the issue body to match the official `bug-report.yml`
template, including correct section headings, code fence rendering for
error output, and multi-select OS options
- Always applies the `type-bug` label and `[Bug]:` title prefix
- Always includes every template section (e.g. Build type) to pass the
`check-template-and-add-labels` GitHub Action validation
- Optionally investigates the codebase for the possible root cause and
adds a comment to the created issue with findings, key file locations,
and a suggested fix approach (opt-in, default: no)

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MMQA-1493

## **Manual testing steps**

```gherkin
Feature: Create bug issue via Claude skill

  Scenario: user creates a bug issue using /create-bug
    Given the user is in a Claude Code session in the metamask-mobile repo
    And gh CLI is installed and authenticated

    When user runs /create-bug
    Then Claude searches for existing issues matching the bug description
    And if a duplicate is found, Claude links to it and stops
    And if no duplicate is found, Claude prompts for all required fields
    And Claude creates a GitHub issue on MetaMask/metamask-mobile
    And the issue title is prefixed with "[Bug]:"
    And the issue has the "type-bug" label
    And the issue body matches the bug-report.yml template structure
    And Claude asks if the user wants a root cause analysis (default: no)
    And if yes, Claude investigates the codebase and adds a comment with findings
```

## **Screenshots/Recordings**

### **Before**

N/A

### **After**

Run `/create-bug` in the Claude Code terminal to create a GitHub bug
issue in the MetaMask Mobile repository.

## **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**

- [ ] 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**
> Adds a documentation-style Claude command for creating GitHub issues;
no production code paths or data/security-sensitive logic are changed.
> 
> **Overview**
> Adds a new Claude command, `/create-bug`
(`.claude/commands/create-bug.md`), to standardize creating MetaMask
Mobile bug issues via the `gh` CLI.
> 
> The command instructs Claude to: parse
`.github/ISSUE_TEMPLATE/bug-report.yml` to drive required/optional field
collection (including special handling for `severity` and `render:
shell`), run a pre-flight duplicate search, and then create a `type-bug`
issue with a `[Bug]:` title prefix and template-ordered body; it also
includes an optional post-create flow to comment a root-cause
investigation summary.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
01f3692. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
## **Description**

The claim button text in the Predict positions header was using
`ComponentTextColor.Inverse` which resolves to a theme-dependent color.
On certain background colors (e.g. the green claim button), this
resulted in poor contrast or incorrect text color. This change hardcodes
the text color to `"white"` to ensure consistent visibility against the
colored button background.

## **Changelog**

CHANGELOG entry: Fixed claim button text color in Predict positions
header to always display white for proper contrast

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/PRED-698

## **Manual testing steps**

```gherkin
Feature: Predict claim button text color

  Scenario: user views a claimable prediction position
    Given the user has a claimable prediction position

    When user views the Predict positions header
    Then the claim button text should be white and clearly visible against the button background
```

## **Screenshots/Recordings**

### **Before**

<!-- screenshots to be added -->

### **After**

<!-- screenshots to be added -->

<img width="974" height="864" alt="Screenshot 2026-02-24 at 1 21 00 PM"
src="https://github.com/user-attachments/assets/53ad80cf-0b30-4e85-a675-c736c6ccfbb8"
/>


## **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
- [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 UI styling change that only affects text color on the Predict
claim button, with no logic, data, or security impact.
> 
> **Overview**
> Fixes the Predict positions header claim button label to always render
in white by replacing theme-dependent `ComponentTextColor.Inverse` with
a hardcoded `"white"`, improving contrast on colored button backgrounds.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
99e83df. 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?
-->

Remove BIP-44 State 2 mock
(`remoteFeatureMultichainAccountsAccountDetailsV2`) for "Incoming
Transactions" E2E.

## **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: None

## **Manual testing steps**

Not applicable

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

Not applicable

## **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**
> Test-only refactor that removes a feature-flag mock dependency; low
product risk, with only potential for E2E flakiness if the flag is still
required in some environments.
> 
> **Overview**
> The `Incoming Transactions` smoke test no longer sets up the remote
feature flags mock (including the `multichainAccountsAccountDetailsV2`
override), and now only stubs the Accounts API transactions endpoint via
`setupMockRequest`.
> 
> This simplifies the test’s mock setup by removing the extra
BIP-44/feature-flag related wiring while keeping the transaction
assertions unchanged.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ecc4a22. 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?
-->

This PR removes sonar cloud steps to unblock since it's failing from
either missing project/token. Debugging and will add back once solution
is found.

Report -
https://consensys.slack.com/archives/C02U025CVU4/p1771949951334369

## **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:
https://consensys.slack.com/archives/C02U025CVU4/p1771949951334369

## **Manual testing steps**

PR should not run sonar cloud steps

## **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**
> Workflow-only change that reduces CI coverage by skipping SonarCloud,
but does not affect runtime code or production behavior.
> 
> **Overview**
> **Temporarily disables SonarCloud in CI** by forcing the `sonar-cloud`
and `sonar-cloud-quality-gate-status` jobs to always skip (`if: false`).
> 
> Updates the `all-jobs-pass` job’s `needs` list to no longer require
the SonarCloud quality gate job, so the workflow can pass without
SonarCloud running.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b2df46b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…7.67.0 (#26495)

<!--
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 UI bug where the mUSD conversion header was left-aligned on
Android in the activity details view.
<!--
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: fix UI bug where the mUSD conversion header was
left-aligned on Android in the activity details view


## **Related issues**

Fixes: [MUSD-368: Conversion header in activity list is left-aligned on
Android](https://consensyssoftware.atlassian.net/browse/MUSD-368)

## **Manual testing steps**

```gherkin
Feature: Centered navbar title in shared title options

  Scenario: user opens a screen that uses shared navigation title options on Android
    Given user is on an Android screen configured with getNavigationOptionsTitle

    When the screen header is rendered
    Then the header title is centered
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="1080" height="2340" alt="image"
src="https://github.com/user-attachments/assets/1224d29f-370c-4183-ae82-b486c401da96"
/>

<!-- [screenshots/recordings] -->


### **After**

<!-- [screenshots/recordings] -->
<img width="1080" height="2340" alt="image"
src="https://github.com/user-attachments/assets/1fc92cd3-6f3d-48e3-882e-3e5e7eb36bd8"
/>
## **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 UI navigation option change with minimal behavioral impact;
risk is limited to potential header layout differences across screens
using `getNavigationOptionsTitle`.
> 
> **Overview**
> Fixes an Android UI alignment issue by updating
`getNavigationOptionsTitle` (Navbar) to explicitly set
`headerTitleAlign: 'center'`, ensuring screens using these shared
options render a centered header title.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9316007. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…6178)

<!--
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**

**Reason:** GitHub Action builds need server API URLs and environments
to come from `builds.yml` (via `apply-build-config.js`) instead of
hardcoded/METAMASK_ENVIRONMENT logic, so each workflow build uses the
correct Rewards, Baanx, Ramp, and Portfolio endpoints.

**Solution:** Use env vars from builds.yml when running in GitHub
Actions (and not E2E). Rewards, Baanx, and Ramps now branch on
`GITHUB_ACTIONS === 'true' && E2E !== 'true'` to read `REWARDS_API_URL`,
`BAANX_API_URL`, and `RAMPS_ENVIRONMENT` from `process.env` (set by the
workflow); otherwise keep the existing METAMASK_ENVIRONMENT/AppConstants
behavior for Bitrise and E2E. `AppConstants` now prefers
`PORTFOLIO_API_URL` for the portfolio URL. Babel test config excludes
the touched modules so unit tests can control env; rewards and Baanx
tests assert both the “GH Actions” path and the legacy path;
rewards-data-service tests force the legacy path via `GITHUB_ACTIONS =
'false'`.

main-beta ✅ 
<img width="200" height="450" alt="Simulator Screenshot - iPhone 16 -
2026-02-19 at 11 39 56"
src="https://github.com/user-attachments/assets/bc5b3006-4fc4-4536-88bc-3992644ef968"
/>
main-test ✅ 
<img width="200" height="450" alt="Simulator Screenshot - iPhone 16 -
2026-02-19 at 11 39 56"
src="https://github.com/user-attachments/assets/5b062f4b-801a-4427-973e-ce5692774971"
/>
main-rc ✅ 
<img width="200" height="450" alt="Simulator Screenshot - iPhone 16 -
2026-02-19 at 11 39 56"
src="https://github.com/user-attachments/assets/765ccdae-a42a-49c9-a268-623980737ce1"
/>
flast-test ✅ 
<img width="200" height="450" alt="Simulator Screenshot - iPhone 16 -
2026-02-19 at 11 39 56"
src="https://github.com/user-attachments/assets/da8d2e76-719e-48fb-8619-31070759916a"
/>


## **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 servers api defined at builds.yml for github
action builds

## **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**
> Changes build-time environment selection and server endpoint wiring
for ramps/rewards/card flows; misconfigured env vars in CI could route
builds to the wrong backend, though behavior is gated to
`GITHUB_ACTIONS` and covered by updated tests.
> 
> **Overview**
> GitHub Actions builds now source **Rewards**, **Baanx**, and **Ramps**
environment/config from `builds.yml` (via `process.env`) when
`GITHUB_ACTIONS === 'true'` and not `E2E`, instead of deriving these
from `METAMASK_ENVIRONMENT`.
> 
> Specifically, `getDefaultRewardsApiBaseUrlForMetaMaskEnv`,
`getDefaultBaanxApiBaseUrlForMetaMaskEnv`, `getRampsEnvironment`, and
both ramps SDK `getSdkEnvironment` helpers add a GH Actions branch that
reads `REWARDS_API_URL` / `BAANX_API_URL` / `RAMPS_ENVIRONMENT`, with
tests expanded to cover both GH Actions and legacy paths. Build config
is aligned by renaming `PORTFOLIO_API_URL` to `MM_PORTFOLIO_URL` in
`builds.yml`, updating `AppConstants` and
`scripts/verify-build-config.js`, and adjusting `babel.config.tests.js`
to avoid inlining env vars for the affected modules during tests.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7163b34. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Wei Sun <wei.sun@consensys.net>
@pull pull Bot locked and limited conversation to collaborators Feb 24, 2026
@pull pull Bot added the ⤵️ pull label Feb 24, 2026
@pull pull Bot merged commit 317dc6a into Reality2byte:main Feb 24, 2026
3 of 13 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.