From da297a3102c786c8f8c36011af55404ff35131bc Mon Sep 17 00:00:00 2001 From: Jongsun Suh Date: Fri, 16 Feb 2024 22:18:47 -0500 Subject: [PATCH] [detectTokens] Apply and refactor fixes for detected tokens being added to wrong network, and detection using `chainId` keyed states - See https://github.com/MetaMask/metamask-extension/pull/22814 - See https://github.com/MetaMask/core/pull/3914 --- .../src/TokenDetectionController.ts | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/assets-controllers/src/TokenDetectionController.ts b/packages/assets-controllers/src/TokenDetectionController.ts index c888648c819..8476e08da42 100644 --- a/packages/assets-controllers/src/TokenDetectionController.ts +++ b/packages/assets-controllers/src/TokenDetectionController.ts @@ -8,11 +8,7 @@ import type { ControllerStateChangeEvent, } from '@metamask/base-controller'; import contractMap from '@metamask/contract-metadata'; -import { - ChainId, - safelyExecute, - toChecksumHexAddress, -} from '@metamask/controller-utils'; +import { ChainId, safelyExecute } from '@metamask/controller-utils'; import type { KeyringControllerGetStateAction, KeyringControllerLockEvent, @@ -48,13 +44,23 @@ import type { const DEFAULT_INTERVAL = 180000; /** - * Finds a case insensitive match in an array of strings - * @param source - An array of strings to search. - * @param target - The target string to search for. - * @returns The first match that is found. + * Compare 2 given strings and return boolean + * eg: "foo" and "FOO" => true + * eg: "foo" and "bar" => false + * eg: "foo" and 123 => false + * + * @param value1 - first string to compare + * @param value2 - first string to compare + * @returns true if 2 strings are identical when they are lowercase */ -function findCaseInsensitiveMatch(source: string[], target: string) { - return source.find((e: string) => e.toLowerCase() === target.toLowerCase()); +export function isEqualCaseInsensitive( + value1: string, + value2: string, +): boolean { + if (typeof value1 !== 'string' || typeof value2 !== 'string') { + return false; + } + return value1.toLowerCase() === value2.toLowerCase(); } type LegacyToken = Omit< @@ -488,35 +494,29 @@ export class TokenDetectionController extends StaticIntervalPollingController< ); const tokenList = tokensChainsCache[chainIdAgainstWhichToDetect]?.data ?? {}; - const tokenListUsed = isTokenDetectionInactiveInMainnet ? STATIC_MAINNET_TOKEN_LIST : tokenList; const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messagingSystem.call('TokensController:getState'); - const tokens = - allTokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ?? - []; - const detectedTokens = - allDetectedTokens[chainIdAgainstWhichToDetect]?.[ - addressAgainstWhichToDetect - ] ?? []; - const ignoredTokens = - allIgnoredTokens[chainIdAgainstWhichToDetect]?.[ - addressAgainstWhichToDetect - ] ?? []; - + const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddreses] = [ + allTokens, + allDetectedTokens, + allIgnoredTokens, + ].map((tokens) => + ( + tokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ?? [] + ).map((value) => (typeof value === 'string' ? value : value.address)), + ); const tokensToDetect: string[] = []; - for (const tokenAddress of Object.keys(tokenListUsed)) { + for (const tokenAddress of Object.keys(tokenList)) { if ( - !findCaseInsensitiveMatch( - tokens.map(({ address }) => address), - tokenAddress, - ) && - !findCaseInsensitiveMatch( - detectedTokens.map(({ address }) => address), - tokenAddress, + [tokensAddresses, detectedTokensAddresses, ignoredTokensAddreses].every( + (addresses) => + !addresses.find((address) => + isEqualCaseInsensitive(address, tokenAddress), + ), ) ) { tokensToDetect.push(tokenAddress);