1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Fix #18199 : Add fallbacks for confirmation title on NFT transfers (#18269)

* add fallbacks for confirmation title on nft transfers

* Add token name and id

* fix

* fix test

---------

Co-authored-by: David Walsh <davidwalsh83@gmail.com>
This commit is contained in:
Alex Donesky 2023-03-30 11:37:29 -05:00 committed by GitHub
parent 9f89d71c6f
commit da06901f79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 10 deletions

View File

@ -1,4 +1,5 @@
import React from 'react'; import React from 'react';
import { hexToDecimal } from '../../../../shared/modules/conversion.utils';
import mockState from '../../../../test/data/mock-state.json'; import mockState from '../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../test/lib/render-helpers'; import { renderWithProvider } from '../../../../test/lib/render-helpers';
@ -45,7 +46,9 @@ describe('ConfirmSubTitle', () => {
mockState.metamask.preferences.showFiatInTestnets = false; mockState.metamask.preferences.showFiatInTestnets = false;
mockState.metamask.allNftContracts = { mockState.metamask.allNftContracts = {
[mockState.metamask.selectedAddress]: { [mockState.metamask.selectedAddress]: {
[mockState.metamask.provider.chainId]: [{ address: '0x9' }], [hexToDecimal(mockState.metamask.provider.chainId)]: [
{ address: '0x9' },
],
}, },
}; };
store = configureStore(mockState); store = configureStore(mockState);

View File

@ -1,4 +1,5 @@
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { hexToDecimal } from '../../shared/modules/conversion.utils';
import { isEqualCaseInsensitive } from '../../shared/modules/string-utils'; import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
@ -10,9 +11,11 @@ export const useTransactionInfo = (txData = {}) => {
} = useSelector((state) => state.metamask); } = useSelector((state) => state.metamask);
const isNftTransfer = Boolean( const isNftTransfer = Boolean(
allNftContracts?.[selectedAddress]?.[chainId]?.find((contract) => { allNftContracts?.[selectedAddress]?.[hexToDecimal(chainId)]?.find(
(contract) => {
return isEqualCaseInsensitive(contract.address, txData.txParams.to); return isEqualCaseInsensitive(contract.address, txData.txParams.to);
}), },
),
); );
return { isNftTransfer }; return { isNftTransfer };

View File

@ -1,4 +1,5 @@
import { renderHookWithProvider } from '../../test/lib/render-helpers'; import { renderHookWithProvider } from '../../test/lib/render-helpers';
import { hexToDecimal } from '../../shared/modules/conversion.utils';
import mockState from '../../test/data/mock-state.json'; import mockState from '../../test/data/mock-state.json';
import { useTransactionInfo } from './useTransactionInfo'; import { useTransactionInfo } from './useTransactionInfo';
@ -17,7 +18,9 @@ describe('useTransactionInfo', () => {
it('should return true if transaction is NFT transfer', () => { it('should return true if transaction is NFT transfer', () => {
mockState.metamask.allNftContracts = { mockState.metamask.allNftContracts = {
[mockState.metamask.selectedAddress]: { [mockState.metamask.selectedAddress]: {
[mockState.metamask.provider.chainId]: [{ address: '0x9' }], [hexToDecimal(mockState.metamask.provider.chainId)]: [
{ address: '0x9' },
],
}, },
}; };

View File

@ -2,6 +2,7 @@ import React, { useContext, useMemo } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { getTokenTrackerLink } from '@metamask/etherscan-link';
import { I18nContext } from '../../contexts/i18n'; import { I18nContext } from '../../contexts/i18n';
import ConfirmTransactionBase from '../confirm-transaction-base'; import ConfirmTransactionBase from '../confirm-transaction-base';
import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display'; import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display';
@ -14,11 +15,15 @@ import {
import { PRIMARY } from '../../helpers/constants/common'; import { PRIMARY } from '../../helpers/constants/common';
import { import {
contractExchangeRateSelector, contractExchangeRateSelector,
getCurrentChainId,
getCurrentCurrency, getCurrentCurrency,
getRpcPrefsForCurrentProvider,
getSelectedAddress,
} from '../../selectors'; } from '../../selectors';
import { import {
getConversionRate, getConversionRate,
getNativeCurrency, getNativeCurrency,
getNftContracts,
} from '../../ducks/metamask/metamask'; } from '../../ducks/metamask/metamask';
import { TokenStandard } from '../../../shared/constants/transaction'; import { TokenStandard } from '../../../shared/constants/transaction';
import { import {
@ -26,6 +31,7 @@ import {
hexWEIToDecETH, hexWEIToDecETH,
} from '../../../shared/modules/conversion.utils'; } from '../../../shared/modules/conversion.utils';
import { EtherDenomination } from '../../../shared/constants/common'; import { EtherDenomination } from '../../../shared/constants/common';
import { CHAIN_IDS, TEST_CHAINS } from '../../../shared/constants/network';
export default function ConfirmTokenTransactionBase({ export default function ConfirmTokenTransactionBase({
image = '', image = '',
@ -46,18 +52,78 @@ export default function ConfirmTokenTransactionBase({
const nativeCurrency = useSelector(getNativeCurrency); const nativeCurrency = useSelector(getNativeCurrency);
const currentCurrency = useSelector(getCurrentCurrency); const currentCurrency = useSelector(getCurrentCurrency);
const conversionRate = useSelector(getConversionRate); const conversionRate = useSelector(getConversionRate);
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider);
const chainId = useSelector(getCurrentChainId);
const userAddress = useSelector(getSelectedAddress);
const nftCollections = useSelector(getNftContracts);
const ethTransactionTotalMaxAmount = Number( const ethTransactionTotalMaxAmount = Number(
hexWEIToDecETH(hexMaximumTransactionFee), 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 = (
<>
<a
href={blockExplorerLink}
target="_blank"
rel="noopener noreferrer"
title={tokenAddress}
className="confirm-approve-content__approval-asset-link"
>
{titleTokenDescription}
</a>
</>
);
return blockExplorerElement;
}
return (
<>
<span
className="confirm-approve-content__approval-asset-title"
title={tokenAddress}
>
{titleTokenDescription}
</span>
</>
);
};
const assetImage = image;
let title, subtitle, subtotalDisplay;
if ( if (
assetStandard === TokenStandard.ERC721 || assetStandard === TokenStandard.ERC721 ||
assetStandard === TokenStandard.ERC1155 assetStandard === TokenStandard.ERC1155
) { ) {
title = assetName; title = assetName || getTitleTokenDescription();
subtitle = `#${tokenId}`; subtitle = `#${tokenId}`;
subtotalDisplay =
assetName || `${getTitleTokenDescription('text')} #${tokenId}`;
} else if (assetStandard === TokenStandard.ERC20) { } else if (assetStandard === TokenStandard.ERC20) {
title = `${tokenAmount} ${tokenSymbol}`; title = `${tokenAmount} ${tokenSymbol}`;
} }
@ -122,13 +188,13 @@ export default function ConfirmTokenTransactionBase({
return ( return (
<ConfirmTransactionBase <ConfirmTransactionBase
toAddress={toAddress} toAddress={toAddress}
image={image} image={assetImage}
onEdit={onEdit} onEdit={onEdit}
tokenAddress={tokenAddress} tokenAddress={tokenAddress}
title={title} title={title}
subtitleComponent={subtitleComponent()} subtitleComponent={subtitleComponent()}
primaryTotalTextOverride={`${title} + ${ethTransactionTotal} ${nativeCurrency}`} primaryTotalTextOverride={`${subtotalDisplay} + ${ethTransactionTotal} ${nativeCurrency}`}
primaryTotalTextOverrideMaxAmount={`${title} + ${ethTransactionTotalMaxAmount} ${nativeCurrency}`} primaryTotalTextOverrideMaxAmount={`${subtotalDisplay} + ${ethTransactionTotalMaxAmount} ${nativeCurrency}`}
secondaryTotalTextOverride={secondaryTotalTextOverride} secondaryTotalTextOverride={secondaryTotalTextOverride}
/> />
); );