Skip to content

[pull] main from MetaMask:main#307

Merged
pull[bot] merged 12 commits into
Reality2byte:mainfrom
MetaMask:main
Nov 7, 2025
Merged

[pull] main from MetaMask:main#307
pull[bot] merged 12 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Nov 7, 2025

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

bfullam and others added 12 commits November 7, 2025 17:29
<!--
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**
Properly calculates insufficient balance state for quote requests. Used
by the backend for simulations and metrics.
<!--
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]
> Compute insufficient balance from latest token balance and include
`insufficientBal` in bridge quote request params; update tests and mocks
accordingly.
> 
> - **Bridge Hook (`useBridgeQuoteRequest`)**:
> - Compute latest source token balance via `useLatestBalance` and
derive insufficiency via `useIsInsufficientBalance`.
> - Track `insufficientBal` with a `useRef` to avoid re-creating the
debounced callback.
> - Include `insufficientBal` in `GenericQuoteRequest` params sent to
`BridgeController.updateBridgeQuoteRequestParams`.
>   - Add `useRef`/`useEffect` imports.
> - **Tests**:
> - Update mocks to include `NetworkController` and
`selectSourceWalletAddress`.
>   - Ensure debounced quote updates still function with new params.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
dbae0c4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…age (#22131)

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

Updated PerpsTutorialCarousel.test.tsx to align with latest component
changes where all users (eligible and non-eligible) are redirected to
the Perps home screen after completing or skipping the tutorial. Removed
deprecated depositWithConfirmation functionality and updated skip button
behavior assertions to match the current implementation.

<!--
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: Update Tutorial Perps Intro to redirect to the markets
home screen view

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TAT-1845
 
## **Manual testing steps**

```gherkin
Scenario: Eligible user completes tutorial and navigates to perps home
  Given I am an eligible user viewing the tutorial
  When I navigate through all 6 tutorial screens
  And I press the "Let's go" button on the final screen
  Then the tutorial should be marked as completed
  And I should be redirected to the Perps home screen

Scenario: Non-eligible user completes tutorial and navigates to perps home
  Given I am a non-eligible user viewing the tutorial
  When I navigate through all 5 tutorial screens
  And I press the "Let's go" button on the final screen
  Then the tutorial should be marked as completed
  And I should be redirected to the Perps home screen

Scenario: Eligible user skips tutorial from last screen
  Given I am an eligible user on the last tutorial screen
  When I view the ready_to_trade screen
  Then the skip button should be enabled
  And I can press skip to navigate to Perps home screen

Scenario: Non-eligible user cannot skip from last screen
  Given I am a non-eligible user on the last tutorial screen
  When I view the close_anytime screen
  Then the skip button should be disabled
  And I must use the "Let's go" button to proceed
```

## **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/19943a7a-8b73-4377-be68-d03accde2b16

<!-- [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]
> Perps tutorial now completes by navigating to Perps home for all
users, removes deposit initiation, updates last-screen button to “Let’s
go,” adjusts skip behavior, and refreshes tests/e2e selectors and i18n.
> 
> - **Perps Tutorial UX**
> - Completion now navigates to `Routes.PERPS.ROOT` →
`Routes.PERPS.PERPS_HOME` for all users; deposit flow removed.
> - Replaces last-screen primary label with
`strings('perps.tutorial.lets_go')` and always shows Skip (disabled on
last screen for non‑eligible users).
> - Removes `usePerpsTrading`/`depositWithConfirmation`,
`usePerpsNetworkManagement`, and confirmation navigation logic.
> - **Tracking/Logic**
> - Keeps metrics events; simplifies `shouldShowSkipButton`; refactors
continue/skip handlers accordingly.
> - **Tests** (`PerpsTutorialCarousel.test.tsx`)
> - Updates expectations for navigation, button labels, skip enablement,
and removes deposit-related assertions and error case.
> - **E2E** (`wdio/screen-objects/PerpsTutorialScreen.js`)
> - Introduces `continueButton` and `tapContinue`; keeps legacy
`addFundsButton`/`tapAddFunds` as aliases.
> - **i18n** (`locales/languages/en.json`)
>   - Adds `perps.tutorial.lets_go` string.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c8bd52b. 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**

### Summary

Fixes incorrect open interest calculation in the market list. Open
interest was showing values in thousands instead of billions because the
calculation wasn't converting raw contract units to USD by multiplying
by the current price.

### Root Cause

The transformMarketData() function used by the market list was parsing
raw open interest values directly:
// BEFORE (incorrect)const openInterest = assetCtx?.openInterest ?
parseFloat(assetCtx.openInterest) : NaN;
This treated open interest as USD when it's actually in contract units.
For example, BTC with 1M open interest contracts at $50K should be $50B,
but was showing as $1M.

### Solution

Created a centralized calculateOpenInterestUSD() utility function that
properly converts contract units to USD by multiplying by the current
price:
// AFTER (correct)const openInterest = calculateOpenInterestUSD(
assetCtx?.openInterest, effectiveCurrentPrice,);
This utility is now used consistently in:
transformMarketData() - Initial REST API data transformation (market
list)
HyperLiquidSubscriptionService - WebSocket real-time updates (2
locations)

### Known Discrepancy (Not Addressed in This PR)

There are two separate data sources for market data:

Market List: Uses REST API snapshot via getMarketDataWithPrices()
Data source: allMids prices from REST API
Update frequency: Cached, refreshes periodically or on pull-to-refresh
Use case: Browsing markets

Market Statistics Card: Uses real-time WebSocket via subscribeToPrices()
Data source: midPx || markPx from WebSocket
Update frequency: Real-time, updates every ~1-2 seconds
Use case: Viewing specific market details

Impact: While both now use the same calculation logic
(calculateOpenInterestUSD), the market list shows a snapshot while the
statistics card shows live real-time values. This is by design to
prevent scroll jumping and excessive re-renders in the list view. Users
can pull-to-refresh to update the market list.

### Changes Made

Created utility function: calculateOpenInterestUSD() in
marketDataTransform.ts
Updated market list: Uses utility in transformMarketData()
Updated WebSocket service: Uses utility in
HyperLiquidSubscriptionService (2 locations)
<!--
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: https://consensyssoftware.atlassian.net/browse/TAT-1972

## **Manual testing steps**

```gherkin
Scenario: Sorting preserves correct open interest calculation
    Given BTC has 1,000,000 contracts at $52,000 per contract
    And ETH has 5,000,000 contracts at $3,100 per contract
    When I sort markets by open interest
    Then BTC displays "$52.00B" and appears before ETH
    And ETH displays "$15.50B" and appears after BTC
    And the sorting uses the calculated USD values (contracts × price)
    And not the raw contract numbers

  Scenario: Switching from volume sort to open interest sort
    Given markets are currently sorted by "Volume"
    And the order is: SOL ($500M), BTC ($450M), ETH ($300M)
    When I change the sort to "Open Interest"
    Then markets reorder immediately
    And the new order is: BTC ($52.00B), ETH ($15.50B), SOL ($1.50B)
    And the sort dropdown shows "Open Interest" as selected
```

## **Screenshots/Recordings**

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

### **Before**

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

### **After**

<img width="400" alt="image"
src="https://github.com/user-attachments/assets/240a07c0-3a32-4e05-ae7e-6ec2ff026d92"
/>

<!-- [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]
> Centralizes open interest USD calculation and uses it in REST
transform and WebSocket subscriptions, updating displays and adding unit
tests.
> 
> - **Utils**:
> - Add `calculateOpenInterestUSD` in
`app/components/UI/Perps/utils/marketDataTransform.ts` and use it in
`transformMarketData()` to convert contract units × price to USD.
> - **Services**:
> - Update
`app/components/UI/Perps/services/HyperLiquidSubscriptionService.ts` to
compute `openInterest` via `calculateOpenInterestUSD` in both
`activeAssetCtx` and `assetCtxs` handlers.
> - **Tests**:
> - Expand `app/components/UI/Perps/utils/marketDataTransform.test.ts`
with comprehensive tests for `calculateOpenInterestUSD` and adjust
expectations (e.g., BTC `openInterest` to `$52.00B`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f48648e. 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**
We don't want developers to accidentally commit EAS configuration
changes during development. We can skip inserting EAS configuration when
building locally.

## **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: Expo Channel Configuration Script

  Scenario: Skip EAS configuration when building in dev environment
    Given METAMASK_ENVIRONMENT is set to "dev"
    When I run the update-expo-channel script
    
    Then the script should skip configuration
    And AndroidManifest.xml should not be modified
    And Expo.plist should not be modified
```

## **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]
> Skip configuring Expo Updates when METAMASK_ENVIRONMENT is "dev" (in
addition to "production"), with updated log output.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ed8bdda. 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**
Bugfix: metaMetrics not tracking events for social login users
Fix: #22296
<!--
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: Bugfix: metaMetrics not tracking events for social
login users

## **Related issues**

Fixes: metaMetrics not tracking events for social login
users(#22296)

## **Manual testing steps**

```gherkin
Feature: track events for social login
  Scenario: New Google login wallet setup track "Wallet Setup Started" event
    Given app is a clean install
    And user is on the onboarding screen
    And user presses "Continue with Google/Apple"
    When user complete onboarding
    Then "Wallet Setup Started" event appears in Segment for this user
```

## **Screenshots/Recordings**

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

### **Before**

N/A

### **After**
<img width="1296" height="821" alt="Screenshot 2025-11-07 at 1 18 15 PM"
src="https://github.com/user-attachments/assets/1460f986-e010-43b7-aee8-fcc8e0d6fc1d"
/>
<img width="1204" height="183" alt="Screenshot 2025-11-07 at 1 18 40 PM"
src="https://github.com/user-attachments/assets/750ada94-ce19-474b-b8b3-40453f6ecea0"
/>

## **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]
> <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is
generating a summary for commit
8b10f73. 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**
Ticket: https://consensyssoftware.atlassian.net/browse/INFRA-3041
Github-tools PR: MetaMask/github-tools#154,
MetaMask/github-tools#160

Changelog PR before updates:
consensys-test#31
Changelog PR after updates:
consensys-test#37

Summary of Changes

Prevented github-tools from appearing in PRs
File: github-tools/.github/workflows/stable-sync.yml
What: Added explicit cleanup commands to unstage and remove github-tools
directory before pushing
Impact: The sync PR will no longer include a github-tools/ submodule or
directory
Disabled package.json version bump for Extension
File: github-tools/.github/scripts/stable-sync.js
What: Removed the yarn version logic that bumped package.json version
Before: Extension ran yarn version to update the version
After: Extension now preserves package.json from stable branch (same as
mobile)
Impact: No version bump will occur in the sync PR for either mobile or
extension
Verified PR title format
File: github-tools/.github/workflows/stable-sync.yml (line 147)
What: Confirmed it already uses release: prefix (no change needed)
Format: "release: sync stable to main for version X.Y.Z"
Testing in Extension:
consensys-test/metamask-extension-test-workflow2#209,
https://github.com/consensys-test/metamask-extension-test-workflow2/actions/runs/18951817173
Testing in Mobile:
consensys-test#30,
https://github.com/consensys-test/metamask-mobile-test-workflow/actions/runs/18951842114

Testing Post CR comments:
consensys-test/metamask-extension-test-workflow2#212


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

## **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]
> Updates the stable branch sync workflow to use metamask/github-tools
commit 701a894 for both the reusable workflow and the input version.
> 
> - **CI/Workflows**:
> - Update `uses` in `.github/workflows/stable-branch-sync.yml` to
`metamask/github-tools/.github/workflows/stable-sync.yml@701a894f38883ab48560f948e98b76cc6b4d623f`.
> - Set `github-tools-version` input to
`701a894f38883ab48560f948e98b76cc6b4d623f`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
77f5118. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
#22327)

## **Description**

PR to fix undefined error when trying to hide a token from Asset details
page.

## **Changelog**

CHANGELOG entry: Fixed a bug that was causing app crash when trying to
hide a token from asset details page.

## **Related issues**

Fixes: #22325

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


https://github.com/user-attachments/assets/c2eafdbd-2399-4294-b37b-7f04e8e5e00c


### **After**

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


https://github.com/user-attachments/assets/a6c9e115-9399-47ab-ae2b-3511db97cbff


## **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]
> Refactors AssetDetails to a container/presentational pattern that
resolves the token via normalized address matching and passes it in,
returning null if missing.
> 
> - **Asset Details refactor**:
>   - Introduce `AssetDetailsContainer` that:
> - Selects tokens by `chainId`/account, finds the token using
`areAddressesEqual(address)`.
>     - Returns `null` if the token is not found.
>     - Passes the resolved `token` to `AssetDetails`.
> - Update `AssetDetails` to accept a `token` prop and remove internal
token selection logic.
> - **Address handling**: Use `areAddressesEqual` for robust token
address comparison.
> - **Export**: Default export switched to `AssetDetailsContainer`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4af9f02. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: sahar-fehri <sahar.fehri@consensys.net>
…22163)

<!--
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 a bug with account switching for MM Connect where changing the
account selector value from the homepage did not result in the dapp
receiving an accountsChanged event. This was because when the app cold
started, there was no BackgroundBridge instantiated for any MMC
connections unless there were pending messages from the relay (for
performance reasons), and because the homepage account selector was no
longer updating the PreferencesController state because the
PreferencesController.selectedAddress is deprecated.

To fix this, BackgroundBridge is now always instantiated on app start up
for all MMC connections. This is suboptimal, but can be rectified later
with TTL enforcement. BackgroundBridge now reads AccountsController for
selected account state. This is also technically deprecated state, but
it's out of the scope of what we are trying to achieve to fully migrate
the BackgroundBridge to read the selected account group instead.

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

No changelog necessary as MM Connect has not been publicly released to
users yet.

## **Related issues**

Fixes:

## **Manual testing steps**

1. Using the [EVM MMC test
dapp](MetaMask/connect-monorepo#21) in the
Native Browser
2. Connect 2 accounts
3. See which account is listed first in the test dapp
4. Go back to the wallet and change the account in the main wallet view
to the other permitted account
5. Return to the native browser
6. See that the newly selected account is listed first in the test dapp

## **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]
> Ensure MMC/remote account changes emit by eagerly initializing the RPC
bridge and reading selected account from AccountsController instead of
PreferencesController.
> 
> - **BackgroundBridge**:
> - Subscribe to `AccountsController:selectedAccountChange` and
unsubscribe on disconnect.
> - Replace `PreferencesController.selectedAddress` with
`AccountsController.getSelectedAccount().address` for `selectedAddress`
in `getState` and change detection in `onStateUpdate`.
> - For WalletConnect/remote, emit `accountsChanged` when the
AccountsController-selected address differs; update `addressSent`
accordingly.
> - **SDKConnectV2**:
> - `rpc-bridge-adapter`: call `ensureInitialized()` in constructor to
instantiate `BackgroundBridge` on startup, enabling timely event
delivery.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
bbd4de4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: ffmcgee <joao.carlos@consensys.net>
Co-authored-by: Alex Donesky <adonesky@gmail.com>
…22202)

Part 2 of 4 to fix:
https://github.com/MetaMask/mobile-planning/issues/2343

https://consensyssoftware.atlassian.net/jira/polaris/projects/MWMR/ideas/view/8845676?selectedIssue=MWMR-10

Previous Part: #21869

## Description

This PR adds `LegacyLinkAdapter`, a bidirectional adapter that bridges
the new `CoreUniversalLink` format (from PR #XXXX) with the existing
legacy deep link handlers. This is the second PR in Phase 1 of the deep
link consolidation project.

### Context
The current deep link system has routing logic fragmented across
multiple files with nested switch-case statements. This adapter enables
gradual migration to a unified routing system while maintaining 100%
backward compatibility with existing handlers.

### What Changed
- **Created `LegacyLinkAdapter`** with bidirectional conversion methods:
- `toLegacyFormat()` - Converts `CoreUniversalLink` to legacy `urlObj` +
`params` format
- `fromLegacyFormat()` - Creates `CoreUniversalLink` from legacy URL
strings
- `extractActionParams()` - Extracts action-specific paths and query
parameters
- `toProtocolUrl()` - Converts links between protocols (metamask://,
https://, ethereum://, dapp://)
- `shouldUseNewSystem()` - Feature flag system for gradual rollout
(currently disabled for all actions)
- `wrapHandler()` - Wraps legacy handlers to accept `CoreUniversalLink`

- **Added comprehensive test coverage** (23 test cases):
  - Format conversion tests
  - Parameter handling (including SDK params)
  - Protocol conversions
  - Edge cases (null/undefined values, empty paths)

### Why This Approach
- **Non-breaking**: No changes to existing deep link handlers in this PR
- **Gradual migration**: `shouldUseNewSystem()` allows action-by-action
rollout
- **Type-safe**: Full TypeScript coverage with proper type guards
- **Testable**: All adapter methods are pure functions with
comprehensive tests

### Dependencies
None

### How to Test
- Only automated tests at this time since this functionality is not
actually "enabled" in the app

---

## Changelog

### Added
- Added `LegacyLinkAdapter` for bidirectional conversion between new
`CoreUniversalLink` format and legacy deep link handlers
- Added migration strategy with `shouldUseNewSystem()` feature flag for
gradual rollout


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduce LegacyLinkAdapter for bidirectional conversion between new
core links and legacy handlers, add protocol/path utilities and tests,
and map `ACTIONS.PERPS_MARKETS` in the normalizer.
> 
> - **Deeplink Adapter**:
>   - Implement `LegacyLinkAdapter` with:
> - `toLegacyFormat` / `fromLegacyFormat` for bidirectional conversion
between `CoreUniversalLink` and legacy `urlObj` + `params`.
>     - `wrapHandler` to adapt legacy handlers to core links.
>     - `extractActionParams` to derive action path/query params.
> - `toProtocolUrl` to convert links across `metamask`, `https`,
`ethereum`, and `dapp`.
>     - `shouldUseNewSystem` feature-flag list (currently empty).
> - **Normalizer**:
> - Add `ACTIONS.PERPS_MARKETS` → `perpsMarketsPath` to
`ACTION_PATH_MAP` in `CoreLinkNormalizer`.
> - **Tests**:
> - Add `LegacyLinkAdapter.test.ts` covering conversions, param handling
(incl. SDK and custom params), protocol conversions, empty/edge cases,
and handler wrapping.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d81867b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR improves error handling in the Predict feature's Polymarket
provider to provide clear, user-friendly error messages for common order
placement failures.

### What is the reason for the change?

When users attempted to place orders on Polymarket markets, various
failure scenarios returned generic or technical error messages that
didn't clearly communicate:
- Why the order failed
- What the user should do next
- Whether the issue was related to their location, order parameters, or
system availability

Additionally, the error handling code was fragile and could crash when
receiving unexpected response formats (e.g., HTML error pages from
proxies).

### What is the improvement/solution?

1. **Added specific user-facing error messages for common scenarios**:
- **Order cannot be filled**: "Failed to fill your order" - shown when
no matching orders are available
- **Geographic restriction**: "Not available in your region" - shown
when the user's location is restricted
- **Generic fallback**: Uses existing generic error messages for other
failures to avoid exposing technical details

2. **Made `submitClobOrder` error handling more robust**:
- Detects 403 responses early and returns "You are unable to access this
provider." before attempting JSON parsing
- Wraps JSON parsing in try-catch to gracefully handle non-JSON error
responses (HTML bodies from load balancers/proxies)
- Falls back to `statusText` when JSON parsing fails, providing
meaningful context
- Wraps entire fetch operation in try-catch to handle network failures
gracefully
- Changed to return error objects instead of throwing, providing
consistent error handling

3. **Fixed URL query parameter formatting**: Removed extraneous spaces
in query parameters (e.g., `limit = 20` → `limit=20`) that were creating
malformed URLs.

4. **Added comprehensive test coverage**: 
   - 4 new tests for `submitClobOrder` error scenarios
   - Tests for 403 geoblock handling
   - Tests for non-JSON error response handling
   - Tests for network failures
   - All 126 tests passing

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: <!-- Add issue number if applicable -->

## **Manual testing steps**

```gherkin
Feature: Predict order error messages

  Scenario: user attempts to place order that cannot be filled
    Given user is on a Polymarket prediction market
    
    When user attempts to place an order that cannot be matched
    Then user sees error message "Failed to fill your order"
    And the order is not submitted

  Scenario: user in restricted region attempts to place order
    Given user is in a geographically restricted region
    
    When user attempts to place an order
    Then user sees error message "Not available in your region"
    And the order is not submitted

  Scenario: user encounters unexpected API error
    Given the Polymarket API returns an unexpected error
    
    When user attempts to place an order
    Then user sees an appropriate error message
    And the app does not crash
    And technical error details are not exposed to the user
```

## **Screenshots/Recordings**

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

### **Before**

Users encountered generic error messages or technical error strings that
did not clearly explain why their order failed.

### **After**

Users receive clear, specific error messages:
- "Failed to fill your order" when no matching orders exist
- "Not available in your region" for geographic restrictions
- Appropriate generic messages for other failures without exposing
technical details

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

---------

Co-authored-by: Luis Taniça <matallui@gmail.com>
…lready registered error (#22183)

## **Description**

This PR adds a logout button to the BasicInfo screen's error banner when
users encounter Transak error code 2020 (phone number already registered
with a different email). This allows users to logout and return to the
email input screen to authenticate with the correct email address.

**What is the reason for the change?**
When users authenticate with the wrong email in the Transak deposit
flow, if they enter a phone number that's already registered to a
different email, they see an error message but have no way to logout and
try again with the correct email. This forces them to restart the entire
app or navigate to settings to logout manually.

**What is the improvement/solution?**
- Added error code 2020 detection from Transak API response structure
- Added localized error message that extracts and displays the
registered email
- Added "Log in with email" button in the error banner that appears only
for error code 2020
- Clicking the button clears authentication and navigates back to email
input screen
- Reuses existing logout functionality and localization strings
- Added comprehensive test coverage

## **Changelog**

CHANGELOG entry: Added logout button to Transak deposit flow when phone
number is already registered

## **Related issues**

Fixes:
[TRAM-2799](https://consensyssoftware.atlassian.net/browse/TRAM-2799)

## **Manual testing steps**

### Option 1: Testing with Real Transak (E2E Validation)

```gherkin
Feature: Logout on Transak phone already registered error

  Scenario: user logs out when encountering phone already registered error
    Given user has authenticated with email A in Transak deposit flow
    And user navigates to BasicInfo screen
    And user enters a phone number already registered to email B

    When user submits the form
    Then error banner displays with message "This phone number is already in use by {masked_email}. Log in using this email to continue."
    And "Log in with email" button is visible in the error banner

    When user clicks the "Log in with email" button
    Then user is logged out from Transak
    And user is navigated back to the email input screen
    And user can now enter the correct email to authenticate
```

**Note:** Requires two Transak accounts with the same phone number
registered to different emails.

---

### Option 2: Testing with Mock Error (Quick Validation)

**1. Add temporary mock** in `BasicInfo.tsx` around line 212:

```typescript
try {
  // TEMPORARY: Simulate Transak error code 2020
  const mockError = Object.assign(new Error('API Error'), {
    error: {
      errorCode: 2020,
      message: 'This phone number is already registered. It has been used by an account created with k****@pedalsup.com. Login with this email to continue.',
    },
  });
  throw mockError;
  
  // Comment out original code for testing:
  // setLoading(true);
  // const { ssn, ...formDataWithoutSsn } = formData;
  // await postKycForm({ personalDetails: { ... } });
```

**2. Run on simulator:**

```bash
yarn watch
# Press 'i' for iOS or 'a' for Android
```

**3. Test the flow:**
- Navigate to Deposit → Verify Identity → BasicInfo
- Fill in form with any valid data
- Click "Continue"
- ✅ Verify error banner shows: "This phone number is already in use by
k****@pedalsup.com. Log in using this email to continue."
- ✅ Verify button shows: "Log in with email"
- Click the button
- ✅ Verify navigation back to email input screen
- ✅ Verify no console errors

**4. Clean up:** Remove the mock code before committing

## **Screenshots/Recordings**

### **Before**
Error banner without logout button - user had no way to logout and try
with correct email

<img width="787" height="1704" alt="image"
src="https://github.com/user-attachments/assets/58285702-078c-4c00-99b9-d36300e6649e"
/>


### **After**

**Error Object From Transak** 

<img width="2174" height="1330" alt="image"
src="https://github.com/user-attachments/assets/3c175ebd-3df9-4447-8fac-3a3cbcca8e34"
/>

**Error banner with "Log in with email" button as shown in design
mockup**


https://github.com/user-attachments/assets/476ae836-beaf-454b-9806-9350920f3cfb


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

[TRAM-2799]:
https://consensyssoftware.atlassian.net/browse/TRAM-2799?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds detection of Transak error 2020 on BasicInfo, displaying a
localized message with the masked email and a "Log in with email" action
that logs out and navigates to EnterEmail.
> 
> - **Deposit › Verify Identity (`BasicInfo.tsx`)**:
> - Detects Transak API `error.errorCode === 2020` (phone already
registered).
> - Extracts masked email from `error.message` and shows localized error
`deposit.basic_info.phone_already_registered`.
> - Displays BannerAlert action button "Log in with email" (`testID:
"basic-info-logout-button"`).
> - On click, calls `logoutFromProvider(false)` and navigates to
`...createEnterEmailNavDetails()`.
> - Resets error/UI flags on retry and field changes; integrates
`logoutFromProvider` from `useDepositSDK`.
> - **Tests (`BasicInfo.test.tsx`)**:
> - Adds cases for: showing logout button on `2020` errors, formatting
message with email, no action for generic errors, successful logout +
navigation, and graceful logout failure logging.
> - **Localization (`locales/languages/en.json`)**:
> - Adds `deposit.basic_info.phone_already_registered` and
`deposit.basic_info.login_with_email`; keeps `unexpected_error`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6bf8336. 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**

- Adds a look to the CLOB `/prices`
[endpoint](https://docs.polymarket.com/api-reference/pricing/get-multiple-market-prices-by-request)
to get the latest prices for all the outcomes displayed within market
details.
- This price should then pass through to the buy preview screen so it's
consistent when the additional lookup occurs there.
- See example of the pricing update in the recording below

<!--
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:
[PRED-263](https://consensyssoftware.atlassian.net/browse/PRED-263)

## **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/48e865d1-1cf0-447f-a5fe-5a02417de580

<!-- [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.


[PRED-263]:
https://consensyssoftware.atlassian.net/browse/PRED-263?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Introduces provider/controller API and React hook to fetch current
BUY/SELL prices from Polymarket CLOB and applies real-time prices in
market details, with comprehensive tests.
> 
> - **Backend/Controller**:
> - Add `PredictController.getPrices` with error/state handling,
defaulting to `polymarket`
(`app/components/UI/Predict/controllers/PredictController.ts`).
> - Extend types with `GetPriceParams`, `GetPriceResponse`,
`PriceQuery`, `PriceResult`, `PriceEntry` (`types/index.ts`).
> - **Provider (Polymarket)**:
> - Implement `getPrices` calling CLOB `POST /prices`, returning
structured BUY/SELL entries; robust error handling and logging
(`providers/polymarket/PolymarketProvider.ts`).
> - Expose `getPrices` in `PredictProvider` interface
(`providers/types.ts`).
> - **Hook**:
> - New `usePredictPrices` for fetching/pruning/polling prices with
error handling and manual `refetch` (`hooks/usePredictPrices.tsx`).
> - **UI**:
> - `PredictMarketDetails` uses `usePredictPrices` to update open
outcomes and action button prices in real time; falls back gracefully;
integrates with existing tabs and chart
(`views/PredictMarketDetails/PredictMarketDetails.tsx`).
> - **Tests**:
> - Add thorough tests for controller `getPrices`, provider `getPrices`,
hook behavior (polling, errors, reactivity), and view integration
(`*.test.ts/tsx`).
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d22efd5. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Luis Taniça <matallui@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Nov 7, 2025
@pull pull Bot added the ⤵️ pull label Nov 7, 2025
@pull pull Bot merged commit dddee92 into Reality2byte:main Nov 7, 2025
6 of 16 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.