import React, { useCallback, useContext, useState } from 'react'; import PropTypes from 'prop-types'; import { useSelector, useDispatch } from 'react-redux'; import { useHistory } from 'react-router-dom'; import log from 'loglevel'; import { isValidSIWEOrigin } from '@metamask/controller-utils'; import { ethErrors, serializeError } from 'eth-rpc-errors'; import { BannerAlert, Text } from '../../component-library'; import Popover from '../../ui/popover'; import Checkbox from '../../ui/check-box'; import Button from '../../ui/button'; import { I18nContext } from '../../../contexts/i18n'; import { PageContainerFooter } from '../../ui/page-container'; import { isAddressLedger } from '../../../ducks/metamask/metamask'; import { accountsWithSendEtherInfoSelector, getSubjectMetadata, getTotalUnapprovedMessagesCount, unconfirmedMessagesHashSelector, } from '../../../selectors'; import { getAccountByAddress, valuesFor } from '../../../helpers/utils/util'; import { isSuspiciousResponse } from '../../../../shared/modules/security-provider.utils'; import { formatMessageParams } from '../../../../shared/modules/siwe'; import { clearConfirmTransaction } from '../../../ducks/confirm-transaction/confirm-transaction.duck'; import { SEVERITIES, TextVariant, } from '../../../helpers/constants/design-system'; import { resolvePendingApproval, rejectPendingApproval, rejectAllMessages, completedTx, showModal, } from '../../../store/actions'; import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message'; import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation'; import { getMostRecentOverviewPage } from '../../../ducks/history/history'; ///: BEGIN:ONLY_INCLUDE_IN(blockaid) import BlockaidBannerAlert from '../security-provider-banner-alert/blockaid-banner-alert/blockaid-banner-alert'; ///: END:ONLY_INCLUDE_IN import LedgerInstructionField from '../ledger-instruction-field'; import SignatureRequestHeader from '../signature-request-header'; import Header from './signature-request-siwe-header'; import Message from './signature-request-siwe-message'; export default function SignatureRequestSIWE({ txData }) { const dispatch = useDispatch(); const history = useHistory(); const t = useContext(I18nContext); const allAccounts = useSelector(accountsWithSendEtherInfoSelector); const subjectMetadata = useSelector(getSubjectMetadata); const messagesCount = useSelector(getTotalUnapprovedMessagesCount); const messagesList = useSelector(unconfirmedMessagesHashSelector); const mostRecentOverviewPage = useSelector(getMostRecentOverviewPage); const { msgParams: { from, origin, siwe: { parsedMessage }, }, id, } = txData; const isLedgerWallet = useSelector((state) => isAddressLedger(state, from)); const fromAccount = getAccountByAddress(allAccounts, from); const targetSubjectMetadata = subjectMetadata[origin]; const isMatchingAddress = from.toLowerCase() === parsedMessage.address.toLowerCase(); const isSIWEDomainValid = isValidSIWEOrigin(txData.msgParams); const [isShowingDomainWarning, setIsShowingDomainWarning] = useState(false); const [hasAgreedToDomainWarning, setHasAgreedToDomainWarning] = useState(false); const showSecurityProviderBanner = isSuspiciousResponse( txData?.securityProviderResponse, ); const onSign = useCallback(async () => { try { await dispatch(resolvePendingApproval(id, null)); dispatch(completedTx(id)); } catch (e) { log.error(e); } }, [id, dispatch]); const onCancel = useCallback(async () => { try { await dispatch( rejectPendingApproval( id, serializeError(ethErrors.provider.userRejectedRequest()), ), ); } catch (e) { log.error(e); } }, []); const handleCancelAll = () => { const unapprovedTxCount = messagesCount; dispatch( showModal({ name: 'REJECT_TRANSACTIONS', unapprovedTxCount, onSubmit: async () => { await dispatch(rejectAllMessages(valuesFor(messagesList))); dispatch(clearConfirmTransaction()); history.push(mostRecentOverviewPage); }, }), ); }; const rejectNText = t('rejectRequestsN', [messagesCount]); return (
{ ///: BEGIN:ONLY_INCLUDE_IN(blockaid) ///: END:ONLY_INCLUDE_IN } {showSecurityProviderBanner && ( )}
{!isMatchingAddress && ( {t('SIWEAddressInvalid', [ parsedMessage.address, fromAccount.address, ])} )} {isLedgerWallet && (
)} {!isSIWEDomainValid && ( {t('SIWEDomainInvalidTitle')} {' '} {t('SIWEDomainInvalidText')} )} setIsShowingDomainWarning(true) } cancelText={t('cancel')} submitText={t('signin')} submitButtonType={isSIWEDomainValid ? 'primary' : 'danger-primary'} /> {messagesCount > 1 ? ( ) : null} {isShowingDomainWarning && ( setIsShowingDomainWarning(false)} title={t('SIWEWarningTitle')} subtitle={t('SIWEWarningSubtitle')} className="signature-request-siwe__warning-popover" footerClassName="signature-request-siwe__warning-popover__footer" footer={ setIsShowingDomainWarning(false)} cancelText={t('cancel')} cancelButtonType="default" onSubmit={onSign} submitText={t('confirm')} submitButtonType="danger-primary" disabled={!hasAgreedToDomainWarning} /> } >
setHasAgreedToDomainWarning((checked) => !checked)} />
)}
); } SignatureRequestSIWE.propTypes = { /** * The display content of transaction data */ txData: PropTypes.object.isRequired, };