import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import copyToClipboard from 'copy-to-clipboard'; import { getBlockExplorerLink } from '@metamask/etherscan-link'; import SenderToRecipient from '../../ui/sender-to-recipient'; import { DEFAULT_VARIANT } from '../../ui/sender-to-recipient/sender-to-recipient.constants'; import Disclosure from '../../ui/disclosure'; import TransactionActivityLog from '../transaction-activity-log'; import TransactionBreakdown from '../transaction-breakdown'; import Button from '../../ui/button'; import Tooltip from '../../ui/tooltip'; import CancelButton from '../cancel-button'; import Popover from '../../ui/popover'; ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) import Box from '../../ui/box/box'; import { Icon, IconName, Text } from '../../component-library'; import { IconColor } from '../../../helpers/constants/design-system'; ///: END:ONLY_INCLUDE_IN import { SECOND } from '../../../../shared/constants/time'; import { MetaMetricsEventCategory } from '../../../../shared/constants/metametrics'; import { TransactionType } from '../../../../shared/constants/transaction'; import { getURLHostName } from '../../../helpers/utils/util'; import TransactionDecoding from '../transaction-decoding'; import { NETWORKS_ROUTE } from '../../../helpers/constants/routes'; export default class TransactionListItemDetails extends PureComponent { static contextTypes = { t: PropTypes.func, trackEvent: PropTypes.func, }; static defaultProps = { recipientEns: null, }; static propTypes = { onCancel: PropTypes.func, onRetry: PropTypes.func, showCancel: PropTypes.bool, showSpeedUp: PropTypes.bool, showRetry: PropTypes.bool, isEarliestNonce: PropTypes.bool, primaryCurrency: PropTypes.string, transactionGroup: PropTypes.object, title: PropTypes.string.isRequired, onClose: PropTypes.func.isRequired, recipientEns: PropTypes.string, recipientAddress: PropTypes.string, recipientName: PropTypes.string, recipientMetadataName: PropTypes.string, rpcPrefs: PropTypes.object, senderAddress: PropTypes.string.isRequired, tryReverseResolveAddress: PropTypes.func.isRequired, senderNickname: PropTypes.string.isRequired, recipientNickname: PropTypes.string, transactionStatus: PropTypes.func, isCustomNetwork: PropTypes.bool, history: PropTypes.object, blockExplorerLinkText: PropTypes.object, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) getCustodianTransactionDeepLink: PropTypes.func, selectedIdentity: PropTypes.object, transactionNote: PropTypes.string, ///: END:ONLY_INCLUDE_IN }; state = { justCopied: false, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) custodyTransactionDeepLink: null, ///: END:ONLY_INCLUDE_IN }; handleBlockExplorerClick = () => { const { transactionGroup: { primaryTransaction }, rpcPrefs, isCustomNetwork, history, onClose, } = this.props; const blockExplorerLink = getBlockExplorerLink( primaryTransaction, rpcPrefs, ); if (!rpcPrefs.blockExplorerUrl && isCustomNetwork) { onClose(); history.push(`${NETWORKS_ROUTE}#blockExplorerUrl`); } else { this.context.trackEvent({ category: MetaMetricsEventCategory.Transactions, event: 'Clicked Block Explorer Link', properties: { link_type: 'Transaction Block Explorer', action: 'Transaction Details', block_explorer_domain: getURLHostName(blockExplorerLink), }, }); global.platform.openTab({ url: blockExplorerLink, }); } }; handleCancel = (event) => { const { onCancel, onClose } = this.props; onCancel(event); onClose(); }; handleRetry = (event) => { const { onClose, onRetry } = this.props; onRetry(event); onClose(); }; handleCopyTxId = () => { const { transactionGroup } = this.props; const { primaryTransaction: transaction } = transactionGroup; const { hash } = transaction; this.context.trackEvent({ category: MetaMetricsEventCategory.Navigation, event: 'Copied Transaction ID', properties: { action: 'Activity Log', legacy_event: true, }, }); this.setState({ justCopied: true }, () => { copyToClipboard(hash); setTimeout(() => this.setState({ justCopied: false }), SECOND); }); }; componentDidMount() { const { recipientAddress, tryReverseResolveAddress, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) selectedIdentity, transactionGroup, ///: END:ONLY_INCLUDE_IN } = this.props; ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) this._mounted = true; const address = selectedIdentity?.address; const custodyId = transactionGroup?.primaryTransaction?.custodyId; if (this._mounted && address && custodyId) { this.getCustodianTransactionDeepLink(address, custodyId); } ///: END:ONLY_INCLUDE_IN if (recipientAddress) { tryReverseResolveAddress(recipientAddress); } } ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) getCustodianTransactionDeepLink = async (address, custodyId) => { const { getCustodianTransactionDeepLink } = this.props; const custodyTransactionDeepLink = await getCustodianTransactionDeepLink( address, custodyId, ); if (custodyTransactionDeepLink && this._mounted) { this.setState({ custodyTransactionDeepLink }); } }; componentWillUnmount() { this._mounted = false; } ///: END:ONLY_INCLUDE_IN render() { const { t } = this.context; const { justCopied, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) custodyTransactionDeepLink, ///: END:ONLY_INCLUDE_IN } = this.state; const { transactionGroup, primaryCurrency, showSpeedUp, showRetry, recipientEns, recipientAddress, recipientName, recipientMetadataName, senderAddress, isEarliestNonce, senderNickname, title, onClose, recipientNickname, showCancel, transactionStatus: TransactionStatus, blockExplorerLinkText, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) transactionNote, ///: END:ONLY_INCLUDE_IN } = this.props; const { primaryTransaction: transaction, initialTransaction: { type }, } = transactionGroup; const { hash } = transaction; return (
{showSpeedUp && ( )} {showCancel && ( )} {showRetry && ( )}
{t('status')}
{ ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) custodyTransactionDeepLink && custodyTransactionDeepLink.url && ( ) ///: END:ONLY_INCLUDE_IN }
{t('from')}
{t('to')}
{ this.context.trackEvent({ category: MetaMetricsEventCategory.Navigation, event: 'Copied "To" Address', properties: { action: 'Activity Log', legacy_event: true, }, }); }} onSenderClick={() => { this.context.trackEvent({ category: MetaMetricsEventCategory.Navigation, event: 'Copied "From" Address', properties: { action: 'Activity Log', legacy_event: true, }, }); }} />
{ ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) transactionNote && transactionNote.length !== 0 && ( {t('transactionNote')} {transactionNote} ) ///: END:ONLY_INCLUDE_IN } {transactionGroup.initialTransaction.type !== TransactionType.incoming && ( )} {transactionGroup.initialTransaction?.txParams?.data ? ( ) : null}
); } }