1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-27 12:56:01 +01:00
metamask-extension/ui/app/hooks/useTokensToSearch.js
MetaMask Bot 14b5c389ed
Version v9.3.0 RC (#10739)
* Replace logic for eth swap token in fetchQuotesAndSetQuoteState with getSwapsEthToken call (#10624)

* Move swaps constants to the shared constants directory (#10614)

* Fix: ETH 'token' now only appears once in the swaps to and from dropdowns. (#10650)

* Swaps support for local testnet (#10658)

* Swaps support for local testnet

* Create util method for comparison of token addresses/symbols to default swaps token

* Get chainId from txMeta in _trackSwapsMetrics of transaction controller

* Add comment to document purpose of getTransactionGroupRecipientAddressFilter

* Use isSwapsDefaultTokenSymbol in place of repeated defaultTokenSymbol comparisons in build-quote.js

* Additional swaps network support (#10721)

* Add swaps support for bnc chain

* Use single default token address in shared/constants/swaps

* Ensure swaps gas prices are fetched from the correct chain specific endpoint (#10744)

* Ensure swaps gas prices are fetched from the correct chain specific endpoint

* Just rely on fetchWithCache to cache swaps gas prices, instead of directly using storage in getSwapsPriceEstimatesLastRetrieved

* Empty commit

* update @metamask/etherscan-link to v2.0.0 (#10747)

* Use correct block explorer name and link in swaps when on custom network (#10743)

* Use correct block explorer name and link in swaps when on custom network.

* Fix up custom etherscan link code in build-quote.js

* Use blockExplorerUrl hostname instead of 'blockExplorerBaseUrl'

* Use correct etherscan-link method for token links in build-quote

* Create correct token link in build-quote for mainnet AND custom networks

* Block explorer url improvements in awaiting-swap.js and build-quote.js

* Use swapVerifyTokenExplanation message with substitutable block explorer for all applicable locales

* Ensure that block explorer links are not shown in awaiting-swap if no url is available

* Ensure that the correct default currency symbols are used for fees on the view quote screen (#10753)

* Updating y18n and netmask to resolve dependency issues (#10765)

netmask@1.0.6 -> 2.0.1, y18n@3.2.1 -> 3.2.2, y18n@4.0.0 -> 4.0.1

* Ensure that priceSlippage fiat amounts are always shown in view-quote.js (#10762)

* Ensure that the approval fee in the swaps custom gas modal is in network specific currency (#10763)

* Use network specific swaps contract address when checking swap contract token approval (#10774)

* Set the BSC_CONTRACT_ADDRESS to lowercase (#10800)

* Ensure correct primary currency image is displayed on home screen and token list (#10777)

* [skip e2e] Update changelog for v9.3.0 (#10740)

* Version v9.3.0

* [skip e2e] Update changelog for v9.3.0 (#10803)

Co-authored-by: Dan J Miller <danjm.com@gmail.com>
Co-authored-by: ryanml <ryanlanese@gmail.com>
Co-authored-by: David Walsh <davidwalsh83@gmail.com>
Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
2021-04-02 17:00:57 -02:30

166 lines
4.8 KiB
JavaScript

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