From aac2b239d0b1e0c118ab162352baba3d59330120 Mon Sep 17 00:00:00 2001 From: cryptodev-2s <109512101+cryptodev-2s@users.noreply.github.com> Date: Thu, 13 Jul 2023 16:45:03 +0200 Subject: [PATCH] refactor: Use selectors for tokens controller state access (#6758) --- app/components/Nav/Main/RootRPCMethodsUI.js | 3 +- app/components/UI/AccountApproval/index.js | 4 ++- .../VerifyContractDetails.tsx | 7 ++-- .../UI/ApproveTransactionReview/index.js | 3 +- app/components/UI/DrawerView/index.js | 4 +-- .../TransactionNotification/index.js | 9 ++--- app/components/UI/PaymentRequest/index.js | 3 +- app/components/UI/Tokens/index.tsx | 6 ++-- .../TransactionDetails/index.js | 9 ++--- app/components/UI/TransactionReview/index.js | 3 +- app/components/UI/Transactions/index.js | 9 ++--- .../Views/ApproveView/Approve/index.js | 3 +- app/components/Views/Asset/index.js | 3 +- app/components/Views/AssetDetails/index.tsx | 6 ++-- app/components/Views/DetectedTokens/index.tsx | 7 ++-- app/components/Views/Send/index.js | 3 +- app/components/Views/SendFlow/Amount/index.js | 3 +- .../Views/TransactionsView/index.js | 3 +- app/components/Views/Wallet/index.tsx | 5 ++- app/reducers/swaps/index.js | 5 ++- app/selectors/tokensController.ts | 35 +++++++++++++++++++ 21 files changed, 76 insertions(+), 57 deletions(-) create mode 100644 app/selectors/tokensController.ts diff --git a/app/components/Nav/Main/RootRPCMethodsUI.js b/app/components/Nav/Main/RootRPCMethodsUI.js index eaf3b7f68b5..3398297259c 100644 --- a/app/components/Nav/Main/RootRPCMethodsUI.js +++ b/app/components/Nav/Main/RootRPCMethodsUI.js @@ -57,6 +57,7 @@ import { selectChainId, selectProviderType, } from '../../../selectors/networkController'; +import { selectTokens } from '../../../selectors/tokensController'; import { createAccountConnectNavDetails } from '../../Views/AccountConnect'; import { ApprovalResult } from '../../UI/Approval/ApprovalResult'; import { ApprovalResultType } from '../../UI/Approval/ApprovalResult/ApprovalResult'; @@ -948,7 +949,7 @@ const mapStateToProps = (state) => ({ selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, chainId: selectChainId(state), - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), swapsTransactions: state.engine.backgroundState.TransactionController.swapsTransactions || {}, providerType: selectProviderType(state), diff --git a/app/components/UI/AccountApproval/index.js b/app/components/UI/AccountApproval/index.js index 41fbf2e21af..a923a962525 100644 --- a/app/components/UI/AccountApproval/index.js +++ b/app/components/UI/AccountApproval/index.js @@ -29,12 +29,14 @@ import { selectChainId, selectProviderType, } from '../../../selectors/networkController'; +import { selectTokensLength } from '../../../selectors/tokensController'; import AppConstants from '../../../../app/core/AppConstants'; import { shuffle } from 'lodash'; import SDKConnect from '../../../core/SDKConnect/SDKConnect'; import Routes from '../../../constants/navigation/Routes'; import CheckBox from '@react-native-community/checkbox'; import generateTestId from '../../../../wdio/utils/generateTestId'; + const createStyles = (colors, typography) => StyleSheet.create({ root: { @@ -463,7 +465,7 @@ const mapStateToProps = (state) => ({ ).length, selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, - tokensLength: state.engine.backgroundState.TokensController.tokens.length, + tokensLength: selectTokensLength(state), networkType: selectProviderType(state), chainId: selectChainId(state), }); diff --git a/app/components/UI/ApproveTransactionReview/VerifyContractDetails/VerifyContractDetails.tsx b/app/components/UI/ApproveTransactionReview/VerifyContractDetails/VerifyContractDetails.tsx index 6698edbb032..1107c3dc373 100644 --- a/app/components/UI/ApproveTransactionReview/VerifyContractDetails/VerifyContractDetails.tsx +++ b/app/components/UI/ApproveTransactionReview/VerifyContractDetails/VerifyContractDetails.tsx @@ -14,7 +14,7 @@ import { findBlockExplorerForRpc } from '../../../../util/networks'; import { RPC } from '../../../../constants/network'; import TransactionTypes from '../../../../core/TransactionTypes'; import { safeToChecksumAddress } from '../../../../util/address'; -import { Token as TokenType } from '@metamask/assets-controllers'; +import { selectTokens } from '../../../../selectors/tokensController'; const { ASSET: { ERC20, ERC1155, ERC721 }, @@ -39,10 +39,7 @@ const VerifyContractDetails = ({ const { colors } = useAppThemeFromContext() || mockTheme; const styles = createStyles(colors); - const tokens = useSelector( - (state: any) => - state.engine.backgroundState.TokensController.tokens as TokenType[], - ); + const tokens = useSelector(selectTokens); const tokenData = useMemo( () => diff --git a/app/components/UI/ApproveTransactionReview/index.js b/app/components/UI/ApproveTransactionReview/index.js index 72903b97092..5c0a6c68af9 100644 --- a/app/components/UI/ApproveTransactionReview/index.js +++ b/app/components/UI/ApproveTransactionReview/index.js @@ -78,6 +78,7 @@ import { selectTicker, selectRpcTarget, } from '../../../selectors/networkController'; +import { selectTokensLength } from '../../../selectors/tokensController'; import Text, { TextVariant, } from '../../../component-library/components/Texts/Text'; @@ -1181,7 +1182,7 @@ const mapStateToProps = (state) => ({ accountsLength: Object.keys( state.engine.backgroundState.AccountTrackerController.accounts || {}, ).length, - tokensLength: state.engine.backgroundState.TokensController.tokens.length, + tokensLength: selectTokensLength(state), providerType: selectProviderType(state), providerRpcTarget: selectRpcTarget(state), primaryCurrency: state.settings.primaryCurrency, diff --git a/app/components/UI/DrawerView/index.js b/app/components/UI/DrawerView/index.js index 29085d1bfa0..d72ced46eba 100644 --- a/app/components/UI/DrawerView/index.js +++ b/app/components/UI/DrawerView/index.js @@ -78,7 +78,7 @@ import { selectTicker, } from '../../../selectors/networkController'; import { selectCurrentCurrency } from '../../../selectors/currencyRateController'; - +import { selectTokens } from '../../../selectors/tokensController'; import { createAccountSelectorNavDetails } from '../../Views/AccountSelector'; import NetworkInfo from '../NetworkInfo'; @@ -1253,7 +1253,7 @@ const mapStateToProps = (state) => ({ passwordSet: state.user.passwordSet, wizard: state.wizard, ticker: selectTicker(state), - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), tokenBalances: state.engine.backgroundState.TokenBalancesController.contractBalances, collectibles: collectiblesSelector(state), diff --git a/app/components/UI/Notification/TransactionNotification/index.js b/app/components/UI/Notification/TransactionNotification/index.js index 7899513d8eb..9b2690e9f4b 100644 --- a/app/components/UI/Notification/TransactionNotification/index.js +++ b/app/components/UI/Notification/TransactionNotification/index.js @@ -31,6 +31,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../../selectors/currencyRateController'; +import { selectTokensByAddress } from '../../../../selectors/tokensController'; const WINDOW_WIDTH = Dimensions.get('window').width; const ACTION_CANCEL = 'cancel'; @@ -422,13 +423,7 @@ const mapStateToProps = (state) => ({ transactions: state.engine.backgroundState.TransactionController.transactions, ticker: selectTicker(state), chainId: selectChainId(state), - tokens: state.engine.backgroundState.TokensController.tokens.reduce( - (tokens, token) => { - tokens[token.address] = token; - return tokens; - }, - {}, - ), + tokens: selectTokensByAddress(state), collectibleContracts: collectibleContractsSelector(state), contractExchangeRates: state.engine.backgroundState.TokenRatesController.contractExchangeRates, diff --git a/app/components/UI/PaymentRequest/index.js b/app/components/UI/PaymentRequest/index.js index 080965dd876..7dc1a7bb804 100644 --- a/app/components/UI/PaymentRequest/index.js +++ b/app/components/UI/PaymentRequest/index.js @@ -57,6 +57,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../selectors/currencyRateController'; +import { selectTokens } from '../../../selectors/tokensController'; import generateTestId from '../../../../wdio/utils/generateTestId'; import { REQUEST_AMOUNT_INPUT, @@ -889,7 +890,7 @@ const mapStateToProps = (state) => ({ searchEngine: state.settings.searchEngine, selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), primaryCurrency: state.settings.primaryCurrency, ticker: selectTicker(state), chainId: selectChainId(state), diff --git a/app/components/UI/Tokens/index.tsx b/app/components/UI/Tokens/index.tsx index b7923cecc24..ee1b6541a04 100644 --- a/app/components/UI/Tokens/index.tsx +++ b/app/components/UI/Tokens/index.tsx @@ -87,6 +87,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../selectors/currencyRateController'; +import { selectDetectedTokens } from '../../../selectors/tokensController'; const Tokens: React.FC = ({ tokens }) => { const { colors, themeAppearance } = useTheme(); @@ -118,10 +119,7 @@ const Tokens: React.FC = ({ tokens }) => { const hideZeroBalanceTokens = useSelector( (state: any) => state.settings.hideZeroBalanceTokens, ); - const detectedTokens = useSelector( - (state: EngineState) => - state.engine.backgroundState.TokensController.detectedTokens, - ); + const detectedTokens = useSelector(selectDetectedTokens); const isTokenDetectionEnabled = useSelector( (state: EngineState) => state.engine.backgroundState.PreferencesController.useTokenDetection, diff --git a/app/components/UI/TransactionElement/TransactionDetails/index.js b/app/components/UI/TransactionElement/TransactionDetails/index.js index 89c13bbe602..6f7c44e445c 100644 --- a/app/components/UI/TransactionElement/TransactionDetails/index.js +++ b/app/components/UI/TransactionElement/TransactionDetails/index.js @@ -35,6 +35,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../../selectors/currencyRateController'; +import { selectTokensByAddress } from '../../../../selectors/tokensController'; const createStyles = (colors) => StyleSheet.create({ @@ -415,13 +416,7 @@ const mapStateToProps = (state) => ({ state.engine.backgroundState.PreferencesController.selectedAddress, transactions: state.engine.backgroundState.TransactionController.transactions, ticker: selectTicker(state), - tokens: state.engine.backgroundState.TokensController.tokens.reduce( - (tokens, token) => { - tokens[token.address] = token; - return tokens; - }, - {}, - ), + tokens: selectTokensByAddress(state), contractExchangeRates: state.engine.backgroundState.TokenRatesController.contractExchangeRates, conversionRate: selectConversionRate(state), diff --git a/app/components/UI/TransactionReview/index.js b/app/components/UI/TransactionReview/index.js index 9ff91ea0197..4258b03d42b 100644 --- a/app/components/UI/TransactionReview/index.js +++ b/app/components/UI/TransactionReview/index.js @@ -57,6 +57,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../selectors/currencyRateController'; +import { selectTokens } from '../../../selectors/tokensController'; import ApproveTransactionHeader from '../ApproveTransactionHeader'; import AppConstants from '../../../core/AppConstants'; @@ -612,7 +613,7 @@ class TransactionReview extends PureComponent { const mapStateToProps = (state) => ({ accounts: state.engine.backgroundState.AccountTrackerController.accounts, - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), conversionRate: selectConversionRate(state), currentCurrency: selectCurrentCurrency(state), contractExchangeRates: diff --git a/app/components/UI/Transactions/index.js b/app/components/UI/Transactions/index.js index 53dec3d126e..7d447d14a6e 100644 --- a/app/components/UI/Transactions/index.js +++ b/app/components/UI/Transactions/index.js @@ -28,6 +28,7 @@ import { selectProviderConfig, selectProviderType, } from '../../../selectors/networkController'; +import { selectTokensByAddress } from '../../../selectors/tokensController'; import { baseStyles, fontStyles } from '../../../styles/common'; import { isQRHardwareAccount } from '../../../util/address'; import Device from '../../../util/device'; @@ -782,13 +783,7 @@ const mapStateToProps = (state) => ({ gasFeeEstimates: state.engine.backgroundState.GasFeeController.gasFeeEstimates, primaryCurrency: state.settings.primaryCurrency, - tokens: state.engine.backgroundState.TokensController.tokens.reduce( - (tokens, token) => { - tokens[token.address] = token; - return tokens; - }, - {}, - ), + tokens: selectTokensByAddress(state), gasEstimateType: state.engine.backgroundState.GasFeeController.gasEstimateType, networkType: selectProviderType(state), diff --git a/app/components/Views/ApproveView/Approve/index.js b/app/components/Views/ApproveView/Approve/index.js index 515ccf59f7c..ff688933337 100644 --- a/app/components/Views/ApproveView/Approve/index.js +++ b/app/components/Views/ApproveView/Approve/index.js @@ -56,6 +56,7 @@ import { selectCurrentCurrency, selectNativeCurrency, } from '../../../../selectors/currencyRateController'; +import { selectTokensLength } from '../../../../selectors/tokensController'; import ShowBlockExplorer from '../../../UI/ApproveTransactionReview/ShowBlockExplorer'; import createStyles from './styles'; import { ethErrors } from 'eth-rpc-errors'; @@ -827,7 +828,7 @@ const mapStateToProps = (state) => ({ accountsLength: Object.keys( state.engine.backgroundState.AccountTrackerController.accounts || {}, ).length, - tokensLength: state.engine.backgroundState.TokensController.tokens.length, + tokensLength: selectTokensLength(state), primaryCurrency: state.settings.primaryCurrency, chainId: selectChainId(state), gasFeeEstimates: diff --git a/app/components/Views/Asset/index.js b/app/components/Views/Asset/index.js index dbdd4b8aaa9..ef2d9cebc5f 100644 --- a/app/components/Views/Asset/index.js +++ b/app/components/Views/Asset/index.js @@ -33,6 +33,7 @@ import { selectChainId, selectRpcTarget, } from '../../../selectors/networkController'; +import { selectTokens } from '../../../selectors/tokensController'; import { sortTransactions } from '../../../util/activity'; import { safeToChecksumAddress } from '../../../util/address'; import { toLowerCaseEquals } from '../../../util/general'; @@ -568,7 +569,7 @@ const mapStateToProps = (state) => ({ state.engine.backgroundState.PreferencesController.selectedAddress, identities: state.engine.backgroundState.PreferencesController.identities, chainId: selectChainId(state), - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), transactions: state.engine.backgroundState.TransactionController.transactions, thirdPartyApiMode: state.privacy.thirdPartyApiMode, rpcTarget: selectRpcTarget(state), diff --git a/app/components/Views/AssetDetails/index.tsx b/app/components/Views/AssetDetails/index.tsx index 8c217a0d21b..1a53934b23d 100644 --- a/app/components/Views/AssetDetails/index.tsx +++ b/app/components/Views/AssetDetails/index.tsx @@ -37,6 +37,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../selectors/currencyRateController'; +import { selectTokens } from '../../../selectors/tokensController'; const createStyles = (colors: any) => StyleSheet.create({ @@ -102,10 +103,7 @@ const AssetDetails = (props: Props) => { const navigation = useNavigation(); const dispatch = useDispatch(); const providerConfig = useSelector(selectProviderConfig); - const tokens = useSelector( - (state: any) => - state.engine.backgroundState.TokensController.tokens as TokenType[], - ); + const tokens = useSelector(selectTokens); const conversionRate = useSelector(selectConversionRate); const currentCurrency = useSelector(selectCurrentCurrency); const primaryCurrency = useSelector( diff --git a/app/components/Views/DetectedTokens/index.tsx b/app/components/Views/DetectedTokens/index.tsx index c82bf10458a..78f82c87775 100644 --- a/app/components/Views/DetectedTokens/index.tsx +++ b/app/components/Views/DetectedTokens/index.tsx @@ -21,6 +21,7 @@ import Routes from '../../../constants/navigation/Routes'; import SheetBottom, { SheetBottomRef, } from '../../../component-library/components/Sheet/SheetBottom'; +import { selectDetectedTokens } from '../../../selectors/tokensController'; const createStyles = (colors: any) => StyleSheet.create({ @@ -65,11 +66,7 @@ interface IgnoredTokensByAddress { const DetectedTokens = () => { const navigation = useNavigation(); const sheetRef = useRef(null); - const detectedTokens = useSelector( - (state) => - state.engine.backgroundState.TokensController - .detectedTokens as TokenType[], - ); + const detectedTokens = useSelector(selectDetectedTokens); const [ignoredTokens, setIgnoredTokens] = useState( {}, ); diff --git a/app/components/Views/Send/index.js b/app/components/Views/Send/index.js index babf8242593..2a15e290403 100644 --- a/app/components/Views/Send/index.js +++ b/app/components/Views/Send/index.js @@ -51,6 +51,7 @@ import { selectNetwork, selectProviderType, } from '../../../selectors/networkController'; +import { selectTokens } from '../../../selectors/tokensController'; import { ethErrors } from 'eth-rpc-errors'; const REVIEW = 'review'; @@ -765,7 +766,7 @@ const mapStateToProps = (state) => ({ state.engine.backgroundState.TokenBalancesController.contractBalances, transaction: state.transaction, networkType: selectProviderType(state), - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), network: selectNetwork(state), identities: state.engine.backgroundState.PreferencesController.identities, selectedAddress: diff --git a/app/components/Views/SendFlow/Amount/index.js b/app/components/Views/SendFlow/Amount/index.js index 89c0a70ec8a..5c7158f3efb 100644 --- a/app/components/Views/SendFlow/Amount/index.js +++ b/app/components/Views/SendFlow/Amount/index.js @@ -96,6 +96,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../../selectors/currencyRateController'; +import { selectTokens } from '../../../../selectors/tokensController'; import { PREFIX_HEX_STRING } from '../../../../constants/transaction'; import Routes from '../../../../constants/navigation/Routes'; @@ -1424,7 +1425,7 @@ const mapStateToProps = (state, ownProps) => ({ selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, ticker: selectTicker(state), - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), transactionState: ownProps.transaction || state.transaction, selectedAsset: state.transaction.selectedAsset, isPaymentRequest: state.transaction.paymentRequest, diff --git a/app/components/Views/TransactionsView/index.js b/app/components/Views/TransactionsView/index.js index 15b75938f77..987da216b95 100644 --- a/app/components/Views/TransactionsView/index.js +++ b/app/components/Views/TransactionsView/index.js @@ -28,6 +28,7 @@ import { selectConversionRate, selectCurrentCurrency, } from '../../../selectors/currencyRateController'; +import { selectTokens } from '../../../selectors/tokensController'; const styles = StyleSheet.create({ wrapper: { @@ -215,7 +216,7 @@ const mapStateToProps = (state) => ({ currentCurrency: selectCurrentCurrency(state), selectedAddress: state.engine.backgroundState.PreferencesController.selectedAddress, - tokens: state.engine.backgroundState.TokensController.tokens, + tokens: selectTokens(state), identities: state.engine.backgroundState.PreferencesController.identities, transactions: state.engine.backgroundState.TransactionController.transactions, networkType: selectProviderType(state), diff --git a/app/components/Views/Wallet/index.tsx b/app/components/Views/Wallet/index.tsx index 757c3379a26..1fb7290e2c4 100644 --- a/app/components/Views/Wallet/index.tsx +++ b/app/components/Views/Wallet/index.tsx @@ -35,6 +35,7 @@ import { selectProviderConfig, selectTicker, } from '../../../selectors/networkController'; +import { selectTokens } from '../../../selectors/tokensController'; import { useNavigation } from '@react-navigation/native'; import { ProviderConfig } from '@metamask/network-controller'; import { WalletAccount } from '../../../components/UI/WalletAccount'; @@ -107,9 +108,7 @@ const Wallet = ({ navigation }: any) => { /** * An array that represents the user tokens */ - const tokens = useSelector( - (state: any) => state.engine.backgroundState.TokensController.tokens, - ); + const tokens = useSelector(selectTokens); /** * Current provider ticker */ diff --git a/app/reducers/swaps/index.js b/app/reducers/swaps/index.js index 5d662055d38..8cd3c5b98a3 100644 --- a/app/reducers/swaps/index.js +++ b/app/reducers/swaps/index.js @@ -5,6 +5,7 @@ import { toLowerCaseEquals } from '../../util/general'; import Engine from '../../core/Engine'; import { lte } from '../../util/lodash'; import { selectChainId } from '../../selectors/networkController'; +import { selectTokens } from '../../selectors/tokensController'; // * Constants export const SWAPS_SET_LIVENESS = 'SWAPS_SET_LIVENESS'; @@ -68,12 +69,10 @@ export const swapsHasOnboardedSelector = createSelector( */ export const swapsControllerTokens = (state) => state.engine.backgroundState.SwapsController.tokens; -const tokensSelectors = (state) => - state.engine.backgroundState.TokensController.tokens; const swapsControllerAndUserTokens = createSelector( swapsControllerTokens, - tokensSelectors, + selectTokens, (swapsTokens, tokens) => { const values = [...(swapsTokens || []), ...(tokens || [])] .filter(Boolean) diff --git a/app/selectors/tokensController.ts b/app/selectors/tokensController.ts new file mode 100644 index 00000000000..5904805d77c --- /dev/null +++ b/app/selectors/tokensController.ts @@ -0,0 +1,35 @@ +import { createSelector } from 'reselect'; +import { TokensState, Token } from '@metamask/assets-controllers'; +import { EngineState } from './types'; + +const selectTokensControllerState = (state: EngineState) => + state?.engine?.backgroundState?.TokensController; + +export const selectTokens = createSelector( + selectTokensControllerState, + (tokensControllerState: TokensState) => tokensControllerState?.tokens, +); + +export const selectTokensByAddress = createSelector( + selectTokens, + (tokens: Token[]) => + tokens.reduce((tokensMap: { [address: string]: Token }, token: Token) => { + tokensMap[token.address] = token; + return tokensMap; + }, {}), +); + +export const selectTokensLength = createSelector( + selectTokens, + (tokens: Token[]) => tokens.length, +); + +export const selectIgnoreTokens = createSelector( + selectTokensControllerState, + (tokensControllerState: TokensState) => tokensControllerState?.ignoredTokens, +); + +export const selectDetectedTokens = createSelector( + selectTokensControllerState, + (tokensControllerState: TokensState) => tokensControllerState?.detectedTokens, +);