Skip to content

[pull] main from MetaMask:main#493

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

[pull] main from MetaMask:main#493
pull[bot] merged 18 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Feb 2, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

abretonc7s and others added 18 commits February 2, 2026 08:25
… 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 -->
@pull pull Bot locked and limited conversation to collaborators Feb 2, 2026
@pull pull Bot added the ⤵️ pull label Feb 2, 2026
@pull pull Bot merged commit bb0fee4 into Reality2byte:main Feb 2, 2026
0 of 10 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.