Skip to content

[pull] main from MetaMask:main#370

Merged
pull[bot] merged 4 commits into
Reality2byte:mainfrom
MetaMask:main
Dec 1, 2025
Merged

[pull] main from MetaMask:main#370
pull[bot] merged 4 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Dec 1, 2025

See Commits and Changes for more details.


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

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

salimtb and others added 4 commits December 1, 2025 18:00
<!--
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**

bump assets to v92

<!--
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: bump assets controllers to v92

## **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]
> Upgrades @metamask/assets-controllers to v92 and wires new options
(mobile platform, bearer token access), plus adjusts token list network
subscription and spot price support mappings.
> 
> - **Dependencies**
> - Bump `@metamask/assets-controllers` to `v92` with updated patch and
lockfile entries.
> - **Controllers**
> - `token-balances-controller-init`: pass `platform: 'mobile'` to
`TokenBalancesController`.
> - `token-list-controller-init`: update `onNetworkStateChange`
subscription to forward `NetworkController:stateChange` with a type
cast.
> - **Messengers**
> - Allow `AuthenticationController:getBearerToken` in
`TokenBalancesController` and `TokenDetectionController` messengers.
> - **Assets patch**
> - In `dist/token-prices-service/codefi-v2.cjs`, set multiple
`SPOT_PRICES_SUPPORT_INFO` chain mappings to `null` (e.g., `0x1`, `0xa`,
`0x89`, `0xa4b1`, etc.).
> - **Tests**
> - Update `token-balances-controller-init.test.ts` to assert `platform:
'mobile'` is passed.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
355391b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Bernardo Garces Chapero <bernardo.chapero@consensys.net>
## **Description**

Removed the default background color from HeaderBase component styles as
part of bottom sheet updates. This change removes the explicit
`backgroundColor: theme.colors.background.default` from the HeaderBase
styles, allowing parent components to control the background color as
needed. The change updates the HeaderBase.styles.ts file and all
affected test snapshots across the codebase.

## **Changelog**

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/MDP-343

## **Manual testing steps**

```gherkin
Feature: HeaderBase background color

  Scenario: HeaderBase renders without explicit background color
    Given the app is running with components using HeaderBase
    When I navigate to screens with bottom sheets using HeaderBase
    Then HeaderBase should inherit background color from parent components
    And all bottom sheet headers should display correctly
```

## **Screenshots/Recordings**

N/A - Style-only change affecting background color inheritance

### **Before**

HeaderBase had explicit white background color set in styles

<img width="200" height="846" alt="Screenshot 2025-11-28 at 7 21 46 AM"
src="https://github.com/user-attachments/assets/40a57b12-d770-475a-b12c-df84e95eee48"
/><img width="200" height="838" alt="Screenshot 2025-11-28 at 7 21
53 AM"
src="https://github.com/user-attachments/assets/e1426cd5-f040-46b1-a32f-b495a6d1f33a"
/>

### **After**

HeaderBase inherits background color from parent component - no change

<img width="200" height="846" alt="Screenshot 2025-11-28 at 7 21 46 AM"
src="https://github.com/user-attachments/assets/40a57b12-d770-475a-b12c-df84e95eee48"
/><img width="200" height="838" alt="Screenshot 2025-11-28 at 7 21
53 AM"
src="https://github.com/user-attachments/assets/e1426cd5-f040-46b1-a32f-b495a6d1f33a"
/>


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

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Removes `backgroundColor` from `HeaderBase` styles and updates
affected header snapshots across the app.
> 
> - **Component Library**:
> - Remove `backgroundColor` from `HeaderBase` `base` style in
`app/component-library/components/HeaderBase/HeaderBase.styles.ts` and
stop destructuring unused `theme`.
> - **Tests**:
> - Update snapshots across bottom sheets, modals, selectors, and views
(e.g., `BottomSheetHeader`, Ramp, Bridge, Earn, Stake, Wallet/Asset,
Network screens) to reflect headers without explicit background color.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ebf437c. 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**

Migrate TokenIcon component from legacy swaps dir to global scope as
it's widely used acrossed the codebase. Changed JS file type to TS and
added missing types. Fixed a type bug. Migrated tests from Enzyme to
React Testing Library.

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3477

## **Manual testing steps**

```
This PR does not introduce any business logic changes.
```

## **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]
> Moves `TokenIcon` to `Base`, converts it to TypeScript with safer
image-source logic, and updates all usages and tests accordingly.
> 
> - **Core Component**:
> - Migrate `UI/Swaps/components/TokenIcon` to `Base/TokenIcon` and
convert to TypeScript (`index.tsx`).
> - Add strong typings (`ThemeColors`, props interfaces) and refine
image source resolution (handles `ETH`, `SOL`, keyed `image-icons`, URL;
returns `undefined` instead of `null`).
> - Adjust imports to local `Base` modules and direct `eth-logo-new.png`
import.
> - **Usage Updates**:
> - Replace imports with `Base/TokenIcon` across Bridge (`TokenButton`,
`TokenInsightsSheet`, `TokenSelectorItem`, `TransactionAsset`), Network
logos (`NetworkAssetLogo`, `NetworkMainAssetLogo`), Swaps (`QuotesView`,
`TokenImportModal`, `TokenSelectButton`, `TokenSelectModal`), and
Confirmations (`Views/confirmations/.../token-icon`).
> - **Tests**:
> - Add new RTL tests for `Base/TokenIcon` (`index.test.tsx`), mocking
images and theme.
> - Update related tests to mock new path; remove old Enzyme test and
snapshots for Swaps `TokenIcon`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
26026a7. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…nt switching (#23351)

## **Description**

This PR creates a temporary fix for a UX issue where the "Fund your
wallet" empty state briefly flashes when importing a wallet with
existing funds or switching between funded accounts. This happened
because the balance calculation returned $0 while price and balance data
were still loading, causing the empty state to appear before the actual
balance was displayed.

_**"Telling a user they need to fund an account that might have
thousands of dollars in it is confusing at best and mildly
panic-inducing at worst."**_

### Problem

PR #21391 introduced a balance empty state that displays when users have
zero mainnet balance. However, due to how balance data loads
asynchronously, users would see:
1. Skeleton loader (correct)
2. **"Fund your wallet" empty state (incorrect - account has funds!)**
3. Actual balance appears (e.g., $49.21)

This flash occurred because:
- Balance calculations depend on multiple data sources (price data,
token balances, native balances)
- These data sources load at different times via polling
- The `AccountTrackerController `always initializes accounts with
`balance: "0x0"`
- We cannot distinguish between "balance is loading" vs "balance is
genuinely $0"

### Solutions Considered

We evaluated several approaches to solve this issue:

#### Option 1: Add Loading State to `AccountTrackerController` ❌
- **Approach**: Modify the core controller to track whether native
balances have been fetched
- **Why rejected**: This is the ideal state but would require changes to
`@metamask/assets-controllers` (shared between mobile and extension),
introducing complexity and breaking type changes across the codebase.
Too large of a scope for this fix.

#### Option 2: Check Controller Initialization State ❌
- **Approach**: Create a selector that validates all price/balance
controllers have initialized
- **Why rejected**: Controllers persist state via redux-persist, so they
always appear "initialized" even with stale data from previous sessions.
Logs confirmed this - all controllers report "state persisted
successfully" immediately on load.

#### Option 3: Balance Change Tracking + Timeout ✅ (Chosen)
- **Approach**: Track when balance values actually change from their
initial value, with a timeout fallback
- **Why chosen**: 
  - Works with existing architecture without controller modifications
- Relies on observable behavior (balance updates) rather than internal
controller state
- Handles all edge cases: fresh imports, account switching, genuinely
empty wallets
  - Simple component-level solution
- **Most importantly**: Prevents showing "fund your wallet" to users
with existing funds

### Implementation

The solution adds balance change tracking to `AccountGroupBalance`
component:

1. **Track account switches** via `groupId` changes - resets all
tracking state
2. **Monitor balance changes** from initial $0 value - marks as
"fetched" when balance updates
3. **Fallback timeout** (3 seconds) - handles genuinely $0 balances or
slow API responses
4. **Dual balance tracking** - watches both `groupBalance` and
`accountGroupBalance` since empty state decision uses the latter

The skeleton loader now displays until either:
- Balance changes from its initial value, OR
- 3-second timeout expires

This ensures users never see the empty state flash for funded accounts.

## **Changelog**

CHANGELOG entry: Fixed an issue where "Fund your wallet" empty state
briefly appeared when importing wallets with existing funds or switching
between funded accounts

## **Related issues**

Fixes: (related to #21391 - balance empty state implementation)

## **Manual testing steps**

\`\`\`gherkin
Feature: Balance empty state loading behavior

  Scenario: Import wallet with funded accounts
    Given the app is freshly installed
    When user imports a wallet using SRP with funded accounts
    Then user should see skeleton loader
    And user should NOT see "Fund your wallet" empty state
    And user should see actual balance (e.g., "$49.21")

  Scenario: Switch between funded accounts
    Given user has multiple accounts with funds
    When user switches from Account 1 to Account 2
    Then user should see skeleton loader briefly
    And user should NOT see "Fund your wallet" empty state
    And user should see Account 2's balance

  Scenario: Import wallet with zero balance
    Given the app is freshly installed
    When user imports a wallet with zero mainnet balance
    Then user should see skeleton loader
    And after 3 seconds, user should see "Fund your wallet" empty state

  Scenario: Switch to account with zero balance
    Given user has account with zero mainnet balance
    When user switches to the zero-balance account
    Then user should see skeleton loader
    And after 3 seconds, user should see "Fund your wallet" empty state
\`\`\`

## **Screenshots/Recordings**

### **Before**

Empty state incorrectly flashed when importing wallet with funds or
switching accounts.


https://github.com/user-attachments/assets/945567d9-e9b1-458d-aecc-66f05384bcc9

### **After**

Skeleton loader now prevents layout shift displays until balance is
confirmed, preventing false "fund your wallet" messaging.


https://github.com/user-attachments/assets/f1763e5c-f9b4-43c3-98a5-4525a2e83a9c

## **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]
> Prevents the “Fund your wallet” flash by tracking balance fetch with a
3s timeout and using Skeleton to hide content until ready; updates
Skeleton behavior and related tests/styles.
> 
> - **Account Group Balance**
> - Implement balance fetch tracking with a 3s timeout using
`hasBalanceFetched`, `groupId` change detection, and initial balance
refs in `AccountGroupBalance.tsx`.
> - Gate empty state rendering (`BalanceEmptyState`) until loading
completes; compute `isLoading = !groupBalance || !hasBalanceFetched`.
> - Wrap balance and change components with `Skeleton` using
`hideChildren` to avoid content flash.
> - Adjust styles to column layout and left alignment in
`AccountGroupBalance.styles.ts`.
> - **Skeleton Component**
> - Change render logic to return `children` directly when
`hideChildren` is false; otherwise render animated placeholder and
optional children wrapper.
> - **Tests**
> - Add timer-based tests covering timeout-driven display, immediate
display on balance change, and zero-balance empty state.
> - Update Skeleton tests to reflect new child rendering behavior and
animation conditions.
> - Remove redundant story/use case and align stories with new
`hideChildren` flow.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
4396697. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators Dec 1, 2025
@pull pull Bot added the ⤵️ pull label Dec 1, 2025
@pull pull Bot merged commit c594a57 into Reality2byte:main Dec 1, 2025
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.

3 participants