From 82a64195a254b39fe3573221d639138b5176db4d Mon Sep 17 00:00:00 2001 From: Jyoti Puri Date: Wed, 26 Apr 2023 05:43:38 +0530 Subject: [PATCH] Enable editing L2 gas on optimism (#18217) --- app/_locales/de/messages.json | 3 - app/_locales/el/messages.json | 3 - app/_locales/en/messages.json | 6 +- app/_locales/es/messages.json | 3 - app/_locales/fr/messages.json | 3 - app/_locales/hi/messages.json | 3 - app/_locales/id/messages.json | 3 - app/_locales/ja/messages.json | 3 - app/_locales/ko/messages.json | 3 - app/_locales/pt/messages.json | 3 - app/_locales/ru/messages.json | 3 - app/_locales/tl/messages.json | 3 - app/_locales/tr/messages.json | 3 - app/_locales/vi/messages.json | 3 - app/_locales/zh_CN/messages.json | 3 - .../advanced-gas-controls.component.js | 8 -- .../advanced-gas-inputs.component.js | 9 -- .../advanced-gas-inputs.container.js | 9 +- .../approve-content-card.js | 47 +++++--- .../confirm-legacy-gas-display.js | 37 ++++++ .../confirm-legacy-gas-display.test.js | 112 ++++++++++++------ .../multi-layer-fee-message.test.js.snap | 98 +++++++++++++++ .../multi-layer-fee-message.js | 74 +++++++----- .../multi-layer-fee-message.test.js | 46 +++++++ .../confirm-approve-content.component.js | 32 ++++- ui/pages/confirm-approve/confirm-approve.js | 9 ++ .../confirm-transaction-base.component.js | 16 +-- .../confirm-transaction-base.container.js | 2 - .../confirm-transaction-base.test.js | 14 ++- .../confirm-token-transaction-switch.js | 3 + .../send-content/send-content.component.js | 4 +- .../send-content/send-content.container.js | 2 + ui/pages/token-allowance/token-allowance.js | 7 ++ ui/selectors/selectors.js | 6 +- 34 files changed, 407 insertions(+), 176 deletions(-) create mode 100644 ui/components/app/multilayer-fee-message/__snapshots__/multi-layer-fee-message.test.js.snap create mode 100644 ui/components/app/multilayer-fee-message/multi-layer-fee-message.test.js diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json index d56c2fe06..4c554e0c6 100644 --- a/app/_locales/de/messages.json +++ b/app/_locales/de/messages.json @@ -1416,9 +1416,6 @@ "message": "Diese Gasgebühr wurde von $1 vorgeschlagen. Dies kann ein Problem mit Ihrer Transaktion verursachen. Bei Fragen wenden Sie sich bitte an $1.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Gasgebühr" - }, "gasLimit": { "message": "Gaslimit" }, diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json index 11a5bdf85..e31f46d2b 100644 --- a/app/_locales/el/messages.json +++ b/app/_locales/el/messages.json @@ -1416,9 +1416,6 @@ "message": "Αυτό το τέλος συναλλαγής έχει προταθεί από το $1. Η παράκαμψη μπορεί να προκαλέσει πρόβλημα με τη συναλλαγή σας. Εάν έχετε απορίες, επικοινωνήστε με $1.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Τέλη Συναλλαγής" - }, "gasLimit": { "message": "Όριο τέλους συναλλαγής" }, diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 545acc4f4..2eba88ef0 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1552,9 +1552,6 @@ "message": "This gas fee has been suggested by $1. Overriding this may cause a problem with your transaction. Please reach out to $1 if you have questions.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Gas fee" - }, "gasLimit": { "message": "Gas limit" }, @@ -1973,6 +1970,9 @@ "lastSold": { "message": "Last sold" }, + "layer1Fees": { + "message": "Layer 1 fees" + }, "learnCancelSpeeedup": { "message": "Learn how to $1", "description": "$1 is link to cancel or speed up transactions" diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json index 6d0036fa4..34a984b51 100644 --- a/app/_locales/es/messages.json +++ b/app/_locales/es/messages.json @@ -1416,9 +1416,6 @@ "message": "Esta tarifa de gas ha sido sugerida por $1. Anularla puede causar un problema con su transacción. Comuníquese con $1 si tiene preguntas.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Cuota de gas" - }, "gasLimit": { "message": "Límite de gas" }, diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json index 42b38286c..d0ea3e1fb 100644 --- a/app/_locales/fr/messages.json +++ b/app/_locales/fr/messages.json @@ -1416,9 +1416,6 @@ "message": "Ce prix de carburant a été suggéré par $1. Si vous n’en tenez pas compte, vous risquez de rencontrer des difficultés lors de votre transaction. Veuillez contacter $1 pour toute question.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Frais de transaction" - }, "gasLimit": { "message": "Montant maximal des frais de transaction" }, diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json index a868af14d..c845b2fa9 100644 --- a/app/_locales/hi/messages.json +++ b/app/_locales/hi/messages.json @@ -1416,9 +1416,6 @@ "message": "यह गैस शुल्क $1 द्वारा सुझाया गया है। इसे ओवरराइड करने से आपके लेन-देन में समस्या हो सकती है। यदि आपके पास कोई सवाल हैं तो कृपया $1 तक पहुंचें।", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "गैस शुल्क" - }, "gasLimit": { "message": "गैस की सीमा" }, diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json index 81e8d6d71..4895a2f11 100644 --- a/app/_locales/id/messages.json +++ b/app/_locales/id/messages.json @@ -1416,9 +1416,6 @@ "message": "Biaya gas ini telah disarankan oleh $1. Pengabaian dapat menyebabkan masalah pada transaksi Anda. Hubungi $1 jika ada pertanyaan.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Biaya gas" - }, "gasLimit": { "message": "Batas gas" }, diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json index 632b32d10..023a1a417 100644 --- a/app/_locales/ja/messages.json +++ b/app/_locales/ja/messages.json @@ -1416,9 +1416,6 @@ "message": "このガス代は$1により提案されています。これを上書きすると、トランザクションに問題が発生する可能性があります。ご質問がございましたら、$1までお問い合わせください。", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "ガス代" - }, "gasLimit": { "message": "ガスリミット" }, diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json index 76a8f0b22..2f69acff1 100644 --- a/app/_locales/ko/messages.json +++ b/app/_locales/ko/messages.json @@ -1416,9 +1416,6 @@ "message": "$1에서 이 가스 요금을 제안했습니다. 이를 무시하면 거래에 문제가 발생할 수 있습니다. 질문이 있는 경우 $1에 문의하세요.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "가스 수수료" - }, "gasLimit": { "message": "가스 한도" }, diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json index 0d06c5bcb..2f2352b27 100644 --- a/app/_locales/pt/messages.json +++ b/app/_locales/pt/messages.json @@ -1416,9 +1416,6 @@ "message": "Essa taxa de gás foi sugerida por $1. Sua substituição pode causar um problema com a sua transação. Entre em contato com $1 se tiver perguntas.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Taxa de gás" - }, "gasLimit": { "message": "Limite de gás" }, diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json index 04fe18e52..b1a5efb92 100644 --- a/app/_locales/ru/messages.json +++ b/app/_locales/ru/messages.json @@ -1416,9 +1416,6 @@ "message": "Эта плата за газ была предложена $1. Ее переопредление может вызвать проблемы с вашей транзакцией. При наличии вопросов обратитесь к $1.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Плата за газ" - }, "gasLimit": { "message": "Лимит газа" }, diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json index 847e1d3eb..f5f608133 100644 --- a/app/_locales/tl/messages.json +++ b/app/_locales/tl/messages.json @@ -1416,9 +1416,6 @@ "message": "Ang gas fee na ito ay iminungkahi ng $1. Ang pag-override dito ay maaaring magdulot ng problema sa iyong transaksyon. Mangyaring makipag-ugnayan sa $1 kung mayroon kang mga tanong.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Bayarin sa Gas" - }, "gasLimit": { "message": "Limitasyon sa Gas" }, diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json index b6be9fdce..d957149c2 100644 --- a/app/_locales/tr/messages.json +++ b/app/_locales/tr/messages.json @@ -1416,9 +1416,6 @@ "message": "Bu gaz ücreti $1 tarafından önerilmiştir. Bu değerin başka bir değerle değiştirilmesi işleminizle ilgili bir soruna neden olabilir. Sorularınız olursa lütfen $1 ile iletişime geçin.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Gaz ücreti" - }, "gasLimit": { "message": "Gaz limiti" }, diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json index 226fbed51..54687ced6 100644 --- a/app/_locales/vi/messages.json +++ b/app/_locales/vi/messages.json @@ -1416,9 +1416,6 @@ "message": "Phí gas này đã được gợi ý bởi $1. Việc sửa đổi có thể khiến giao dịch của bạn gặp sự cố. Vui lòng liên hệ với $1 nếu bạn có câu hỏi.", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "Phí gas" - }, "gasLimit": { "message": "Giới hạn gas" }, diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json index ce0020821..8a05db500 100644 --- a/app/_locales/zh_CN/messages.json +++ b/app/_locales/zh_CN/messages.json @@ -1416,9 +1416,6 @@ "message": "这笔燃料费是由 $1 建议的。忽略它可能会导致您的交易出现问题。如果您有疑问,请联系 $1。", "description": "$1 represents the Dapp's origin" }, - "gasFee": { - "message": "燃料费" - }, "gasLimit": { "message": "燃料上限" }, diff --git a/ui/components/app/advanced-gas-controls/advanced-gas-controls.component.js b/ui/components/app/advanced-gas-controls/advanced-gas-controls.component.js index 547d0dced..8068a41e9 100644 --- a/ui/components/app/advanced-gas-controls/advanced-gas-controls.component.js +++ b/ui/components/app/advanced-gas-controls/advanced-gas-controls.component.js @@ -1,11 +1,9 @@ import React, { useContext } from 'react'; import PropTypes from 'prop-types'; -import { useSelector } from 'react-redux'; import { I18nContext } from '../../../contexts/i18n'; import FormField from '../../ui/form-field'; import { getGasFormErrorText } from '../../../helpers/constants/gas'; -import { getNetworkSupportsSettingGasFees } from '../../../selectors'; export default function AdvancedGasControls({ onManualChange, @@ -18,10 +16,6 @@ export default function AdvancedGasControls({ }) { const t = useContext(I18nContext); - const networkSupportsSettingGasFees = useSelector( - getNetworkSupportsSettingGasFees, - ); - return (
<> @@ -58,7 +51,6 @@ export default function AdvancedGasControls({ ? getGasFormErrorText(gasErrors.gasPrice, t) : null } - disabled={!networkSupportsSettingGasFees} />
diff --git a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js index a6841767a..cda7f4d73 100644 --- a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -20,12 +20,10 @@ export default class AdvancedGasInputs extends Component { customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, customPriceIsExcessive: PropTypes.bool, - networkSupportsSettingGasFees: PropTypes.bool, }; static defaultProps = { customPriceIsExcessive: false, - networkSupportsSettingGasFees: true, }; constructor(props) { @@ -203,14 +201,9 @@ export default class AdvancedGasInputs extends Component { customGasLimitMessage, minimumGasLimit, customPriceIsExcessive, - networkSupportsSettingGasFees, } = this.props; const { gasPrice, gasLimit } = this.state; - if (!networkSupportsSettingGasFees) { - return null; - } - const { errorText: gasPriceErrorText, errorType: gasPriceErrorType } = this.gasPriceError({ insufficientBalance, @@ -253,7 +246,6 @@ export default class AdvancedGasInputs extends Component { onChange: this.onChangeGasPrice, errorComponent: gasPriceErrorComponent, errorType: gasPriceErrorType, - disabled: !networkSupportsSettingGasFees, })} {this.renderGasInput({ label: this.context.t('gasLimit'), @@ -264,7 +256,6 @@ export default class AdvancedGasInputs extends Component { errorComponent: gasLimitErrorComponent, customMessageComponent: gasLimitCustomMessageComponent, errorType: gasLimitErrorType, - disabled: !networkSupportsSettingGasFees, })} ); diff --git a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.container.js b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.container.js index dc2b09a17..4736de011 100644 --- a/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.container.js +++ b/ui/components/app/advanced-gas-inputs/advanced-gas-inputs.container.js @@ -1,5 +1,4 @@ import { connect } from 'react-redux'; -import { getNetworkSupportsSettingGasFees } from '../../../selectors/selectors'; import { MIN_GAS_LIMIT_DEC } from '../../../pages/send/send.constants'; import { decGWEIToHexWEI, @@ -20,12 +19,6 @@ function convertMinimumGasLimitForInputs(minimumGasLimit = MIN_GAS_LIMIT_DEC) { return parseInt(minimumGasLimit, 10); } -function mapStateToProps(state) { - return { - networkSupportsSettingGasFees: getNetworkSupportsSettingGasFees(state), - }; -} - function mergeProps(stateProps, dispatchProps, ownProps) { const { customGasPrice, @@ -47,4 +40,4 @@ function mergeProps(stateProps, dispatchProps, ownProps) { }; } -export default connect(mapStateToProps, null, mergeProps)(AdvancedGasInputs); +export default connect(undefined, null, mergeProps)(AdvancedGasInputs); diff --git a/ui/components/app/approve-content-card/approve-content-card.js b/ui/components/app/approve-content-card/approve-content-card.js index bc5665209..8f188b9ba 100644 --- a/ui/components/app/approve-content-card/approve-content-card.js +++ b/ui/components/app/approve-content-card/approve-content-card.js @@ -1,6 +1,8 @@ import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; +import { useSelector } from 'react-redux'; + import Box from '../../ui/box/box'; import Button from '../../ui/button'; import EditGasFeeButton from '../edit-gas-fee-button/edit-gas-fee-button'; @@ -16,10 +18,14 @@ import { TextColor, TextVariant, } from '../../../helpers/constants/design-system'; +import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; import { I18nContext } from '../../../contexts/i18n'; +import { getPreferences } from '../../../selectors'; import { ConfirmGasDisplay } from '../confirm-gas-display'; import MultiLayerFeeMessage from '../multilayer-fee-message/multi-layer-fee-message'; import { formatCurrency } from '../../../helpers/utils/confirm-tx.util'; +import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component'; +import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; export default function ApproveContentCard({ showHeader = true, @@ -37,6 +43,7 @@ export default function ApproveContentCard({ ethTransactionTotal, nativeCurrency, fullTxData, + hexMinimumTransactionFee, hexTransactionTotal, fiatTransactionTotal, currentCurrency, @@ -48,6 +55,7 @@ export default function ApproveContentCard({ useCurrencyRateCheck, }) { const t = useContext(I18nContext); + const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); return ( - - - {t('transactionDetailLayer2GasHeading')} - {`${ethTransactionTotal} ${nativeCurrency}`} - - + + } + detailText={ + + } + noBold + flexWidthValues + /> process.env.IN_TEST ? null : ; @@ -32,8 +35,10 @@ const ConfirmLegacyGasDisplay = () => { // state selectors const isMainnet = useSelector(getIsMainnet); + const isMultiLayerFeeNetwork = useSelector(getIsMultiLayerFeeNetwork); const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); + const nativeCurrency = useSelector(getNativeCurrency); const unapprovedTxs = useSelector(getUnapprovedTransactions); const { transactionData } = useDraftTransactionGasValues(); const txData = useSelector((state) => txDataSelector(state)); @@ -45,6 +50,38 @@ const ConfirmLegacyGasDisplay = () => { (state) => transactionFeeSelector(state, transaction), ); + if (isMultiLayerFeeNetwork) { + return [ + + } + detailText={ + + } + noBold + flexWidthValues + />, + , + ]; + } + return ( { - const store = configureStore({ - ...mockState, - ...contextProps, - metamask: { - ...mockState.metamask, - accounts: { - [mockState.metamask.selectedAddress]: { - address: mockState.metamask.selectedAddress, - balance: '0x1F4', - }, - }, - unapprovedTxs: { - 8393540981007587: { - ...mockState.metamask.unapprovedTxs[8393540981007587], - txParams: { - from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', - to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', - value: '0x0', - gas: '0x5208', - gasPrice: '0x3b9aca00', - type: '0x0', - }, - }, - }, - preferences: { - useNativeCurrencyAsPrimaryCurrency: true, +const mmState = { + ...mockState, + metamask: { + ...mockState.metamask, + accounts: { + [mockState.metamask.selectedAddress]: { + address: mockState.metamask.selectedAddress, + balance: '0x1F4', }, }, - confirmTransaction: { - txData: { - id: 8393540981007587, - status: 'unapproved', - chainId: '0x5', + unapprovedTxs: { + 8393540981007587: { + ...mockState.metamask.unapprovedTxs[8393540981007587], txParams: { from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', @@ -51,7 +31,29 @@ const render = ({ contextProps } = {}) => { }, }, }, - }); + preferences: { + useNativeCurrencyAsPrimaryCurrency: true, + }, + }, + confirmTransaction: { + txData: { + id: 8393540981007587, + status: 'unapproved', + chainId: '0x5', + txParams: { + from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc', + to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813', + value: '0x0', + gas: '0x5208', + gasPrice: '0x3b9aca00', + type: '0x0', + }, + }, + }, +}; + +const render = ({ contextProps, state = mmState } = {}) => { + const store = configureStore({ ...state, ...contextProps }); return renderWithProvider(, store); }; @@ -107,4 +109,48 @@ describe('ConfirmLegacyGasDisplay', () => { expect(screen.queryAllByTitle('0.000021 ETH').length).toBeGreaterThan(0); }); }); + + it('should contain L1 L2 fee details for optimism', async () => { + mmState.metamask.provider.chainId = CHAIN_IDS.OPTIMISM; + mmState.confirmTransaction.txData.chainId = CHAIN_IDS.OPTIMISM; + const state = { + metamask: { + ...mmState.metamask, + provider: { + ...mmState.metamask.provider, + chainId: CHAIN_IDS.OPTIMISM, + }, + }, + confirmTransaction: { + ...mmState.confirmTransaction, + txData: { + ...mmState.confirmTransaction.txData, + chainId: CHAIN_IDS.OPTIMISM, + }, + }, + }; + render( + { + send: { + currentTransactionUUID: '1d40b578-6184-4607-8513-762c24d0a19b', + draftTransactions: { + '1d40b578-6184-4607-8513-762c24d0a19b': { + gas: { + error: null, + gasLimit: '0x5208', + gasPrice: '0x3b9aca00', + gasTotal: '0x157c9fbb9a000', + wasManuallyEdited: false, + }, + }, + }, + }, + }, + state, + ); + await waitFor(() => { + expect(screen.queryByText('Layer 1 fees')).toBeInTheDocument(); + expect(screen.queryByText('Layer 2 gas fee')).toBeInTheDocument(); + }); + }); }); diff --git a/ui/components/app/multilayer-fee-message/__snapshots__/multi-layer-fee-message.test.js.snap b/ui/components/app/multilayer-fee-message/__snapshots__/multi-layer-fee-message.test.js.snap new file mode 100644 index 000000000..523ee6cdb --- /dev/null +++ b/ui/components/app/multilayer-fee-message/__snapshots__/multi-layer-fee-message.test.js.snap @@ -0,0 +1,98 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Multi layer fee message should match snapshot 1`] = ` +
+
+
+
+
+ Layer 1 fees +
+
+
+ Unknown +
+
+ Unknown +
+
+
+
+
+
+
+
+
+
+
+ Total +
+
+
+
+ + + $0.56 + +
+
+
+ 0.001000021000 ETH +
+
+
+
+
+ Amount + fees +
+
+
+
+
+
+`; diff --git a/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js b/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js index 60eb8c3c3..d14507215 100644 --- a/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js +++ b/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js @@ -17,36 +17,17 @@ export default function MultilayerFeeMessage({ plainStyle, }) { const t = useContext(I18nContext); - const [fetchedLayer1Total, setLayer1Total] = useState(null); - let layer1Total = 'unknown'; - let layer1TotalBN; - - if (fetchedLayer1Total !== null) { - layer1TotalBN = new Numeric(fetchedLayer1Total, 16, EtherDenomination.WEI); - layer1Total = `${layer1TotalBN - .toDenomination(EtherDenomination.ETH) - .toFixed(12)} ${nativeCurrency}`; - } - - const feeTotal = sumHexes(layer2fee || '0x0', fetchedLayer1Total || '0x0'); - - const totalInWeiHex = sumHexes( - feeTotal || '0x0', - transaction.txParams.value || '0x0', - ); - - const totalBN = new Numeric(totalInWeiHex, 16, EtherDenomination.WEI); - const totalInEth = `${totalBN - .toDenomination(EtherDenomination.ETH) - .toFixed(12)} ${nativeCurrency}`; useEffect(() => { + if (!transaction?.txParams) { + return; + } const getEstimatedL1Fee = async () => { try { const result = await fetchEstimatedL1Fee( - transaction.chainId, - transaction.txParams, + transaction?.chainId, + transaction, ); setLayer1Total(result); } catch (e) { @@ -57,15 +38,44 @@ export default function MultilayerFeeMessage({ getEstimatedL1Fee(); }, [transaction]); - const feeTotalInFiat = ( - + if (!transaction?.txParams) { + return null; + } + + let layer1Total = t('unknown'); + let feeTotalInFiat = t('unknown'); + + if (fetchedLayer1Total !== null) { + const layer1TotalBN = new Numeric( + fetchedLayer1Total, + 16, + EtherDenomination.WEI, + ); + layer1Total = `${layer1TotalBN + .toDenomination(EtherDenomination.ETH) + .toFixed(12)} ${nativeCurrency}`; + + feeTotalInFiat = ( + + ); + } + + const totalInWeiHex = sumHexes( + layer2fee || '0x0', + fetchedLayer1Total || '0x0', + transaction?.txParams?.value || '0x0', ); + const totalBN = new Numeric(totalInWeiHex, 16, EtherDenomination.WEI); + const totalInEth = `${totalBN + .toDenomination(EtherDenomination.ETH) + .toFixed(12)} ${nativeCurrency}`; + const totalInFiat = ( '0x5'); + +describe('Multi layer fee message', () => { + const store = configureStore(mockState); + + it('should match snapshot', () => { + const { container } = renderWithProvider( + , + store, + ); + expect(container).toMatchSnapshot(); + }); + + it('should containe fee values', () => { + const { getByText } = renderWithProvider( + , + store, + ); + expect(getByText('Layer 1 fees')).toBeInTheDocument(); + expect(getByText('Amount + fees')).toBeInTheDocument(); + expect(getByText('0.001000021000 ETH')).toBeInTheDocument(); + }); +}); diff --git a/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js b/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js index a3586aa32..b9046209d 100644 --- a/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js +++ b/ui/pages/confirm-approve/confirm-approve-content/confirm-approve-content.component.js @@ -33,6 +33,9 @@ import { IconName, Text, } from '../../../components/component-library'; +import TransactionDetailItem from '../../../components/app/transaction-detail-item/transaction-detail-item.component'; +import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; +import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; import { ConfirmGasDisplay } from '../../../components/app/confirm-gas-display'; export default class ConfirmApproveContent extends Component { @@ -65,6 +68,7 @@ export default class ConfirmApproveContent extends Component { rpcPrefs: PropTypes.object, isContract: PropTypes.bool, hexTransactionTotal: PropTypes.string, + hexMinimumTransactionFee: PropTypes.string, isMultiLayerFeeNetwork: PropTypes.bool, supportsEIP1559: PropTypes.bool, assetName: PropTypes.string, @@ -77,6 +81,7 @@ export default class ConfirmApproveContent extends Component { setUserAcknowledgedGasMissing: PropTypes.func, renderSimulationFailureWarning: PropTypes.bool, useCurrencyRateCheck: PropTypes.bool, + useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, }; state = { @@ -157,12 +162,14 @@ export default class ConfirmApproveContent extends Component { ethTransactionTotal, fiatTransactionTotal, hexTransactionTotal, + hexMinimumTransactionFee, txData, isMultiLayerFeeNetwork, supportsEIP1559, userAcknowledgedGasMissing, renderSimulationFailureWarning, useCurrencyRateCheck, + useNativeCurrencyAsPrimaryCurrency, } = this.props; if ( !isMultiLayerFeeNetwork && @@ -179,10 +186,27 @@ export default class ConfirmApproveContent extends Component {
{isMultiLayerFeeNetwork ? (
-
- {t('transactionDetailLayer2GasHeading')} - {`${ethTransactionTotal} ${nativeCurrency}`} -
+ + } + detailText={ + + } + noBold + flexWidthValues + /> {showCustomizeGasPopover && !supportsEIP1559 && ( this.handleEditGas() + renderSimulationFailureWarning ? null : () => this.handleEditGas() } rows={[ renderSimulationFailureWarning && simulationFailureWarning(), - !renderSimulationFailureWarning && !isMultiLayerFeeNetwork && ( + !renderSimulationFailureWarning && ( ), - !renderSimulationFailureWarning && isMultiLayerFeeNetwork && ( - - ), !isMultiLayerFeeNetwork && ( { const { hexTransactionAmount, - hexMinimumTransactionFee, hexMaximumTransactionFee, hexTransactionTotal, gasEstimationObject, @@ -206,7 +205,6 @@ const mapStateToProps = (state, ownProps) => { toName, toNickname, hexTransactionAmount, - hexMinimumTransactionFee, hexMaximumTransactionFee, hexTransactionTotal, txData: fullTxData, diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js index ae33ad632..30d699486 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.test.js @@ -146,12 +146,24 @@ const baseStore = { }; describe('Confirm Transaction Base', () => { - const store = configureMockStore(middleware)(baseStore); it('should match snapshot', () => { + const store = configureMockStore(middleware)(baseStore); const { container } = renderWithProvider( , store, ); expect(container).toMatchSnapshot(); }); + + it('should contain L1 L2 fee details for optimism', () => { + baseStore.metamask.provider.chainId = CHAIN_IDS.OPTIMISM; + baseStore.confirmTransaction.txData.chainId = CHAIN_IDS.OPTIMISM; + const store = configureMockStore(middleware)(baseStore); + const { getByText } = renderWithProvider( + , + store, + ); + expect(getByText('Layer 1 fees')).toBeInTheDocument(); + expect(getByText('Layer 2 gas fee')).toBeInTheDocument(); + }); }); diff --git a/ui/pages/confirm-transaction/confirm-token-transaction-switch.js b/ui/pages/confirm-transaction/confirm-token-transaction-switch.js index 8b0bd17e1..e04b7c404 100644 --- a/ui/pages/confirm-transaction/confirm-token-transaction-switch.js +++ b/ui/pages/confirm-transaction/confirm-token-transaction-switch.js @@ -46,6 +46,7 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { fiatTransactionTotal, hexTransactionTotal, hexMaximumTransactionFee, + hexMinimumTransactionFee, } = useSelector((state) => transactionFeeSelector(state, transaction)); return ( @@ -70,6 +71,7 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { ethTransactionTotal={ethTransactionTotal} fiatTransactionTotal={fiatTransactionTotal} hexTransactionTotal={hexTransactionTotal} + hexMinimumTransactionFee={hexMinimumTransactionFee} /> )} /> @@ -94,6 +96,7 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { ethTransactionTotal={ethTransactionTotal} fiatTransactionTotal={fiatTransactionTotal} hexTransactionTotal={hexTransactionTotal} + hexMinimumTransactionFee={hexMinimumTransactionFee} /> )} /> diff --git a/ui/pages/send/send-content/send-content.component.js b/ui/pages/send/send-content/send-content.component.js index b57b59a51..d358a6c87 100644 --- a/ui/pages/send/send-content/send-content.component.js +++ b/ui/pages/send/send-content/send-content.component.js @@ -34,6 +34,7 @@ export default class SendContent extends Component { recipient: PropTypes.object, acknowledgeRecipientWarning: PropTypes.func, recipientWarningAcknowledged: PropTypes.bool, + isMultiLayerFeeNetwork: PropTypes.bool, }; render() { @@ -48,6 +49,7 @@ export default class SendContent extends Component { assetError, recipient, recipientWarningAcknowledged, + isMultiLayerFeeNetwork, } = this.props; let gasError; @@ -80,7 +82,7 @@ export default class SendContent extends Component { {networkOrAccountNotSupports1559 ? : null} {showHexData ? : null} - + {!isMultiLayerFeeNetwork && }
); diff --git a/ui/pages/send/send-content/send-content.container.js b/ui/pages/send/send-content/send-content.container.js index e9d3f6f02..6bf19dea3 100644 --- a/ui/pages/send/send-content/send-content.container.js +++ b/ui/pages/send/send-content/send-content.container.js @@ -3,6 +3,7 @@ import { getIsEthGasPriceFetched, getNoGasPriceFetched, checkNetworkOrAccountNotSupports1559, + getIsMultiLayerFeeNetwork, } from '../../../selectors'; import { getIsBalanceInsufficient, @@ -29,6 +30,7 @@ function mapStateToProps(state) { assetError: getAssetError(state), recipient, recipientWarningAcknowledged, + isMultiLayerFeeNetwork: getIsMultiLayerFeeNetwork(state), }; } diff --git a/ui/pages/token-allowance/token-allowance.js b/ui/pages/token-allowance/token-allowance.js index 9fe4244ef..57453a838 100644 --- a/ui/pages/token-allowance/token-allowance.js +++ b/ui/pages/token-allowance/token-allowance.js @@ -78,6 +78,7 @@ export default function TokenAllowance({ ethTransactionTotal, fiatTransactionTotal, hexTransactionTotal, + hexMinimumTransactionFee, txData, isMultiLayerFeeNetwork, supportsEIP1559, @@ -460,6 +461,7 @@ export default function TokenAllowance({ userAcknowledgedGasMissing={userAcknowledgedGasMissing} renderSimulationFailureWarning={renderSimulationFailureWarning} hexTransactionTotal={hexTransactionTotal} + hexMinimumTransactionFee={hexMinimumTransactionFee} fiatTransactionTotal={fiatTransactionTotal} currentCurrency={currentCurrency} useCurrencyRateCheck={useCurrencyRateCheck} @@ -511,6 +513,7 @@ export default function TokenAllowance({ isApprovalOrRejection={isApprovalOrRejection} data={customTxParamsData || data} useCurrencyRateCheck={useCurrencyRateCheck} + hexMinimumTransactionFee={hexMinimumTransactionFee} /> @@ -592,6 +595,10 @@ TokenAllowance.propTypes = { * Total sum of the transaction converted to hex value */ hexTransactionTotal: PropTypes.string, + /** + * Minimum transaction fee converted to hex value + */ + hexMinimumTransactionFee: PropTypes.string, /** * Current transaction */ diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index 13a198bac..538fa7f35 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -843,7 +843,7 @@ export const getFullTxData = createDeepEqualSelector( (txData, transaction, customTxParamsData) => { let fullTxData = { ...txData, ...transaction }; if (transaction && transaction.simulationFails) { - txData.simulationFails = transaction.simulationFails; + fullTxData.simulationFails = { ...transaction.simulationFails }; } if (customTxParamsData) { fullTxData = { @@ -1222,10 +1222,6 @@ export function getIsOptimism(state) { ); } -export function getNetworkSupportsSettingGasFees(state) { - return !getIsOptimism(state); -} - export function getIsMultiLayerFeeNetwork(state) { return getIsOptimism(state); }