diff --git a/ui/components/app/confirm-subtitle/confirm-subtitle.test.js b/ui/components/app/confirm-subtitle/confirm-subtitle.test.js index ac2662a39..41cdc3da4 100644 --- a/ui/components/app/confirm-subtitle/confirm-subtitle.test.js +++ b/ui/components/app/confirm-subtitle/confirm-subtitle.test.js @@ -1,4 +1,5 @@ import React from 'react'; +import { hexToDecimal } from '../../../../shared/modules/conversion.utils'; import mockState from '../../../../test/data/mock-state.json'; import { renderWithProvider } from '../../../../test/lib/render-helpers'; @@ -45,7 +46,9 @@ describe('ConfirmSubTitle', () => { mockState.metamask.preferences.showFiatInTestnets = false; mockState.metamask.allNftContracts = { [mockState.metamask.selectedAddress]: { - [mockState.metamask.provider.chainId]: [{ address: '0x9' }], + [hexToDecimal(mockState.metamask.provider.chainId)]: [ + { address: '0x9' }, + ], }, }; store = configureStore(mockState); diff --git a/ui/hooks/useTransactionInfo.js b/ui/hooks/useTransactionInfo.js index 245a24734..8312fe1bf 100644 --- a/ui/hooks/useTransactionInfo.js +++ b/ui/hooks/useTransactionInfo.js @@ -1,4 +1,5 @@ import { useSelector } from 'react-redux'; +import { hexToDecimal } from '../../shared/modules/conversion.utils'; import { isEqualCaseInsensitive } from '../../shared/modules/string-utils'; @@ -10,9 +11,11 @@ export const useTransactionInfo = (txData = {}) => { } = useSelector((state) => state.metamask); const isNftTransfer = Boolean( - allNftContracts?.[selectedAddress]?.[chainId]?.find((contract) => { - return isEqualCaseInsensitive(contract.address, txData.txParams.to); - }), + allNftContracts?.[selectedAddress]?.[hexToDecimal(chainId)]?.find( + (contract) => { + return isEqualCaseInsensitive(contract.address, txData.txParams.to); + }, + ), ); return { isNftTransfer }; diff --git a/ui/hooks/useTransactionInfo.test.js b/ui/hooks/useTransactionInfo.test.js index e7fa5f40a..9858185ed 100644 --- a/ui/hooks/useTransactionInfo.test.js +++ b/ui/hooks/useTransactionInfo.test.js @@ -1,4 +1,5 @@ import { renderHookWithProvider } from '../../test/lib/render-helpers'; +import { hexToDecimal } from '../../shared/modules/conversion.utils'; import mockState from '../../test/data/mock-state.json'; import { useTransactionInfo } from './useTransactionInfo'; @@ -17,7 +18,9 @@ describe('useTransactionInfo', () => { it('should return true if transaction is NFT transfer', () => { mockState.metamask.allNftContracts = { [mockState.metamask.selectedAddress]: { - [mockState.metamask.provider.chainId]: [{ address: '0x9' }], + [hexToDecimal(mockState.metamask.provider.chainId)]: [ + { address: '0x9' }, + ], }, }; diff --git a/ui/pages/confirm-token-transaction-base/confirm-token-transaction-base.js b/ui/pages/confirm-token-transaction-base/confirm-token-transaction-base.js index e81b5e061..e7f53a4db 100644 --- a/ui/pages/confirm-token-transaction-base/confirm-token-transaction-base.js +++ b/ui/pages/confirm-token-transaction-base/confirm-token-transaction-base.js @@ -2,6 +2,7 @@ import React, { useContext, useMemo } from 'react'; import PropTypes from 'prop-types'; import BigNumber from 'bignumber.js'; import { useSelector } from 'react-redux'; +import { getTokenTrackerLink } from '@metamask/etherscan-link'; import { I18nContext } from '../../contexts/i18n'; import ConfirmTransactionBase from '../confirm-transaction-base'; import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display'; @@ -14,11 +15,15 @@ import { import { PRIMARY } from '../../helpers/constants/common'; import { contractExchangeRateSelector, + getCurrentChainId, getCurrentCurrency, + getRpcPrefsForCurrentProvider, + getSelectedAddress, } from '../../selectors'; import { getConversionRate, getNativeCurrency, + getNftContracts, } from '../../ducks/metamask/metamask'; import { TokenStandard } from '../../../shared/constants/transaction'; import { @@ -26,6 +31,7 @@ import { hexWEIToDecETH, } from '../../../shared/modules/conversion.utils'; import { EtherDenomination } from '../../../shared/constants/common'; +import { CHAIN_IDS, TEST_CHAINS } from '../../../shared/constants/network'; export default function ConfirmTokenTransactionBase({ image = '', @@ -46,18 +52,78 @@ export default function ConfirmTokenTransactionBase({ const nativeCurrency = useSelector(getNativeCurrency); const currentCurrency = useSelector(getCurrentCurrency); const conversionRate = useSelector(getConversionRate); + const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider); + const chainId = useSelector(getCurrentChainId); + const userAddress = useSelector(getSelectedAddress); + const nftCollections = useSelector(getNftContracts); const ethTransactionTotalMaxAmount = Number( hexWEIToDecETH(hexMaximumTransactionFee), ); - let title, subtitle; + const getTitleTokenDescription = (renderType) => { + const useBlockExplorer = + rpcPrefs?.blockExplorerUrl || + [...TEST_CHAINS, CHAIN_IDS.MAINNET].includes(chainId); + + const nftCollection = nftCollections.find( + (collection) => + collection.address.toLowerCase() === tokenAddress.toLowerCase(), + ); + const titleTokenDescription = + tokenSymbol || nftCollection?.name || t('unknownCollection'); + + if (renderType === 'text') { + return titleTokenDescription; + } + + if (useBlockExplorer) { + const blockExplorerLink = getTokenTrackerLink( + tokenAddress, + chainId, + null, + userAddress, + { + blockExplorerUrl: rpcPrefs?.blockExplorerUrl ?? null, + }, + ); + const blockExplorerElement = ( + <> + + {titleTokenDescription} + + + ); + return blockExplorerElement; + } + return ( + <> + + {titleTokenDescription} + + + ); + }; + + const assetImage = image; + let title, subtitle, subtotalDisplay; if ( assetStandard === TokenStandard.ERC721 || assetStandard === TokenStandard.ERC1155 ) { - title = assetName; + title = assetName || getTitleTokenDescription(); subtitle = `#${tokenId}`; + subtotalDisplay = + assetName || `${getTitleTokenDescription('text')} #${tokenId}`; } else if (assetStandard === TokenStandard.ERC20) { title = `${tokenAmount} ${tokenSymbol}`; } @@ -122,13 +188,13 @@ export default function ConfirmTokenTransactionBase({ return ( );