Skip to content

Conversation

@salimtb
Copy link
Contributor

@salimtb salimtb commented Oct 9, 2025

Explanation

Current Issue:
The AccountsApiBalanceFetcher had a bug caused by address format incompatibility between controllers:

  • TokenBalancesController uses lowercase addresses for ERC20 tokens
  • AccountTrackerController uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong token balances state

Solution:
Fixed by implementing conditional address formatting:

  • Native tokens: Use checksummed addresses (compatible with AccountTrackerController)
  • ERC20 tokens: Use lowercase addresses (compatible with TokenBalancesController)

Also fixed the || '' fallback bug that could pass empty strings to the checksum() function.

References

  • Fixes duplicate native token entries in AccountsApiBalanceFetcher by ensuring controller-compatible address formatting

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

Note

Aligns address casing between controllers by conditionally formatting account addresses in AccountsApiBalanceFetcher and updating TokenBalancesController state access; updates changelog.

  • Balances:
    • multi-chain-accounts-service/api-balance-fetcher.ts:
      • Conditionally format account per token type (checksum for native ZERO_ADDRESS, original for ERC20) and propagate via finalAccount.
      • Track native balances using the formatted key and widen ProcessedBalance.account to ChecksumAddress | string.
    • TokenBalancesController.ts:
      • Access and write state.tokenBalances using account as ChecksumAddress to handle mixed address formats during updates.
  • Docs:
    • CHANGELOG.md: Add "Fixed" note about address format compatibility between TokenBalancesController and AccountTrackerController in AccountsApiBalanceFetcher.

Written by Cursor Bugbot for commit 29bd9b8. This will update automatically on new commits. Configure here.

@salimtb salimtb marked this pull request as ready for review October 10, 2025 09:15
@salimtb salimtb requested review from a team as code owners October 10, 2025 09:15
cursor[bot]

This comment was marked as outdated.

@bergarces
Copy link
Contributor

@metamaskbot publish-preview

cursor[bot]

This comment was marked as outdated.

@github-actions
Copy link
Contributor

Preview builds have been published. See these instructions for more information about preview builds.

Expand for full list of packages and versions.
{
  "@metamask-previews/account-tree-controller": "1.4.1-preview-e8868d87",
  "@metamask-previews/accounts-controller": "33.1.1-preview-e8868d87",
  "@metamask-previews/address-book-controller": "6.2.0-preview-e8868d87",
  "@metamask-previews/announcement-controller": "7.1.0-preview-e8868d87",
  "@metamask-previews/app-metadata-controller": "1.1.0-preview-e8868d87",
  "@metamask-previews/approval-controller": "7.2.0-preview-e8868d87",
  "@metamask-previews/assets-controllers": "79.0.1-preview-e8868d87",
  "@metamask-previews/base-controller": "8.4.1-preview-e8868d87",
  "@metamask-previews/bridge-controller": "49.0.1-preview-e8868d87",
  "@metamask-previews/bridge-status-controller": "49.0.1-preview-e8868d87",
  "@metamask-previews/build-utils": "3.0.4-preview-e8868d87",
  "@metamask-previews/chain-agnostic-permission": "1.2.0-preview-e8868d87",
  "@metamask-previews/composable-controller": "11.1.0-preview-e8868d87",
  "@metamask-previews/controller-utils": "11.14.1-preview-e8868d87",
  "@metamask-previews/core-backend": "1.0.1-preview-e8868d87",
  "@metamask-previews/delegation-controller": "0.8.0-preview-e8868d87",
  "@metamask-previews/earn-controller": "8.0.1-preview-e8868d87",
  "@metamask-previews/eip-5792-middleware": "1.2.2-preview-e8868d87",
  "@metamask-previews/eip1193-permission-middleware": "1.0.1-preview-e8868d87",
  "@metamask-previews/ens-controller": "17.1.0-preview-e8868d87",
  "@metamask-previews/error-reporting-service": "2.2.1-preview-e8868d87",
  "@metamask-previews/eth-json-rpc-provider": "5.0.1-preview-e8868d87",
  "@metamask-previews/foundryup": "1.0.1-preview-e8868d87",
  "@metamask-previews/gas-fee-controller": "24.1.0-preview-e8868d87",
  "@metamask-previews/gator-permissions-controller": "0.2.1-preview-e8868d87",
  "@metamask-previews/json-rpc-engine": "10.1.1-preview-e8868d87",
  "@metamask-previews/json-rpc-middleware-stream": "8.0.8-preview-e8868d87",
  "@metamask-previews/keyring-controller": "23.1.1-preview-e8868d87",
  "@metamask-previews/logging-controller": "6.1.0-preview-e8868d87",
  "@metamask-previews/message-manager": "13.0.1-preview-e8868d87",
  "@metamask-previews/messenger": "0.3.0-preview-e8868d87",
  "@metamask-previews/multichain-account-service": "1.6.1-preview-e8868d87",
  "@metamask-previews/multichain-api-middleware": "1.2.1-preview-e8868d87",
  "@metamask-previews/multichain-network-controller": "1.0.1-preview-e8868d87",
  "@metamask-previews/multichain-transactions-controller": "5.1.0-preview-e8868d87",
  "@metamask-previews/name-controller": "8.1.0-preview-e8868d87",
  "@metamask-previews/network-controller": "24.2.1-preview-e8868d87",
  "@metamask-previews/network-enablement-controller": "2.1.1-preview-e8868d87",
  "@metamask-previews/notification-services-controller": "18.3.0-preview-e8868d87",
  "@metamask-previews/permission-controller": "11.1.0-preview-e8868d87",
  "@metamask-previews/permission-log-controller": "4.1.0-preview-e8868d87",
  "@metamask-previews/phishing-controller": "14.1.1-preview-e8868d87",
  "@metamask-previews/polling-controller": "14.0.1-preview-e8868d87",
  "@metamask-previews/preferences-controller": "20.0.2-preview-e8868d87",
  "@metamask-previews/profile-sync-controller": "25.1.1-preview-e8868d87",
  "@metamask-previews/rate-limit-controller": "6.1.0-preview-e8868d87",
  "@metamask-previews/remote-feature-flag-controller": "1.8.0-preview-e8868d87",
  "@metamask-previews/sample-controllers": "2.0.1-preview-e8868d87",
  "@metamask-previews/seedless-onboarding-controller": "4.1.0-preview-e8868d87",
  "@metamask-previews/selected-network-controller": "24.0.1-preview-e8868d87",
  "@metamask-previews/shield-controller": "0.3.1-preview-e8868d87",
  "@metamask-previews/signature-controller": "34.0.1-preview-e8868d87",
  "@metamask-previews/subscription-controller": "1.0.1-preview-e8868d87",
  "@metamask-previews/token-search-discovery-controller": "3.4.0-preview-e8868d87",
  "@metamask-previews/transaction-controller": "60.6.1-preview-e8868d87",
  "@metamask-previews/user-operation-controller": "39.1.0-preview-e8868d87"
}

bergarces
bergarces previously approved these changes Oct 10, 2025
@bergarces bergarces force-pushed the fix/fix-api-fetcher-balances branch from 01f9177 to d397002 Compare October 10, 2025 16:13
juanmigdr
juanmigdr previously approved these changes Oct 10, 2025
@bergarces bergarces merged commit b0fd6ae into main Oct 10, 2025
243 checks passed
@bergarces bergarces deleted the fix/fix-api-fetcher-balances branch October 10, 2025 16:29
github-merge-queue bot pushed a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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**

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
> 
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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**

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
> 
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
salimtb added a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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.
-->

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

Fixes: #21030

```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]
```

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

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

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

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

- [ ] 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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
>
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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**

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
> 
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
runway-github bot added a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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**

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
> 
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
weitingsun pushed a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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.
-->

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

Fixes: #21030

```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]
```

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

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

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

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

- [ ] 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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
>
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
weitingsun pushed a commit to MetaMask/metamask-mobile that referenced this pull request Oct 10, 2025
<!--
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.
-->

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

Fixes: #21030

```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]
```

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

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

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

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

- [ ] 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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
>
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Cal-L added a commit to MetaMask/metamask-mobile that referenced this pull request Oct 14, 2025
- fix: cp-7.57.0 fix api fetcher balances (#21014)

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

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use checksum addresses for
native tokens and original casing for ERC-20, and adds a Yarn patch for
`@metamask/assets-controllers`.
> 
> - **Assets Controllers (API balance fetcher)**:
> - In `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`, emit
`account` and track `nativeBalancesFromAPI` using `finalAccount`:
>     - Use checksum address for native (`token === ZERO_ADDRESS`).
>     - Use original `addressPart` for ERC-20.
> - **Dependencies**:
> - Adds Yarn patch for `@metamask/assets-controllers@78.0.1` in
`package.json` and updates `yarn.lock` to the patched resolution.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
066a3d4. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->


[368c6ec](368c6ec)

Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com>
Co-authored-by: Cal Leung <cal.leung@consensys.net>
weitingsun pushed a commit to MetaMask/metamask-mobile that referenced this pull request Oct 15, 2025
<!--
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**

The `AccountsApiBalanceFetcher` had a bug caused by address format
incompatibility between controllers:
- `TokenBalancesController` uses lowercase addresses for ERC20 tokens
- `AccountTrackerController` uses checksum addresses for native tokens

The original code always checksummed all addresses, causing a wrong
token balances state

core PR: MetaMask/core#6812

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

## **Changelog**

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

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

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

CHANGELOG entry: fix balances issue update when api fetcher is used

## **Related issues**

Fixes: #21030 

## **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]
> Adjusts `AccountsApiBalanceFetcher` to use the correct account address
format per token type and applies Yarn patches for
`@metamask/assets-controllers` v78/v79.
> 
> - **Services**:
>   - `dist/multi-chain-accounts-service/api-balance-fetcher.cjs`:
> - Introduces `finalAccount` based on token type (zero address vs.
others).
> - Uses `finalAccount` for `nativeBalancesFromAPI` keys and returned
`account` field.
> - **Build/Tooling**:
> - Adds Yarn patches for `@metamask/assets-controllers` `^78.0.1` and
`^79.0.0` in `package.json` and `.yarn/patches/`.
> - Updates `yarn.lock` to reference patched
`@metamask/assets-controllers` 79.0.0.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
3968057. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants