diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index f46d6cdb5d6b..cfa1a07f97aa 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -27,7 +27,11 @@ import { TRANSACTION_ENVELOPE_TYPES, } from '../../../../shared/constants/transaction'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; -import { GAS_LIMITS } from '../../../../shared/constants/gas'; +import { + GAS_LIMITS, + GAS_ESTIMATE_TYPES, +} from '../../../../shared/constants/gas'; +import { decGWEIToHexWEI } from '../../../../shared/modules/conversion.utils'; import { HARDFORKS, MAINNET, @@ -107,6 +111,7 @@ export default class TransactionController extends EventEmitter { this.inProcessOfSigning = new Set(); this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent; this._getParticipateInMetrics = opts.getParticipateInMetrics; + this._getEIP1559GasFeeEstimates = opts.getEIP1559GasFeeEstimates; this.memStore = new ObservableStore({}); this.query = new EthQuery(this.provider); @@ -400,7 +405,13 @@ export default class TransactionController extends EventEmitter { * @returns {Promise} resolves with txMeta */ async addTxGasDefaults(txMeta, getCodeResponse) { - const defaultGasPrice = await this._getDefaultGasPrice(txMeta); + const eip1559Compatibility = await this.getEIP1559Compatibility(); + + const { + gasPrice: defaultGasPrice, + maxFeePerGas: defaultMaxFeePerGas, + maxPriorityFeePerGas: defaultMaxPriorityFeePerGas, + } = await this._getDefaultGasFees(txMeta, eip1559Compatibility); const { gasLimit: defaultGasLimit, simulationFails, @@ -411,6 +422,67 @@ export default class TransactionController extends EventEmitter { if (simulationFails) { txMeta.simulationFails = simulationFails; } + + if (eip1559Compatibility) { + // If the dapp has suggested a gas price, but no maxFeePerGas or maxPriorityFeePerGas + // then we set maxFeePerGas and maxPriorityFeePerGas to the suggested gasPrice. + if ( + txMeta.txParams.gasPrice && + !txMeta.txParams.maxFeePerGas && + !txMeta.txParams.maxPriorityFeePerGas + ) { + txMeta.txParams.maxFeePerGas = txMeta.txParams.gasPrice; + txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.gasPrice; + } else { + if (defaultMaxFeePerGas && !txMeta.txParams.maxFeePerGas) { + // If the dapp has not set the gasPrice or the maxFeePerGas, then we set maxFeePerGas + // with the one returned by the gasFeeController, if that is available. + txMeta.txParams.maxFeePerGas = defaultMaxFeePerGas; + } + + if ( + defaultMaxPriorityFeePerGas && + !txMeta.txParams.maxPriorityFeePerGas + ) { + // If the dapp has not set the gasPrice or the maxPriorityFeePerGas, then we set maxPriorityFeePerGas + // with the one returned by the gasFeeController, if that is available. + txMeta.txParams.maxPriorityFeePerGas = defaultMaxPriorityFeePerGas; + } + + if (defaultGasPrice && !txMeta.txParams.maxFeePerGas) { + // If the dapp has not set the gasPrice or the maxFeePerGas, and no maxFeePerGas is available + // from the gasFeeController, then we set maxFeePerGas to the defaultGasPrice, assuming it is + // available. + txMeta.txParams.maxFeePerGas = defaultGasPrice; + } + + if ( + txMeta.txParams.maxFeePerGas && + !txMeta.txParams.maxPriorityFeePerGas + ) { + // If the dapp has not set the gasPrice or the maxPriorityFeePerGas, and no maxPriorityFeePerGas is + // available from the gasFeeController, then we set maxPriorityFeePerGas to + // txMeta.txParams.maxFeePerGas, which will either be the gasPrice from the controller, the maxFeePerGas + // set by the dapp, or the maxFeePerGas from the controller. + txMeta.txParams.maxPriorityFeePerGas = txMeta.txParams.maxFeePerGas; + } + } + + // We remove the gasPrice param entirely when on an eip1559 compatible network + + delete txMeta.txParams.gasPrice; + } else { + // We ensure that maxFeePerGas and maxPriorityFeePerGas are not in the transaction params + // when not on a EIP1559 compatible network + + delete txMeta.txParams.maxPriorityFeePerGas; + delete txMeta.txParams.maxFeePerGas; + } + + // If we have gotten to this point, and none of gasPrice, maxPriorityFeePerGas or maxFeePerGas are + // set on txParams, it means that either we are on a non-EIP1559 network and the dapp didn't suggest + // a gas price, or we are on an EIP1559 network, and none of gasPrice, maxPriorityFeePerGas or maxFeePerGas + // were available from either the dapp or the network. if ( defaultGasPrice && !txMeta.txParams.gasPrice && @@ -419,6 +491,7 @@ export default class TransactionController extends EventEmitter { ) { txMeta.txParams.gasPrice = defaultGasPrice; } + if (defaultGasLimit && !txMeta.txParams.gas) { txMeta.txParams.gas = defaultGasLimit; } @@ -426,20 +499,59 @@ export default class TransactionController extends EventEmitter { } /** - * Gets default gas price, or returns `undefined` if gas price is already set + * Gets default gas fees, or returns `undefined` if gas fees are already set * @param {Object} txMeta - The txMeta object * @returns {Promise} The default gas price */ - async _getDefaultGasPrice(txMeta) { + async _getDefaultGasFees(txMeta, eip1559Compatibility) { if ( - txMeta.txParams.gasPrice || + (!eip1559Compatibility && txMeta.txParams.gasPrice) || (txMeta.txParams.maxFeePerGas && txMeta.txParams.maxPriorityFeePerGas) ) { - return undefined; + return {}; + } + + try { + const { + gasFeeEstimates, + gasEstimateType, + } = await this._getEIP1559GasFeeEstimates(); + if ( + eip1559Compatibility && + gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET + ) { + const { + medium: { suggestedMaxPriorityFeePerGas, suggestedMaxFeePerGas } = {}, + } = gasFeeEstimates; + + if (suggestedMaxPriorityFeePerGas && suggestedMaxFeePerGas) { + return { + maxFeePerGas: decGWEIToHexWEI(suggestedMaxFeePerGas), + maxPriorityFeePerGas: decGWEIToHexWEI( + suggestedMaxPriorityFeePerGas, + ), + }; + } + } else if (gasEstimateType === GAS_ESTIMATE_TYPES.LEGACY) { + // The LEGACY type includes low, medium and high estimates of + // gas price values. + return { + gasPrice: decGWEIToHexWEI(gasFeeEstimates.medium), + }; + } else if (gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE) { + // The ETH_GASPRICE type just includes a single gas price property, + // which we can assume was retrieved from eth_gasPrice + return { + gasPrice: decGWEIToHexWEI(gasFeeEstimates.gasPrice), + }; + } + } catch (e) { + console.error(e); } + const gasPrice = await this.query.gasPrice(); - return addHexPrefix(gasPrice.toString(16)); + return { gasPrice: gasPrice && addHexPrefix(gasPrice.toString(16)) }; } /** @@ -683,7 +795,7 @@ export default class TransactionController extends EventEmitter { this.txStateManager.setTxStatusApproved(txId); // get next nonce const txMeta = this.txStateManager.getTransaction(txId); - console.log(txMeta); + const fromAddress = txMeta.txParams.from; // wait for a nonce let { customNonceValue } = txMeta; diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 9a415b280717..8d12c4138d20 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -14,6 +14,7 @@ import { TRANSACTION_TYPES, } from '../../../../shared/constants/transaction'; import { SECOND } from '../../../../shared/constants/time'; +import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; import TransactionController, { TRANSACTION_EVENTS } from '.'; @@ -50,9 +51,8 @@ describe('Transaction Controller', function () { return '0xee6b2800'; }, networkStore: new ObservableStore(currentNetworkId), - getEIP1559Compatibility: () => Promise.resolve(true), - getCurrentNetworkEIP1559Compatibility: () => Promise.resolve(true), - getCurrentAccountEIP1559Compatibility: () => true, + getCurrentNetworkEIP1559Compatibility: () => Promise.resolve(false), + getCurrentAccountEIP1559Compatibility: () => false, txHistoryLimit: 10, blockTracker: blockTrackerStub, signTransaction: (ethTx) => @@ -64,6 +64,7 @@ describe('Transaction Controller', function () { getCurrentChainId: () => currentChainId, getParticipateInMetrics: () => false, trackMetaMetricsEvent: () => undefined, + getEIP1559GasFeeEstimates: () => undefined, }); txController.nonceTracker.getNonceLock = () => Promise.resolve({ nextNonce: 0, releaseLock: noop }); @@ -419,6 +420,237 @@ describe('Transaction Controller', function () { 'should have added the gas field', ); }); + + it('should add EIP1559 tx defaults', async function () { + const TEST_MAX_FEE_PER_GAS = '0x12a05f200'; + const TEST_MAX_PRIORITY_FEE_PER_GAS = '0x77359400'; + + const stub1 = sinon + .stub(txController, 'getEIP1559Compatibility') + .returns(true); + + const stub2 = sinon + .stub(txController, '_getDefaultGasFees') + .callsFake(() => ({ + maxFeePerGas: TEST_MAX_FEE_PER_GAS, + maxPriorityFeePerGas: TEST_MAX_PRIORITY_FEE_PER_GAS, + })); + + txController.txStateManager._addTransactionsToState([ + { + id: 1, + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + to: VALID_ADDRESS, + from: VALID_ADDRESS_TWO, + }, + history: [{}], + }, + ]); + const txMeta = { + id: 1, + txParams: { + from: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + }, + history: [{}], + }; + providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }; + providerResultStub.eth_estimateGas = '5209'; + + const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta); + + assert.equal( + txMetaWithDefaults.txParams.maxFeePerGas, + TEST_MAX_FEE_PER_GAS, + 'should have added the correct max fee per gas', + ); + assert.equal( + txMetaWithDefaults.txParams.maxPriorityFeePerGas, + TEST_MAX_PRIORITY_FEE_PER_GAS, + 'should have added the correct max priority fee per gas', + ); + stub1.restore(); + stub2.restore(); + }); + + it('should add gasPrice as maxFeePerGas and maxPriorityFeePerGas if there are no sources of other fee data available', async function () { + const TEST_GASPRICE = '0x12a05f200'; + + const stub1 = sinon + .stub(txController, 'getEIP1559Compatibility') + .returns(true); + + const stub2 = sinon + .stub(txController, '_getDefaultGasFees') + .callsFake(() => ({ gasPrice: TEST_GASPRICE })); + + txController.txStateManager._addTransactionsToState([ + { + id: 1, + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + to: VALID_ADDRESS, + from: VALID_ADDRESS_TWO, + }, + history: [{}], + }, + ]); + const txMeta = { + id: 1, + txParams: { + from: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + }, + history: [{}], + }; + providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }; + providerResultStub.eth_estimateGas = '5209'; + + const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta); + + assert.equal( + txMetaWithDefaults.txParams.maxFeePerGas, + TEST_GASPRICE, + 'should have added the correct max fee per gas', + ); + assert.equal( + txMetaWithDefaults.txParams.maxPriorityFeePerGas, + TEST_GASPRICE, + 'should have added the correct max priority fee per gas', + ); + stub1.restore(); + stub2.restore(); + }); + + it('should not add gasPrice if the fee data is available from the dapp', async function () { + const TEST_GASPRICE = '0x12a05f200'; + const TEST_MAX_FEE_PER_GAS = '0x12a05f200'; + const TEST_MAX_PRIORITY_FEE_PER_GAS = '0x77359400'; + + const stub1 = sinon + .stub(txController, 'getEIP1559Compatibility') + .returns(true); + + const stub2 = sinon + .stub(txController, '_getDefaultGasFees') + .callsFake(() => ({ gasPrice: TEST_GASPRICE })); + + txController.txStateManager._addTransactionsToState([ + { + id: 1, + status: TRANSACTION_STATUSES.UNAPPROVED, + metamaskNetworkId: currentNetworkId, + txParams: { + to: VALID_ADDRESS, + from: VALID_ADDRESS_TWO, + maxFeePerGas: TEST_MAX_FEE_PER_GAS, + maxPriorityFeePerGas: TEST_MAX_PRIORITY_FEE_PER_GAS, + }, + history: [{}], + }, + ]); + const txMeta = { + id: 1, + txParams: { + from: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + to: '0xc684832530fcbddae4b4230a47e991ddcec2831d', + }, + history: [{}], + }; + providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }; + providerResultStub.eth_estimateGas = '5209'; + + const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta); + + assert.equal( + txMetaWithDefaults.txParams.maxFeePerGas, + TEST_MAX_FEE_PER_GAS, + 'should have added the correct max fee per gas', + ); + assert.equal( + txMetaWithDefaults.txParams.maxPriorityFeePerGas, + TEST_MAX_PRIORITY_FEE_PER_GAS, + 'should have added the correct max priority fee per gas', + ); + stub1.restore(); + stub2.restore(); + }); + }); + + describe('_getDefaultGasFees', function () { + let getGasFeeStub; + + beforeEach(function () { + getGasFeeStub = sinon.stub(txController, '_getEIP1559GasFeeEstimates'); + }); + + afterEach(function () { + getGasFeeStub.restore(); + }); + + it('should return the correct fee data when the gas estimate type is FEE_MARKET', async function () { + const EXPECTED_MAX_FEE_PER_GAS = '12a05f200'; + const EXPECTED_MAX_PRIORITY_FEE_PER_GAS = '77359400'; + + getGasFeeStub.callsFake(() => ({ + gasFeeEstimates: { + medium: { + suggestedMaxPriorityFeePerGas: '2', + suggestedMaxFeePerGas: '5', + }, + }, + gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET, + })); + + const defaultGasFees = await txController._getDefaultGasFees( + { txParams: {} }, + true, + ); + + assert.deepEqual(defaultGasFees, { + maxPriorityFeePerGas: EXPECTED_MAX_PRIORITY_FEE_PER_GAS, + maxFeePerGas: EXPECTED_MAX_FEE_PER_GAS, + }); + }); + + it('should return the correct fee data when the gas estimate type is LEGACY', async function () { + const EXPECTED_GAS_PRICE = '77359400'; + + getGasFeeStub.callsFake(() => ({ + gasFeeEstimates: { medium: '2' }, + gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY, + })); + + const defaultGasFees = await txController._getDefaultGasFees( + { txParams: {} }, + false, + ); + + assert.deepEqual(defaultGasFees, { + gasPrice: EXPECTED_GAS_PRICE, + }); + }); + + it('should return the correct fee data when the gas estimate type is ETH_GASPRICE', async function () { + const EXPECTED_GAS_PRICE = '77359400'; + + getGasFeeStub.callsFake(() => ({ + gasFeeEstimates: { gasPrice: '2' }, + gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE, + })); + + const defaultGasFees = await txController._getDefaultGasFees( + { txParams: {} }, + false, + ); + + assert.deepEqual(defaultGasFees, { + gasPrice: EXPECTED_GAS_PRICE, + }); + }); }); describe('#addTransaction', function () { @@ -807,6 +1039,9 @@ describe('Transaction Controller', function () { }); it('sets txParams.type to 0x2 (EIP-1559)', async function () { + const eip1559CompatibilityStub = sinon + .stub(txController, 'getEIP1559Compatibility') + .returns(true); txController.txStateManager._addTransactionsToState([ { status: TRANSACTION_STATUSES.UNAPPROVED, @@ -825,6 +1060,7 @@ describe('Transaction Controller', function () { ]); await txController.signTransaction('2'); assert.equal(fromTxDataSpy.getCall(0).args[0].type, '0x2'); + eip1559CompatibilityStub.restore(); }); }); diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 5e095e2a565e..bb17887e0d49 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -423,6 +423,9 @@ export default class MetamaskController extends EventEmitter { ), getParticipateInMetrics: () => this.metaMetricsController.state.participateInMetaMetrics, + getEIP1559GasFeeEstimates: this.gasFeeController.fetchGasFeeEstimates.bind( + this.gasFeeController, + ), }); this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()); diff --git a/package.json b/package.json index e9d75204ddde..848c2ddf3b75 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "@fortawesome/fontawesome-free": "^5.13.0", "@material-ui/core": "^4.11.0", "@metamask/contract-metadata": "^1.28.0", - "@metamask/controllers": "^12.0.0", + "@metamask/controllers": "^14.0.2", "@metamask/eth-ledger-bridge-keyring": "^0.6.0", "@metamask/eth-token-tracker": "^3.0.1", "@metamask/etherscan-link": "^2.1.0", diff --git a/shared/modules/conversion.utils.js b/shared/modules/conversion.utils.js index 0b550e67bfd4..bad872787a78 100644 --- a/shared/modules/conversion.utils.js +++ b/shared/modules/conversion.utils.js @@ -268,6 +268,15 @@ const toNegative = (n, options = {}) => { return multiplyCurrencies(n, -1, options); }; +function decGWEIToHexWEI(decGWEI) { + return conversionUtil(decGWEI, { + fromNumericBase: 'dec', + toNumericBase: 'hex', + fromDenomination: 'GWEI', + toDenomination: 'WEI', + }); +} + export { conversionUtil, addCurrencies, @@ -279,4 +288,5 @@ export { conversionMax, toNegative, subtractCurrencies, + decGWEIToHexWEI, }; 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 23f2e77cbcaa..c6980624b970 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 @@ -33,31 +33,33 @@ export default function AdvancedGasControls({ maxPriorityFeeFiat, maxFeeFiat, gasErrors, + networkSupportsEIP1559, }) { const t = useContext(I18nContext); const suggestedValues = {}; - switch (gasEstimateType) { - case GAS_ESTIMATE_TYPES.FEE_MARKET: - suggestedValues.maxPriorityFeePerGas = - gasFeeEstimates?.[estimateToUse]?.suggestedMaxPriorityFeePerGas; - suggestedValues.maxFeePerGas = - gasFeeEstimates?.[estimateToUse]?.suggestedMaxFeePerGas; - break; - case GAS_ESTIMATE_TYPES.LEGACY: - suggestedValues.gasPrice = gasFeeEstimates?.[estimateToUse]; - break; - case GAS_ESTIMATE_TYPES.ETH_GASPRICE: - suggestedValues.gasPrice = gasFeeEstimates?.gasPrice; - break; - default: - break; + if (networkSupportsEIP1559) { + suggestedValues.maxFeePerGas = + gasFeeEstimates?.[estimateToUse]?.suggestedMaxFeePerGas || + gasFeeEstimates?.gasPrice; + suggestedValues.maxPriorityFeePerGas = + gasFeeEstimates?.[estimateToUse]?.suggestedMaxPriorityFeePerGas || + suggestedValues.maxFeePerGas; + } else { + switch (gasEstimateType) { + case GAS_ESTIMATE_TYPES.LEGACY: + suggestedValues.gasPrice = gasFeeEstimates?.[estimateToUse]; + break; + case GAS_ESTIMATE_TYPES.ETH_GASPRICE: + suggestedValues.gasPrice = gasFeeEstimates?.gasPrice; + break; + default: + break; + } } - const showFeeMarketFields = - process.env.SHOW_EIP_1559_UI && - gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET; + const showFeeMarketFields = networkSupportsEIP1559; return (
@@ -231,4 +233,5 @@ AdvancedGasControls.propTypes = { maxPriorityFeeFiat: PropTypes.string, maxFeeFiat: PropTypes.string, gasErrors: PropTypes.object, + networkSupportsEIP1559: PropTypes.object, }; diff --git a/ui/components/app/edit-gas-display/edit-gas-display.component.js b/ui/components/app/edit-gas-display/edit-gas-display.component.js index f9417ae4c5e8..be537b62a0c8 100644 --- a/ui/components/app/edit-gas-display/edit-gas-display.component.js +++ b/ui/components/app/edit-gas-display/edit-gas-display.component.js @@ -7,10 +7,10 @@ import { EDIT_GAS_MODES, } from '../../../../shared/constants/gas'; -import { isEIP1559Network } from '../../../ducks/metamask/metamask'; - import Button from '../../ui/button'; import Typography from '../../ui/typography/typography'; +import { isEIP1559Network } from '../../../ducks/metamask/metamask'; + import { COLORS, TYPOGRAPHY, @@ -62,6 +62,7 @@ export default function EditGasDisplay({ onManualChange, }) { const t = useContext(I18nContext); + const supportsEIP1559 = useSelector(isEIP1559Network); const dappSuggestedAndTxParamGasFeesAreTheSame = areDappSuggestedAndTxParamGasFeesTheSame( transaction, @@ -128,7 +129,11 @@ export default function EditGasDisplay({ , ]) } - timing={} + timing={ + supportsEIP1559 && ( + + ) + } /> {requireDappAcknowledgement && (
diff --git a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js index fc55ec9a296c..91b85c21d131 100644 --- a/ui/components/app/edit-gas-popover/edit-gas-popover.component.js +++ b/ui/components/app/edit-gas-popover/edit-gas-popover.component.js @@ -1,14 +1,11 @@ import React, { useCallback, useContext, useState } from 'react'; import PropTypes from 'prop-types'; - import { useDispatch, useSelector } from 'react-redux'; +import { isEIP1559Network } from '../../../ducks/metamask/metamask'; import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs'; import { useShouldAnimateGasEstimations } from '../../../hooks/useShouldAnimateGasEstimations'; -import { - GAS_ESTIMATE_TYPES, - EDIT_GAS_MODES, -} from '../../../../shared/constants/gas'; +import { EDIT_GAS_MODES } from '../../../../shared/constants/gas'; import { decGWEIToHexWEI, @@ -42,6 +39,7 @@ export default function EditGasPopover({ const t = useContext(I18nContext); const dispatch = useDispatch(); const showSidebar = useSelector((state) => state.appState.sidebar.isOpen); + const supportsEIP1559 = useSelector(isEIP1559Network); const shouldAnimate = useShouldAnimateGasEstimations(); @@ -105,19 +103,20 @@ export default function EditGasPopover({ closePopover(); } - const newGasSettings = - gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET - ? { - gas: decimalToHex(gasLimit), - gasLimit: decimalToHex(gasLimit), - maxFeePerGas: decGWEIToHexWEI(maxFeePerGas), - maxPriorityFeePerGas: decGWEIToHexWEI(maxPriorityFeePerGas), - } - : { - gas: decimalToHex(gasLimit), - gasLimit: decimalToHex(gasLimit), - gasPrice: decGWEIToHexWEI(gasPrice), - }; + const newGasSettings = supportsEIP1559 + ? { + gas: decimalToHex(gasLimit), + gasLimit: decimalToHex(gasLimit), + maxFeePerGas: decGWEIToHexWEI(maxFeePerGas ?? gasPrice), + maxPriorityFeePerGas: decGWEIToHexWEI( + maxPriorityFeePerGas ?? maxFeePerGas ?? gasPrice, + ), + } + : { + gas: decimalToHex(gasLimit), + gasLimit: decimalToHex(gasLimit), + gasPrice: decGWEIToHexWEI(gasPrice), + }; switch (mode) { case EDIT_GAS_MODES.CANCEL: @@ -151,7 +150,7 @@ export default function EditGasPopover({ gasPrice, maxFeePerGas, maxPriorityFeePerGas, - gasEstimateType, + supportsEIP1559, ]); let title = t('editGasTitle'); diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index 2b8669fc95a5..3d20a9f7d2b4 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -73,6 +73,7 @@ import { getGasEstimateType, getTokens, getUnapprovedTxs, + isEIP1559Network, } from '../metamask/metamask'; import { resetEnsResolution } from '../ens'; import { @@ -408,6 +409,7 @@ export const initializeSendState = createAsyncThunk( const state = thunkApi.getState(); const isNonStandardEthChain = getIsNonStandardEthChain(state); const chainId = getCurrentChainId(state); + const eip1559support = isEIP1559Network(state); const { send: { asset, stage, recipient, amount, draftTransaction }, metamask, @@ -505,6 +507,7 @@ export const initializeSendState = createAsyncThunk( gasLimit, gasTotal: addHexPrefix(calcGasTotal(gasLimit, gasPrice)), gasEstimatePollToken, + eip1559support, }; }, ); @@ -516,6 +519,8 @@ export const initialState = { status: SEND_STATUSES.VALID, // Determines type of transaction being sent, defaulted to 0x0 (legacy) transactionType: TRANSACTION_ENVELOPE_TYPES.LEGACY, + // tracks whether the current network supports EIP 1559 transactions + eip1559support: false, account: { // from account address, defaults to selected account. will be the account // the original transaction was sent from in the case of the EDIT stage @@ -910,28 +915,40 @@ const slice = createSlice({ } // We need to make sure that we only include the right gas fee fields - // based on the type of transaction we are sending. We will also set + // based on the type of transaction the network supports. We will also set // the type param here. We must delete the opposite fields to avoid // stale data in txParams. - switch (state.transactionType) { - case TRANSACTION_ENVELOPE_TYPES.FEE_MARKET: - delete state.draftTransaction.txParams.gasPrice; + if (state.eip1559support) { + state.draftTransaction.txParams.type = + TRANSACTION_ENVELOPE_TYPES.FEE_MARKET; + + state.draftTransaction.txParams.maxFeePerGas = state.gas.maxFeePerGas; + state.draftTransaction.txParams.maxPriorityFeePerGas = + state.gas.maxPriorityFeePerGas; + + if ( + !state.draftTransaction.txParams.maxFeePerGas || + state.draftTransaction.txParams.maxFeePerGas === '0x0' + ) { + state.draftTransaction.txParams.maxFeePerGas = state.gas.gasPrice; + } - state.draftTransaction.txParams.type = - TRANSACTION_ENVELOPE_TYPES.FEE_MARKET; + if ( + !state.draftTransaction.txParams.maxPriorityFeePerGas || + state.draftTransaction.txParams.maxPriorityFeePerGas === '0x0' + ) { state.draftTransaction.txParams.maxPriorityFeePerGas = - state.gas.maxPriorityFeePerGas; - state.draftTransaction.txParams.maxFeePerGas = - state.gas.maxFeePerGas; - break; - case TRANSACTION_ENVELOPE_TYPES.LEGACY: - default: - delete state.draftTransaction.txParams.maxFeePerGas; - delete state.draftTransaction.txParams.maxPriorityFeePerGas; + state.draftTransaction.txParams.maxFeePerGas; + } + + delete state.draftTransaction.txParams.gasPrice; + } else { + delete state.draftTransaction.txParams.maxFeePerGas; + delete state.draftTransaction.txParams.maxPriorityFeePerGas; - state.draftTransaction.txParams.gasPrice = state.gas.gasPrice; - state.draftTransaction.txParams.type = - TRANSACTION_ENVELOPE_TYPES.LEGACY; + state.draftTransaction.txParams.gasPrice = state.gas.gasPrice; + state.draftTransaction.txParams.type = + TRANSACTION_ENVELOPE_TYPES.LEGACY; } } }, @@ -1163,6 +1180,7 @@ const slice = createSlice({ .addCase(initializeSendState.fulfilled, (state, action) => { // writes the computed initialized state values into the slice and then // calculates slice validity using the caseReducers. + state.eip1559support = action.payload.eip1559support; state.account.address = action.payload.address; state.account.balance = action.payload.nativeBalance; state.asset.balance = action.payload.assetBalance; diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index 5212082478ff..bc34c4ec56f8 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -474,6 +474,7 @@ describe('Send Slice', () => { maxPriorityFeePerGas: '0x3b9aca00', // 1 GWEI gasLimit: '0x5208', // 21000 }, + eip1559support: true, }; const action = { @@ -524,6 +525,7 @@ describe('Send Slice', () => { maxPriorityFeePerGas: '0x3b9aca00', // 1 GWEI gasLimit: '0x5208', // 21000 }, + eip1559support: true, }; const action = { diff --git a/ui/hooks/useGasFeeEstimates.js b/ui/hooks/useGasFeeEstimates.js index e5ce222355a6..c17c43e75b9e 100644 --- a/ui/hooks/useGasFeeEstimates.js +++ b/ui/hooks/useGasFeeEstimates.js @@ -42,12 +42,14 @@ export function useGasFeeEstimates() { useSafeGasEstimatePolling(); // We consider the gas estimate to be loading if the gasEstimateType is - // 'NONE' or if the current gasEstimateType does not match the type we expect - // for the current network. e.g, a ETH_GASPRICE estimate when on a network - // supporting EIP-1559. + // 'NONE' or if the current gasEstimateType cannot be supported by the current + // network + const isEIP1559TolerableEstimateType = + gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET || + gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE; const isGasEstimatesLoading = gasEstimateType === GAS_ESTIMATE_TYPES.NONE || - (supportsEIP1559 && gasEstimateType !== GAS_ESTIMATE_TYPES.FEE_MARKET) || + (supportsEIP1559 && !isEIP1559TolerableEstimateType) || (!supportsEIP1559 && gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET); return { diff --git a/ui/hooks/useGasFeeEstimates.test.js b/ui/hooks/useGasFeeEstimates.test.js index d30127759921..3b54dd825a37 100644 --- a/ui/hooks/useGasFeeEstimates.test.js +++ b/ui/hooks/useGasFeeEstimates.test.js @@ -173,11 +173,11 @@ describe('useGasFeeEstimates', () => { }); }); - it('indicates that gas estimates are loading when gasEstimateType is not FEE_MARKET but network supports EIP-1559', () => { + it('indicates that gas estimates are loading when gasEstimateType is not FEE_MARKET or ETH_GASPRICE, but network supports EIP-1559', () => { useSelector.mockImplementation( generateUseSelectorRouter({ isEIP1559Network: true, - gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE, + gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY, gasFeeEstimates: { gasPrice: '10', }, @@ -189,7 +189,7 @@ describe('useGasFeeEstimates', () => { } = renderHook(() => useGasFeeEstimates()); expect(current).toMatchObject({ gasFeeEstimates: { gasPrice: '10' }, - gasEstimateType: GAS_ESTIMATE_TYPES.ETH_GASPRICE, + gasEstimateType: GAS_ESTIMATE_TYPES.LEGACY, estimatedGasFeeTimeBounds: undefined, isGasEstimatesLoading: true, }); diff --git a/ui/hooks/useGasFeeInputs.js b/ui/hooks/useGasFeeInputs.js index 140e0fa198b4..fd9a01790180 100644 --- a/ui/hooks/useGasFeeInputs.js +++ b/ui/hooks/useGasFeeInputs.js @@ -10,6 +10,8 @@ import { getMinimumGasTotalInHexWei, } from '../../shared/modules/gas.utils'; import { PRIMARY, SECONDARY } from '../helpers/constants/common'; +import { isEIP1559Network } from '../ducks/metamask/metamask'; + import { hexWEIToDecGWEI, decGWEIToHexWEI, @@ -153,6 +155,7 @@ function getMatchingEstimateFromGasFees( * ).GasEstimates} - gas fee input state and the GasFeeEstimates object */ export function useGasFeeInputs(defaultEstimateToUse = 'medium', transaction) { + const networkSupportsEIP1559 = useSelector(isEIP1559Network); // We need to know whether to show fiat conversions or not, so that we can // default our fiat values to empty strings if showing fiat is not wanted or // possible. @@ -260,11 +263,13 @@ export function useGasFeeInputs(defaultEstimateToUse = 'medium', transaction) { const gasSettings = { gasLimit: decimalToHex(gasLimit), }; - if (gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET) { - gasSettings.maxFeePerGas = decGWEIToHexWEI(maxFeePerGasToUse); - gasSettings.maxPriorityFeePerGas = decGWEIToHexWEI( - maxPriorityFeePerGasToUse, - ); + if (networkSupportsEIP1559) { + gasSettings.maxFeePerGas = maxFeePerGasToUse + ? decGWEIToHexWEI(maxFeePerGasToUse) + : decGWEIToHexWEI(gasPriceToUse); + gasSettings.maxPriorityFeePerGas = maxPriorityFeePerGas + ? decGWEIToHexWEI(maxPriorityFeePerGas) + : gasSettings.maxFeePerGas; gasSettings.baseFeePerGas = decGWEIToHexWEI( gasFeeEstimates.estimatedBaseFee ?? '0', ); diff --git a/ui/hooks/useGasFeeInputs.test.js b/ui/hooks/useGasFeeInputs.test.js index a4b1400bb6ee..64eff46a3eff 100644 --- a/ui/hooks/useGasFeeInputs.test.js +++ b/ui/hooks/useGasFeeInputs.test.js @@ -3,9 +3,11 @@ import { useSelector } from 'react-redux'; import { GAS_ESTIMATE_TYPES } from '../../shared/constants/gas'; import { multiplyCurrencies } from '../../shared/modules/conversion.utils'; import { + isEIP1559Network, getConversionRate, getNativeCurrency, } from '../ducks/metamask/metamask'; + import { ETH, PRIMARY } from '../helpers/constants/common'; import { getCurrentCurrency, getShouldShowFiat } from '../selectors'; import { useGasFeeEstimates } from './useGasFeeEstimates'; @@ -71,7 +73,9 @@ const FEE_MARKET_ESTIMATE_RETURN_VALUE = { estimatedGasFeeTimeBounds: {}, }; -const generateUseSelectorRouter = () => (selector) => { +const generateUseSelectorRouter = ({ isEIP1559NetworkResponse } = {}) => ( + selector, +) => { if (selector === getConversionRate) { return MOCK_ETH_USD_CONVERSION_RATE; } @@ -84,6 +88,9 @@ const generateUseSelectorRouter = () => (selector) => { if (selector === getShouldShowFiat) { return true; } + if (selector === isEIP1559Network) { + return isEIP1559NetworkResponse; + } return undefined; }; @@ -135,6 +142,9 @@ describe('useGasFeeInputs', () => { }); it('updates values when user modifies gasPrice', () => { + useSelector.mockImplementation( + generateUseSelectorRouter({ isEIP1559NetworkResponse: false }), + ); const { result } = renderHook(() => useGasFeeInputs()); expect(result.current.gasPrice).toBe( LEGACY_GAS_ESTIMATE_RETURN_VALUE.gasFeeEstimates.medium, @@ -199,6 +209,9 @@ describe('useGasFeeInputs', () => { }); it('updates values when user modifies maxFeePerGas', () => { + useSelector.mockImplementation( + generateUseSelectorRouter({ isEIP1559NetworkResponse: true }), + ); const { result } = renderHook(() => useGasFeeInputs()); expect(result.current.maxFeePerGas).toBe( FEE_MARKET_ESTIMATE_RETURN_VALUE.gasFeeEstimates.medium diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js index 4e6c601b1b72..a086c48e49d2 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -116,6 +116,7 @@ export default class ConfirmTransactionBase extends Component { isEthGasPrice: PropTypes.bool, noGasPrice: PropTypes.bool, setDefaultHomeActiveTabName: PropTypes.func, + supportsEIP1599: PropTypes.bool, }; state = { @@ -303,6 +304,7 @@ export default class ConfirmTransactionBase extends Component { isEthGasPrice, noGasPrice, txData, + supportsEIP1599, } = this.props; const { t } = this.context; @@ -385,7 +387,9 @@ export default class ConfirmTransactionBase extends Component { detailTitle={ txData.dappSuggestedGasFees ? ( <> - {t('transactionDetailDappGasHeading', [getRequestingOrigin()])} + {t('transactionDetailDappGasHeading', [ + getRequestingOrigin(), + ])} , ])} subTitle={ - + supportsEIP1599 && ( + + ) } />, { @@ -65,6 +68,7 @@ const mapStateToProps = (state, ownProps) => { } = ownProps; const { id: paramsTransactionId } = params; const isMainnet = getIsMainnet(state); + const supportsEIP1599 = isEIP1559Network(state); const { confirmTransaction, metamask } = state; const { ensResolutionsByAddress, @@ -189,6 +193,7 @@ const mapStateToProps = (state, ownProps) => { isMainnet, isEthGasPrice, noGasPrice, + supportsEIP1599, }; }; diff --git a/ui/selectors/confirm-transaction.js b/ui/selectors/confirm-transaction.js index b3c3ea1bc358..d97b009af7bf 100644 --- a/ui/selectors/confirm-transaction.js +++ b/ui/selectors/confirm-transaction.js @@ -14,6 +14,7 @@ import { getGasEstimateType, getGasFeeEstimates, getNativeCurrency, + isEIP1559Network, } from '../ducks/metamask/metamask'; import { TRANSACTION_ENVELOPE_TYPES } from '../../shared/constants/transaction'; import { decGWEIToHexWEI } from '../helpers/utils/conversions.util'; @@ -228,44 +229,52 @@ export const transactionFeeSelector = function (state, txData) { const currentCurrency = currentCurrencySelector(state); const conversionRate = conversionRateSelector(state); const nativeCurrency = getNativeCurrency(state); - const gasFeeEstimates = getGasFeeEstimates(state); + const gasFeeEstimates = getGasFeeEstimates(state) || {}; const gasEstimateType = getGasEstimateType(state); + const networkSupportsEIP1559 = isEIP1559Network(state); const gasEstimationObject = { gasLimit: txData.txParams?.gas ?? '0x0', }; - switch (gasEstimateType) { - case GAS_ESTIMATE_TYPES.NONE: - gasEstimationObject.gasPrice = txData.txParams?.gasPrice ?? '0x0'; - break; - case GAS_ESTIMATE_TYPES.ETH_GASPRICE: + if (networkSupportsEIP1559) { + const { medium = {}, gasPrice = '0' } = gasFeeEstimates; + if (txData.txParams?.type === TRANSACTION_ENVELOPE_TYPES.LEGACY) { gasEstimationObject.gasPrice = - txData.txParams?.gasPrice ?? decGWEIToHexWEI(gasFeeEstimates.gasPrice); - break; - case GAS_ESTIMATE_TYPES.LEGACY: - gasEstimationObject.gasPrice = - txData.txParams?.gasPrice ?? getAveragePriceEstimateInHexWEI(state); - break; - case GAS_ESTIMATE_TYPES.FEE_MARKET: - if (txData.txParams?.type === TRANSACTION_ENVELOPE_TYPES.LEGACY) { + txData.txParams?.gasPrice ?? decGWEIToHexWEI(gasPrice); + } else { + const { suggestedMaxPriorityFeePerGas, suggestedMaxFeePerGas } = medium; + gasEstimationObject.maxFeePerGas = + txData.txParams?.maxFeePerGas ?? + decGWEIToHexWEI(suggestedMaxFeePerGas || gasPrice); + gasEstimationObject.maxPriorityFeePerGas = + txData.txParams?.maxPriorityFeePerGas ?? + ((suggestedMaxPriorityFeePerGas && + decGWEIToHexWEI(suggestedMaxPriorityFeePerGas)) || + gasEstimationObject.maxFeePerGas); + gasEstimationObject.baseFeePerGas = decGWEIToHexWEI( + gasFeeEstimates.estimatedBaseFee, + ); + } + } else { + switch (gasEstimateType) { + case GAS_ESTIMATE_TYPES.NONE: gasEstimationObject.gasPrice = txData.txParams?.gasPrice ?? '0x0'; - } else { - gasEstimationObject.maxFeePerGas = - txData.txParams?.maxFeePerGas ?? - decGWEIToHexWEI(gasFeeEstimates?.medium.suggestedMaxFeePerGas); - gasEstimationObject.maxPriorityFeePerGas = - txData.txParams?.maxPriorityFeePerGas ?? - decGWEIToHexWEI( - gasFeeEstimates?.medium.suggestedMaxPriorityFeePerGas, - ); - gasEstimationObject.baseFeePerGas = decGWEIToHexWEI( - gasFeeEstimates.estimatedBaseFee, - ); - } - break; - default: - break; + break; + case GAS_ESTIMATE_TYPES.ETH_GASPRICE: + gasEstimationObject.gasPrice = + txData.txParams?.gasPrice ?? + decGWEIToHexWEI(gasFeeEstimates.gasPrice); + break; + case GAS_ESTIMATE_TYPES.LEGACY: + gasEstimationObject.gasPrice = + txData.txParams?.gasPrice ?? getAveragePriceEstimateInHexWEI(state); + break; + case GAS_ESTIMATE_TYPES.FEE_MARKET: + break; + default: + break; + } } const { txParams: { value = '0x0' } = {} } = txData; diff --git a/yarn.lock b/yarn.lock index 63858704dbff..d7bb3e8e0858 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1564,6 +1564,14 @@ crc-32 "^1.2.0" ethereumjs-util "^7.0.10" +"@ethereumjs/common@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.4.0.tgz#2d67f6e6ba22246c5c89104e6b9a119fb3039766" + integrity sha512-UdkhFWzWcJCZVsj1O/H8/oqj/0RVYjLc1OhPjBrQdALAkQHpCp8xXI4WLnuGTADqTdJZww0NtgwG+TRPkXt27w== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.0" + "@ethereumjs/tx@^3.1.1", "@ethereumjs/tx@^3.1.4", "@ethereumjs/tx@^3.2.1": version "3.2.1" resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.2.1.tgz#65f5f1c11541764f08377a94ba4b0dcbbd67739e" @@ -1572,6 +1580,14 @@ "@ethereumjs/common" "^2.3.1" ethereumjs-util "^7.0.10" +"@ethereumjs/tx@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.0.tgz#14ed1b7fa0f28e1cd61e3ecbdab824205f6a4378" + integrity sha512-yTwEj2lVzSMgE6Hjw9Oa1DZks/nKTWM8Wn4ykDNapBPua2f4nXO3qKnni86O6lgDj5fVNRqbDsD0yy7/XNGDEA== + dependencies: + "@ethereumjs/common" "^2.4.0" + ethereumjs-util "^7.1.0" + "@ethersproject/abi@5.0.0-beta.153": version "5.0.0-beta.153" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz#43a37172b33794e4562999f6e2d555b7599a8eee" @@ -1602,6 +1618,21 @@ "@ethersproject/properties" "^5.0.7" "@ethersproject/strings" "^5.0.8" +"@ethersproject/abi@5.4.0", "@ethersproject/abi@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.0.tgz#a6d63bdb3672f738398846d4279fa6b6c9818242" + integrity sha512-9gU2H+/yK1j2eVMdzm6xvHSnMxk8waIHQGYCZg5uvAyH0rsAzxkModzBSpbAkAuhKFEovC2S9hM4nPuLym8IZw== + dependencies: + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/hash" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/abstract-provider@5.0.10", "@ethersproject/abstract-provider@^5.0.8": version "5.0.10" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.10.tgz#a533aed39a5f27312745c8c4c40fa25fc884831c" @@ -1615,6 +1646,19 @@ "@ethersproject/transactions" "^5.0.9" "@ethersproject/web" "^5.0.12" +"@ethersproject/abstract-provider@5.4.0", "@ethersproject/abstract-provider@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.0.tgz#415331031b0f678388971e1987305244edc04e1d" + integrity sha512-vPBR7HKUBY0lpdllIn7tLIzNN7DrVnhCLKSzY0l8WAwxz686m/aL7ASDzrVxV93GJtIub6N2t4dfZ29CkPOxgA== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/networks" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/web" "^5.4.0" + "@ethersproject/abstract-provider@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.5.tgz#797a32a8707830af1ad8f833e9c228994d5572b9" @@ -1639,6 +1683,17 @@ "@ethersproject/logger" "^5.0.8" "@ethersproject/properties" "^5.0.7" +"@ethersproject/abstract-signer@5.4.0", "@ethersproject/abstract-signer@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.0.tgz#cd5f50b93141ee9f9f49feb4075a0b3eafb57d65" + integrity sha512-AieQAzt05HJZS2bMofpuxMEp81AHufA5D6M4ScKwtolj041nrfIbIi8ciNW7+F59VYxXq+V4c3d568Q6l2m8ew== + dependencies: + "@ethersproject/abstract-provider" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/abstract-signer@^5.0.6": version "5.0.7" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.7.tgz#cdbd3bd479edf77c71b7f6a6156b0275b1176ded" @@ -1661,6 +1716,17 @@ "@ethersproject/logger" "^5.0.8" "@ethersproject/rlp" "^5.0.7" +"@ethersproject/address@5.4.0", "@ethersproject/address@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.4.0.tgz#ba2d00a0f8c4c0854933b963b9a3a9f6eb4a37a3" + integrity sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/rlp" "^5.4.0" + "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.5": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.5.tgz#2caa65f6b7125015395b1b54c985ee0b27059cc7" @@ -1680,6 +1746,13 @@ dependencies: "@ethersproject/bytes" "^5.0.9" +"@ethersproject/base64@5.4.0", "@ethersproject/base64@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.4.0.tgz#7252bf65295954c9048c7ca5f43e5c86441b2a9a" + integrity sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/base64@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.4.tgz#b0d8fdbf3dda977cf546dcd35725a7b1d5256caa" @@ -1695,6 +1768,14 @@ "@ethersproject/bytes" "^5.0.9" "@ethersproject/properties" "^5.0.7" +"@ethersproject/basex@5.4.0", "@ethersproject/basex@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.4.0.tgz#0a2da0f4e76c504a94f2b21d3161ed9438c7f8a6" + integrity sha512-J07+QCVJ7np2bcpxydFVf/CuYo9mZ7T73Pe7KQY4c1lRlrixMeblauMxHXD0MPwFmUHZIILDNViVkykFBZylbg== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/bignumber@5.0.15", "@ethersproject/bignumber@^5.0.13": version "5.0.15" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.15.tgz#b089b3f1e0381338d764ac1c10512f0c93b184ed" @@ -1704,6 +1785,15 @@ "@ethersproject/logger" "^5.0.8" bn.js "^4.4.0" +"@ethersproject/bignumber@5.4.1", "@ethersproject/bignumber@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.1.tgz#64399d3b9ae80aa83d483e550ba57ea062c1042d" + integrity sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + bn.js "^4.11.9" + "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": version "5.0.8" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.8.tgz#cee33bd8eb0266176def0d371b45274b1d2c4ec0" @@ -1720,6 +1810,13 @@ dependencies: "@ethersproject/logger" "^5.0.8" +"@ethersproject/bytes@5.4.0", "@ethersproject/bytes@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e" + integrity sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA== + dependencies: + "@ethersproject/logger" "^5.4.0" + "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.5.tgz#688b70000e550de0c97a151a21f15b87d7f97d7c" @@ -1734,6 +1831,13 @@ dependencies: "@ethersproject/bignumber" "^5.0.13" +"@ethersproject/constants@5.4.0", "@ethersproject/constants@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.4.0.tgz#ee0bdcb30bf1b532d2353c977bf2ef1ee117958a" + integrity sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.5.tgz#0ed19b002e8404bdf6d135234dc86a7d9bcf9b71" @@ -1756,6 +1860,22 @@ "@ethersproject/logger" "^5.0.8" "@ethersproject/properties" "^5.0.7" +"@ethersproject/contracts@5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.4.0.tgz#e05fe6bd33acc98741e27d553889ec5920078abb" + integrity sha512-hkO3L3IhS1Z3ZtHtaAG/T87nQ7KiPV+/qnvutag35I0IkiQ8G3ZpCQ9NNOpSCzn4pWSW4CfzmtE02FcqnLI+hw== + dependencies: + "@ethersproject/abi" "^5.4.0" + "@ethersproject/abstract-provider" "^5.4.0" + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/hash@5.0.12", "@ethersproject/hash@^5.0.10": version "5.0.12" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.12.tgz#1074599f7509e2ca2bb7a3d4f4e39ab3a796da42" @@ -1770,6 +1890,20 @@ "@ethersproject/properties" "^5.0.7" "@ethersproject/strings" "^5.0.8" +"@ethersproject/hash@5.4.0", "@ethersproject/hash@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.4.0.tgz#d18a8e927e828e22860a011f39e429d388344ae0" + integrity sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA== + dependencies: + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/hash@>=5.0.0-beta.128": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.6.tgz#2a2e8a1470685421217e9e86e9971ca636e609ce" @@ -1802,6 +1936,24 @@ "@ethersproject/transactions" "^5.0.9" "@ethersproject/wordlists" "^5.0.8" +"@ethersproject/hdnode@5.4.0", "@ethersproject/hdnode@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.4.0.tgz#4bc9999b9a12eb5ce80c5faa83114a57e4107cac" + integrity sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q== + dependencies: + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/basex" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/pbkdf2" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/sha2" "^5.4.0" + "@ethersproject/signing-key" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/wordlists" "^5.4.0" + "@ethersproject/json-wallets@5.0.12", "@ethersproject/json-wallets@^5.0.10": version "5.0.12" resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.0.12.tgz#8946a0fcce1634b636313a50330b7d30a24996e8" @@ -1821,6 +1973,25 @@ aes-js "3.0.0" scrypt-js "3.0.1" +"@ethersproject/json-wallets@5.4.0", "@ethersproject/json-wallets@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz#2583341cfe313fc9856642e8ace3080154145e95" + integrity sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ== + dependencies: + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/hdnode" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/pbkdf2" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/random" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + aes-js "3.0.0" + scrypt-js "3.0.1" + "@ethersproject/keccak256@5.0.9", "@ethersproject/keccak256@^5.0.7": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.9.tgz#ca0d86e4af56c13b1ef25e533bde3e96d28f647d" @@ -1829,6 +2000,14 @@ "@ethersproject/bytes" "^5.0.9" js-sha3 "0.5.7" +"@ethersproject/keccak256@5.4.0", "@ethersproject/keccak256@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.4.0.tgz#7143b8eea4976080241d2bd92e3b1f1bf7025318" + integrity sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A== + dependencies: + "@ethersproject/bytes" "^5.4.0" + js-sha3 "0.5.7" + "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.4.tgz#36ca0a7d1ae2a272da5654cb886776d0c680ef3a" @@ -1842,6 +2021,11 @@ resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.10.tgz#fd884688b3143253e0356ef92d5f22d109d2e026" integrity sha512-0y2T2NqykDrbPM3Zw9RSbPkDOxwChAL8detXaom76CfYoGxsOnRP/zTX8OUAV+x9LdwzgbWvWmeXrc0M7SuDZw== +"@ethersproject/logger@5.4.0", "@ethersproject/logger@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.0.tgz#f39adadf62ad610c420bcd156fd41270e91b3ca9" + integrity sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ== + "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.6.tgz#faa484203e86e08be9e07fef826afeef7183fe88" @@ -1854,6 +2038,13 @@ dependencies: "@ethersproject/logger" "^5.0.8" +"@ethersproject/networks@5.4.1", "@ethersproject/networks@^5.4.0": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.1.tgz#2ce83b8e42aa85216e5d277a7952d97b6ce8d852" + integrity sha512-8SvowCKz9Uf4xC5DTKI8+il8lWqOr78kmiqAVLYT9lzB8aSmJHQMD1GSuJI0CW4hMAnzocpGpZLgiMdzsNSPig== + dependencies: + "@ethersproject/logger" "^5.4.0" + "@ethersproject/networks@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.4.tgz#6d320a5e15a0cda804f5da88be0ba846156f6eec" @@ -1869,6 +2060,14 @@ "@ethersproject/bytes" "^5.0.9" "@ethersproject/sha2" "^5.0.7" +"@ethersproject/pbkdf2@5.4.0", "@ethersproject/pbkdf2@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz#ed88782a67fda1594c22d60d0ca911a9d669641c" + integrity sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/sha2" "^5.4.0" + "@ethersproject/properties@5.0.9", "@ethersproject/properties@^5.0.7": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.9.tgz#d7aae634680760136ea522e25c3ef043ec15b5c2" @@ -1876,6 +2075,13 @@ dependencies: "@ethersproject/logger" "^5.0.8" +"@ethersproject/properties@5.4.0", "@ethersproject/properties@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.0.tgz#38ba20539b44dcc5d5f80c45ad902017dcdbefe7" + integrity sha512-7jczalGVRAJ+XSRvNA6D5sAwT4gavLq3OXPuV/74o3Rd2wuzSL035IMpIMgei4CYyBdialJMrTqkOnzccLHn4A== + dependencies: + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.4.tgz#a67a1f5a52c30850b5062c861631e73d131f666e" @@ -1908,6 +2114,31 @@ bech32 "1.1.4" ws "7.2.3" +"@ethersproject/providers@5.4.2": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.2.tgz#73df9767869a31bd88d9e27e78cff96364b8fbed" + integrity sha512-Qr8Am8hlj2gL9HwNymhFlYd52MQVVEBLoDwPxhv4ASeyNpaoRiUAQnNEuE6SnEQtiwYkpLrQtSALNLUSeyuvjA== + dependencies: + "@ethersproject/abstract-provider" "^5.4.0" + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/basex" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/hash" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/networks" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/random" "^5.4.0" + "@ethersproject/rlp" "^5.4.0" + "@ethersproject/sha2" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/web" "^5.4.0" + bech32 "1.1.4" + ws "7.4.6" + "@ethersproject/random@5.0.9", "@ethersproject/random@^5.0.7": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.0.9.tgz#1903d4436ba66e4c8ac77968b16f756abea3a0d0" @@ -1916,6 +2147,14 @@ "@ethersproject/bytes" "^5.0.9" "@ethersproject/logger" "^5.0.8" +"@ethersproject/random@5.4.0", "@ethersproject/random@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.4.0.tgz#9cdde60e160d024be39cc16f8de3b9ce39191e16" + integrity sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/rlp@5.0.9", "@ethersproject/rlp@^5.0.7": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.9.tgz#da205bf8a34d3c3409eb73ddd237130a4b376aff" @@ -1924,6 +2163,14 @@ "@ethersproject/bytes" "^5.0.9" "@ethersproject/logger" "^5.0.8" +"@ethersproject/rlp@5.4.0", "@ethersproject/rlp@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.4.0.tgz#de61afda5ff979454e76d3b3310a6c32ad060931" + integrity sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/rlp@^5.0.3": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.4.tgz#0090a0271e84ea803016a112a79f5cfd80271a77" @@ -1941,6 +2188,15 @@ "@ethersproject/logger" "^5.0.8" hash.js "1.1.3" +"@ethersproject/sha2@5.4.0", "@ethersproject/sha2@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.4.0.tgz#c9a8db1037014cbc4e9482bd662f86c090440371" + integrity sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + hash.js "1.1.7" + "@ethersproject/signing-key@5.0.11", "@ethersproject/signing-key@^5.0.4", "@ethersproject/signing-key@^5.0.8": version "5.0.11" resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.11.tgz#19fc5c4597e18ad0a5efc6417ba5b74069fdd2af" @@ -1951,6 +2207,18 @@ "@ethersproject/properties" "^5.0.7" elliptic "6.5.4" +"@ethersproject/signing-key@5.4.0", "@ethersproject/signing-key@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.4.0.tgz#2f05120984e81cf89a3d5f6dec5c68ee0894fbec" + integrity sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + bn.js "^4.11.9" + elliptic "6.5.4" + hash.js "1.1.7" + "@ethersproject/solidity@5.0.10": version "5.0.10" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.10.tgz#128c9289761cf83d81ff62a1195d6079a924a86c" @@ -1962,6 +2230,17 @@ "@ethersproject/sha2" "^5.0.7" "@ethersproject/strings" "^5.0.8" +"@ethersproject/solidity@5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.4.0.tgz#1305e058ea02dc4891df18b33232b11a14ece9ec" + integrity sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/sha2" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/strings@5.0.10", "@ethersproject/strings@^5.0.8": version "5.0.10" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.10.tgz#ddce1e9724f4ac4f3f67e0cac0b48748e964bfdb" @@ -1971,6 +2250,15 @@ "@ethersproject/constants" "^5.0.8" "@ethersproject/logger" "^5.0.8" +"@ethersproject/strings@5.4.0", "@ethersproject/strings@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.4.0.tgz#fb12270132dd84b02906a8d895ae7e7fa3d07d9a" + integrity sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.5.tgz#ed7e99a282a02f40757691b04a24cd83f3752195" @@ -1995,6 +2283,21 @@ "@ethersproject/rlp" "^5.0.7" "@ethersproject/signing-key" "^5.0.8" +"@ethersproject/transactions@5.4.0", "@ethersproject/transactions@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.4.0.tgz#a159d035179334bd92f340ce0f77e83e9e1522e0" + integrity sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ== + dependencies: + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/rlp" "^5.4.0" + "@ethersproject/signing-key" "^5.4.0" + "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": version "5.0.6" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.6.tgz#b8b27938be6e9ed671dbdd35fe98af8b14d0df7c" @@ -2019,6 +2322,15 @@ "@ethersproject/constants" "^5.0.8" "@ethersproject/logger" "^5.0.8" +"@ethersproject/units@5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.4.0.tgz#d57477a4498b14b88b10396062c8cbbaf20c79fe" + integrity sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg== + dependencies: + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/constants" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/wallet@5.0.12": version "5.0.12" resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.0.12.tgz#bfb96f95e066b4b1b4591c4615207b87afedda8b" @@ -2040,6 +2352,27 @@ "@ethersproject/transactions" "^5.0.9" "@ethersproject/wordlists" "^5.0.8" +"@ethersproject/wallet@5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.4.0.tgz#fa5b59830b42e9be56eadd45a16a2e0933ad9353" + integrity sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ== + dependencies: + "@ethersproject/abstract-provider" "^5.4.0" + "@ethersproject/abstract-signer" "^5.4.0" + "@ethersproject/address" "^5.4.0" + "@ethersproject/bignumber" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/hash" "^5.4.0" + "@ethersproject/hdnode" "^5.4.0" + "@ethersproject/json-wallets" "^5.4.0" + "@ethersproject/keccak256" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/random" "^5.4.0" + "@ethersproject/signing-key" "^5.4.0" + "@ethersproject/transactions" "^5.4.0" + "@ethersproject/wordlists" "^5.4.0" + "@ethersproject/web@5.0.14", "@ethersproject/web@^5.0.12": version "5.0.14" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.14.tgz#6e7bebdd9fb967cb25ee60f44d9218dc0803bac4" @@ -2051,6 +2384,17 @@ "@ethersproject/properties" "^5.0.7" "@ethersproject/strings" "^5.0.8" +"@ethersproject/web@5.4.0", "@ethersproject/web@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.4.0.tgz#49fac173b96992334ed36a175538ba07a7413d1f" + integrity sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og== + dependencies: + "@ethersproject/base64" "^5.4.0" + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@ethersproject/web@^5.0.6": version "5.0.9" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.9.tgz#b08f8295f4bfd4777c8723fe9572f5453b9f03cb" @@ -2073,6 +2417,17 @@ "@ethersproject/properties" "^5.0.7" "@ethersproject/strings" "^5.0.8" +"@ethersproject/wordlists@5.4.0", "@ethersproject/wordlists@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.4.0.tgz#f34205ec3bbc9e2c49cadaee774cf0b07e7573d7" + integrity sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA== + dependencies: + "@ethersproject/bytes" "^5.4.0" + "@ethersproject/hash" "^5.4.0" + "@ethersproject/logger" "^5.4.0" + "@ethersproject/properties" "^5.4.0" + "@ethersproject/strings" "^5.4.0" + "@formatjs/intl-relativetimeformat@^5.2.6": version "5.2.6" resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-5.2.6.tgz#3d67b75a900e7b5416615beeb2d0eeff33a1e01a" @@ -2698,24 +3053,19 @@ resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.25.0.tgz#442ace91fb40165310764b68d8096d0017bb0492" integrity sha512-yhmYB9CQPv0dckNcPoWDcgtrdUp0OgK0uvkRE5QIBv4b3qENI1/03BztvK2ijbTuMlORUpjPq7/1MQDUPoRPVw== -"@metamask/contract-metadata@^1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.27.0.tgz#1e65b821bad6f7d8313dd881116e4366b0662f75" - integrity sha512-ZAvuROiHjSksy40buCL4M6m16bAmXQl6vjllK/XQxt9+UElhwJSp7PJ1ZULuZXmznBBY64WXlCPjm94JhW4l3g== - "@metamask/contract-metadata@^1.28.0": version "1.28.0" resolved "https://registry.yarnpkg.com/@metamask/contract-metadata/-/contract-metadata-1.28.0.tgz#76796f5010aa4aa6d28bf6fe36392017cea687cb" integrity sha512-QZj6Y1nmSs9BHufBS1GSuPX5TVFa5gbtMhEo/KRuSdKyY43OdlbBKuyT36/l5p30krlzfMX8bN0MAWqw3g0Bog== -"@metamask/controllers@^12.0.0": - version "12.0.0" - resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-12.0.0.tgz#afc36e6e8eb53133996b6e41dfc30d01c25ba9d9" - integrity sha512-YGi3rcfBjjL0UqtyoAgYQUmjBJ4V9e1uQPcmreDghDxeyFdTMAXEySWlyON84SLgsCK1FLiZ2rYm/P/FIhUXJw== +"@metamask/controllers@^14.0.2": + version "14.0.2" + resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-14.0.2.tgz#5b7cc044e6c5442e9728a6923ab7d29c7a07b2f3" + integrity sha512-abR1GTDxyOI2+2+jl8xv0WweFzHTmiuvvfe1y7qFtVKHpswO4p+xUjT7UmyDFe4nxsjqf6npct7ZDeS/EjEudg== dependencies: "@ethereumjs/common" "^2.3.1" "@ethereumjs/tx" "^3.2.1" - "@metamask/contract-metadata" "^1.27.0" + "@metamask/contract-metadata" "^1.28.0" "@types/uuid" "^8.3.0" async-mutex "^0.2.6" babel-runtime "^6.26.0" @@ -2729,6 +3079,7 @@ eth-sig-util "^3.0.0" ethereumjs-util "^7.0.10" ethereumjs-wallet "^1.0.1" + ethers "^5.4.1" ethjs-unit "^0.1.6" ethjs-util "^0.1.6" human-standard-collectible-abi "^1.0.2" @@ -2741,7 +3092,7 @@ single-call-balance-checker-abi "^1.0.0" uuid "^8.3.2" web3 "^0.20.7" - web3-provider-engine "^16.0.1" + web3-provider-engine "^16.0.3" "@metamask/controllers@^5.0.0": version "5.1.0" @@ -11402,6 +11753,18 @@ ethereumjs-util@^7.0.2, ethereumjs-util@^7.0.9: ethjs-util "0.1.6" rlp "^2.2.4" +ethereumjs-util@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.0.tgz#e2b43a30bfcdbcb432a4eb42bd5f2393209b3fd5" + integrity sha512-kR+vhu++mUDARrsMMhsjjzPduRVAeundLGXucGRHF3B4oEltOUspfgCVco4kckucj3FMlLaZHUl9n7/kdmr6Tw== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + ethjs-util "0.1.6" + rlp "^2.2.4" + ethereumjs-util@~6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" @@ -11533,6 +11896,42 @@ ethers@^5.0.8: "@ethersproject/web" "5.0.14" "@ethersproject/wordlists" "5.0.10" +ethers@^5.4.1: + version "5.4.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.2.tgz#91368e4d9c39f1111157de1c2aa1d8c1616c0f7b" + integrity sha512-JcFcNWjULzhm4tMp5cZKnU45zqN/c7rqabIITiUiQzZuP7LcYSD4WAbADo4Ja6G2orU4d/PbhAWGHGtAKYrB4Q== + dependencies: + "@ethersproject/abi" "5.4.0" + "@ethersproject/abstract-provider" "5.4.0" + "@ethersproject/abstract-signer" "5.4.0" + "@ethersproject/address" "5.4.0" + "@ethersproject/base64" "5.4.0" + "@ethersproject/basex" "5.4.0" + "@ethersproject/bignumber" "5.4.1" + "@ethersproject/bytes" "5.4.0" + "@ethersproject/constants" "5.4.0" + "@ethersproject/contracts" "5.4.0" + "@ethersproject/hash" "5.4.0" + "@ethersproject/hdnode" "5.4.0" + "@ethersproject/json-wallets" "5.4.0" + "@ethersproject/keccak256" "5.4.0" + "@ethersproject/logger" "5.4.0" + "@ethersproject/networks" "5.4.1" + "@ethersproject/pbkdf2" "5.4.0" + "@ethersproject/properties" "5.4.0" + "@ethersproject/providers" "5.4.2" + "@ethersproject/random" "5.4.0" + "@ethersproject/rlp" "5.4.0" + "@ethersproject/sha2" "5.4.0" + "@ethersproject/signing-key" "5.4.0" + "@ethersproject/solidity" "5.4.0" + "@ethersproject/strings" "5.4.0" + "@ethersproject/transactions" "5.4.0" + "@ethersproject/units" "5.4.0" + "@ethersproject/wallet" "5.4.0" + "@ethersproject/web" "5.4.0" + "@ethersproject/wordlists" "5.4.0" + ethjs-abi@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.2.0.tgz#d3e2c221011520fc499b71682036c14fcc2f5b25" @@ -13904,7 +14303,7 @@ hash.js@1.1.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -27711,6 +28110,34 @@ web3-provider-engine@^16.0.1: xhr "^2.2.0" xtend "^4.0.1" +web3-provider-engine@^16.0.3: + version "16.0.3" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-16.0.3.tgz#8ff93edf3a8da2f70d7f85c5116028c06a0d9f07" + integrity sha512-Q3bKhGqLfMTdLvkd4TtkGYJHcoVQ82D1l8jTIwwuJp/sAp7VHnRYb9YJ14SW/69VMWoOhSpPLZV2tWb9V0WJoA== + dependencies: + "@ethereumjs/tx" "^3.3.0" + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^4.4.2" + eth-json-rpc-filters "^4.2.1" + eth-json-rpc-infura "^5.1.0" + eth-json-rpc-middleware "^6.0.0" + eth-rpc-errors "^3.0.0" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + web3-providers-http@1.2.11: version "1.2.11" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.11.tgz#1cd03442c61670572d40e4dcdf1faff8bd91e7c6" @@ -28182,7 +28609,7 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -ws@7.1.0, ws@7.2.3, ws@^1.1.0, ws@^3.0.0, ws@^5.1.1, ws@^7, ws@^7.2.0, ws@^7.4.0, ws@^7.4.4, ws@^7.4.6, ws@~7.4.2: +ws@7.1.0, ws@7.2.3, ws@7.4.6, ws@^1.1.0, ws@^3.0.0, ws@^5.1.1, ws@^7, ws@^7.2.0, ws@^7.4.0, ws@^7.4.4, ws@^7.4.6, ws@~7.4.2: version "7.4.6" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==