import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { ObjectInspector } from 'react-inspector'; import LedgerInstructionField from '../ledger-instruction-field'; import { MESSAGE_TYPE } from '../../../../shared/constants/app'; import { getURLHostName, sanitizeString, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) shortenAddress, ///: END:ONLY_INCLUDE_IN } from '../../../helpers/utils/util'; import { stripHexPrefix } from '../../../../shared/modules/hexstring-utils'; import Button from '../../ui/button'; import SiteOrigin from '../../ui/site-origin'; import NetworkAccountBalanceHeader from '../network-account-balance-header'; import Typography from '../../ui/typography/typography'; import { PageContainerFooter } from '../../ui/page-container'; import { TypographyVariant, FONT_WEIGHT, TEXT_ALIGN, TextColor, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) IconColor, DISPLAY, BLOCK_SIZES, TextVariant, BackgroundColor, ///: END:ONLY_INCLUDE_IN } from '../../../helpers/constants/design-system'; import { NETWORK_TYPES } from '../../../../shared/constants/network'; import { Numeric } from '../../../../shared/modules/Numeric'; import { EtherDenomination } from '../../../../shared/constants/common'; import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation'; import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message'; import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants'; import { formatCurrency } from '../../../helpers/utils/confirm-tx.util'; import { getValueFromWeiHex } from '../../../../shared/modules/conversion.utils'; ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) import { Icon, IconName, Text } from '../../component-library'; import Box from '../../ui/box/box'; ///: END:ONLY_INCLUDE_IN import SignatureRequestOriginalWarning from './signature-request-original-warning'; export default class SignatureRequestOriginal extends Component { static contextTypes = { t: PropTypes.func.isRequired, }; static propTypes = { fromAccount: PropTypes.shape({ address: PropTypes.string.isRequired, balance: PropTypes.string, name: PropTypes.string, }).isRequired, cancel: PropTypes.func.isRequired, clearConfirmTransaction: PropTypes.func.isRequired, history: PropTypes.object.isRequired, mostRecentOverviewPage: PropTypes.string.isRequired, sign: PropTypes.func.isRequired, txData: PropTypes.object.isRequired, subjectMetadata: PropTypes.object, hardwareWalletRequiresConnection: PropTypes.bool, isLedgerWallet: PropTypes.bool, nativeCurrency: PropTypes.string.isRequired, currentCurrency: PropTypes.string.isRequired, conversionRate: PropTypes.number, messagesCount: PropTypes.number, showRejectTransactionsConfirmationModal: PropTypes.func.isRequired, cancelAll: PropTypes.func.isRequired, provider: PropTypes.object, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) selectedAccount: PropTypes.object, ///: END:ONLY_INCLUDE_IN }; state = { showSignatureRequestWarning: false, }; getNetworkName() { const { provider } = this.props; const providerName = provider.type; const { t } = this.context; switch (providerName) { case NETWORK_TYPES.MAINNET: return t('mainnet'); case NETWORK_TYPES.GOERLI: return t('goerli'); case NETWORK_TYPES.SEPOLIA: return t('sepolia'); case NETWORK_TYPES.LINEA_TESTNET: return t('lineatestnet'); case NETWORK_TYPES.LOCALHOST: return t('localhost'); default: return provider.nickname || t('unknownNetwork'); } } msgHexToText = (hex) => { try { const stripped = stripHexPrefix(hex); const buff = Buffer.from(stripped, 'hex'); return buff.length === 32 ? hex : buff.toString('utf8'); } catch (e) { return hex; } }; renderAccountInfo = () => { return (
{this.renderAccount()} {this.renderRequestIcon()} {this.renderBalance()}
); }; renderTypedData = (data) => { const { t } = this.context; const { domain, message } = JSON.parse(data); return (
{domain ? (

{t('domain')}

) : ( '' )} {message ? (

{t('message')}

) : ( '' )}
); }; renderBody = () => { let rows; const notice = `${this.context.t('youSign')}:`; const { txData, subjectMetadata } = this.props; const { type, msgParams: { data }, } = txData; if (type === MESSAGE_TYPE.PERSONAL_SIGN) { rows = [ { name: this.context.t('message'), value: this.msgHexToText(data) }, ]; } else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) { rows = data; } else if (type === MESSAGE_TYPE.ETH_SIGN) { rows = [{ name: this.context.t('message'), value: data }]; } const targetSubjectMetadata = txData.msgParams.origin ? subjectMetadata?.[txData.msgParams.origin] : null; return (
{(txData?.securityProviderResponse?.flagAsDangerous !== undefined && txData?.securityProviderResponse?.flagAsDangerous !== SECURITY_PROVIDER_MESSAGE_SEVERITIES.NOT_MALICIOUS) || (txData?.securityProviderResponse && Object.keys(txData.securityProviderResponse).length === 0) ? ( ) : null} { ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) this.props.selectedAccount.address === this.props.fromAccount.address ? null : ( {this.context.t('mismatchAccount', [ shortenAddress(this.props.selectedAccount.address), shortenAddress(this.props.fromAccount.address), ])} ) ///: END:ONLY_INCLUDE_IN }
{this.context.t('sigRequest')} {this.context.t('signatureRequestGuidance')}
{notice}
{rows.map(({ name, value }, index) => { if (typeof value === 'boolean') { // eslint-disable-next-line no-param-reassign value = value.toString(); } return (
{sanitizeString(`${name}:`)}
{sanitizeString(value)}
); })}
); }; onSubmit = async (event) => { const { clearConfirmTransaction, history, mostRecentOverviewPage, sign } = this.props; await sign(event); clearConfirmTransaction(); history.push(mostRecentOverviewPage); }; onCancel = async (event) => { const { clearConfirmTransaction, history, mostRecentOverviewPage, cancel } = this.props; await cancel(event); clearConfirmTransaction(); history.push(mostRecentOverviewPage); }; renderFooter = () => { const { cancel, sign, clearConfirmTransaction, history, mostRecentOverviewPage, txData: { type }, hardwareWalletRequiresConnection, } = this.props; const { t } = this.context; return ( { await cancel(event); clearConfirmTransaction(); history.push(mostRecentOverviewPage); }} onSubmit={async (event) => { if (type === MESSAGE_TYPE.ETH_SIGN) { this.setState({ showSignatureRequestWarning: true }); } else { await sign(event); clearConfirmTransaction(); history.push(mostRecentOverviewPage); } }} disabled={hardwareWalletRequiresConnection} /> ); }; handleCancelAll = () => { const { cancelAll, clearConfirmTransaction, history, mostRecentOverviewPage, showRejectTransactionsConfirmationModal, messagesCount, } = this.props; const unapprovedTxCount = messagesCount; showRejectTransactionsConfirmationModal({ unapprovedTxCount, onSubmit: async () => { await cancelAll(); clearConfirmTransaction(); history.push(mostRecentOverviewPage); }, }); }; render = () => { const { messagesCount, nativeCurrency, currentCurrency, fromAccount: { address, balance, name }, conversionRate, } = this.props; const { showSignatureRequestWarning } = this.state; const { t } = this.context; const rejectNText = t('rejectRequestsN', [messagesCount]); const currentNetwork = this.getNetworkName(); const balanceInBaseAsset = conversionRate ? formatCurrency( getValueFromWeiHex({ value: balance, fromCurrency: nativeCurrency, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 6, toDenomination: EtherDenomination.ETH, }), currentCurrency, ) : new Numeric(balance, 16, EtherDenomination.WEI) .toDenomination(EtherDenomination.ETH) .round(6) .toBase(10) .toString(); return (
{this.renderBody()} {this.props.isLedgerWallet ? (
) : null} {showSignatureRequestWarning && ( await this.onSubmit(event)} onCancel={async (event) => await this.onCancel(event)} /> )} {this.renderFooter()} {messagesCount > 1 ? ( ) : null}
); }; }