From 048d7840f6c594d174288923896eddda0d9950c4 Mon Sep 17 00:00:00 2001 From: metamaskbot Date: Fri, 21 Nov 2025 06:59:23 +0000 Subject: [PATCH 1/7] bump semvar version to 13.10.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c4f343bb28d..be99b65f9a06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "13.10.0", + "version": "13.10.1", "private": true, "repository": { "type": "git", From e3774547ec2672523320c095e18d157c5809a19c Mon Sep 17 00:00:00 2001 From: "runway-github[bot]" <73448015+runway-github[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 11:10:07 +0100 Subject: [PATCH 2/7] release(runway): cherry-pick fix: cp-13.10.1 prevent account list from fetching list of all accounts balances (#38098) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix: cp-13.10.1 prevent account list from fetching list of all accounts balances (#38065) ## **Description** prevent token list from fetching balances for all accounts [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/38065?quickstart=1) ## **Changelog** CHANGELOG entry: prevent token list from fetching balances for all accounts ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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. --- > [!NOTE] > Pass `platform: 'extension'` to `TokenBalancesController` and switch the hook’s `updateBalancesFoAccounts` flag to `false`, updating tests accordingly. > > - **Controllers**: > - `TokenBalancesControllerInit` now passes `platform: 'extension'` when constructing `TokenBalancesController`. > - Updated test to assert `platform: 'extension'` is provided. > - **UI Hooks**: > - `useAssetsUpdateAllAccountBalances` switches `updateBalancesFoAccounts(enabledChainIds, false)` (from `true`). > - Updated related tests to expect the new boolean argument and re-render behavior. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 6236adcb9880eff6baa704b0550b8ae2bcfa89c3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). [b5eaa85](https://github.com/MetaMask/metamask-extension/commit/b5eaa8528dc3343abb494c4b27f352dbf76ff88a) Co-authored-by: Salim TOUBAL --- .../controller-init/token-balances-controller-init.test.ts | 1 + app/scripts/controller-init/token-balances-controller-init.ts | 1 + ui/hooks/useAssetsUpdateAllAccountBalances.test.ts | 4 ++-- ui/hooks/useAssetsUpdateAllAccountBalances.ts | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/scripts/controller-init/token-balances-controller-init.test.ts b/app/scripts/controller-init/token-balances-controller-init.test.ts index 7a0e007b7743..3b553d02ab74 100644 --- a/app/scripts/controller-init/token-balances-controller-init.test.ts +++ b/app/scripts/controller-init/token-balances-controller-init.test.ts @@ -72,6 +72,7 @@ describe('TokenBalancesControllerInit', () => { queryMultipleAccounts: true, allowExternalServices: expect.any(Function), accountsApiChainIds: expect.any(Function), + platform: 'extension', }); }); }); diff --git a/app/scripts/controller-init/token-balances-controller-init.ts b/app/scripts/controller-init/token-balances-controller-init.ts index f9679acb7148..ef5764bf65cd 100644 --- a/app/scripts/controller-init/token-balances-controller-init.ts +++ b/app/scripts/controller-init/token-balances-controller-init.ts @@ -33,6 +33,7 @@ export const TokenBalancesControllerInit: ControllerInitFunction< ? (featureFlagForAccountApiBalances as `0x${string}`[]) : []; }, + platform: 'extension', }); return { diff --git a/ui/hooks/useAssetsUpdateAllAccountBalances.test.ts b/ui/hooks/useAssetsUpdateAllAccountBalances.test.ts index 4f74632e65f4..27c946bda330 100644 --- a/ui/hooks/useAssetsUpdateAllAccountBalances.test.ts +++ b/ui/hooks/useAssetsUpdateAllAccountBalances.test.ts @@ -130,7 +130,7 @@ describe('useAssetsUpdateAllAccountBalances', () => { expect(mockDispatch).toHaveBeenCalledTimes(1); expect(mockUpdateBalancesFoAccounts).toHaveBeenCalledWith( initialChainIds, - true, + false, ); // Update chain IDs and rerender @@ -140,7 +140,7 @@ describe('useAssetsUpdateAllAccountBalances', () => { expect(mockDispatch).toHaveBeenCalledTimes(2); expect(mockUpdateBalancesFoAccounts).toHaveBeenCalledWith( updatedChainIds, - true, + false, ); }); diff --git a/ui/hooks/useAssetsUpdateAllAccountBalances.ts b/ui/hooks/useAssetsUpdateAllAccountBalances.ts index 0d1e68f4ac95..fe4b6fca12fd 100644 --- a/ui/hooks/useAssetsUpdateAllAccountBalances.ts +++ b/ui/hooks/useAssetsUpdateAllAccountBalances.ts @@ -37,7 +37,7 @@ export const useAssetsUpdateAllAccountBalances = (): { // Update balance state for ALL accounts across all enabled EVM chains // TokenBalancesController is configured with queryMultipleAccounts: true // so this will update balances for all accounts, not just the selected one - await dispatch(updateBalancesFoAccounts(enabledChainIds, true)); + await dispatch(updateBalancesFoAccounts(enabledChainIds, false)); } } catch (error) { console.warn('Error updating balances state for all accounts', error); From eea4d3d50718c0b1de2c9c43616ee807d7a8a70b Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Fri, 21 Nov 2025 18:06:47 +0530 Subject: [PATCH 3/7] fix: dapp-swap comparison fiat rate fetching for native tokens (#38108) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** fix: dapp-swap comparison fiat rate fetching for native tokens ## **Changelog** CHANGELOG entry: ## **Related issues** Fixes: https://github.com/MetaMask/MetaMask-planning/issues/6327 ## **Manual testing steps** 1. Trigger swap including native tokens 2. Check that fait conversion in metrics is correct ## **Screenshots/Recordings** TODO ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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. --- > [!NOTE] > Fetch fiat rates only for non-native tokens in the dapp-swap comparison hook to correctly handle native assets. > > - **Hooks**: > - Update `ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts` to filter out native addresses from `tokenAddresses` before calling `fetchTokenExchangeRates('usd', ...)`, avoiding fiat rate requests for native tokens. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 7ff0f9bc6e18d40a66c99149d42306ca2da38c2d. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). --- .../dapp-swap-comparison/useDappSwapUSDValues.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts index 1c167d7a9147..22778665590b 100644 --- a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts +++ b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts @@ -30,10 +30,12 @@ export function useDappSwapUSDValues({ const { value: fiatRates, pending: fiatRatesPending } = useAsyncResult< Record - >( - () => fetchTokenExchangeRates('usd', tokenAddresses as Hex[], chainId), - [chainId, tokenAddresses?.length], - ); + >(() => { + const addresses = tokenAddresses.filter( + (tokenAddress) => !isNativeAddress(tokenAddress), + ); + return fetchTokenExchangeRates('usd', addresses as Hex[], chainId); + }, [chainId, tokenAddresses?.length]); const { value: tokenDetails, pending: tokenDetailsPending } = useAsyncResult< Record From 8f631e6cbb3577bf7482a235cd175f3e87ee866e Mon Sep 17 00:00:00 2001 From: "runway-github[bot]" <73448015+runway-github[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 18:30:47 +0100 Subject: [PATCH 4/7] release(runway): cherry-pick fix: dapp swap fix conversion rate for pol native token (#38136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix: cp-13.10.1 dapp swap fix conversion rate for pol native token (#38102) ## **Description** Fix conversion rate for POL native token. ## **Changelog** CHANGELOG entry: ## **Related issues** Fixes: https://github.com/MetaMask/MetaMask-planning/issues/6327 ## **Manual testing steps** 1. Trigger swap including POL native token 2. Check that metrics are recorded correctly and dapp-swap UI shows correct values ## **Screenshots/Recordings** TODO ## **Pre-merge author checklist** - [X] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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. --- > [!NOTE] > Fixes USD rate lookup for Polygon native token by mapping native address to `0x0000000000000000000000000000000000001010` and adds tests. > > - **Hooks**: > - Update `ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts` to adjust fiat rate fetching: > - When `chainId === CHAIN_IDS.POLYGON`, map the native asset address to the rate from `0x0000000000000000000000000000000000001010`. > - Wrap rate fetching in an async function to inject the Polygon-specific mapping. > - **Tests**: > - Enhance `useDappSwapUSDValues.test.ts`: > - Allow `runHook` to accept custom `tokenAddresses` and `mockConfirmation`. > - Add Polygon-specific test asserting correct fiat rates for native POL (`0x...0000`) and `0x0000000000000000000000000000000000001010`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit c7fe19352c4d39ddcc13efa7f1f9cbd70758c887. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). [0aa98dc](https://github.com/MetaMask/metamask-extension/commit/0aa98dc78131eca0e3f838a43873baea9b2c4474) Co-authored-by: Jyoti Puri --- .../useDappSwapUSDValues.test.ts | 44 +++++++++++++++++-- .../useDappSwapUSDValues.ts | 19 ++++++-- 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts index 5872d9900d5f..a1229292f1f4 100644 --- a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts +++ b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.test.ts @@ -1,4 +1,6 @@ import { BigNumber } from 'bignumber.js'; +import { CHAIN_IDS } from '@metamask/transaction-controller'; +import { Hex } from '@metamask/utils'; import { act } from '@testing-library/react'; import { getMockConfirmStateForTransaction } from '../../../../../../test/data/confirmations/helper'; @@ -10,18 +12,23 @@ import * as TokenUtils from '../../../utils/token'; import { Confirmation } from '../../../types/confirm'; import { useDappSwapUSDValues } from './useDappSwapUSDValues'; -async function runHook() { +async function runHook( + tokenAddresses?: Hex[], + mockConfirmation?: Confirmation, +) { const response = renderHookWithConfirmContextProvider( () => useDappSwapUSDValues({ - tokenAddresses: [ + tokenAddresses: tokenAddresses ?? [ '0x0000000000000000000000000000000000000000', '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', ], destTokenAddress: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', }), - getMockConfirmStateForTransaction(mockSwapConfirmation as Confirmation), + getMockConfirmStateForTransaction( + mockConfirmation ?? (mockSwapConfirmation as Confirmation), + ), ); await act(async () => { @@ -98,4 +105,35 @@ describe('useDappSwapUSDValues', () => { '0xfdcc3dd6671eab0709a4c0f3f53de9a333d80798': 1, }); }); + + it('return correct fiat rates token on Polygon', async () => { + jest.spyOn(Utils, 'fetchTokenExchangeRates').mockResolvedValue({ + '0x0000000000000000000000000000000000001010': 4052.27, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 0.999804, + }); + jest.spyOn(TokenUtils, 'fetchAllTokenDetails').mockResolvedValue({ + '0x0000000000000000000000000000000000000000': { + symbol: 'POL', + decimals: '18', + } as TokenStandAndDetails, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': { + symbol: 'USDT', + decimals: '6', + } as TokenStandAndDetails, + }); + + const result = await runHook( + [ + '0x0000000000000000000000000000000000000000', + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913', + ], + { ...mockSwapConfirmation, chainId: CHAIN_IDS.POLYGON } as Confirmation, + ); + + expect(result.fiatRates).toEqual({ + '0x0000000000000000000000000000000000000000': 4052.27, + '0x0000000000000000000000000000000000001010': 4052.27, + '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 0.999804, + }); + }); }); diff --git a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts index 22778665590b..2365dcfc3b1d 100644 --- a/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts +++ b/ui/pages/confirmations/hooks/transactions/dapp-swap-comparison/useDappSwapUSDValues.ts @@ -5,7 +5,7 @@ import { getNativeAssetForChainId, isNativeAddress, } from '@metamask/bridge-controller'; -import { TransactionMeta } from '@metamask/transaction-controller'; +import { CHAIN_IDS, TransactionMeta } from '@metamask/transaction-controller'; import { useCallback } from 'react'; import { TokenStandAndDetails } from '../../../../../store/actions'; @@ -15,6 +15,8 @@ import { fetchAllTokenDetails } from '../../../utils/token'; import { getTokenValueFromRecord } from '../../../utils/dapp-swap-comparison-utils'; import { useConfirmContext } from '../../../context/confirm'; +const POLYGON_NATIVE_ASSET = '0x0000000000000000000000000000000000001010'; + export function useDappSwapUSDValues({ tokenAddresses = [], destTokenAddress, @@ -30,11 +32,22 @@ export function useDappSwapUSDValues({ const { value: fiatRates, pending: fiatRatesPending } = useAsyncResult< Record - >(() => { + >(async () => { const addresses = tokenAddresses.filter( (tokenAddress) => !isNativeAddress(tokenAddress), ); - return fetchTokenExchangeRates('usd', addresses as Hex[], chainId); + const exchangeRates = await fetchTokenExchangeRates( + 'usd', + addresses as Hex[], + chainId, + ); + + if (chainId === CHAIN_IDS.POLYGON) { + const nativeAddress = getNativeAssetForChainId(chainId).address; + exchangeRates[nativeAddress] = exchangeRates[POLYGON_NATIVE_ASSET]; + } + + return exchangeRates; }, [chainId, tokenAddresses?.length]); const { value: tokenDetails, pending: tokenDetailsPending } = useAsyncResult< From 8a53979983332a831132f2d611b8d0602a439840 Mon Sep 17 00:00:00 2001 From: "runway-github[bot]" <73448015+runway-github[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 19:29:21 +0100 Subject: [PATCH 5/7] release(runway): cherry-pick fix: patch TokenBalancesController to resolve missing balance state (#38140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix: cp-13.10.1 patch TokenBalancesController to resolve missing balance state (#38126) ## **Description** [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/38126?quickstart=1) ## **Changelog** CHANGELOG entry: fix missing native token balances in wallet balance ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/38114 ## **Manual testing steps** Onboard or existing user with AccountsAPI enabled 1. Go to a network with native + erc tokens 2. Notice aggregated wallet balance - it should have both native + erc tokens aggregated together for the balance. ## **Screenshots/Recordings** ### **Before** ### **After** https://www.loom.com/share/aeccc8e3cef4479da0e9d44fc5ebf4fa ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/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-extension/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. --- > [!NOTE] > Patches `TokenBalancesController` to use lowercase account addresses for balance reads/writes and wires the patched `@metamask/assets-controllers@88.0.0` via Yarn patch. > > - **Assets Controllers Patch (`@metamask/assets-controllers@88.0.0`)**: > - Normalize `account` to lowercase in `TokenBalancesController` when reading/updating `d.tokenBalances` (cjs/mjs builds), ensuring balance updates are applied. > - **Dependencies**: > - Switch `@metamask/assets-controllers` in `package.json` to a Yarn patch source and add patched entry in `yarn.lock`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 75c9d9526426eee4a774a424a1f34aefdbacc4d6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). [a2fe8c4](https://github.com/MetaMask/metamask-extension/commit/a2fe8c40244690700c026950d2f002a0a24db692) Co-authored-by: Prithpal Sooriya --- ...ts-controllers-npm-88.0.0-3dfc0ab8f1.patch | 48 ++++++++++++++++ package.json | 2 +- yarn.lock | 56 ++++++++++++++++++- 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 .yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch diff --git a/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch b/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch new file mode 100644 index 000000000000..86499bd20c8d --- /dev/null +++ b/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch @@ -0,0 +1,48 @@ +diff --git a/dist/TokenBalancesController.cjs b/dist/TokenBalancesController.cjs +index 24c2b2d22d3678352fd2ea4932181f3f11ffe41a..e63d3bcd80d68391d713394ec7f340b80fd8b79d 100644 +--- a/dist/TokenBalancesController.cjs ++++ b/dist/TokenBalancesController.cjs +@@ -527,14 +527,16 @@ class TokenBalancesController extends (0, polling_controller_1.StaticIntervalPol + } + // Update with actual fetched balances only if the value has changed + aggregated.forEach(({ success, value, account, token, chainId }) => { +- var _a, _b, _c; ++ var _a, _b; + if (success && value !== undefined) { ++ // Ensure all accounts we add/update are in lower-case ++ const lowerCaseAccount = account.toLowerCase(); + const newBalance = (0, controller_utils_1.toHex)(value); + const tokenAddress = checksum(token); +- const currentBalance = d.tokenBalances[account]?.[chainId]?.[tokenAddress]; ++ const currentBalance = d.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress]; + // Only update if the balance has actually changed + if (currentBalance !== newBalance) { +- ((_c = ((_a = d.tokenBalances)[_b = account] ?? (_a[_b] = {})))[chainId] ?? (_c[chainId] = {}))[tokenAddress] = newBalance; ++ ((_b = ((_a = d.tokenBalances)[lowerCaseAccount] ?? (_a[lowerCaseAccount] = {})))[chainId] ?? (_b[chainId] = {}))[tokenAddress] = newBalance; + } + } + }); +diff --git a/dist/TokenBalancesController.mjs b/dist/TokenBalancesController.mjs +index 420934fb16ed6151b5b80fb7be04f81352b4aaf4..d735379adcaf77cbd46b4659f9bfd32046abebdf 100644 +--- a/dist/TokenBalancesController.mjs ++++ b/dist/TokenBalancesController.mjs +@@ -523,14 +523,16 @@ export class TokenBalancesController extends StaticIntervalPollingController() { + } + // Update with actual fetched balances only if the value has changed + aggregated.forEach(({ success, value, account, token, chainId }) => { +- var _a, _b, _c; ++ var _a, _b; + if (success && value !== undefined) { ++ // Ensure all accounts we add/update are in lower-case ++ const lowerCaseAccount = account.toLowerCase(); + const newBalance = toHex(value); + const tokenAddress = checksum(token); +- const currentBalance = d.tokenBalances[account]?.[chainId]?.[tokenAddress]; ++ const currentBalance = d.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress]; + // Only update if the balance has actually changed + if (currentBalance !== newBalance) { +- ((_c = ((_a = d.tokenBalances)[_b = account] ?? (_a[_b] = {})))[chainId] ?? (_c[chainId] = {}))[tokenAddress] = newBalance; ++ ((_b = ((_a = d.tokenBalances)[lowerCaseAccount] ?? (_a[lowerCaseAccount] = {})))[chainId] ?? (_b[chainId] = {}))[tokenAddress] = newBalance; + } + } + }); diff --git a/package.json b/package.json index be99b65f9a06..0e7393be59e5 100644 --- a/package.json +++ b/package.json @@ -271,7 +271,7 @@ "@metamask/address-book-controller": "^7.0.0", "@metamask/announcement-controller": "^8.0.0", "@metamask/approval-controller": "^8.0.0", - "@metamask/assets-controllers": "^88.0.0", + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A88.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch", "@metamask/base-controller": "^9.0.0", "@metamask/bitcoin-wallet-snap": "^1.6.0", "@metamask/bridge-controller": "^60.1.0", diff --git a/yarn.lock b/yarn.lock index 3c1e4262c2cd..3e9d985e6a9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5591,7 +5591,7 @@ __metadata: languageName: node linkType: hard -"@metamask/assets-controllers@npm:^88.0.0": +"@metamask/assets-controllers@npm:88.0.0": version: 88.0.0 resolution: "@metamask/assets-controllers@npm:88.0.0" dependencies: @@ -5643,6 +5643,58 @@ __metadata: languageName: node linkType: hard +"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A88.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch": + version: 88.0.0 + resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A88.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch::version=88.0.0&hash=ab5ccb" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@ethersproject/abi": "npm:^5.7.0" + "@ethersproject/address": "npm:^5.7.0" + "@ethersproject/bignumber": "npm:^5.7.0" + "@ethersproject/contracts": "npm:^5.7.0" + "@ethersproject/providers": "npm:^5.7.0" + "@metamask/abi-utils": "npm:^2.0.3" + "@metamask/base-controller": "npm:^9.0.0" + "@metamask/contract-metadata": "npm:^2.4.0" + "@metamask/controller-utils": "npm:^11.15.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/keyring-api": "npm:^21.0.0" + "@metamask/messenger": "npm:^0.3.0" + "@metamask/metamask-eth-abis": "npm:^3.1.1" + "@metamask/polling-controller": "npm:^15.0.0" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/snaps-sdk": "npm:^9.0.0" + "@metamask/snaps-utils": "npm:^11.0.0" + "@metamask/utils": "npm:^11.8.1" + "@types/bn.js": "npm:^5.1.5" + "@types/uuid": "npm:^8.3.0" + async-mutex: "npm:^0.5.0" + bitcoin-address-validation: "npm:^2.2.3" + bn.js: "npm:^5.2.1" + immer: "npm:^9.0.6" + lodash: "npm:^4.17.21" + multiformats: "npm:^9.9.0" + reselect: "npm:^5.1.1" + single-call-balance-checker-abi: "npm:^1.0.0" + uuid: "npm:^8.3.2" + peerDependencies: + "@metamask/account-tree-controller": ^3.0.0 + "@metamask/accounts-controller": ^34.0.0 + "@metamask/approval-controller": ^8.0.0 + "@metamask/core-backend": ^4.0.0 + "@metamask/keyring-controller": ^24.0.0 + "@metamask/network-controller": ^25.0.0 + "@metamask/permission-controller": ^12.0.0 + "@metamask/phishing-controller": ^15.0.0 + "@metamask/preferences-controller": ^21.0.0 + "@metamask/providers": ^22.0.0 + "@metamask/snaps-controllers": ^14.0.0 + "@metamask/transaction-controller": ^61.0.0 + webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 + checksum: 10/17587884760c7856d4459c2f60a1acff0d2430b4ae0f9710bff15076e7d21f726d2a1380781d427d32859f1e6e7568eda48e277093d3b85aaffab82021a14c0c + languageName: node + linkType: hard + "@metamask/auth-network-utils@npm:^0.3.0, @metamask/auth-network-utils@npm:^0.3.1": version: 0.3.1 resolution: "@metamask/auth-network-utils@npm:0.3.1" @@ -32492,7 +32544,7 @@ __metadata: "@metamask/announcement-controller": "npm:^8.0.0" "@metamask/api-specs": "npm:^0.13.0" "@metamask/approval-controller": "npm:^8.0.0" - "@metamask/assets-controllers": "npm:^88.0.0" + "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A88.0.0#~/.yarn/patches/@metamask-assets-controllers-npm-88.0.0-3dfc0ab8f1.patch" "@metamask/auto-changelog": "npm:^5.1.0" "@metamask/base-controller": "npm:^9.0.0" "@metamask/bitcoin-wallet-snap": "npm:^1.6.0" From e97c9f7bb2cc957f32a9fdf6fadfda0b9d211ed9 Mon Sep 17 00:00:00 2001 From: MetaMask Bot <37885440+metamaskbot@users.noreply.github.com> Date: Fri, 21 Nov 2025 19:30:54 +0100 Subject: [PATCH 6/7] release: release/13.10.1-Changelog (#38085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the change log for 13.10.1. (Hotfix - no test plan generated.) --- > [!NOTE] > Updates CHANGELOG with 13.10.1 fixes and adjusts version comparison links. > > - **Documentation** (`CHANGELOG.md`): > - **Add `13.10.1` – Fixed**: > - Prevent token list from fetching balances for all accounts. > - Correct dapp-swap comparison fiat rate for native tokens. > - Fix conversion rate for POL native token in dapp-swap. > - Remove unnecessary extension permission. > - Restore missing native token balances in wallet balance. > - **Links**: > - Update `[Unreleased]` compare link to start from `v13.10.1`. > - Add `[13.10.1]` compare link to `v13.10.0...v13.10.1`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit b15b2741a81aeced70beb89f2ec22de9b0677b8a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). --------- Co-authored-by: metamaskbot Co-authored-by: Gauthier Petetin --- CHANGELOG.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 734b4ae431e8..04686b304416 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [13.10.1] + +### Fixed + +- Prevents token list from fetching balances for all accounts (#38065) +- Fixes dapp-swap comparison fiat rate fetching for native tokens (#37980) +- Fixes dapp-swap fix conversion rate for pol native token (#38102) +- Removes unnecessary extension permission (#38075) +- Fixes missing native token balances in wallet balance (#38126) + ## [13.10.0] ### Added @@ -1217,7 +1227,8 @@ authorized by the user.` error until the user fully revoked dapp - This changelog was split off with 12.22.0 - All older changes can be found in [docs/CHANGELOG_older.md](https://github.com/MetaMask/metamask-extension/blob/main/docs/CHANGELOG_older.md) -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v13.10.0...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v13.10.1...HEAD +[13.10.1]: https://github.com/MetaMask/metamask-extension/compare/v13.10.0...v13.10.1 [13.10.0]: https://github.com/MetaMask/metamask-extension/compare/v13.9.0...v13.10.0 [13.9.0]: https://github.com/MetaMask/metamask-extension/compare/v13.8.0...v13.9.0 [13.8.0]: https://github.com/MetaMask/metamask-extension/compare/v13.7.0...v13.8.0 From fb60f40ab862665d94cf074a89a8585f09d3b7e8 Mon Sep 17 00:00:00 2001 From: "runway-github[bot]" <73448015+runway-github[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 20:24:45 +0100 Subject: [PATCH 7/7] release(runway): cherry-pick fix: Remove `tabs` permission to avoid new warnings cp-13.10.1 (#38146) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix: Remove `tabs` permission to avoid new warnings cp-13.10.1 (#38075) ## **Description** The recent addition of the `tabs` permission will result in new permission warnings upon update, which is extremely disruptive and is something we'd never do except as a last resort. The permission wasn't actually needed, and has been removed. This removal uncovered a bug in our Webpack build (the `tabs` permission was erroneously only added for MV2 test builds, but we need it for MV3 test builds as well), which has been fixed. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/38075?quickstart=1) ## **Changelog** CHANGELOG entry: Remove unnecessary extension permission ## **Related issues** N/A ## **Manual testing steps** Test that the sidepanel still works in general. Particularly with dapp confirmations, and the "Connected status" indicator, and current selected dapp. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] 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-extension/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. --- > [!NOTE] > Removes the `tabs` permission from the MV3 base manifest. > > - **Manifest (MV3)**: > - Update `app/manifest/v3/_base.json` to remove `permissions` entry `tabs`. > > Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 77782319cb492d86f70ed35aad0f01218840996c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot). [bba4201](https://github.com/MetaMask/metamask-extension/commit/bba4201ffe430cbec71bdd74d0eaeaf5cda5bcc7) Co-authored-by: Mark Stacey --- app/manifest/v3/_base.json | 1 - 1 file changed, 1 deletion(-) diff --git a/app/manifest/v3/_base.json b/app/manifest/v3/_base.json index 775e9e605753..169d30a8cd9a 100644 --- a/app/manifest/v3/_base.json +++ b/app/manifest/v3/_base.json @@ -77,7 +77,6 @@ "notifications", "scripting", "storage", - "tabs", "unlimitedStorage", "webRequest", "offscreen",