Skip to content

Commit

Permalink
refactor: use new multichain selectors in accounts related components (
Browse files Browse the repository at this point in the history
…#25290)

## **Description**

This is first work of migrating some components to use the new
`multichain` selectors that have been introduced for non-EVM support
within the extension.

None regression is expected with the introduction of those selectors.

Having a pre-PR would make future non-EVM related PRs much simpler to
review too.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/25290?quickstart=1)

## **Related issues**

Fixes:

## **Manual testing steps**

> Mostly relying on unit and e2e tests here, since there is no new
feature

1. `yarn start:flask`
2. Use the extension as usual

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.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: Gustavo Antunes <[email protected]>
  • Loading branch information
ccharly and gantunesr authored Jun 14, 2024
1 parent 8539477 commit b7d7a34
Show file tree
Hide file tree
Showing 15 changed files with 349 additions and 157 deletions.
31 changes: 17 additions & 14 deletions ui/components/app/asset-list/asset-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency';
import {
getSelectedAccountCachedBalance,
getShouldShowFiat,
getNativeCurrencyImage,
getDetectedTokensInCurrentNetwork,
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
getShouldHideZeroBalanceTokens,
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
getIsBuyableChain,
///: END:ONLY_INCLUDE_IF
getCurrentNetwork,
getSelectedAccount,
getPreferences,
getIsMainnet,
} from '../../../selectors';
import {
getNativeCurrency,
getProviderConfig,
} from '../../../ducks/metamask/metamask';
getMultichainCurrentNetwork,
getMultichainNativeCurrency,
getMultichainIsEvm,
getMultichainShouldShowFiat,
getMultichainCurrencyImage,
getMultichainIsMainnet,
} from '../../../selectors/multichain';
import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay';
import { MetaMetricsContext } from '../../../contexts/metametrics';
import {
Expand Down Expand Up @@ -53,12 +53,13 @@ import {
const AssetList = ({ onClickAsset }) => {
const [showDetectedTokens, setShowDetectedTokens] = useState(false);
const selectedAccountBalance = useSelector(getSelectedAccountCachedBalance);
const nativeCurrency = useSelector(getNativeCurrency);
const showFiat = useSelector(getShouldShowFiat);
const { chainId } = useSelector(getCurrentNetwork);
const isMainnet = useSelector(getIsMainnet);
const nativeCurrency = useSelector(getMultichainNativeCurrency);
const showFiat = useSelector(getMultichainShouldShowFiat);
const isMainnet = useSelector(getMultichainIsMainnet);
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
const { ticker, type, rpcUrl } = useSelector(getProviderConfig);
const { chainId, ticker, type, rpcUrl } = useSelector(
getMultichainCurrentNetwork,
);
const isOriginalNativeSymbol = useIsOriginalNativeTokenSymbol(
chainId,
ticker,
Expand Down Expand Up @@ -94,7 +95,7 @@ const AssetList = ({ onClickAsset }) => {
currency: secondaryCurrency,
});

const primaryTokenImage = useSelector(getNativeCurrencyImage);
const primaryTokenImage = useSelector(getMultichainCurrencyImage);
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork) || [];
const isTokenDetectionInactiveOnNonMainnetSupportedNetwork = useSelector(
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
Expand All @@ -112,7 +113,9 @@ const AssetList = ({ onClickAsset }) => {
const shouldShowBuy = isBuyableChain && balanceIsZero;
///: END:ONLY_INCLUDE_IF

let isStakeable = isMainnet;
const isEvm = useSelector(getMultichainIsEvm);

let isStakeable = isMainnet && isEvm;
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
isStakeable = false;
///: END:ONLY_INCLUDE_IF
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import { EtherDenomination } from '../../../../shared/constants/common';
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
import CurrencyDisplay from '../../ui/currency-display';
import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency';
import { AvatarNetwork, AvatarNetworkSize } from '../../component-library';
import { getCurrentNetwork } from '../../../selectors';
import { getNativeCurrency } from '../../../ducks/metamask/metamask';
import {
getMultichainNativeCurrency,
getMultichainCurrentNetwork,
} from '../../../selectors/multichain';

/* eslint-disable jsdoc/require-param-name */
// eslint-disable-next-line jsdoc/require-param
Expand All @@ -24,8 +26,8 @@ export default function UserPreferencedCurrencyDisplay({
showCurrencySuffix,
...restProps
}) {
const currentNetwork = useSelector(getCurrentNetwork);
const nativeCurrency = useSelector(getNativeCurrency);
const currentNetwork = useSelector(getMultichainCurrentNetwork);
const nativeCurrency = useSelector(getMultichainNativeCurrency);
const { currency, numberOfDecimals } = useUserPreferencedCurrency(type, {
ethNumberOfDecimals,
fiatNumberOfDecimals,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const AvatarNetwork: AvatarNetworkComponent = React.forwardRef(
}
onError={handleOnError}
src={src}
alt={`${name} logo` || 'network logo'}
alt={(name && `${name} logo`) || 'network logo'}
/>
</>
)}
Expand Down
11 changes: 8 additions & 3 deletions ui/components/multichain/ramps-card/ramps-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import {
TextVariant,
} from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { getCurrentNetwork, getSwapsDefaultToken } from '../../../selectors';
import {
getMultichainDefaultToken,
getMultichainCurrentNetwork,
} from '../../../selectors/multichain';
import {
MetaMetricsEventCategory,
MetaMetricsEventName,
Expand Down Expand Up @@ -68,14 +71,15 @@ export const RampsCard = ({ variant }) => {
const { openBuyCryptoInPdapp } = useRamps(metamaskEntryMap[variant]);
const trackEvent = useContext(MetaMetricsContext);
const currentLocale = useSelector(getCurrentLocale);
const { chainId, nickname } = useSelector(getCurrentNetwork);
const { symbol = 'ETH' } = useSelector(getSwapsDefaultToken);
const { chainId, nickname } = useSelector(getMultichainCurrentNetwork);
const { symbol } = useSelector(getMultichainDefaultToken);

useEffect(() => {
trackEvent({
event: MetaMetricsEventName.EmptyBuyBannerDisplayed,
category: MetaMetricsEventCategory.Navigation,
properties: {
// FIXME: This might not be a number for non-EVM networks
chain_id: chainId,
locale: currentLocale,
network: nickname,
Expand All @@ -92,6 +96,7 @@ export const RampsCard = ({ variant }) => {
properties: {
location: `${variant} tab`,
text: `Buy ${symbol}`,
// FIXME: This might not be a number for non-EVM networks
chain_id: chainId,
token_symbol: symbol,
},
Expand Down
4 changes: 2 additions & 2 deletions ui/components/multichain/token-list-item/token-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ import { ModalContent } from '../../component-library/modal-content/deprecated';
import { ModalHeader } from '../../component-library/modal-header/deprecated';
import {
getCurrentChainId,
getCurrentNetwork,
getMetaMetricsId,
getNativeCurrencyImage,
getPreferences,
getTestNetworkBackgroundColor,
} from '../../../selectors';
import { getMultichainCurrentNetwork } from '../../../selectors/multichain';
import Tooltip from '../../ui/tooltip';
import { useI18nContext } from '../../../hooks/useI18nContext';
import { MetaMetricsContext } from '../../../contexts/metametrics';
Expand Down Expand Up @@ -132,7 +132,7 @@ export const TokenListItem = ({
</Box>
);
// Used for badge icon
const currentNetwork = useSelector(getCurrentNetwork);
const currentNetwork = useSelector(getMultichainCurrentNetwork);
const testNetworkBackgroundColor = useSelector(getTestNetworkBackgroundColor);

return (
Expand Down
72 changes: 42 additions & 30 deletions ui/hooks/useCurrencyDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { useMemo } from 'react';
import { useSelector } from 'react-redux';
import BigNumber from 'bignumber.js';
import { formatCurrency } from '../helpers/utils/confirm-tx.util';
import { getCurrentCurrency } from '../selectors';
import {
getConversionRate,
getNativeCurrency,
} from '../ducks/metamask/metamask';
getMultichainCurrentCurrency,
getMultichainIsEvm,
getMultichainNativeCurrency,
} from '../selectors/multichain';
import { getConversionRate } from '../ducks/metamask/metamask';

import { getValueFromWeiHex } from '../../shared/modules/conversion.utils';
import { TEST_NETWORK_TICKER_MAP } from '../../shared/constants/network';
Expand Down Expand Up @@ -60,40 +61,51 @@ export function useCurrencyDisplay(
inputValue,
{ displayValue, prefix, numberOfDecimals, denomination, currency, ...opts },
) {
const currentCurrency = useSelector(getCurrentCurrency);
const nativeCurrency = useSelector(getNativeCurrency);
const isEvm = useSelector(getMultichainIsEvm);
const currentCurrency = useSelector(getMultichainCurrentCurrency);
const nativeCurrency = useSelector(getMultichainNativeCurrency);
const conversionRate = useSelector(getConversionRate);
const isUserPreferredCurrency = currency === currentCurrency;

const value = useMemo(() => {
if (displayValue) {
return displayValue;
}
if (
currency === nativeCurrency ||
(!isUserPreferredCurrency && !nativeCurrency)
) {
const ethDisplayValue = new Numeric(inputValue, 16, EtherDenomination.WEI)
.toDenomination(denomination || EtherDenomination.ETH)
.round(numberOfDecimals || DEFAULT_PRECISION)
.toBase(10)
.toString();

return ethDisplayValue === '0' && inputValue && Number(inputValue) !== 0
? MIN_AMOUNT_DISPLAY
: ethDisplayValue;
} else if (isUserPreferredCurrency && conversionRate) {
return formatCurrency(
getValueFromWeiHex({
value: inputValue,
fromCurrency: nativeCurrency,
toCurrency: currency,
conversionRate,
numberOfDecimals: numberOfDecimals || 2,
toDenomination: denomination,
}),
currency,
);
if (isEvm) {
if (
currency === nativeCurrency ||
(!isUserPreferredCurrency && !nativeCurrency)
) {
const ethDisplayValue = new Numeric(
inputValue,
16,
EtherDenomination.WEI,
)
.toDenomination(denomination || EtherDenomination.ETH)
.round(numberOfDecimals || DEFAULT_PRECISION)
.toBase(10)
.toString();

return ethDisplayValue === '0' && inputValue && Number(inputValue) !== 0
? MIN_AMOUNT_DISPLAY
: ethDisplayValue;
} else if (isUserPreferredCurrency && conversionRate) {
return formatCurrency(
getValueFromWeiHex({
value: inputValue,
fromCurrency: nativeCurrency,
toCurrency: currency,
conversionRate,
numberOfDecimals: numberOfDecimals || 2,
toDenomination: denomination,
}),
currency,
);
}
} else {
// For non-EVM we assume the input value can be formatted "as-is"
return formatCurrency(inputValue, currency);
}
return null;
}, [
Expand Down
17 changes: 15 additions & 2 deletions ui/hooks/useCurrencyDisplay.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { renderHook } from '@testing-library/react-hooks';
import * as reactRedux from 'react-redux';
import sinon from 'sinon';
import { getCurrentCurrency } from '../selectors';
import {
getMultichainCurrentCurrency,
getMultichainIsEvm,
getMultichainNativeCurrency,
} from '../selectors/multichain';
import {
getConversionRate,
getNativeCurrency,
Expand Down Expand Up @@ -128,9 +133,17 @@ describe('useCurrencyDisplay', () => {
describe(`when input is { value: ${value}, decimals: ${restProps.numberOfDecimals}, denomation: ${restProps.denomination} }`, () => {
const stub = sinon.stub(reactRedux, 'useSelector');
stub.callsFake((selector) => {
if (selector === getCurrentCurrency) {
if (selector === getMultichainIsEvm) {
return true;
} else if (
selector === getCurrentCurrency ||
selector === getMultichainCurrentCurrency
) {
return 'usd';
} else if (selector === getNativeCurrency) {
} else if (
selector === getNativeCurrency ||
selector === getMultichainNativeCurrency
) {
return 'ETH';
} else if (selector === getConversionRate) {
return 280.45;
Expand Down
25 changes: 21 additions & 4 deletions ui/hooks/useTransactionDisplayData.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import { CHAIN_IDS } from '../../shared/constants/network';
import { TransactionGroupCategory } from '../../shared/constants/transaction';
import { formatDateWithYearContext } from '../helpers/utils/util';
import { getMessage } from '../helpers/utils/i18n-helper';
import {
getMultichainCurrentCurrency,
getMultichainIsEvm,
getMultichainNativeCurrency,
getMultichainShouldShowFiat,
} from '../selectors/multichain';
import * as i18nhooks from './useI18nContext';
import * as useTokenFiatAmountHooks from './useTokenFiatAmount';
import { useTransactionDisplayData } from './useTransactionDisplayData';
Expand Down Expand Up @@ -201,7 +207,9 @@ describe('useTransactionDisplayData', () => {
getMessage('en', messages, key, variables),
);
useSelector.callsFake((selector) => {
if (selector === getTokens) {
if (selector === getMultichainIsEvm) {
return true;
} else if (selector === getTokens) {
return [
{
address: '0xabca64466f257793eaa52fcfff5066894b76a149',
Expand All @@ -213,11 +221,20 @@ describe('useTransactionDisplayData', () => {
return {
useNativeCurrencyAsPrimaryCurrency: true,
};
} else if (selector === getShouldShowFiat) {
} else if (
selector === getShouldShowFiat ||
selector === getMultichainShouldShowFiat
) {
return false;
} else if (selector === getNativeCurrency) {
} else if (
selector === getNativeCurrency ||
selector === getMultichainNativeCurrency
) {
return 'ETH';
} else if (selector === getCurrentCurrency) {
} else if (
selector === getCurrentCurrency ||
selector === getMultichainCurrentCurrency
) {
return 'ETH';
} else if (selector === getCurrentChainId) {
return CHAIN_IDS.MAINNET;
Expand Down
17 changes: 9 additions & 8 deletions ui/hooks/useUserPreferencedCurrency.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { shallowEqual, useSelector } from 'react-redux';
import { getPreferences } from '../selectors';
import {
getPreferences,
getShouldShowFiat,
getCurrentCurrency,
} from '../selectors';
import { getNativeCurrency } from '../ducks/metamask/metamask';
getMultichainNativeCurrency,
getMultichainCurrentCurrency,
getMultichainShouldShowFiat,
} from '../selectors/multichain';

import { PRIMARY, SECONDARY } from '../helpers/constants/common';
import { EtherDenomination } from '../../shared/constants/common';
Expand Down Expand Up @@ -41,13 +41,14 @@ import { ETH_DEFAULT_DECIMALS } from '../constants';
* @returns {UserPreferredCurrency}
*/
export function useUserPreferencedCurrency(type, opts = {}) {
const nativeCurrency = useSelector(getNativeCurrency);
const nativeCurrency = useSelector(getMultichainNativeCurrency);

const { useNativeCurrencyAsPrimaryCurrency } = useSelector(
getPreferences,
shallowEqual,
);
const showFiat = useSelector(getShouldShowFiat);
const currentCurrency = useSelector(getCurrentCurrency);
const showFiat = useSelector(getMultichainShouldShowFiat);
const currentCurrency = useSelector(getMultichainCurrentCurrency);

const fiatReturn = {
currency: currentCurrency,
Expand Down
Loading

0 comments on commit b7d7a34

Please sign in to comment.