import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, withRouter } from 'react-router-dom'; import log from 'loglevel'; import { cloneDeep } from 'lodash'; import { SubjectType } from '@metamask/permission-controller'; import * as actions from '../../store/actions'; import txHelper from '../../helpers/utils/tx-helper'; import SignatureRequest from '../../components/app/signature-request'; import SignatureRequestSIWE from '../../components/app/signature-request-siwe'; import SignatureRequestOriginal from '../../components/app/signature-request-original'; import Loading from '../../components/ui/loading-screen'; import { useRouting } from '../../hooks/useRouting'; import { getTotalUnapprovedSignatureRequestCount, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) getSelectedAccount, ///: END:ONLY_INCLUDE_IN getTargetSubjectMetadata, } from '../../selectors'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { TransactionStatus } from '../../../shared/constants/transaction'; import { getSendTo } from '../../ducks/send'; import { getProviderConfig } from '../../ducks/metamask/metamask'; const signatureSelect = (txData, targetSubjectMetadata) => { const { type, msgParams: { version, siwe }, } = txData; // Temporarily direct only v3 and v4 requests to new code. if ( type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA && (version === 'V3' || version === 'V4') ) { return SignatureRequest; } if (siwe?.isSIWEMessage && targetSubjectMetadata !== SubjectType.Snap) { return SignatureRequestSIWE; } return SignatureRequestOriginal; }; const ConfirmTxScreen = ({ match }) => { const dispatch = useDispatch(); const { navigateToMostRecentOverviewPage } = useRouting(); const unapprovedMessagesTotal = useSelector( getTotalUnapprovedSignatureRequestCount, ); const sendTo = useSelector(getSendTo); const { unapprovedTxs, identities, currentNetworkTxList, currentCurrency, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, networkId, blockGasLimit, } = useSelector((state) => state.metamask); const { chainId } = useSelector(getProviderConfig); const { txId: index } = useSelector((state) => state.appState); ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) const selectedAccount = useSelector(getSelectedAccount); ///: END:ONLY_INCLUDE_IN const [prevValue, setPrevValues] = useState(); const history = useHistory(); useEffect(() => { const unconfTxList = txHelper( unapprovedTxs || {}, {}, {}, {}, networkId, chainId, ); if (unconfTxList.length === 0 && !sendTo && unapprovedMessagesTotal === 0) { navigateToMostRecentOverviewPage(); } }, []); useEffect(() => { if (!prevValue) { setPrevValues({ index, unapprovedTxs }); return; } let prevTx; const { params: { id: transactionId } = {} } = match; if (transactionId) { prevTx = currentNetworkTxList.find(({ id }) => `${id}` === transactionId); } else { const { index: prevIndex, unapprovedTxs: prevUnapprovedTxs } = prevValue; const prevUnconfTxList = txHelper( prevUnapprovedTxs, {}, {}, {}, networkId, chainId, ); const prevTxData = prevUnconfTxList[prevIndex] || {}; prevTx = currentNetworkTxList.find(({ id }) => id === prevTxData.id) || {}; } const unconfTxList = txHelper( unapprovedTxs || {}, {}, {}, {}, networkId, chainId, ); if (prevTx && prevTx.status === TransactionStatus.dropped) { dispatch( actions.showModal({ name: 'TRANSACTION_CONFIRMED', onSubmit: () => navigateToMostRecentOverviewPage(), }), ); return; } if (unconfTxList.length === 0 && !sendTo && unapprovedMessagesTotal === 0) { navigateToMostRecentOverviewPage(); } setPrevValues({ index, unapprovedTxs }); }, [ chainId, currentNetworkTxList, match, networkId, sendTo, unapprovedMessagesTotal, unapprovedTxs, ]); const getTxData = () => { const { params: { id: transactionId } = {} } = match; const unconfTxList = txHelper( unapprovedTxs || {}, unapprovedMsgs, unapprovedPersonalMsgs, unapprovedTypedMessages, networkId, chainId, ); log.info(`rendering a combined ${unconfTxList.length} unconf msgs & txs`); const unconfirmedTx = transactionId ? unconfTxList.find(({ id }) => `${id}` === transactionId) : unconfTxList[index]; return cloneDeep(unconfirmedTx); }; const txData = getTxData() || {}; const { msgParams } = txData; const targetSubjectMetadata = useSelector((state) => getTargetSubjectMetadata(state, msgParams?.origin), ); if (!msgParams) { return ; } const SigComponent = signatureSelect(txData, targetSubjectMetadata); return ( ); }; ConfirmTxScreen.propTypes = { match: PropTypes.shape({ params: PropTypes.shape({ id: PropTypes.string, }), }), }; export default withRouter(ConfirmTxScreen);