From 35a2b3d82e4893bddafe96dbe8bdce5c366b40a7 Mon Sep 17 00:00:00 2001 From: sahar-fehri Date: Thu, 5 Dec 2024 03:21:11 +0100 Subject: [PATCH] fix: fix check for undefined marketData (#28870) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This PR fixes app crash after user removes a network then adds it back and clicks on import token banner [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/28870?quickstart=1) ## **Related issues** Fixes: https://github.com/MetaMask/metamask-extension/issues/28019#issuecomment-2513839152 Fixes: https://github.com/MetaMask/metamask-extension/issues/28882 Fixes: https://github.com/MetaMask/metamask-extension/issues/28864 ## **Manual testing steps** Manual steps are also described in the github [issue](https://github.com/MetaMask/metamask-extension/issues/28019#issuecomment-2513839152). However; I do not think that the Show native token as main balance needs to be ONt o repro the initial issue. Also no need to add new RPC from chainList; Settings: 1. Show balance and token price OFF 2. Token autodetect ON On main view 1. Select an account which has some ERC20 tokens in Polygon 2. Add Polygon default network 3. See tokens are autodetected and you can open the modal -> but don't import the tokens! 4. Switch to another network 5. Delete Polygon network 6. Re-add Polygon default network 7. Click Import tokens --> Wallet should not crash 12. ## **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. --------- Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com> --- .../asset-list-control-bar.tsx | 2 +- .../app/assets/asset-list/asset-list.tsx | 5 +++-- .../app/assets/token-list/token-list.tsx | 4 +--- ui/hooks/useTokenFiatAmount.js | 19 ++++++++++--------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx index 8e6abb940d1c..00e0692cfc73 100644 --- a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx +++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx @@ -99,7 +99,7 @@ const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => { // When a network gets added/removed we want to make sure that we switch to the filtered list of the current network // We only want to do this if the "Current Network" filter is selected useEffect(() => { - if (Object.keys(tokenNetworkFilter).length === 1) { + if (Object.keys(tokenNetworkFilter || {}).length === 1) { dispatch(setTokenNetworkFilter({ [currentNetwork.chainId]: true })); } }, [Object.keys(allNetworks).length]); diff --git a/ui/components/app/assets/asset-list/asset-list.tsx b/ui/components/app/assets/asset-list/asset-list.tsx index 6a3036f88764..ab2adb308bf4 100644 --- a/ui/components/app/assets/asset-list/asset-list.tsx +++ b/ui/components/app/assets/asset-list/asset-list.tsx @@ -117,14 +117,15 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => { ); const totalTokens = - process.env.PORTFOLIO_VIEW && !allNetworksFilterShown + process.env.PORTFOLIO_VIEW && + !allNetworksFilterShown && + detectedTokensMultichain ? (Object.values(detectedTokensMultichain).reduce( // @ts-expect-error TS18046: 'tokenArray' is of type 'unknown' (count, tokenArray) => count + tokenArray.length, 0, ) as number) : detectedTokens.length; - return ( <> {totalTokens && diff --git a/ui/components/app/assets/token-list/token-list.tsx b/ui/components/app/assets/token-list/token-list.tsx index 5e25c7ff5f41..d3e67f6204cc 100644 --- a/ui/components/app/assets/token-list/token-list.tsx +++ b/ui/components/app/assets/token-list/token-list.tsx @@ -116,8 +116,7 @@ export default function TokenList({ const allNetworkFilters = Object.fromEntries( Object.keys(allNetworks).map((chainId) => [chainId, true]), ); - - if (Object.keys(tokenNetworkFilter).length > 1) { + if (Object.keys(tokenNetworkFilter || {}).length > 1) { dispatch(setTokenNetworkFilter(allNetworkFilters)); } } @@ -125,7 +124,6 @@ export default function TokenList({ const consolidatedBalances = () => { const tokensWithBalance: TokenWithFiatAmount[] = []; - Object.entries(selectedAccountTokensChains).forEach( ([stringChainKey, tokens]) => { const chainId = stringChainKey as Hex; diff --git a/ui/hooks/useTokenFiatAmount.js b/ui/hooks/useTokenFiatAmount.js index 486b8ba14fd6..325dbf5eea22 100644 --- a/ui/hooks/useTokenFiatAmount.js +++ b/ui/hooks/useTokenFiatAmount.js @@ -42,15 +42,16 @@ export function useTokenFiatAmount( shallowEqual, ); - const contractMarketData = chainId - ? Object.entries(allMarketData[chainId]).reduce( - (acc, [address, marketData]) => { - acc[address] = marketData?.price ?? null; - return acc; - }, - {}, - ) - : null; + const contractMarketData = + chainId && allMarketData[chainId] + ? Object.entries(allMarketData[chainId]).reduce( + (acc, [address, marketData]) => { + acc[address] = marketData?.price ?? null; + return acc; + }, + {}, + ) + : null; const tokenMarketData = chainId ? contractMarketData : contractExchangeRates;