mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Improvements for multi-layer fee UX (#13547)
* Show fiat on confirm screen on multilayer-fee network * Disable gas editing on optimism * Fix send max mode on optimism * Represent layer 2 gas fee as a single value * Hide gas fee edit UI on optimism * Improvement multilayer-fee-message styling * Lint fix * Fix locales * Remove unnecessary code change Co-authored-by: David Walsh <davidwalsh83@gmail.com>
This commit is contained in:
parent
7cb22bd883
commit
09512c7148
3
app/_locales/de/messages.json
generated
3
app/_locales/de/messages.json
generated
@ -1408,9 +1408,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Zuletzt verbunden"
|
"message": "Zuletzt verbunden"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Ebene 1 Gebühren"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Wollen Sie 1 $ über Gas?"
|
"message": "Wollen Sie 1 $ über Gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/el/messages.json
generated
3
app/_locales/el/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Τελευταία Σύνδεση"
|
"message": "Τελευταία Σύνδεση"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Τέλη επιπέδου 1"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Θέλετε να $1 για το τέλος συναλλαγής;"
|
"message": "Θέλετε να $1 για το τέλος συναλλαγής;"
|
||||||
},
|
},
|
||||||
|
6
app/_locales/en/messages.json
generated
6
app/_locales/en/messages.json
generated
@ -1277,6 +1277,9 @@
|
|||||||
"gasEstimatesUnavailableWarning": {
|
"gasEstimatesUnavailableWarning": {
|
||||||
"message": "Our low, medium and high estimates are not available."
|
"message": "Our low, medium and high estimates are not available."
|
||||||
},
|
},
|
||||||
|
"gasFee": {
|
||||||
|
"message": "Gas Fee"
|
||||||
|
},
|
||||||
"gasLimit": {
|
"gasLimit": {
|
||||||
"message": "Gas Limit"
|
"message": "Gas Limit"
|
||||||
},
|
},
|
||||||
@ -1629,9 +1632,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Last Connected"
|
"message": "Last Connected"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Layer 1 fees"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Want to $1 about gas?"
|
"message": "Want to $1 about gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/es_419/messages.json
generated
3
app/_locales/es_419/messages.json
generated
@ -1454,9 +1454,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Última conexión"
|
"message": "Última conexión"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Cargos de capa 1"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "¿Quiere $1 sobre el gas?"
|
"message": "¿Quiere $1 sobre el gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/fr/messages.json
generated
3
app/_locales/fr/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Dernière connexion"
|
"message": "Dernière connexion"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Frais de couche 1 (L1)"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Souhaitez-vous $1 sur le carburant ?"
|
"message": "Souhaitez-vous $1 sur le carburant ?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/hi/messages.json
generated
3
app/_locales/hi/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "अंतिम बार कनेक्ट किया गया"
|
"message": "अंतिम बार कनेक्ट किया गया"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "लेयर 1 शुल्क"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "गैस के बारे में $1 चाहते हैं?"
|
"message": "गैस के बारे में $1 चाहते हैं?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/id/messages.json
generated
3
app/_locales/id/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Terakhir Terhubung"
|
"message": "Terakhir Terhubung"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Biaya lapis 1"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Ingin $1 seputar gas?"
|
"message": "Ingin $1 seputar gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/ja/messages.json
generated
3
app/_locales/ja/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "前回の接続"
|
"message": "前回の接続"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "レイヤー1手数料"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "ガスについて$1しますか?"
|
"message": "ガスについて$1しますか?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/ko/messages.json
generated
3
app/_locales/ko/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "마지막 연결"
|
"message": "마지막 연결"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "레이어 1 요금"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "가스에 대해 $1하시겠습니까?"
|
"message": "가스에 대해 $1하시겠습니까?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/pt_BR/messages.json
generated
3
app/_locales/pt_BR/messages.json
generated
@ -1438,9 +1438,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Conectado pela última vez em"
|
"message": "Conectado pela última vez em"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Taxas de camada 1"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Quer $1 sobre o gás?"
|
"message": "Quer $1 sobre o gás?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/ru/messages.json
generated
3
app/_locales/ru/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Последнее подключение"
|
"message": "Последнее подключение"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Комиссии 1-го уровня"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Хотите $1 о газе?"
|
"message": "Хотите $1 о газе?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/tl/messages.json
generated
3
app/_locales/tl/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Huling Kumonekta"
|
"message": "Huling Kumonekta"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Layer 1 fees"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Gusto mo bang $1 ang tungkol sa gas?"
|
"message": "Gusto mo bang $1 ang tungkol sa gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/tr/messages.json
generated
3
app/_locales/tr/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Son Bağlanma"
|
"message": "Son Bağlanma"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Aşama 1 ücretleri"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Gaz hakkında $1 istiyor musunuz?"
|
"message": "Gaz hakkında $1 istiyor musunuz?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/vi/messages.json
generated
3
app/_locales/vi/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "Đã kết nối lần cuối"
|
"message": "Đã kết nối lần cuối"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "Phí Lớp 1"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "Muốn $1 về gas?"
|
"message": "Muốn $1 về gas?"
|
||||||
},
|
},
|
||||||
|
3
app/_locales/zh_CN/messages.json
generated
3
app/_locales/zh_CN/messages.json
generated
@ -1405,9 +1405,6 @@
|
|||||||
"lastConnected": {
|
"lastConnected": {
|
||||||
"message": "最后连接"
|
"message": "最后连接"
|
||||||
},
|
},
|
||||||
"layer1Fees": {
|
|
||||||
"message": "1层费用"
|
|
||||||
},
|
|
||||||
"learmMoreAboutGas": {
|
"learmMoreAboutGas": {
|
||||||
"message": "想要有关燃料$1?"
|
"message": "想要有关燃料$1?"
|
||||||
},
|
},
|
||||||
|
@ -7,7 +7,7 @@ import FormField from '../../ui/form-field';
|
|||||||
import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas';
|
import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas';
|
||||||
import { getGasFormErrorText } from '../../../helpers/constants/gas';
|
import { getGasFormErrorText } from '../../../helpers/constants/gas';
|
||||||
import { getIsGasEstimatesLoading } from '../../../ducks/metamask/metamask';
|
import { getIsGasEstimatesLoading } from '../../../ducks/metamask/metamask';
|
||||||
import { getNetworkSupportsSettingGasPrice } from '../../../selectors';
|
import { getNetworkSupportsSettingGasFees } from '../../../selectors';
|
||||||
|
|
||||||
export default function AdvancedGasControls({
|
export default function AdvancedGasControls({
|
||||||
gasEstimateType,
|
gasEstimateType,
|
||||||
@ -35,8 +35,8 @@ export default function AdvancedGasControls({
|
|||||||
gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE ||
|
gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE ||
|
||||||
isGasEstimatesLoading);
|
isGasEstimatesLoading);
|
||||||
|
|
||||||
const networkSupportsSettingGasPrice = useSelector(
|
const networkSupportsSettingGasFees = useSelector(
|
||||||
getNetworkSupportsSettingGasPrice,
|
getNetworkSupportsSettingGasFees,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -55,6 +55,7 @@ export default function AdvancedGasControls({
|
|||||||
tooltipText={t('editGasLimitTooltip')}
|
tooltipText={t('editGasLimitTooltip')}
|
||||||
value={gasLimit}
|
value={gasLimit}
|
||||||
allowDecimals={false}
|
allowDecimals={false}
|
||||||
|
disabled={!networkSupportsSettingGasFees}
|
||||||
numeric
|
numeric
|
||||||
/>
|
/>
|
||||||
{showFeeMarketFields ? (
|
{showFeeMarketFields ? (
|
||||||
@ -111,7 +112,7 @@ export default function AdvancedGasControls({
|
|||||||
? getGasFormErrorText(gasErrors.gasPrice, t)
|
? getGasFormErrorText(gasErrors.gasPrice, t)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
disabled={!networkSupportsSettingGasPrice}
|
disabled={!networkSupportsSettingGasFees}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
@import 'menu-bar/index';
|
@import 'menu-bar/index';
|
||||||
@import 'modal/index';
|
@import 'modal/index';
|
||||||
@import 'modals/index';
|
@import 'modals/index';
|
||||||
|
@import 'multilayer-fee-message/index';
|
||||||
@import 'multiple-notifications/index';
|
@import 'multiple-notifications/index';
|
||||||
@import 'network-display/index';
|
@import 'network-display/index';
|
||||||
@import 'permission-page-container/index';
|
@import 'permission-page-container/index';
|
||||||
|
@ -20,12 +20,12 @@ export default class AdvancedGasInputs extends Component {
|
|||||||
customGasLimitMessage: PropTypes.string,
|
customGasLimitMessage: PropTypes.string,
|
||||||
minimumGasLimit: PropTypes.number,
|
minimumGasLimit: PropTypes.number,
|
||||||
customPriceIsExcessive: PropTypes.bool,
|
customPriceIsExcessive: PropTypes.bool,
|
||||||
networkSupportsSettingGasPrice: PropTypes.bool,
|
networkSupportsSettingGasFees: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
customPriceIsExcessive: false,
|
customPriceIsExcessive: false,
|
||||||
networkSupportsSettingGasPrice: true,
|
networkSupportsSettingGasFees: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -202,10 +202,14 @@ export default class AdvancedGasInputs extends Component {
|
|||||||
customGasLimitMessage,
|
customGasLimitMessage,
|
||||||
minimumGasLimit,
|
minimumGasLimit,
|
||||||
customPriceIsExcessive,
|
customPriceIsExcessive,
|
||||||
networkSupportsSettingGasPrice,
|
networkSupportsSettingGasFees,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { gasPrice, gasLimit } = this.state;
|
const { gasPrice, gasLimit } = this.state;
|
||||||
|
|
||||||
|
if (!networkSupportsSettingGasFees) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
errorText: gasPriceErrorText,
|
errorText: gasPriceErrorText,
|
||||||
errorType: gasPriceErrorType,
|
errorType: gasPriceErrorType,
|
||||||
@ -252,7 +256,7 @@ export default class AdvancedGasInputs extends Component {
|
|||||||
onChange: this.onChangeGasPrice,
|
onChange: this.onChangeGasPrice,
|
||||||
errorComponent: gasPriceErrorComponent,
|
errorComponent: gasPriceErrorComponent,
|
||||||
errorType: gasPriceErrorType,
|
errorType: gasPriceErrorType,
|
||||||
disabled: !networkSupportsSettingGasPrice,
|
disabled: !networkSupportsSettingGasFees,
|
||||||
})}
|
})}
|
||||||
{this.renderGasInput({
|
{this.renderGasInput({
|
||||||
label: this.context.t('gasLimit'),
|
label: this.context.t('gasLimit'),
|
||||||
@ -263,6 +267,7 @@ export default class AdvancedGasInputs extends Component {
|
|||||||
errorComponent: gasLimitErrorComponent,
|
errorComponent: gasLimitErrorComponent,
|
||||||
customMessageComponent: gasLimitCustomMessageComponent,
|
customMessageComponent: gasLimitCustomMessageComponent,
|
||||||
errorType: gasLimitErrorType,
|
errorType: gasLimitErrorType,
|
||||||
|
disabled: !networkSupportsSettingGasFees,
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@ import {
|
|||||||
decimalToHex,
|
decimalToHex,
|
||||||
hexWEIToDecGWEI,
|
hexWEIToDecGWEI,
|
||||||
} from '../../../../helpers/utils/conversions.util';
|
} from '../../../../helpers/utils/conversions.util';
|
||||||
import { getNetworkSupportsSettingGasPrice } from '../../../../selectors/selectors';
|
import { getNetworkSupportsSettingGasFees } from '../../../../selectors/selectors';
|
||||||
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants';
|
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants';
|
||||||
import AdvancedGasInputs from './advanced-gas-inputs.component';
|
import AdvancedGasInputs from './advanced-gas-inputs.component';
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ function convertMinimumGasLimitForInputs(minimumGasLimit = MIN_GAS_LIMIT_DEC) {
|
|||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
networkSupportsSettingGasPrice: getNetworkSupportsSettingGasPrice(state),
|
networkSupportsSettingGasFees: getNetworkSupportsSettingGasFees(state),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
ui/components/app/multilayer-fee-message/index.scss
Normal file
3
ui/components/app/multilayer-fee-message/index.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.multi-layer-fee-message {
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
@ -2,7 +2,9 @@ import React, { useContext, useState, useEffect } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { captureException } from '@sentry/browser';
|
import { captureException } from '@sentry/browser';
|
||||||
import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component';
|
import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component';
|
||||||
|
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display';
|
||||||
import fetchEstimatedL1Fee from '../../../helpers/utils/optimism/fetchEstimatedL1Fee';
|
import fetchEstimatedL1Fee from '../../../helpers/utils/optimism/fetchEstimatedL1Fee';
|
||||||
|
import { SECONDARY } from '../../../helpers/constants/common';
|
||||||
import { I18nContext } from '../../../contexts/i18n';
|
import { I18nContext } from '../../../contexts/i18n';
|
||||||
import { sumHexes } from '../../../helpers/utils/transactions.util';
|
import { sumHexes } from '../../../helpers/utils/transactions.util';
|
||||||
import {
|
import {
|
||||||
@ -21,23 +23,26 @@ export default function MultilayerFeeMessage({
|
|||||||
const [fetchedLayer1Total, setLayer1Total] = useState(null);
|
const [fetchedLayer1Total, setLayer1Total] = useState(null);
|
||||||
|
|
||||||
let layer1Total = 'unknown';
|
let layer1Total = 'unknown';
|
||||||
|
let layer1TotalBN;
|
||||||
|
|
||||||
if (fetchedLayer1Total !== null) {
|
if (fetchedLayer1Total !== null) {
|
||||||
const layer1TotalBN = toBigNumber.hex(fetchedLayer1Total);
|
layer1TotalBN = toBigNumber.hex(fetchedLayer1Total);
|
||||||
layer1Total = `${toNormalizedDenomination
|
layer1Total = `${toNormalizedDenomination
|
||||||
.WEI(layer1TotalBN)
|
.WEI(layer1TotalBN)
|
||||||
.toString(10)} ${nativeCurrency}`;
|
.toFixed(12)} ${nativeCurrency}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const feeTotal = sumHexes(layer2fee || '0x0', fetchedLayer1Total || '0x0');
|
||||||
|
|
||||||
const totalInWeiHex = sumHexes(
|
const totalInWeiHex = sumHexes(
|
||||||
layer2fee || '0x0',
|
feeTotal || '0x0',
|
||||||
fetchedLayer1Total || '0x0',
|
|
||||||
transaction.txParams.value || '0x0',
|
transaction.txParams.value || '0x0',
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalBN = toBigNumber.hex(totalInWeiHex);
|
const totalBN = toBigNumber.hex(totalInWeiHex);
|
||||||
const totalInEth = `${toNormalizedDenomination
|
const totalInEth = `${toNormalizedDenomination
|
||||||
.WEI(totalBN)
|
.WEI(totalBN)
|
||||||
.toString(10)} ${nativeCurrency}`;
|
.toFixed(12)} ${nativeCurrency}`;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getEstimatedL1Fee = async () => {
|
const getEstimatedL1Fee = async () => {
|
||||||
@ -52,12 +57,31 @@ export default function MultilayerFeeMessage({
|
|||||||
getEstimatedL1Fee();
|
getEstimatedL1Fee();
|
||||||
}, [transaction]);
|
}, [transaction]);
|
||||||
|
|
||||||
|
const feeTotalInFiat = (
|
||||||
|
<UserPreferencedCurrencyDisplay
|
||||||
|
type={SECONDARY}
|
||||||
|
value={feeTotal}
|
||||||
|
showFiat
|
||||||
|
hideLabel
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalInFiat = (
|
||||||
|
<UserPreferencedCurrencyDisplay
|
||||||
|
type={SECONDARY}
|
||||||
|
value={totalInWeiHex}
|
||||||
|
showFiat
|
||||||
|
hideLabel
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="multi-layer-fee-message">
|
||||||
<TransactionDetailItem
|
<TransactionDetailItem
|
||||||
key="total-item"
|
key="total-item"
|
||||||
detailTitle={t('layer1Fees')}
|
detailTitle={t('gasFee')}
|
||||||
detailTotal={layer1Total}
|
detailTotal={layer1Total}
|
||||||
|
detailText={feeTotalInFiat}
|
||||||
noBold={plainStyle}
|
noBold={plainStyle}
|
||||||
flexWidthValues={plainStyle}
|
flexWidthValues={plainStyle}
|
||||||
/>
|
/>
|
||||||
@ -65,11 +89,12 @@ export default function MultilayerFeeMessage({
|
|||||||
key="total-item"
|
key="total-item"
|
||||||
detailTitle={t('total')}
|
detailTitle={t('total')}
|
||||||
detailTotal={totalInEth}
|
detailTotal={totalInEth}
|
||||||
|
detailText={totalInFiat}
|
||||||
subTitle={t('transactionDetailMultiLayerTotalSubtitle')}
|
subTitle={t('transactionDetailMultiLayerTotalSubtitle')}
|
||||||
noBold={plainStyle}
|
noBold={plainStyle}
|
||||||
flexWidthValues={plainStyle}
|
flexWidthValues={plainStyle}
|
||||||
/>
|
/>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,12 +12,14 @@ export default function UserPreferencedCurrencyDisplay({
|
|||||||
numberOfDecimals: propsNumberOfDecimals,
|
numberOfDecimals: propsNumberOfDecimals,
|
||||||
showEthLogo,
|
showEthLogo,
|
||||||
type,
|
type,
|
||||||
|
showFiat,
|
||||||
...restProps
|
...restProps
|
||||||
}) {
|
}) {
|
||||||
const { currency, numberOfDecimals } = useUserPreferencedCurrency(type, {
|
const { currency, numberOfDecimals } = useUserPreferencedCurrency(type, {
|
||||||
ethNumberOfDecimals,
|
ethNumberOfDecimals,
|
||||||
fiatNumberOfDecimals,
|
fiatNumberOfDecimals,
|
||||||
numberOfDecimals: propsNumberOfDecimals,
|
numberOfDecimals: propsNumberOfDecimals,
|
||||||
|
showFiatOverride: showFiat,
|
||||||
});
|
});
|
||||||
const prefixComponent = useMemo(() => {
|
const prefixComponent = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
@ -65,4 +67,5 @@ UserPreferencedCurrencyDisplay.propTypes = {
|
|||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
PropTypes.number,
|
PropTypes.number,
|
||||||
]),
|
]),
|
||||||
|
showFiat: PropTypes.boolean,
|
||||||
};
|
};
|
||||||
|
@ -44,6 +44,7 @@ import {
|
|||||||
getUseTokenDetection,
|
getUseTokenDetection,
|
||||||
getTokenList,
|
getTokenList,
|
||||||
getAddressBookEntryOrAccountName,
|
getAddressBookEntryOrAccountName,
|
||||||
|
getIsMultiLayerFeeNetwork,
|
||||||
} from '../../selectors';
|
} from '../../selectors';
|
||||||
import {
|
import {
|
||||||
disconnectGasFeeEstimatePoller,
|
disconnectGasFeeEstimatePoller,
|
||||||
@ -91,6 +92,9 @@ import {
|
|||||||
isBurnAddress,
|
isBurnAddress,
|
||||||
isValidHexAddress,
|
isValidHexAddress,
|
||||||
} from '../../../shared/modules/hexstring-utils';
|
} from '../../../shared/modules/hexstring-utils';
|
||||||
|
import { sumHexes } from '../../helpers/utils/transactions.util';
|
||||||
|
import fetchEstimatedL1Fee from '../../helpers/utils/optimism/fetchEstimatedL1Fee';
|
||||||
|
|
||||||
import { CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP } from '../../../shared/constants/network';
|
import { CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP } from '../../../shared/constants/network';
|
||||||
import {
|
import {
|
||||||
ERC20,
|
ERC20,
|
||||||
@ -192,6 +196,7 @@ async function estimateGasLimitForSend({
|
|||||||
data,
|
data,
|
||||||
isNonStandardEthChain,
|
isNonStandardEthChain,
|
||||||
chainId,
|
chainId,
|
||||||
|
gasLimit,
|
||||||
...options
|
...options
|
||||||
}) {
|
}) {
|
||||||
let isSimpleSendOnNonStandardNetwork = false;
|
let isSimpleSendOnNonStandardNetwork = false;
|
||||||
@ -313,12 +318,14 @@ async function estimateGasLimitForSend({
|
|||||||
error.message.includes('Transaction execution error.') ||
|
error.message.includes('Transaction execution error.') ||
|
||||||
error.message.includes(
|
error.message.includes(
|
||||||
'gas required exceeds allowance or always failing transaction',
|
'gas required exceeds allowance or always failing transaction',
|
||||||
);
|
) ||
|
||||||
|
(CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP[chainId] &&
|
||||||
|
error.message.includes('gas required exceeds allowance'));
|
||||||
if (simulationFailed) {
|
if (simulationFailed) {
|
||||||
const estimateWithBuffer = addGasBuffer(
|
const estimateWithBuffer = addGasBuffer(
|
||||||
paramsForGasEstimate.gas,
|
paramsForGasEstimate?.gas ?? gasLimit,
|
||||||
blockGasLimit,
|
blockGasLimit,
|
||||||
1.5,
|
bufferMultiplier,
|
||||||
);
|
);
|
||||||
return addHexPrefix(estimateWithBuffer);
|
return addHexPrefix(estimateWithBuffer);
|
||||||
}
|
}
|
||||||
@ -362,9 +369,29 @@ export const computeEstimatedGasLimit = createAsyncThunk(
|
|||||||
const state = thunkApi.getState();
|
const state = thunkApi.getState();
|
||||||
const { send, metamask } = state;
|
const { send, metamask } = state;
|
||||||
const unapprovedTxs = getUnapprovedTxs(state);
|
const unapprovedTxs = getUnapprovedTxs(state);
|
||||||
|
const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state);
|
||||||
const transaction = unapprovedTxs[send.draftTransaction.id];
|
const transaction = unapprovedTxs[send.draftTransaction.id];
|
||||||
const isNonStandardEthChain = getIsNonStandardEthChain(state);
|
const isNonStandardEthChain = getIsNonStandardEthChain(state);
|
||||||
const chainId = getCurrentChainId(state);
|
const chainId = getCurrentChainId(state);
|
||||||
|
|
||||||
|
let layer1GasTotal;
|
||||||
|
if (isMultiLayerFeeNetwork) {
|
||||||
|
layer1GasTotal = await fetchEstimatedL1Fee(global.eth, {
|
||||||
|
txParams: {
|
||||||
|
gasPrice: send.gas.gasPrice,
|
||||||
|
gas: send.gas.gasLimit,
|
||||||
|
to: send.recipient.address?.toLowerCase(),
|
||||||
|
value:
|
||||||
|
send.amount.mode === 'MAX'
|
||||||
|
? send.account.balance
|
||||||
|
: send.amount.value,
|
||||||
|
from: send.account.address,
|
||||||
|
data: send.draftTransaction.userInputHexData,
|
||||||
|
type: '0x0',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
send.stage !== SEND_STAGES.EDIT ||
|
send.stage !== SEND_STAGES.EDIT ||
|
||||||
!transaction.dappSuggestedGasFees?.gas ||
|
!transaction.dappSuggestedGasFees?.gas ||
|
||||||
@ -380,10 +407,12 @@ export const computeEstimatedGasLimit = createAsyncThunk(
|
|||||||
data: send.draftTransaction.userInputHexData,
|
data: send.draftTransaction.userInputHexData,
|
||||||
isNonStandardEthChain,
|
isNonStandardEthChain,
|
||||||
chainId,
|
chainId,
|
||||||
|
gasLimit: send.gas.gasLimit,
|
||||||
});
|
});
|
||||||
await thunkApi.dispatch(setCustomGasLimit(gasLimit));
|
await thunkApi.dispatch(setCustomGasLimit(gasLimit));
|
||||||
return {
|
return {
|
||||||
gasLimit,
|
gasLimit,
|
||||||
|
layer1GasTotal,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -651,6 +680,10 @@ export const initialState = {
|
|||||||
// Warning to display on the address field
|
// Warning to display on the address field
|
||||||
warning: null,
|
warning: null,
|
||||||
},
|
},
|
||||||
|
multiLayerFees: {
|
||||||
|
// Layer 1 gas fee total on multi-layer fee networks
|
||||||
|
layer1GasTotal: '0x0',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const slice = createSlice({
|
const slice = createSlice({
|
||||||
@ -697,9 +730,13 @@ const slice = createSlice({
|
|||||||
multiplierBase: 10,
|
multiplierBase: 10,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
const _gasTotal = sumHexes(
|
||||||
|
state.gas.gasTotal || '0x0',
|
||||||
|
state.multiLayerFees?.layer1GasTotal || '0x0',
|
||||||
|
);
|
||||||
amount = subtractCurrencies(
|
amount = subtractCurrencies(
|
||||||
addHexPrefix(state.asset.balance),
|
addHexPrefix(state.asset.balance),
|
||||||
addHexPrefix(state.gas.gasTotal),
|
addHexPrefix(_gasTotal),
|
||||||
{
|
{
|
||||||
toNumericBase: 'hex',
|
toNumericBase: 'hex',
|
||||||
aBase: 16,
|
aBase: 16,
|
||||||
@ -881,6 +918,21 @@ const slice = createSlice({
|
|||||||
// Record the latest gasPriceEstimate for future comparisons
|
// Record the latest gasPriceEstimate for future comparisons
|
||||||
state.gas.gasPriceEstimate = addHexPrefix(gasPriceEstimate);
|
state.gas.gasPriceEstimate = addHexPrefix(gasPriceEstimate);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* sets the layer 1 fees total (for a multi-layer fee network)
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @param action
|
||||||
|
*/
|
||||||
|
updateLayer1Fees: (state, action) => {
|
||||||
|
state.multiLayerFees.layer1GasTotal = action.payload;
|
||||||
|
if (
|
||||||
|
state.amount.mode === AMOUNT_MODES.MAX &&
|
||||||
|
state.asset.type === ASSET_TYPES.NATIVE
|
||||||
|
) {
|
||||||
|
slice.caseReducers.updateAmountToMax(state);
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* sets the amount mode to the provided value as long as it is one of the
|
* sets the amount mode to the provided value as long as it is one of the
|
||||||
* supported modes (MAX|INPUT)
|
* supported modes (MAX|INPUT)
|
||||||
@ -1319,6 +1371,11 @@ const slice = createSlice({
|
|||||||
payload: action.payload.gasLimit,
|
payload: action.payload.gasLimit,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (action.payload?.layer1GasTotal) {
|
||||||
|
slice.caseReducers.updateLayer1Fees(state, {
|
||||||
|
payload: action.payload.layer1GasTotal,
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.addCase(computeEstimatedGasLimit.rejected, (state) => {
|
.addCase(computeEstimatedGasLimit.rejected, (state) => {
|
||||||
// If gas estimation fails, we should set the loading state to false,
|
// If gas estimation fails, we should set the loading state to false,
|
||||||
|
@ -44,7 +44,7 @@ export function useUserPreferencedCurrency(type, opts = {}) {
|
|||||||
getPreferences,
|
getPreferences,
|
||||||
shallowEqual,
|
shallowEqual,
|
||||||
);
|
);
|
||||||
const showFiat = useSelector(getShouldShowFiat);
|
const showFiat = useSelector(getShouldShowFiat) || opts.showFiatOverride;
|
||||||
const currentCurrency = useSelector(getCurrentCurrency);
|
const currentCurrency = useSelector(getCurrentCurrency);
|
||||||
|
|
||||||
let currency, numberOfDecimals;
|
let currency, numberOfDecimals;
|
||||||
|
@ -449,9 +449,7 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
detailTitle={
|
detailTitle={
|
||||||
txData.dappSuggestedGasFees ? (
|
txData.dappSuggestedGasFees ? (
|
||||||
<>
|
<>
|
||||||
{isMultiLayerFeeNetwork
|
{t('transactionDetailGasHeading')}
|
||||||
? t('transactionDetailLayer2GasHeading')
|
|
||||||
: t('transactionDetailGasHeading')}
|
|
||||||
<InfoTooltip
|
<InfoTooltip
|
||||||
contentText={t('transactionDetailDappGasTooltip')}
|
contentText={t('transactionDetailDappGasTooltip')}
|
||||||
position="top"
|
position="top"
|
||||||
@ -461,9 +459,7 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{isMultiLayerFeeNetwork
|
{t('transactionDetailGasHeading')}
|
||||||
? t('transactionDetailLayer2GasHeading')
|
|
||||||
: t('transactionDetailGasHeading')}
|
|
||||||
<InfoTooltip
|
<InfoTooltip
|
||||||
contentText={
|
contentText={
|
||||||
<>
|
<>
|
||||||
@ -492,16 +488,14 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
detailText={
|
detailText={
|
||||||
!isMultiLayerFeeNetwork && (
|
<div className="confirm-page-container-content__currency-container test">
|
||||||
<div className="confirm-page-container-content__currency-container">
|
{renderHeartBeatIfNotInTest()}
|
||||||
{renderHeartBeatIfNotInTest()}
|
<UserPreferencedCurrencyDisplay
|
||||||
<UserPreferencedCurrencyDisplay
|
type={SECONDARY}
|
||||||
type={SECONDARY}
|
value={hexMinimumTransactionFee}
|
||||||
value={hexMinimumTransactionFee}
|
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
detailTotal={
|
detailTotal={
|
||||||
<div className="confirm-page-container-content__currency-container">
|
<div className="confirm-page-container-content__currency-container">
|
||||||
@ -510,30 +504,28 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
type={PRIMARY}
|
type={PRIMARY}
|
||||||
value={hexMinimumTransactionFee}
|
value={hexMinimumTransactionFee}
|
||||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||||
numberOfDecimals={isMultiLayerFeeNetwork ? 18 : 6}
|
numberOfDecimals={6}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
subText={
|
subText={
|
||||||
!isMultiLayerFeeNetwork && (
|
<>
|
||||||
<>
|
<strong key="editGasSubTextFeeLabel">
|
||||||
<strong key="editGasSubTextFeeLabel">
|
{t('editGasSubTextFeeLabel')}
|
||||||
{t('editGasSubTextFeeLabel')}
|
</strong>
|
||||||
</strong>
|
<div
|
||||||
<div
|
key="editGasSubTextFeeValue"
|
||||||
key="editGasSubTextFeeValue"
|
className="confirm-page-container-content__currency-container"
|
||||||
className="confirm-page-container-content__currency-container"
|
>
|
||||||
>
|
{renderHeartBeatIfNotInTest()}
|
||||||
{renderHeartBeatIfNotInTest()}
|
<UserPreferencedCurrencyDisplay
|
||||||
<UserPreferencedCurrencyDisplay
|
key="editGasSubTextFeeAmount"
|
||||||
key="editGasSubTextFeeAmount"
|
type={PRIMARY}
|
||||||
type={PRIMARY}
|
value={hexMaximumTransactionFee}
|
||||||
value={hexMaximumTransactionFee}
|
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
subTitle={
|
subTitle={
|
||||||
<>
|
<>
|
||||||
@ -596,11 +588,15 @@ export default class ConfirmTransactionBase extends Component {
|
|||||||
disabled={isDisabled()}
|
disabled={isDisabled()}
|
||||||
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
||||||
onEdit={
|
onEdit={
|
||||||
renderSimulationFailureWarning ? null : () => this.handleEditGas()
|
renderSimulationFailureWarning || isMultiLayerFeeNetwork
|
||||||
|
? null
|
||||||
|
: () => this.handleEditGas()
|
||||||
}
|
}
|
||||||
rows={[
|
rows={[
|
||||||
renderSimulationFailureWarning && simulationFailureWarning(),
|
renderSimulationFailureWarning && simulationFailureWarning(),
|
||||||
!renderSimulationFailureWarning && renderGasDetailsItem(),
|
!renderSimulationFailureWarning &&
|
||||||
|
!isMultiLayerFeeNetwork &&
|
||||||
|
renderGasDetailsItem(),
|
||||||
!renderSimulationFailureWarning && isMultiLayerFeeNetwork && (
|
!renderSimulationFailureWarning && isMultiLayerFeeNetwork && (
|
||||||
<MultiLayerFeeMessage
|
<MultiLayerFeeMessage
|
||||||
transaction={txData}
|
transaction={txData}
|
||||||
|
@ -866,7 +866,7 @@ export function getIsOptimism(state) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNetworkSupportsSettingGasPrice(state) {
|
export function getNetworkSupportsSettingGasFees(state) {
|
||||||
return !getIsOptimism(state);
|
return !getIsOptimism(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user