1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-23 10:30:04 +01:00
metamask-extension/ui/hooks/useTokensToSearch.js

171 lines
5.0 KiB
JavaScript
Raw Normal View History

import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import contractMap from '@metamask/contract-metadata';
import BigNumber from 'bignumber.js';
import { isEqual, shuffle, uniqBy } from 'lodash';
import { getTokenFiatAmount } from '../helpers/utils/token-util';
2020-11-03 00:41:28 +01:00
import {
getTokenExchangeRates,
getCurrentCurrency,
getSwapsDefaultToken,
getCurrentChainId,
} from '../selectors';
import { getConversionRate } from '../ducks/metamask/metamask';
import { getSwapsTokens } from '../ducks/swaps/swaps';
import { isSwapsDefaultTokenSymbol } from '../../shared/modules/swaps.utils';
2021-05-17 23:19:39 +02:00
import { toChecksumHexAddress } from '../../shared/modules/hexstring-utils';
import { useEqualityCheck } from './useEqualityCheck';
2020-10-06 20:28:38 +02:00
2020-11-03 00:41:28 +01:00
const tokenList = shuffle(
Object.entries(contractMap)
.map(([address, tokenData]) => ({
...tokenData,
address: address.toLowerCase(),
}))
.filter((tokenData) => Boolean(tokenData.erc20)),
);
2020-10-06 20:28:38 +02:00
2020-11-03 00:41:28 +01:00
export function getRenderableTokenData(
token,
contractExchangeRates,
conversionRate,
currentCurrency,
chainId,
2020-11-03 00:41:28 +01:00
) {
const { symbol, name, address, iconUrl, string, balance, decimals } = token;
2020-10-06 20:28:38 +02:00
2020-11-03 00:41:28 +01:00
const formattedFiat =
getTokenFiatAmount(
isSwapsDefaultTokenSymbol(symbol, chainId)
? 1
: contractExchangeRates[address],
2020-11-03 00:41:28 +01:00
conversionRate,
currentCurrency,
string,
symbol,
true,
) || '';
2020-11-03 00:41:28 +01:00
const rawFiat =
getTokenFiatAmount(
isSwapsDefaultTokenSymbol(symbol, chainId)
? 1
: contractExchangeRates[address],
2020-11-03 00:41:28 +01:00
conversionRate,
currentCurrency,
string,
symbol,
false,
) || '';
2020-11-03 00:41:28 +01:00
const usedIconUrl =
iconUrl ||
2021-05-17 23:19:39 +02:00
(contractMap[toChecksumHexAddress(address)] &&
`images/contract/${contractMap[toChecksumHexAddress(address)].logo}`);
2020-10-06 20:28:38 +02:00
return {
...token,
primaryLabel: symbol,
2021-05-17 23:19:39 +02:00
secondaryLabel: name || contractMap[toChecksumHexAddress(address)]?.name,
2020-11-03 00:41:28 +01:00
rightPrimaryLabel:
string && `${new BigNumber(string).round(6).toString()} ${symbol}`,
2020-10-06 20:28:38 +02:00
rightSecondaryLabel: formattedFiat,
iconUrl: usedIconUrl,
identiconAddress: usedIconUrl ? null : address,
balance,
decimals,
2021-05-17 23:19:39 +02:00
name: name || contractMap[toChecksumHexAddress(address)]?.name,
2020-10-06 20:28:38 +02:00
rawFiat,
};
2020-10-06 20:28:38 +02:00
}
export function useTokensToSearch({ usersTokens = [], topTokens = {} }) {
const chainId = useSelector(getCurrentChainId);
const tokenConversionRates = useSelector(getTokenExchangeRates, isEqual);
const conversionRate = useSelector(getConversionRate);
const currentCurrency = useSelector(getCurrentCurrency);
const defaultSwapsToken = useSelector(getSwapsDefaultToken);
2020-10-06 20:28:38 +02:00
const memoizedTopTokens = useEqualityCheck(topTokens);
const memoizedUsersToken = useEqualityCheck(usersTokens);
2020-10-06 20:28:38 +02:00
const defaultToken = getRenderableTokenData(
defaultSwapsToken,
2020-10-06 20:28:38 +02:00
tokenConversionRates,
conversionRate,
currentCurrency,
chainId,
);
const memoizedDefaultToken = useEqualityCheck(defaultToken);
2020-10-06 20:28:38 +02:00
const swapsTokens = useSelector(getSwapsTokens) || [];
const tokensToSearch = swapsTokens.length
? swapsTokens
: [
memoizedDefaultToken,
...tokenList.filter(
(token) => token.symbol !== memoizedDefaultToken.symbol,
),
];
const memoizedTokensToSearch = useEqualityCheck(tokensToSearch);
2020-10-06 20:28:38 +02:00
return useMemo(() => {
2020-11-03 00:41:28 +01:00
const usersTokensAddressMap = memoizedUsersToken.reduce(
(acc, token) => ({ ...acc, [token.address]: token }),
{},
);
2020-10-06 20:28:38 +02:00
const tokensToSearchBuckets = {
owned: [],
2020-10-06 20:28:38 +02:00
top: [],
others: [],
};
2020-10-06 20:28:38 +02:00
const memoizedSwapsAndUserTokensWithoutDuplicities = uniqBy(
[...memoizedTokensToSearch, ...memoizedUsersToken],
'address',
);
memoizedSwapsAndUserTokensWithoutDuplicities.forEach((token) => {
2020-11-03 00:41:28 +01:00
const renderableDataToken = getRenderableTokenData(
{ ...usersTokensAddressMap[token.address], ...token },
tokenConversionRates,
conversionRate,
currentCurrency,
chainId,
);
2020-11-03 00:41:28 +01:00
if (
isSwapsDefaultTokenSymbol(renderableDataToken.symbol, chainId) ||
usersTokensAddressMap[token.address]
2020-11-03 00:41:28 +01:00
) {
tokensToSearchBuckets.owned.push(renderableDataToken);
2020-10-06 20:28:38 +02:00
} else if (memoizedTopTokens[token.address]) {
2020-11-03 00:41:28 +01:00
tokensToSearchBuckets.top[
memoizedTopTokens[token.address].index
] = renderableDataToken;
2020-10-06 20:28:38 +02:00
} else {
tokensToSearchBuckets.others.push(renderableDataToken);
2020-10-06 20:28:38 +02:00
}
});
2020-10-06 20:28:38 +02:00
2020-11-03 00:41:28 +01:00
tokensToSearchBuckets.owned = tokensToSearchBuckets.owned.sort(
({ rawFiat }, { rawFiat: secondRawFiat }) => {
return new BigNumber(rawFiat || 0).gt(secondRawFiat || 0) ? -1 : 1;
2020-11-03 00:41:28 +01:00
},
);
tokensToSearchBuckets.top = tokensToSearchBuckets.top.filter(Boolean);
2020-10-06 20:28:38 +02:00
return [
...tokensToSearchBuckets.owned,
...tokensToSearchBuckets.top,
...tokensToSearchBuckets.others,
];
2020-11-03 00:41:28 +01:00
}, [
memoizedTokensToSearch,
memoizedUsersToken,
tokenConversionRates,
conversionRate,
currentCurrency,
memoizedTopTokens,
chainId,
]);
2020-10-06 20:28:38 +02:00
}