[pull] main from MetaMask:main#493
Merged
Merged
Conversation
… cp-7.63.0 (#25493) ## **Description** **fix(perps): add spotMeta caching to reduce API calls on HIP-3 markets** This PR adds session-based caching for HyperLiquid's global `spotMeta` endpoint to avoid redundant API calls during HIP-3 operations. ### Context Following a rate limiting incident where excessive API calls triggered HyperLiquid's rate limits (2000 msg/min), this is a defensive improvement to reduce unnecessary network requests. ### Problem The `spotMeta` API (which returns token metadata like USDC/USDH indices) was being called multiple times per trading session: - `getUsdcTokenId()` - called during transfers - `isUsdhCollateralDex()` - called to check collateral type - `swapUsdcToUsdh()` - called during HIP-3 USDH swaps Each call was making a fresh API request, even though the data (token indices) doesn't change during a session. ### Solution - Added `cachedSpotMeta` property for session-based caching (no TTL - token indices are stable) - Added `getCachedSpotMeta()` method that returns cached data or fetches once - Pre-fetch spotMeta in `ensureReadyForTrading()` when HIP-3 is enabled (non-blocking) - Cache invalidated on `disconnect()` to ensure fresh state on reconnect/account switch ### Design Decisions - **Global cache** (not per-DEX): `spotMeta` is a global endpoint returning all tokens - **Session-based** (no TTL): Token indices don't change during a session - **Graceful fallback**: If pre-fetch fails, methods fetch on-demand - Follows existing patterns: `getCachedMeta()`, `getCachedPerpDexs()` ## **Changelog** CHANGELOG entry: Fixed excessive API calls on HIP-3 markets by caching spot metadata ## **Related issues** Fixes: N/A (Defensive improvement following rate limiting incident) ## **Manual testing steps** ```gherkin Feature: SpotMeta caching for HIP-3 operations Scenario: User places order on HIP-3 DEX (SILVER) Given user has connected wallet with USDC balance And user is on a HIP-3 enabled DEX (e.g., SILVER) When user places an order Then order should succeed And spotMeta API should only be called once per session (check debug logs) Scenario: User disconnects and reconnects Given user has placed orders (spotMeta is cached) When user disconnects wallet And user reconnects wallet Then spotMeta cache should be cleared And next HIP-3 operation should fetch fresh spotMeta ``` ## **Screenshots/Recordings** N/A - Internal optimization, no UI changes ### **Before** Multiple `spotMeta` API calls per session (one per HIP-3 operation) ### **After** Single `spotMeta` API call per session, cached for subsequent operations ## **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 perps trading setup and HIP-3 collateral/token resolution by introducing session-cached `spotMeta`; incorrect caching or cache invalidation could affect order/transfer flows, though it falls back to on-demand fetch and clears on disconnect. > > **Overview** > Reduces HyperLiquid rate-limit pressure on HIP-3 flows by adding a **session-level `spotMeta` cache** in `HyperLiquidProvider`, prefetching it during `ensureReadyForTrading()`, reusing it in USDC/USDH collateral checks and swaps, and clearing it on disconnect. > > Standardizes error handling across perps controllers/providers by extending `ensureError` with optional context (including better messages for `null`/`undefined`) and replacing ad-hoc `instanceof Error` checks in connection, streaming, deposit/testnet toggle, and provider operations; updates related tests and types (`SpotMetaResponse`). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3ee4cb2. 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**
KeyringController.verifyPassword throw `Error: error in DoCipher,
status: 2` instead of `incorrect password`.
This is causing the biometric setting not showing any alert when user
key in incorrect password
<!--
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: create wallet without biometric
Scenario: user enable biometric from setting
Given user enable biometric from setting
When user enter wrong password
Then alert should prompt for invalid passwrod
```
## **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/fc83639e-8a0a-4b1f-a2a0-619cc5017989
### **After**
<!-- [screenshots/recordings] -->
https://github.com/user-attachments/assets/2537e861-d109-463b-939c-af7379fef529
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk: a small change to error-message matching in
`updateAuthPreference` to improve user feedback, without altering
password verification or storage flows.
>
> **Overview**
> Improves `updateAuthPreference` error handling so an incorrect
password on Android that surfaces as the cipher error `error in
DoCipher, status: 2` is treated like an invalid password.
>
> This adds `UNLOCK_WALLET_ERROR_MESSAGES.ANDROID_WRONG_PASSWORD_2`
matching to trigger the existing invalid-password alert and analytics
tracking instead of falling through to generic logging.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f3e26db. 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**
Change previous season summary icon colors
<!--
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: Change Rewards season summary icon colors
## **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**
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-01-30 at 13 47 45"
src="https://github.com/user-attachments/assets/ca310cf4-e720-42c9-bb3b-07d73671acaf"
/>
<img width="1179" height="2556" alt="Simulator Screenshot - E2E Test -
2026-01-30 at 13 47 38"
src="https://github.com/user-attachments/assets/4471209f-045a-46b4-9f81-6cabb2e92b1c"
/>
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk visual-only updates: icon tint classes and an SVG asset are
adjusted with no changes to rewards data fetching or control flow.
>
> **Overview**
> Updates the Previous Season rewards summary tiles to use themed icon
colors by adding `twClassName` to the Rocket (tier) and People
(referrals) icons.
>
> Replaces `metamask-rewards-points-alternative.svg` with a new 24x24
orange-stroked version (was 14x14 gray).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c4855ac. 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** Implement new slippage modal UI, which allow users to set a custom slippage value. Implement an new generic component called InputStepper and also extracted some common utilities to separate functions. <!-- 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? AI agent: Be specific about what you changed and why. Include context about the fix/feature, not generic descriptions. --> ## **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) AI agent: Use format `CHANGELOG entry: [fix/feat/chore]: [User-facing description in past tense]`. Examples: `fix: resolved token name display issue`, `feat: added dark mode toggle`, `chore: updated dependencies`. For non-user-facing changes, use `CHANGELOG entry: null`. --> CHANGELOG entry: update slippage UI, adding option for users to set a custom slippage ## **Related issues** <!-- AI agent: Replace with `Fixes: #[ISSUE_NUMBER]` using the actual issue number you're implementing. --> Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3428 ## **Manual testing steps** <!-- AI agent: Write specific, contextual Gherkin steps based on what you actually implemented. Do NOT use generic placeholders like "my feature name". Be concrete about the feature, scenario, and steps. --> ```gherkin Ensure functionality matches signed-off acceptance criteria. ``` ## **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/f52f0f26-102d-4878-b541-ae9ba13b34c9 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- AI agent: Check ALL boxes in this section (mark all as [x]). --> - [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** <!-- AI agent: Leave ALL boxes unchecked ([ ]) - these are for reviewers to check, not the author. --> - [ ] 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** > Medium risk because it replaces the slippage-selection UI and navigation flow and introduces new input/validation logic that affects swap execution parameters. Main risk is incorrect bounds/rounding/formatting leading to unintended slippage values being saved. > > **Overview** > Replaces the Bridge slippage settings UX with a new modal flow: a `DefaultSlippageModal` for preset/auto options and a `CustomSlippageModal` for entering a custom percentage, including navigation plumbing and passing `sourceChainId`/`destChainId` through route params. > > Adds a reusable `InputStepper` component (with optional description row + icon) and wires it into the custom slippage modal alongside keypad entry, including max/min clamping, decimal precision enforcement, and state dispatch via `setSlippage`. Updates `QuoteDetailsCard` to open the new default slippage modal, and removes the legacy `SlippageModal` implementation/tests/styles, replacing them with extensive new snapshot/unit tests for the new components. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0f0f2d2. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…cp-7.63.0 cp-7.64.0 (#25496) ## **Description** This PR addresses WebSocket subscription issues identified during the rate limiting incident investigation. The fixes reduce subscription message volume by ~75% and prevent subscription leaks. ### Root Causes Identified 1. **Subscriptions to unregistered DEXs** - System subscribed to ALL 8 DEXs from API instead of only the 2 in our allowlist (main + xyz) 2. **Duplicate DEX subscriptions from race conditions** - Concurrent calls created 2× subscriptions per DEX 3. **Candle subscription leaks** - Cleanup failed when component unmounted before async subscription resolved ### Fixes Implemented #### 1. Filter DEXs by Allowlist on Mainnet (HIGH PRIORITY) **Files:** `hyperLiquidConfig.ts`, `HyperLiquidProvider.ts` - Added `MAINNET_HIP3_CONFIG` with `AutoDiscoverAll: false` - DEX filtering is now dynamic - extracts DEX names from the `allowlistMarkets` feature flag patterns - Added `extractDexsFromAllowlist()` method that parses patterns like `xyz:*`, `xyz:TSLA`, or `xyz` - **Impact:** Reduces from 8 DEXs to 2 (main + xyz), ~75% reduction in subscription messages #### 2. Prevent Duplicate DEX Subscriptions (HIGH PRIORITY) **File:** `HyperLiquidSubscriptionService.ts` - Added `pendingClearinghouseSubscriptions` and `pendingOpenOrdersSubscriptions` Maps - Refactored `ensureClearinghouseStateSubscription()` and `ensureOpenOrdersSubscription()` to check for pending promises - Concurrent calls now wait for the pending promise instead of creating duplicate subscriptions - **Impact:** Prevents 50% redundant subscriptions from race conditions #### 3. Fix Candle Subscription Cleanup (HIGH PRIORITY) **File:** `HyperLiquidClientService.ts` - Store subscription promise to enable cleanup even when pending - Updated cleanup function to wait for pending promise and unsubscribe - **Impact:** Prevents WebSocket subscription leaks when component unmounts before subscription resolves ### Test Results | Metric | Before | After | Improvement | |--------|--------|-------|-------------| | DEXs subscribed | 8 | 2 | 75% reduction | | clearinghouseState subscriptions | 16 | 2 | 87% reduction | | openOrders subscriptions | 16 | 2 | 87% reduction | | Candle subscription leaks | Yes | No | Fixed | ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: Rate limiting incident from WebSocket over-subscription Related: [WebSocket Subscription Investigation Report](docs/perps/perps-websocket-subscription-investigation.md) ## **Manual testing steps** ```gherkin Feature: WebSocket subscription optimization Scenario: User connects to perps and only allowlisted DEXs are subscribed Given user has the app installed with perps feature enabled And WebSocket logging is enabled in dev mode When user navigates to Perps home screen Then WebSocket logs show subscriptions only for main and xyz DEXs And no subscriptions for flx, vntl, hyna, km, abcd, cash DEXs Scenario: User navigates between markets without duplicate subscriptions Given user is connected to perps And WebSocket logging is enabled When user navigates from Home to xyz:XYZ100 market details And user returns to Home And user navigates back to xyz:XYZ100 Then WebSocket logs show no duplicate clearinghouseState subscriptions And WebSocket logs show no duplicate openOrders subscriptions Scenario: User views candle chart and subscriptions are properly cleaned up Given user is on a market details screen with chart visible When user quickly navigates away from the screen And user waits for 2 seconds Then candle subscriptions are properly unsubscribed And no orphaned candle subscriptions exist ``` ## **Screenshots/Recordings** ### **Before** WebSocket subscription breakdown (full trading flow): - clearinghouseState: 16 subscriptions (8 DEXs × 2 duplicates) - openOrders: 16 subscriptions (8 DEXs × 2 duplicates) - candle: 4 subscriptions, 0 unsubscriptions (leak) ### **After** WebSocket subscription breakdown (full trading flow): - clearinghouseState: 2 subscriptions (main + xyz only) - openOrders: 2 subscriptions (main + xyz only) - candle: 2 subscriptions, 2 unsubscriptions (balanced) **Total outgoing messages:** 44 **Total incoming messages:** 402 (down from ~750) ## **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. --- ### Subscription Breakdown - `clearinghouseState`: 2 (main + xyz) - `openOrders`: 2 (main + xyz) - `userFills`: 1 - `webData3`: 1 - `allMids`: 1 - `assetCtxs`: 2 (xyz only, subscribed/unsubscribed on navigation) - `activeAssetCtx`: 2 (xyz:XYZ100, subscribed/unsubscribed on navigation) - `candle`: 2 (1h + 15m intervals) - `bbo`: 2 (subscribed/unsubscribed during order flow) ### Future Optimization Opportunity Trading operations (order placement, cancellation, modification) currently use **HTTP transport**: - `ExchangeClient` is configured with `httpTransport` to avoid 429 rate limiting - `InfoClient` uses `wsTransport` for info queries (multiplexed over single WS connection) Now that subscription volume is reduced by 75%, we could consider moving `ExchangeClient` to WebSocket transport (see follow-up investigation). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches core perps WebSocket subscription and DEX-discovery behavior; bugs could lead to missing market data or stale positions/orders, though changes are localized and defensive. > > **Overview** > Reduces perps WebSocket load by **filtering mainnet HIP-3 DEX discovery/subscription based on the `allowlistMarkets` feature flag**, falling back to main DEX only when no HIP-3 patterns are allowlisted (via new `MAINNET_HIP3_CONFIG` and allowlist DEX parsing in `HyperLiquidProvider`). > > Prevents subscription churn/leaks by **deduplicating concurrent `clearinghouseState`/`openOrders` subscriptions** with pending-promise tracking in `HyperLiquidSubscriptionService`, and by **fixing candle unsubscription when the async subscribe promise hasn’t resolved yet** in `HyperLiquidClientService`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 73e62ff. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude <noreply@anthropic.com>
…cross tests and workflows (#25427) <!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## Summary - Consolidate `SmokeConfirmationsRedesigned` tag into `SmokeConfirmations` - Remove duplicate confirmation test tags and unify under single tag - Increase CI shard count from 3 to 4 to handle larger test suite efficiently ## Changes - **E2E Tests**: Rename `smokeConfirmationsRedesigned` → `smokeConfirmations` in `e2e/tags.js` - **Test Files**: Update 20 test files to use `SmokeConfirmations` instead of `SmokeConfirmationsRedesigned` - **CI Configuration**: Update iOS/Android smoke test workflows to use consolidated tag - **CI Sharding**: Increase confirmation test shards from 3→4 (39 tests across 4 shards) - **Bitrise**: Update workflow names and tag references - **Regression**: Remove duplicate `RegressionConfirmationsRedesigned` tag ## **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** * Run All E2E jobs ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: changes are limited to E2E test tagging and CI workflow configuration, with no product/runtime logic impact; main risk is misconfigured tags/shards causing tests to be skipped or not reported. > > **Overview** > Unifies the confirmations smoke suite by replacing `SmokeConfirmationsRedesigned`/`RegressionConfirmationsRedesigned` with `SmokeConfirmations` across the E2E tag registry and affected specs, and updates tag descriptions/references to match. > > Updates CI orchestration to run confirmations smoke on iOS/Android under the new tag and **increases confirmations smoke sharding from 3→4 splits**; removes the separate redesigned confirmations regression job and updates Bitrise workflow names/env `TEST_SUITE_TAG` accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0b1d898. 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?
-->
Adds robust retry logic with exponential backoff to OAuth getAuthTokens
requests to handle transient network failures and server errors
gracefully.
## **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: New retryWithDelay utility - A generic, well-tested
retry utility
CHANGELOG entry: Updated getAuthTokens - Now automatically retries up to
3 times on transient failures with logging
## **Related issues**
Fixes:
[SL-457]
## **Manual testing steps**
```gherkin
Feature: my feature name
Scenario: user login with requests blocked
Given User fresh install app
When user login with social
Then block the request to toprf server from the device
```
## **Screenshots/Recordings**
<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->
### **Before**
<!-- [screenshots/recordings] -->
### **After**
<!-- [screenshots/recordings] -->
## **Pre-merge author checklist**
- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
[SL-457]:
https://consensyssoftware.atlassian.net/browse/SL-457?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Changes the OAuth token exchange path to automatically retry on
failures, which can affect login latency and request volume; behavior
now depends on correct classification of 4xx vs 5xx via
`OAuthError.data.status`. Backwards compatibility is mostly preserved,
but regressions here directly impact sign-in reliability.
>
> **Overview**
> **OAuth token exchange now automatically retries on transient
failures.** `BaseLoginHandler.getAuthTokens` is wrapped in a new
`retryWithDelay` helper (exponential backoff + jitter), with logging on
each failed attempt and no retries for *client (4xx) errors*.
>
> **Error metadata and utilities were expanded.** `OAuthError` now
carries a `data` object (including HTTP `status` from failed auth-server
responses), and `OAuthLoginHandlers/utils.ts` adds `retryWithDelay` +
`isRetryableError`, covered by a new `utils.test.ts` suite;
`baseHandler.test.ts` was updated to mock `Logger` for the new retry
logging.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b539f65. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…tion failure (#25429) ## **Description** When a user starts a one-click trade (Long/Short from market details) and transaction creation fails—e.g. `depositWithOrder()` rejects due to rejection, network, or backend error—the app previously only logged the error. There was no user feedback or analytics. This PR adds: 1. **Mixpanel / analytics** On failure we send a `Perp Error` event with: - `error_type`: backend - `error_message`: thrown error message - `source`: trade_action 2. **Toast** A dedicated error toast is shown: - **Title:** "Could not open position" - **Description:** "Transaction creation failed. Please try again." ## **Changelog** CHANGELOG entry: When one-click trade transaction creation fails, users now see an error toast ("Could not open position") and the failure is tracked in analytics. ## **Related issues** Relates to #24964 ## **Manual testing steps** ```gherkin Feature: Perps one-click trade error handling Scenario: user tries one-click trade and tx creation fails Given user is on Perps market details (e.g. ETH) with one-click Long/Short When user taps Long or Short and deposit/tx creation fails (e.g. reject in confirmation or simulate failure) Then a toast appears: "Could not open position" / "Transaction creation failed. Please try again." And a Perp Error analytics event is sent with error_type backend and source trade_action ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> <img width="1206" height="2622" alt="simulator_screenshot_53600E3E-B994-46F9-9243-54FB873E070E" src="https://github.com/user-attachments/assets/95e49819-4e85-47d8-9694-0bb46a354e92" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: adds user-facing toast and error analytics in the one-click trade failure path without changing successful trade/navigation behavior. > > **Overview** > Adds explicit failure handling for one-click trade initiation: when `depositWithOrder()` rejects in `usePerpsNavigation.navigateToOrder`, the app now **tracks a `PERPS_ERROR` event** (backend error type, message, trade_action source) and **shows a dedicated error toast** instead of only logging. > > Extends `usePerpsToasts` with `accountManagement.oneClickTrade.txCreationFailed` plus new English strings, and updates related hook tests to cover the new toast/tracking behavior. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3758945. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** Store the last 50 successful points estimates in state logs to help Customer Support verify user-reported discrepancies between estimated and awarded points. Note: Snapshot tests need to be regenerated to include the new `pointsEstimateHistory` field in state. ## **Changelog** CHANGELOG entry: Added points estimate history tracking to state logs for Customer Support diagnostics <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new persisted/logged state field that records recent `estimatePoints` requests (including account IDs and asset/fee amounts) and responses; while bounded and best-effort, it increases logged/persisted data surface and could affect state size/debug output. > > **Overview** > `RewardsController.estimatePoints` now records each *successful* points estimate into a new `pointsEstimateHistory` state field (best-effort; failures are caught/logged and do not impact the estimate result). > > The history stores a **flat, diagnostic-friendly** snapshot of request/response details for `SWAP`, `PERPS` (single only), `PREDICT`, and `SHIELD`, and keeps only the most recent 50 entries. State metadata, default state, types, snapshot fixtures, and tests were updated to include and validate this new persisted field. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3270126. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## **Description**
Removed the complex nested ternary conditional rendering logic inside
TrendingTokensFullView.
I've also revamped the related UTs.
<!--
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: refactor: remove complex render logic in
TrendingTokensFullView
## **Related issues**
Fixes: N/A
## **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/99f7118f32ad4aa98e207c97c8531f79
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> Low risk refactor that mainly reorganizes rendering and test code;
behavioral changes are limited to adding `testID`s and adjusting tests
to match the current bottom-sheet interaction patterns.
>
> **Overview**
> Refactors `TrendingTokensFullView` by extracting the
loading/empty/list rendering into a dedicated `TrendingTokensData`
component (using tailwind layout) to replace the prior nested ternary
block.
>
> Improves testability by adding `testID`s to trending bottom sheets and
their selectable options, and adds a retry button `testID` to
`EmptyErrorTrendingState`.
>
> Revamps `TrendingTokensFullView.test.tsx` to use `userEvent`, add
focused unit coverage for `TrendingTokensData`, and update bottom-sheet
interaction tests (including the price-change *Apply* flow and
pull-to-refresh via `RefreshControl`).
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
299381f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
…ler state (#25296) <!-- 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** This PR adopts `@metamask/ramps-controller@5.0.0` and updates the mobile app to align with the new controller API. ### Renamed `preferredProvider` to `selectedProvider` Updated all references across hooks (`useRampsController`), selectors (`selectSelectedProvider`), components, and test files. The `setSelectedProvider` method now accepts `null` to clear the selection, which is used during logout flows. ### Added state-based data access for countries, tokens, and providers These data types are now stored directly on controller state rather than being accessed through request cache data. New selectors (`selectCountries`, `selectTokens`, `selectProviders`) provide direct access to this state. The `countries` type changed from `Country[] | null` to `Country[]` (empty array when not loaded), requiring updates to null-checks throughout the codebase. ### Removed unused fetch functions from hooks Removed `fetchTokens`, `fetchProviders`, and `fetchCountries` from their respective hooks and from `useRampsController`. The controller now manages data fetching internally via `hydrateState`, eliminating the need for UI components to trigger fetches manually. This also removed the `useEffect` in `RegionSelector` that called `fetchCountries` on mount, and the retry button from the error state. ### Added `useHydrateRampsController` hook New hook that calls `hydrateState` on the controller when invoked. This is used on the wallet home page to ensure ramps data (countries, user region, etc.) is loaded when the app starts, making it available before users enter any ramps flows. ### Simplified `selectCountriesRequest` selector Countries are no longer action-specific in the controller API, so the selector no longer requires a `'buy' | 'sell'` action parameter. The cache key changed from `'getCountries:["buy"]'` to `'getCountries:[]'`. 2 minute video demonstration of the PR showing that the breaking changes adopted without issues for both v1 and v2 unified buy flags: https://www.loom.com/share/b500c78640894b888b470473b920cc51 <!-- 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] --> ## **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** > Medium risk because it changes how ramps data is loaded (moving from UI-triggered fetches to controller-managed hydration) and renames/rewires provider/token selection state, which can affect buy/sell flow behavior and empty/error states. > > **Overview** > **Aligns the mobile ramps UI with `@metamask/ramps-controller@5` by shifting ramps data access to controller state and updating selection semantics.** `preferredProvider` is replaced with `selectedProvider` throughout, including logout flows that now clear selection via `setSelectedProvider(null)`. > > `useRampsController` is refactored to drop `fetchProviders`/`fetchTokens`/`fetchCountries`, expose `selectedToken` and new payment-method state (`paymentMethods`, `selectedPaymentMethod`, `setSelectedPaymentMethod`), and have `useRampsCountries` return an always-present `Country[]` (empty array when unloaded). A new `useHydrateRampsController` hook calls `RampsController.hydrateState()` when V2 unified is enabled and a saved region exists, and UI like `RegionSelector` is updated accordingly (new `supported` shape handling, no mount-time fetch/retry UI, updated disabled prop usage). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 9cd4534. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description** This PR migrates Earn-related components from the legacy `BottomSheetHeader` component to the new `HeaderCenter` component, and updates navigation options from `getStakingNavbar` to `getHeaderCenterNavbarOptions`. This brings consistency to header styling across the Earn feature by using the new centered header pattern based on the design system. **Key changes:** - Replaced `BottomSheetHeader` with `HeaderCenter` in `LendingLearnMoreModal`, `EarnTokenList`, and `PoolStakingLearnMoreModal` - Migrated `EarnInputView` navigation from `getStakingNavbar` to use `HeaderCenter` with refactored event handlers - Updated `InteractiveTimespanChart` to accept a dynamic `color` prop instead of hardcoded design token reference - Updated `MultichainAccountSelectorList` search field border radius to use `rounded-full` pattern (9999px) - Minor styling fixes in confirmations components (Tooltip, expandable, gas-fee-token-modal, estimates-modal) ## **Changelog** CHANGELOG entry: chore: migrated Earn headers to use HeaderCenter component ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/jira/software/c/projects/MDP/boards/2972?assignee=62afb43d33a882e2be47c36f&quickFilter=3325&selectedIssue=MDP-691 ## **Manual testing steps** ```gherkin Feature: Earn Header Components Scenario: User views Learn More modal for staking Given the user is on the Stake ETH input screen When user taps the info button Then the "Stake ETH and earn" modal displays with centered title and close button Scenario: User views Learn More modal for lending Given the user is on the Supply USDC input screen When user taps the info button Then the "How it works" modal displays with centered title and close button And the APY chart displays in success color Scenario: User views token selection list Given the user is on the Earn input view When user taps to select a different token Then the token selector bottom sheet displays with centered title and close button ``` ## **Screenshots/Recordings** ### **Before** <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/37467f52-143d-4159-b158-a466321ea8cc <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Mostly UI/navigation refactors, but it touches navigation headers/gestures and analytics tracking for Earn/confirmations, which could impact back/close behavior if miswired. > > **Overview** > Standardizes header UI by replacing legacy `BottomSheetHeader`/custom navbars with the new centered `HeaderCenter` across Earn modals and screens (Earn token list, staking/lending “learn more”, and Earn input), including new back/close/info button wiring. > > Refactors Earn input header behavior to render `HeaderCenter` in-content (and hide the React Navigation header), adds explicit back/info handlers with metrics events, and updates related tests/snapshots. > > Makes chart/visual tweaks: `InteractiveTimespanChart` now derives its default color from theme (callers pass success color where desired), adjusts staking learn-more footer padding (platform-specific), and applies small styling tweaks to confirmation modals (Tooltip/expandable/gas fee token/estimates) plus a rounded-full search field radius in multichain account selector. > > Also simplifies confirmation navigation options to always hide the native header and adds `HeaderCenter` for full-screen confirmations. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 89773f4. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
…25506) <!-- 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** remove legacy swaps liveness service in favor of new stx hooks <!-- 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: remove legacy swaps liveness service in favor of new stx hooks ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3856 ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Medium risk because it removes a background liveness-fetching/polling mechanism that may still be relied on by parts of the swaps/STX flow; regressions would show up as stale or missing liveness/feature-flag state. > > **Overview** > Removes the legacy swaps liveness service (`LegacySwapLiveness`) that fetched swaps feature flags on mount, network change, app foregrounding, and an interval, and removes its rendering from `Main`. > > Deletes the component implementation and its unit tests, leaving liveness/feature-flag determination to the newer STX/bridge hooks. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 56c4f1d. 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** It was discovered that when a user pressed the Max button after receiving a quote for a non-max amount, they would encounter an "insufficient funds" error. This issue occurred because the quote parameters were not updated after an insufficient balance was detected; the values were wrapped in a ref, which prevented infinite requests in certain scenarios. However, the root cause was in the useInsufficientBalance hook, which recalculated the condition every time the quotes object changed. To resolve both the insufficient funds error and the risk of infinite requests, we now return a memoized version of the condition that only depends on specific quote values. <!-- 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: fixes an issue preventing insufficient funds error when pressing max balance after inputting non-max balance in swaps ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3925 ## **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** https://github.com/user-attachments/assets/1dba469b-4672-46a1-9911-da92d36be1bb <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/9fcfcf9a-7bb9-4cbb-a20a-68c77bbbe800 ## **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 swap/bridge quote parameter updates and insufficient-balance calculation; regressions could cause incorrect quote requests or false insufficient-funds gating, but changes are localized to UI hooks. > > **Overview** > Fixes a quoting edge case where pressing *Max* after receiving a non-max quote could get stuck showing **insufficient funds**. > > `useBridgeQuoteRequest` now sends the live `insufficientBal` value (and re-runs when it changes) instead of freezing it in a ref. To avoid the prior infinite-request risk, `useIsInsufficientBalance` memoizes its result and only depends on specific fields from the recommended quote (gas flags/amount) rather than the whole quotes object. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 504317a. 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** Following #24313 we're looking to centralize all tools and test resources in one place. This PR moves spec files for `Trending`, `Wallet`, `Swaps` to `/tests`. Previous related PRs: - #24988 - #24313 - #25031 - #25095 - #25167 - #25198 - #25219 - #25263 - #25279 <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: my feature name Scenario: user [verb for user action] Given [describe expected initial app state] When user [verb for user action] Then [describe expected outcome] ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk: this is a test-only reorganization that mainly updates import paths and consolidates swap/bridge helper utilities, with no product/runtime logic changes. > > **Overview** > Moves Swap/Bridge, Trending, and Wallet (mUSD) E2E specs to the `tests/` tree and updates imports to use the new `tests/framework`, `tests/helpers`, and `e2e/pages` locations. > > Centralizes swap/bridge test utilities under `tests/helpers/swap` (e.g., `swap-unified-ui`, `prepareSwapsTestEnvironment`, `swap-mocks`, `bridge-mocks`) and updates affected specs (smoke/regression/quarantine) to consume these shared helpers and mocks. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2b49165. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
## **Description**
- Upgrades `@metamask/assets-controllers` to v99.0.0
**Fix:** Added resolutions to force all
`@metamask/transaction-controller` instances to use the same patched
version:
"@metamask/transaction-controller@npm:^62.9.2": "patch:...",
"@metamask/transaction-controller@npm:^62.10.0": "patch:..."
## **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**
> Medium risk due to a controller dependency upgrade plus a new
persisted-state migration and messenger permission change that could
impact token list initialization on app start.
>
> **Overview**
> Upgrades `@metamask/assets-controllers` to `^99.0.0` (lockfile updated
accordingly).
>
> Adds migration `115` to strip deprecated
`TokenListController.preventPollingOnNetworkRestart` from persisted
state, with Sentry reporting for invalid shapes/failures, and wires it
into the migration manifest.
>
> Updates TokenListController wiring/fixtures/tests to match the new
controller shape: removes the field from mocked background state,
snapshots, and test fixtures, and drops `StorageService:removeItem` from
`token-list-controller-messenger` delegated actions.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
b979f16. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com>
Co-authored-by: Julink <julien.fontanel@consensys.net>
…red balance of 1 cent (#25454) <!-- 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** Hides the Earn CTA for asset when the asset's balance is less than minimum required. <!-- 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: updated Earn CTAs to not render when the asset's balance is less than minimum required ## **Related issues** Fixes: [MUSD-270: Earn CTA is displayed for zero balance tokens](https://consensyssoftware.atlassian.net/browse/MUSD-268) ## **Manual testing steps** ```gherkin Feature: Earn CTA visibility based on token balance Scenario: user views a token with balance below minimum earn threshold Given user has a token in the wallet with balance below 0.01 When user views the token in the token list Then no "Earn" call-to-action is displayed Scenario: user views a token with balance at or above minimum earn threshold Given user has a token in the wallet with balance at or above 0.01 When user views the token in the token list Then an "Earn" call-to-action is displayed ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> <img width="450" height="81" alt="image" src="https://github.com/user-attachments/assets/10f7fab9-8826-43dd-a7d6-99ffe8e01210" /> <img width="450" height="209" alt="image" src="https://github.com/user-attachments/assets/71f2daba-9590-482c-8bec-69f2c66fcf6e" /> ### **After** <!-- [screenshots/recordings] --> <img width="456" height="82" alt="image" src="https://github.com/user-attachments/assets/241a9ff1-da48-4e3e-8802-62c0e6d08e90" /> <img width="450" height="209" alt="image" src="https://github.com/user-attachments/assets/2b16a88f-ac36-4a2c-8cb3-75844dccbfff" /> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk UI gating change that only affects when Earn CTAs render; main risk is incorrectly hiding/showing CTAs due to balance/fiat conversions. > > **Overview** > Introduces `MINIMUM_BALANCE_FOR_EARN_CTA` (0.01) and uses it to *suppress Earn/Stake CTAs* for assets whose `earnToken.balanceFiatNumber` is below the threshold. > > `StakeButton` now derives an `earnToken` via `useEarnToken` and returns `null` when the user is ineligible, the earn token is missing, or the minimum balance isn’t met; `TokenListItem` similarly only shows the stablecoin lending Earn CTA when the minimum is met (otherwise it falls back to percentage change). > > Updates and adds unit tests to cover the new threshold behavior and adjusts mocks to use `earnSelectors.selectEarnToken`/`useStablecoinLendingRedirect` accordingly. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e49bf26. 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** https://consensyssoftware.atlassian.net/browse/RWDS-942 Remove e2e tests for Rewards season 1 <!-- 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] --> ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk since this only deletes E2E test code and CI jobs; primary impact is reduced automated coverage for Rewards. > > **Overview** > Removes the Rewards Season 1 E2E coverage by deleting the Rewards smoke spec, its mock server fixtures, and related page objects. > > Updates smoke-test infrastructure to drop the `SmokeRewards` tag and stop scheduling `rewards-*-smoke` jobs in the iOS/Android GitHub Actions workflows (including removing them from the reporting job dependencies). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 54f68a9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )