diff --git a/CHANGELOG.md b/CHANGELOG.md index 01f3e7b4d..3e3f994f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [10.5.1] +### Changed +- [#12658](https://github.com/MetaMask/metamask-extension/pull/12658): Properly display transaction fees on layer two networks like Optimism which have fees on both layers + ## [10.5.0] ### Added - [#12411](https://github.com/MetaMask/metamask-extension/pull/12411): Add support for connecting Ledger devices to MetaMask via WebHID @@ -2546,7 +2550,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Uncategorized - Added the ability to restore accounts from seed words. -[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.5.0...HEAD +[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.5.1...HEAD +[10.5.1]: https://github.com/MetaMask/metamask-extension/compare/v10.5.0...v10.5.1 [10.5.0]: https://github.com/MetaMask/metamask-extension/compare/v10.4.1...v10.5.0 [10.4.1]: https://github.com/MetaMask/metamask-extension/compare/v10.4.0...v10.4.1 [10.4.0]: https://github.com/MetaMask/metamask-extension/compare/v10.3.0...v10.4.0 diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index f874e186e..8c7a3f49d 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -1246,6 +1246,9 @@ "lastConnected": { "message": "Last Connected" }, + "layer1Fees": { + "message": "Layer 1 fees" + }, "learnMore": { "message": "Learn more" }, @@ -2794,6 +2797,12 @@ "transactionDetailGasTotalSubtitle": { "message": "Amount + gas fee" }, + "transactionDetailLayer2GasHeading": { + "message": "Layer 2 gas fee" + }, + "transactionDetailMultiLayerTotalSubtitle": { + "message": "Amount + fees" + }, "transactionDropped": { "message": "Transaction dropped at $2." }, @@ -2812,6 +2821,15 @@ "transactionHistoryBaseFee": { "message": "Base Fee (GWEI)" }, + "transactionHistoryL1GasLabel": { + "message": "Total L1 Gas Fee" + }, + "transactionHistoryL2GasLimitLabel": { + "message": "L2 Gas Limit" + }, + "transactionHistoryL2GasPriceLabel": { + "message": "L2 Gas Price" + }, "transactionHistoryMaxFeePerGas": { "message": "Max Fee Per Gas" }, diff --git a/lavamoat/browserify/policy.json b/lavamoat/browserify/policy.json index b920f9059..1cd3d2110 100644 --- a/lavamoat/browserify/policy.json +++ b/lavamoat/browserify/policy.json @@ -84,6 +84,12 @@ "multihashes": true } }, + "@eth-optimism/contracts": { + "packages": { + "@ethersproject/abstract-provider": true, + "ethers": true + } + }, "@ethereumjs/common": { "packages": { "buffer": true, diff --git a/package.json b/package.json index 755a3fc5b..8d085fc15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask-crx", - "version": "10.5.0", + "version": "10.5.1", "private": true, "repository": { "type": "git", @@ -98,6 +98,7 @@ "@babel/runtime": "^7.5.5", "@download/blockies": "^1.0.3", "@ensdomains/content-hash": "^2.5.6", + "@eth-optimism/contracts": "0.0.0-2021919175625", "@ethereumjs/common": "^2.3.1", "@ethereumjs/tx": "^3.2.1", "@formatjs/intl-relativetimeformat": "^5.2.6", @@ -361,7 +362,9 @@ "github:assemblyscript/assemblyscript": false, "tiny-secp256k1": false, "@lavamoat/preinstall-always-fail": false, - "fsevents": false + "fsevents": false, + "node-hid": false, + "usb": false } } } diff --git a/shared/modules/conversion.utils.js b/shared/modules/conversion.utils.js index bad872787..5c139bbbc 100644 --- a/shared/modules/conversion.utils.js +++ b/shared/modules/conversion.utils.js @@ -289,4 +289,6 @@ export { toNegative, subtractCurrencies, decGWEIToHexWEI, + toBigNumber, + toNormalizedDenomination, }; diff --git a/test/jest/index.js b/test/jest/index.js index 098877489..9e6510ca8 100644 --- a/test/jest/index.js +++ b/test/jest/index.js @@ -1,3 +1,4 @@ +export { screen, fireEvent } from '@testing-library/react'; export { createSwapsMockStore } from './mock-store'; export { renderWithProvider } from './rendering'; export { setBackgroundConnection } from './background'; 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 e9e3117ac..e13d293c8 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 @@ -7,6 +7,7 @@ import FormField from '../../ui/form-field'; import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas'; import { getGasFormErrorText } from '../../../helpers/constants/gas'; import { getIsGasEstimatesLoading } from '../../../ducks/metamask/metamask'; +import { getNetworkSupportsSettingGasPrice } from '../../../selectors/selectors'; export default function AdvancedGasControls({ gasEstimateType, @@ -34,6 +35,10 @@ export default function AdvancedGasControls({ gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE || isGasEstimatesLoading); + const networkSupportsSettingGasPrice = useSelector( + getNetworkSupportsSettingGasPrice, + ); + return (
)} diff --git a/ui/components/app/advanced-gas-controls/advanced-gas-controls.test.js b/ui/components/app/advanced-gas-controls/advanced-gas-controls.test.js index f99cd1618..e44fb0a50 100644 --- a/ui/components/app/advanced-gas-controls/advanced-gas-controls.test.js +++ b/ui/components/app/advanced-gas-controls/advanced-gas-controls.test.js @@ -7,7 +7,9 @@ import { renderWithProvider } from '../../../../test/jest/rendering'; import AdvancedGasControls from './advanced-gas-controls.component'; const renderComponent = (props) => { - const store = configureMockStore([])({ metamask: { identities: [] } }); + const store = configureMockStore([])({ + metamask: { identities: [], provider: {} }, + }); return renderWithProvider(, store); }; diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js deleted file mode 100644 index 29b0e6702..000000000 --- a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-input-component.test.js +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react'; -import sinon from 'sinon'; -import { mount } from 'enzyme'; -import AdvancedTabContent from './advanced-gas-inputs.container'; - -describe('Advanced Gas Inputs', () => { - let wrapper, clock; - - const props = { - updateCustomGasPrice: sinon.spy(), - updateCustomGasLimit: sinon.spy(), - showGasPriceInfoModal: sinon.spy(), - showGasLimitInfoModal: sinon.spy(), - customGasPrice: 0, - customGasLimit: 0, - insufficientBalance: false, - customPriceIsSafe: true, - isSpeedUp: false, - minimumGasLimit: 21000, - }; - - beforeEach(() => { - clock = sinon.useFakeTimers(); - - wrapper = mount(, { - context: { - t: (str) => str, - }, - }); - }); - - afterEach(() => { - clock.restore(); - }); - - it('wont update gasPrice in props before debounce', () => { - const event = { target: { value: 1 } }; - - wrapper.find('input').at(0).simulate('change', event); - clock.tick(499); - - expect(props.updateCustomGasPrice.callCount).toStrictEqual(0); - }); - - it('simulates onChange on gas price after debounce', () => { - const event = { target: { value: 1 } }; - - wrapper.find('input').at(0).simulate('change', event); - clock.tick(500); - - expect(props.updateCustomGasPrice.calledOnce).toStrictEqual(true); - expect(props.updateCustomGasPrice.calledWith(1)).toStrictEqual(true); - }); - - it('wont update gasLimit in props before debounce', () => { - const event = { target: { value: 21000 } }; - - wrapper.find('input').at(1).simulate('change', event); - clock.tick(499); - - expect(props.updateCustomGasLimit.callCount).toStrictEqual(0); - }); - - it('simulates onChange on gas limit after debounce', () => { - const event = { target: { value: 21000 } }; - - wrapper.find('input').at(1).simulate('change', event); - clock.tick(500); - - expect(props.updateCustomGasLimit.calledOnce).toStrictEqual(true); - expect(props.updateCustomGasLimit.calledWith(21000)).toStrictEqual(true); - }); - - it('errors when insufficientBalance under gas price and gas limit', () => { - wrapper.setProps({ insufficientBalance: true }); - const renderError = wrapper.find( - '.advanced-gas-inputs__gas-edit-row__error-text', - ); - expect(renderError).toHaveLength(2); - - expect(renderError.at(0).text()).toStrictEqual('insufficientBalance'); - expect(renderError.at(1).text()).toStrictEqual('insufficientBalance'); - }); - - it('errors zero gas price / speed up', () => { - wrapper.setProps({ isSpeedUp: true }); - - const renderError = wrapper.find( - '.advanced-gas-inputs__gas-edit-row__error-text', - ); - expect(renderError).toHaveLength(2); - - expect(renderError.at(0).text()).toStrictEqual( - 'zeroGasPriceOnSpeedUpError', - ); - expect(renderError.at(1).text()).toStrictEqual( - 'gasLimitTooLowWithDynamicFee', - ); - }); - - it('warns when custom gas price is too low', () => { - wrapper.setProps({ customPriceIsSafe: false }); - - const renderWarning = wrapper.find( - '.advanced-gas-inputs__gas-edit-row__warning-text', - ); - expect(renderWarning).toHaveLength(1); - - expect(renderWarning.text()).toStrictEqual('gasPriceExtremelyLow'); - }); - - it('errors when custom gas price is too excessive', () => { - wrapper.setProps({ customPriceIsExcessive: true }); - - const renderError = wrapper.find( - '.advanced-gas-inputs__gas-edit-row__error-text', - ); - - expect(renderError).toHaveLength(2); - expect(renderError.at(0).text()).toStrictEqual('gasPriceExcessiveInput'); - }); -}); diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js index 21a76c41a..128b8361f 100644 --- a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -20,10 +20,12 @@ export default class AdvancedGasInputs extends Component { customGasLimitMessage: PropTypes.string, minimumGasLimit: PropTypes.number, customPriceIsExcessive: PropTypes.bool, + networkSupportsSettingGasPrice: PropTypes.bool, }; static defaultProps = { customPriceIsExcessive: false, + networkSupportsSettingGasPrice: true, }; constructor(props) { @@ -128,8 +130,10 @@ export default class AdvancedGasInputs extends Component { errorComponent, errorType, label, + testId, customMessageComponent, tooltipTitle, + disabled, }) { return (
@@ -151,6 +155,8 @@ export default class AdvancedGasInputs extends Component { min="0" value={value} onChange={onChange} + disabled={disabled} + data-testid={testId} />
onChange({ target: { value: value + 1 } })} + onClick={() => + !disabled && onChange({ target: { value: value + 1 } }) + } >
+ !disabled && onChange({ target: { value: Math.max(value - 1, 0) } }) } > @@ -192,6 +202,7 @@ export default class AdvancedGasInputs extends Component { customGasLimitMessage, minimumGasLimit, customPriceIsExcessive, + networkSupportsSettingGasPrice, } = this.props; const { gasPrice, gasLimit } = this.state; @@ -235,14 +246,17 @@ export default class AdvancedGasInputs extends Component {
{this.renderGasInput({ label: this.context.t('gasPrice'), + testId: 'gas-price', tooltipTitle: this.context.t('gasPriceInfoTooltipContent'), value: this.state.gasPrice, onChange: this.onChangeGasPrice, errorComponent: gasPriceErrorComponent, errorType: gasPriceErrorType, + disabled: !networkSupportsSettingGasPrice, })} {this.renderGasInput({ label: this.context.t('gasLimit'), + testId: 'gas-limit', tooltipTitle: this.context.t('gasLimitInfoTooltipContent'), value: this.state.gasLimit, onChange: this.onChangeGasLimit, diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js index 09eb26fdd..314410aa5 100644 --- a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js +++ b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js @@ -4,6 +4,7 @@ import { decimalToHex, hexWEIToDecGWEI, } from '../../../../helpers/utils/conversions.util'; +import { getNetworkSupportsSettingGasPrice } from '../../../../selectors/selectors'; import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; import AdvancedGasInputs from './advanced-gas-inputs.component'; @@ -19,7 +20,13 @@ function convertMinimumGasLimitForInputs(minimumGasLimit = MIN_GAS_LIMIT_DEC) { return parseInt(minimumGasLimit, 10); } -const mergeProps = (stateProps, dispatchProps, ownProps) => { +function mapStateToProps(state) { + return { + networkSupportsSettingGasPrice: getNetworkSupportsSettingGasPrice(state), + }; +} + +function mergeProps(stateProps, dispatchProps, ownProps) { const { customGasPrice, customGasLimit, @@ -38,6 +45,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { updateCustomGasPrice(decGWEIToHexWEI(price)), updateCustomGasLimit: (limit) => updateCustomGasLimit(decimalToHex(limit)), }; -}; +} -export default connect(null, null, mergeProps)(AdvancedGasInputs); +export default connect(mapStateToProps, null, mergeProps)(AdvancedGasInputs); diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.test.js b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.test.js new file mode 100644 index 000000000..35b0ddcf0 --- /dev/null +++ b/ui/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.test.js @@ -0,0 +1,119 @@ +import React from 'react'; +import sinon from 'sinon'; +import { renderWithProvider, fireEvent } from '../../../../../test/jest'; +import configureStore from '../../../../store/store'; +import AdvancedGasInputs from '.'; + +describe('AdvancedGasInputs', () => { + let clock; + + const props = { + updateCustomGasPrice: jest.fn(), + updateCustomGasLimit: jest.fn(), + showGasPriceInfoModal: jest.fn(), + showGasLimitInfoModal: jest.fn(), + customGasPrice: 0, + customGasLimit: 0, + insufficientBalance: false, + customPriceIsSafe: true, + isSpeedUp: false, + minimumGasLimit: 21000, + }; + + const store = configureStore({ metamask: { provider: {} } }); + + beforeEach(() => { + clock = sinon.useFakeTimers(); + }); + + afterEach(() => { + clock.restore(); + }); + + it("won't update gasPrice in props before debounce", () => { + const { getByTestId } = renderWithProvider( + , + store, + ); + + fireEvent.change(getByTestId('gas-price'), { target: { value: '10' } }); + clock.tick(499); + + expect(props.updateCustomGasPrice).toHaveBeenCalledTimes(0); + }); + + it('simulates onChange on gas price after debounce', () => { + const { getByTestId } = renderWithProvider( + , + store, + ); + + fireEvent.change(getByTestId('gas-price'), { target: { value: '10' } }); + clock.tick(500); + + expect(props.updateCustomGasPrice).toHaveBeenCalledTimes(1); + expect(props.updateCustomGasPrice).toHaveBeenCalledWith('2540be400'); + }); + + it('wont update gasLimit in props before debounce', () => { + const { getByTestId } = renderWithProvider( + , + store, + ); + + fireEvent.change(getByTestId('gas-limit'), { target: { value: '21000' } }); + clock.tick(499); + + expect(props.updateCustomGasLimit).toHaveBeenCalledTimes(0); + }); + + it('simulates onChange on gas limit after debounce', () => { + const { getByTestId } = renderWithProvider( + , + store, + ); + + fireEvent.change(getByTestId('gas-limit'), { target: { value: '21000' } }); + clock.tick(500); + + expect(props.updateCustomGasLimit).toHaveBeenCalledTimes(1); + expect(props.updateCustomGasLimit).toHaveBeenCalledWith('5208'); + }); + + it('errors when insufficientBalance under gas price and gas limit', () => { + const { getAllByText } = renderWithProvider( + , + store, + ); + + expect(getAllByText('Insufficient balance.')).toHaveLength(2); + }); + + it('errors zero gas price / speed up', () => { + const { queryByText } = renderWithProvider( + , + store, + ); + + expect(queryByText('Zero gas price on speed up')).toBeInTheDocument(); + expect(queryByText('Gas limit must be at least 21000')).toBeInTheDocument(); + }); + + it('warns when custom gas price is too low', () => { + const { queryByText } = renderWithProvider( + , + store, + ); + + expect(queryByText('Gas Price Extremely Low')).toBeInTheDocument(); + }); + + it('errors when custom gas price is too excessive', () => { + const { queryByText } = renderWithProvider( + , + store, + ); + + expect(queryByText('Gas Price Is Excessive')).toBeInTheDocument(); + }); +}); diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/index.scss b/ui/components/app/gas-customization/advanced-gas-inputs/index.scss index fbb1a35ad..7e414047d 100644 --- a/ui/components/app/gas-customization/advanced-gas-inputs/index.scss +++ b/ui/components/app/gas-customization/advanced-gas-inputs/index.scss @@ -109,6 +109,10 @@ i { font-size: $font-size-h8; } + + &--hidden { + display: none; + } } &__input-arrows--error { diff --git a/ui/components/app/multilayer-fee-message/index.js b/ui/components/app/multilayer-fee-message/index.js new file mode 100644 index 000000000..f32f25422 --- /dev/null +++ b/ui/components/app/multilayer-fee-message/index.js @@ -0,0 +1 @@ +export { default } from './multi-layer-fee-message'; diff --git a/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js b/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js new file mode 100644 index 000000000..6dc671c89 --- /dev/null +++ b/ui/components/app/multilayer-fee-message/multi-layer-fee-message.js @@ -0,0 +1,75 @@ +import React, { useContext, useState, useEffect } from 'react'; +import PropTypes from 'prop-types'; +import { captureException } from '@sentry/browser'; +import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component'; +import fetchEstimatedL1Fee from '../../../helpers/utils/optimism/fetchEstimatedL1Fee'; +import { I18nContext } from '../../../contexts/i18n'; +import { sumHexes } from '../../../helpers/utils/transactions.util'; +import { + toBigNumber, + toNormalizedDenomination, +} from '../../../../shared/modules/conversion.utils'; + +export default function MultilayerFeeMessage({ + transaction, + layer2fee, + nativeCurrency, +}) { + const t = useContext(I18nContext); + + const [fetchedLayer1Total, setLayer1Total] = useState(null); + + let layer1Total = 'unknown'; + + if (fetchedLayer1Total !== null) { + const layer1TotalBN = toBigNumber.hex(fetchedLayer1Total); + layer1Total = `${toNormalizedDenomination + .WEI(layer1TotalBN) + .toString(10)} ${nativeCurrency}`; + } + + const totalInWeiHex = sumHexes( + layer2fee || '0x0', + fetchedLayer1Total || '0x0', + transaction.txParams.value || '0x0', + ); + const totalBN = toBigNumber.hex(totalInWeiHex); + const totalInEth = `${toNormalizedDenomination + .WEI(totalBN) + .toString(10)} ${nativeCurrency}`; + + useEffect(() => { + const getEstimatedL1Fee = async () => { + try { + const result = await fetchEstimatedL1Fee(global.eth, transaction); + setLayer1Total(result); + } catch (e) { + captureException(e); + setLayer1Total(null); + } + }; + getEstimatedL1Fee(); + }, [transaction]); + + return ( + <> + + + + ); +} + +MultilayerFeeMessage.propTypes = { + transaction: PropTypes.object, + layer2fee: PropTypes.string, + nativeCurrency: PropTypes.string, +}; diff --git a/ui/components/app/transaction-activity-log/transaction-activity-log.util.js b/ui/components/app/transaction-activity-log/transaction-activity-log.util.js index f33421280..6eaba0977 100644 --- a/ui/components/app/transaction-activity-log/transaction-activity-log.util.js +++ b/ui/components/app/transaction-activity-log/transaction-activity-log.util.js @@ -89,7 +89,7 @@ export function getActivities(transaction, isFirstTransaction = false) { // need to cache these values because the status update history events don't provide us with // the latest gas limit and gas price. cachedGasLimit = gas; - cachedGasPrice = eip1559Price || gasPrice || '0x0'; + cachedGasPrice = eip1559Price || gasPrice || paramsGasPrice || '0x0'; if (isFirstTransaction) { return acc.concat({ diff --git a/ui/components/app/transaction-breakdown/transaction-breakdown.component.js b/ui/components/app/transaction-breakdown/transaction-breakdown.component.js index d079db4e7..d046d09e0 100644 --- a/ui/components/app/transaction-breakdown/transaction-breakdown.component.js +++ b/ui/components/app/transaction-breakdown/transaction-breakdown.component.js @@ -33,6 +33,8 @@ export default class TransactionBreakdown extends PureComponent { priorityFee: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), hexGasTotal: PropTypes.string, isEIP1559Transaction: PropTypes.bool, + isMultiLayerFeeNetwork: PropTypes.bool, + l1HexGasTotal: PropTypes.string, }; static defaultProps = { @@ -57,6 +59,8 @@ export default class TransactionBreakdown extends PureComponent { priorityFee, hexGasTotal, isEIP1559Transaction, + isMultiLayerFeeNetwork, + l1HexGasTotal, } = this.props; return (
@@ -77,7 +81,11 @@ export default class TransactionBreakdown extends PureComponent { {typeof gas === 'undefined' ? ( @@ -127,7 +135,13 @@ export default class TransactionBreakdown extends PureComponent { ) : null} {!isEIP1559Transaction && ( - + {typeof gasPrice === 'undefined' ? ( '?' ) : ( @@ -182,11 +196,30 @@ export default class TransactionBreakdown extends PureComponent { )} )} + {isMultiLayerFeeNetwork && ( + + + {showFiat && ( + + )} + + )} {showFiat && ( { const { transaction, isTokenApprove } = ownProps; const { txParams: { gas, gasPrice, maxFeePerGas, value } = {}, - txReceipt: { gasUsed, effectiveGasPrice } = {}, + txReceipt: { gasUsed, effectiveGasPrice, l1Fee: l1HexGasTotal } = {}, baseFeePerGas, } = transaction; @@ -33,7 +37,15 @@ const mapStateToProps = (state, ownProps) => { usedGasPrice && getHexGasTotal({ gasLimit, gasPrice: usedGasPrice })) || '0x0'; - const totalInHex = sumHexes(hexGasTotal, value); + + let totalInHex = sumHexes(hexGasTotal, value); + + const isMultiLayerFeeNetwork = + getIsMultiLayerFeeNetwork(state) && l1HexGasTotal !== undefined; + + if (isMultiLayerFeeNetwork) { + totalInHex = sumHexes(totalInHex, l1HexGasTotal); + } return { nativeCurrency: getNativeCurrency(state), @@ -48,6 +60,8 @@ const mapStateToProps = (state, ownProps) => { priorityFee, baseFee: baseFeePerGas, isEIP1559Transaction: isEIP1559Transaction(transaction), + isMultiLayerFeeNetwork, + l1HexGasTotal, }; }; diff --git a/ui/helpers/utils/optimism/buildUnserializedTransaction.js b/ui/helpers/utils/optimism/buildUnserializedTransaction.js new file mode 100644 index 000000000..c65b3aaf0 --- /dev/null +++ b/ui/helpers/utils/optimism/buildUnserializedTransaction.js @@ -0,0 +1,33 @@ +import { omit } from 'lodash'; +import { BN, stripHexPrefix } from 'ethereumjs-util'; +import Common, { Chain, Hardfork } from '@ethereumjs/common'; +import { TransactionFactory } from '@ethereumjs/tx'; + +function buildTxParams(txMeta) { + return { + ...omit(txMeta.txParams, 'gas'), + gasLimit: txMeta.txParams.gas, + }; +} + +function buildTransactionCommon(txMeta) { + // This produces a transaction whose information does not completely match an + // Optimism transaction — for instance, DEFAULT_CHAIN is still 'mainnet' and + // genesis points to the mainnet genesis, not the Optimism genesis — but + // considering that all we want to do is serialize a transaction, this works + // fine for our use case. + return Common.forCustomChain(Chain.Mainnet, { + chainId: new BN(stripHexPrefix(txMeta.chainId), 16), + networkId: new BN(txMeta.metamaskNetworkId, 10), + // Optimism only supports type-0 transactions; it does not support any of + // the newer EIPs since EIP-155. Source: + // + defaultHardfork: Hardfork.SpuriousDragon, + }); +} + +export default function buildUnserializedTransaction(txMeta) { + const txParams = buildTxParams(txMeta); + const common = buildTransactionCommon(txMeta); + return TransactionFactory.fromTxData(txParams, { common }); +} diff --git a/ui/helpers/utils/optimism/buildUnserializedTransaction.test.js b/ui/helpers/utils/optimism/buildUnserializedTransaction.test.js new file mode 100644 index 000000000..1beaac13c --- /dev/null +++ b/ui/helpers/utils/optimism/buildUnserializedTransaction.test.js @@ -0,0 +1,28 @@ +import { BN } from 'ethereumjs-util'; +import { times } from 'lodash'; +import buildUnserializedTransaction from './buildUnserializedTransaction'; + +describe('buildUnserializedTransaction', () => { + it('returns a transaction that can be serialized and fed to an Optimism smart contract', () => { + const unserializedTransaction = buildUnserializedTransaction({ + txParams: { + nonce: '0x0', + gasPrice: `0x${new BN('100').toString(16)}`, + gas: `0x${new BN('21000').toString(16)}`, + to: '0x0000000000000000000000000000000000000000', + value: `0x${new BN('10000000000000').toString(16)}`, + data: '0x0', + }, + }); + expect(unserializedTransaction).toMatchObject({ + nonce: new BN('00', 16), + gasPrice: new BN('64', 16), + gasLimit: new BN('5208', 16), + to: expect.objectContaining({ + buf: Buffer.from(times(20, 0)), + }), + value: new BN('09184e72a000', 16), + data: Buffer.from([0]), + }); + }); +}); diff --git a/ui/helpers/utils/optimism/fetchEstimatedL1Fee.js b/ui/helpers/utils/optimism/fetchEstimatedL1Fee.js new file mode 100644 index 000000000..2491f0c82 --- /dev/null +++ b/ui/helpers/utils/optimism/fetchEstimatedL1Fee.js @@ -0,0 +1,24 @@ +import * as ethers from 'ethers'; +import * as optimismContracts from '@eth-optimism/contracts'; +import buildUnserializedTransaction from './buildUnserializedTransaction'; + +// The code in this file is largely drawn from https://community.optimism.io/docs/developers/l2/new-fees.html#for-frontend-and-wallet-developers + +function buildOVMGasPriceOracleContract(eth) { + const OVMGasPriceOracle = optimismContracts + .getContractFactory('OVM_GasPriceOracle') + .attach(optimismContracts.predeploys.OVM_GasPriceOracle); + const abi = JSON.parse( + OVMGasPriceOracle.interface.format(ethers.utils.FormatTypes.json), + ); + return eth.contract(abi).at(OVMGasPriceOracle.address); +} + +export default async function fetchEstimatedL1Fee(eth, txMeta) { + const contract = buildOVMGasPriceOracleContract(eth); + const serializedTransaction = buildUnserializedTransaction( + txMeta, + ).serialize(); + const result = await contract.getL1Fee(serializedTransaction); + return result?.[0]?.toString(16); +} 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 03bab18ab..e984e8d52 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -36,6 +36,7 @@ import InfoTooltip from '../../components/ui/info-tooltip/info-tooltip'; import LoadingHeartBeat from '../../components/ui/loading-heartbeat'; import GasTiming from '../../components/app/gas-timing/gas-timing.component'; import LedgerInstructionField from '../../components/app/ledger-instruction-field'; +import MultiLayerFeeMessage from '../../components/app/multilayer-fee-message'; import { COLORS, @@ -129,6 +130,7 @@ export default class ConfirmTransactionBase extends Component { nativeCurrency: PropTypes.string, supportsEIP1559: PropTypes.bool, hardwareWalletRequiresConnection: PropTypes.bool, + isMultiLayerFeeNetwork: PropTypes.bool, }; state = { @@ -310,6 +312,8 @@ export default class ConfirmTransactionBase extends Component { isMainnet, showLedgerSteps, supportsEIP1559, + isMultiLayerFeeNetwork, + nativeCurrency, } = this.props; const { t } = this.context; @@ -413,7 +417,9 @@ export default class ConfirmTransactionBase extends Component { detailTitle={ txData.dappSuggestedGasFees ? ( <> - {t('transactionDetailGasHeading')} + {isMultiLayerFeeNetwork + ? t('transactionDetailLayer2GasHeading') + : t('transactionDetailGasHeading')} ) : ( <> - {t('transactionDetailGasHeading')} + {isMultiLayerFeeNetwork + ? t('transactionDetailLayer2GasHeading') + : t('transactionDetailGasHeading')} @@ -453,14 +461,16 @@ export default class ConfirmTransactionBase extends Component { } detailTitleColor={COLORS.BLACK} detailText={ -
- {renderHeartBeatIfNotInTest()} - -
+ !isMultiLayerFeeNetwork && ( +
+ {renderHeartBeatIfNotInTest()} + +
+ ) } detailTotal={
@@ -469,26 +479,30 @@ export default class ConfirmTransactionBase extends Component { type={PRIMARY} value={hexMinimumTransactionFee} hideLabel={!useNativeCurrencyAsPrimaryCurrency} + numberOfDecimals={isMultiLayerFeeNetwork ? 18 : 6} />
} - subText={t('editGasSubTextFee', [ - - {t('editGasSubTextFeeLabel')} - , -
- {renderHeartBeatIfNotInTest()} - -
, - ])} + subText={ + !isMultiLayerFeeNetwork && + t('editGasSubTextFee', [ + + {t('editGasSubTextFeeLabel')} + , +
+ {renderHeartBeatIfNotInTest()} + +
, + ]) + } subTitle={ <> {txData.dappSuggestedGasFees ? ( @@ -516,19 +530,28 @@ export default class ConfirmTransactionBase extends Component { } />, - - {t('editGasSubTextAmountLabel')} - , - renderTotalMaxAmount(), - ])} - />, + isMultiLayerFeeNetwork && ( + + ), + !isMultiLayerFeeNetwork && ( + + {t('editGasSubTextAmountLabel')} + , + renderTotalMaxAmount(), + ])} + /> + ), ]} /> {nonceField} diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index dfaa57a57..5b646a3b8 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -31,6 +31,7 @@ import { doesAddressRequireLedgerHidConnection, getUseTokenDetection, getTokenList, + getIsMultiLayerFeeNetwork, } from '../../selectors'; import { getMostRecentOverviewPage } from '../../ducks/history/history'; import { @@ -178,6 +179,8 @@ const mapStateToProps = (state, ownProps) => { fromAddress, ); + const isMultiLayerFeeNetwork = getIsMultiLayerFeeNetwork(state); + return { balance, fromAddress, @@ -226,6 +229,7 @@ const mapStateToProps = (state, ownProps) => { showLedgerSteps: fromAddressIsLedger, nativeCurrency, hardwareWalletRequiresConnection, + isMultiLayerFeeNetwork, }; }; diff --git a/ui/selectors/selectors.js b/ui/selectors/selectors.js index af65b2d8a..3f4642342 100644 --- a/ui/selectors/selectors.js +++ b/ui/selectors/selectors.js @@ -5,6 +5,8 @@ import { TEST_CHAINS, NETWORK_TYPE_RPC, NATIVE_CURRENCY_TOKEN_IMAGE_MAP, + OPTIMISM_CHAIN_ID, + OPTIMISM_TESTNET_CHAIN_ID, } from '../../shared/constants/network'; import { KEYRING_TYPES, @@ -671,3 +673,18 @@ export function doesAddressRequireLedgerHidConnection(state, address) { (webHidIsNotConnected || transportIsNotSuccessfullyCreated) ); } + +export function getIsOptimism(state) { + return ( + getCurrentChainId(state) === OPTIMISM_CHAIN_ID || + getCurrentChainId(state) === OPTIMISM_TESTNET_CHAIN_ID + ); +} + +export function getNetworkSupportsSettingGasPrice(state) { + return !getIsOptimism(state); +} + +export function getIsMultiLayerFeeNetwork(state) { + return getIsOptimism(state); +} diff --git a/yarn.lock b/yarn.lock index cd63f7985..7be2ac596 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1561,6 +1561,28 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eth-optimism/contracts@0.0.0-2021919175625": + version "0.0.0-2021919175625" + resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.0.0-2021919175625.tgz#551ed5d98ac4405596e97f723c28ee6376e65546" + integrity sha512-vf/rH0lUk5TRvY7/Rq8jAYXfJvAixcgnYyHVPPBdPUdWlOPfnUx1bG5N1xfaBI/zKJ1zen5gsJW4zaM+rUVKsQ== + dependencies: + "@eth-optimism/core-utils" "^0.0.0-2021919175625" + "@ethersproject/abstract-provider" "^5.4.1" + "@ethersproject/abstract-signer" "^5.4.1" + "@ethersproject/contracts" "^5.4.1" + "@ethersproject/hardware-wallets" "^5.4.0" + +"@eth-optimism/core-utils@^0.0.0-2021919175625": + version "0.0.0-2021919175625" + resolved "https://registry.yarnpkg.com/@eth-optimism/core-utils/-/core-utils-0.0.0-2021919175625.tgz#0769495b54d797b313c55ef84c6f8d9bd3227374" + integrity sha512-2AGVJKEILtbyVAxzAhtrJPDK2aIg5PmCFs1h5zGZgV5/NpygTWjMF2fq4gcGy9qW54ofChrLHdMqCOXKZuZCsQ== + dependencies: + "@ethersproject/abstract-provider" "^5.4.1" + "@ethersproject/providers" "^5.4.5" + chai "^4.3.4" + ethers "^5.4.5" + lodash "^4.17.21" + "@ethereumjs/common@^2.3.1", "@ethereumjs/common@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.4.0.tgz#2d67f6e6ba22246c5c89104e6b9a119fb3039766" @@ -1607,6 +1629,21 @@ "@ethersproject/properties" "^5.4.0" "@ethersproject/strings" "^5.4.0" +"@ethersproject/abi@5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b" + integrity sha512-9mhbjUk76BiSluiiW4BaYyI58KSbDMMQpCLdsAR+RsT2GyATiNYxVv+pGWRrekmsIdY3I+hOqsYQSTkc8L/mcg== + 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.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" @@ -1620,6 +1657,19 @@ "@ethersproject/transactions" "^5.4.0" "@ethersproject/web" "^5.4.0" +"@ethersproject/abstract-provider@5.4.1", "@ethersproject/abstract-provider@^5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e" + integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ== + 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" @@ -1644,6 +1694,17 @@ "@ethersproject/logger" "^5.4.0" "@ethersproject/properties" "^5.4.0" +"@ethersproject/abstract-signer@5.4.1", "@ethersproject/abstract-signer@^5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz#e4e9abcf4dd4f1ba0db7dff9746a5f78f355ea81" + integrity sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA== + 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" @@ -1709,6 +1770,15 @@ "@ethersproject/logger" "^5.4.0" bn.js "^4.11.9" +"@ethersproject/bignumber@5.4.2": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.2.tgz#44232e015ae4ce82ac034de549eb3583c71283d8" + integrity sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA== + 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" @@ -1769,6 +1839,34 @@ "@ethersproject/properties" "^5.4.0" "@ethersproject/transactions" "^5.4.0" +"@ethersproject/contracts@5.4.1", "@ethersproject/contracts@^5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.4.1.tgz#3eb4f35b7fe60a962a75804ada2746494df3e470" + integrity sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w== + 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/hardware-wallets@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hardware-wallets/-/hardware-wallets-5.4.0.tgz#bce275b395e26b6f50481095331157614490a473" + integrity sha512-Ea4ymm4etZoSWy93OcEGZkuVqyYdl/RjMlaXY6yQIYjsGi75sm4apbTiBA8DA9uajkv1FVakJZEBBTaVGgnBLA== + dependencies: + "@ledgerhq/hw-app-eth" "5.27.2" + "@ledgerhq/hw-transport" "5.26.0" + "@ledgerhq/hw-transport-u2f" "5.26.0" + ethers "^5.4.0" + optionalDependencies: + "@ledgerhq/hw-transport-node-hid" "5.26.0" + "@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" @@ -1855,6 +1953,11 @@ resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.0.tgz#f39adadf62ad610c420bcd156fd41270e91b3ca9" integrity sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ== +"@ethersproject/logger@5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.1.tgz#503bd33683538b923c578c07d1c2c0dd18672054" + integrity sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A== + "@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" @@ -1872,6 +1975,13 @@ dependencies: "@ethersproject/logger" "^5.4.0" +"@ethersproject/networks@5.4.2": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.2.tgz#2247d977626e97e2c3b8ee73cd2457babde0ce35" + integrity sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw== + 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" @@ -1894,6 +2004,13 @@ dependencies: "@ethersproject/logger" "^5.4.0" +"@ethersproject/properties@5.4.1": + version "5.4.1" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.1.tgz#9f051f976ce790142c6261ccb7b826eaae1f2f36" + integrity sha512-cyCGlF8wWlIZyizsj2PpbJ9I7rIlUAfnHYwy/T90pdkSn/NFTa5YWZx2wTJBe9V7dD65dcrrEMisCRUJiq6n3w== + 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" @@ -1933,6 +2050,31 @@ bech32 "1.1.4" ws "7.4.6" +"@ethersproject/providers@5.4.5", "@ethersproject/providers@^5.4.5": + version "5.4.5" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.5.tgz#eb2ea2a743a8115f79604a8157233a3a2c832928" + integrity sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw== + 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.4.0", "@ethersproject/random@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.4.0.tgz#9cdde60e160d024be39cc16f8de3b9ce39191e16" @@ -2657,6 +2799,97 @@ resolved "https://registry.yarnpkg.com/@lavamoat/preinstall-always-fail/-/preinstall-always-fail-1.0.0.tgz#e78a6e3d9e212a4fef869ec37d4f5fb498dea373" integrity sha512-vD2DcC0ffJj1w2y1Lu0OU39wHmlPEd2tCDW04Bm6Kf4LyRnCHCezTsS8yzeSJ+4so7XP+TITuR5FGJRWxPb+GA== +"@ledgerhq/cryptoassets@^5.27.2": + version "5.53.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-5.53.0.tgz#11dcc93211960c6fd6620392e4dd91896aaabe58" + integrity sha512-M3ibc3LRuHid5UtL7FI3IC6nMEppvly98QHFoSa7lJU0HDzQxY6zHec/SPM4uuJUC8sXoGVAiRJDkgny54damw== + dependencies: + invariant "2" + +"@ledgerhq/devices@^5.26.0", "@ledgerhq/devices@^5.51.1": + version "5.51.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.51.1.tgz#d741a4a5d8f17c2f9d282fd27147e6fe1999edb7" + integrity sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA== + dependencies: + "@ledgerhq/errors" "^5.50.0" + "@ledgerhq/logs" "^5.50.0" + rxjs "6" + semver "^7.3.5" + +"@ledgerhq/errors@^5.26.0", "@ledgerhq/errors@^5.50.0": + version "5.50.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.50.0.tgz#e3a6834cb8c19346efca214c1af84ed28e69dad9" + integrity sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow== + +"@ledgerhq/hw-app-eth@5.27.2": + version "5.27.2" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-5.27.2.tgz#65a2ed613a69340e0cd69c942147455ec513d006" + integrity sha512-llNdrE894cCN8j6yxJEUniciyLVcLmu5N0UmIJLOObztG+5rOF4bX54h4SreTWK+E10Z0CzHSeyE5Lz/tVcqqQ== + dependencies: + "@ledgerhq/cryptoassets" "^5.27.2" + "@ledgerhq/errors" "^5.26.0" + "@ledgerhq/hw-transport" "^5.26.0" + bignumber.js "^9.0.1" + rlp "^2.2.6" + +"@ledgerhq/hw-transport-node-hid-noevents@^5.26.0": + version "5.51.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz#71f37f812e448178ad0bcc2258982150d211c1ab" + integrity sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg== + dependencies: + "@ledgerhq/devices" "^5.51.1" + "@ledgerhq/errors" "^5.50.0" + "@ledgerhq/hw-transport" "^5.51.1" + "@ledgerhq/logs" "^5.50.0" + node-hid "2.1.1" + +"@ledgerhq/hw-transport-node-hid@5.26.0": + version "5.26.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.26.0.tgz#69bc4f8067cdd9c09ef4aed0e0b3c58328936e4b" + integrity sha512-qhaefZVZatJ6UuK8Wb6WSFNOLWc2mxcv/xgsfKi5HJCIr4bPF/ecIeN+7fRcEaycxj4XykY6Z4A7zDVulfFH4w== + dependencies: + "@ledgerhq/devices" "^5.26.0" + "@ledgerhq/errors" "^5.26.0" + "@ledgerhq/hw-transport" "^5.26.0" + "@ledgerhq/hw-transport-node-hid-noevents" "^5.26.0" + "@ledgerhq/logs" "^5.26.0" + lodash "^4.17.20" + node-hid "1.3.0" + usb "^1.6.3" + +"@ledgerhq/hw-transport-u2f@5.26.0": + version "5.26.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.26.0.tgz#b7d9d13193eb82b051fd7a838cd652372f907ec5" + integrity sha512-QTxP1Rsh+WZ184LUOelYVLeaQl3++V3I2jFik+l9JZtakwEHjD0XqOT750xpYNL/vfHsy31Wlz+oicdxGzFk+w== + dependencies: + "@ledgerhq/errors" "^5.26.0" + "@ledgerhq/hw-transport" "^5.26.0" + "@ledgerhq/logs" "^5.26.0" + u2f-api "0.2.7" + +"@ledgerhq/hw-transport@5.26.0": + version "5.26.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.26.0.tgz#bfedc3d48400ad2fe48278d9444344b72aa9d0fe" + integrity sha512-NFeJOJmyEfAX8uuIBTpocWHcz630sqPcXbu864Q+OCBm4EK5UOKV1h/pX7e0xgNIKY8zhJ/O4p4cIZp9tnXLHQ== + dependencies: + "@ledgerhq/devices" "^5.26.0" + "@ledgerhq/errors" "^5.26.0" + events "^3.2.0" + +"@ledgerhq/hw-transport@^5.26.0", "@ledgerhq/hw-transport@^5.51.1": + version "5.51.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz#8dd14a8e58cbee4df0c29eaeef983a79f5f22578" + integrity sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw== + dependencies: + "@ledgerhq/devices" "^5.51.1" + "@ledgerhq/errors" "^5.50.0" + events "^3.3.0" + +"@ledgerhq/logs@^5.26.0", "@ledgerhq/logs@^5.50.0": + version "5.50.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.50.0.tgz#29c6419e8379d496ab6d0426eadf3c4d100cd186" + integrity sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA== + "@material-ui/core@^4.11.0": version "4.11.0" resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.0.tgz#b69b26e4553c9e53f2bfaf1053e216a0af9be15a" @@ -5597,6 +5830,11 @@ assertion-error@^1.0.1: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" integrity sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw= +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -6963,6 +7201,15 @@ bl@^3.0.0: dependencies: readable-stream "^3.0.1" +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + "blake2b-wasm@https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b": version "2.0.0" resolved "https://github.com/BitGo/blake2b-wasm#193cdb71656c1a6c7f89b05d0327bb9b758d071b" @@ -7016,6 +7263,11 @@ bn.js@^5.1.1, bn.js@^5.1.2: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== +bn.js@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + bo-selector@0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/bo-selector/-/bo-selector-0.0.10.tgz#9816dcb00adf374ea87941a863b2acfc026afa3e" @@ -7819,6 +8071,18 @@ chai-checkmark@^1.0.1: deep-eql "^0.1.3" type-detect "^1.0.0" +chai@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.4.tgz#b55e655b31e1eac7099be4c08c21964fce2e6c49" + integrity sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.1" + type-detect "^4.0.5" + chain-function@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.1.tgz#c63045e5b4b663fb86f1c6e186adaf1de402a1cc" @@ -7904,6 +8168,11 @@ charenc@0.0.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + checkpoint-store@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/checkpoint-store/-/checkpoint-store-1.1.0.tgz#04e4cb516b91433893581e6d4601a78e9552ea06" @@ -9354,6 +9623,13 @@ decompress-response@^3.2.0, decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -9366,6 +9642,13 @@ deep-eql@^0.1.3: dependencies: type-detect "0.1.1" +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + deep-equal@^1.0.0, deep-equal@^1.0.1, deep-equal@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" @@ -9665,7 +9948,7 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" -detect-libc@^1.0.2: +detect-libc@^1.0.2, detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= @@ -11692,6 +11975,42 @@ ethers@^5.0.8, ethers@^5.4.1: "@ethersproject/web" "5.4.0" "@ethersproject/wordlists" "5.4.0" +ethers@^5.4.0, ethers@^5.4.5: + version "5.4.7" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.7.tgz#0fd491a5da7c9793de2d6058d76b41b1e7efba8f" + integrity sha512-iZc5p2nqfWK1sj8RabwsPM28cr37Bpq7ehTQ5rWExBr2Y09Sn1lDKZOED26n+TsZMye7Y6mIgQ/1cwpSD8XZew== + dependencies: + "@ethersproject/abi" "5.4.1" + "@ethersproject/abstract-provider" "5.4.1" + "@ethersproject/abstract-signer" "5.4.1" + "@ethersproject/address" "5.4.0" + "@ethersproject/base64" "5.4.0" + "@ethersproject/basex" "5.4.0" + "@ethersproject/bignumber" "5.4.2" + "@ethersproject/bytes" "5.4.0" + "@ethersproject/constants" "5.4.0" + "@ethersproject/contracts" "5.4.1" + "@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.1" + "@ethersproject/networks" "5.4.2" + "@ethersproject/pbkdf2" "5.4.0" + "@ethersproject/properties" "5.4.1" + "@ethersproject/providers" "5.4.5" + "@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" @@ -11948,6 +12267,11 @@ events@^3.0.0, events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -12066,6 +12390,11 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -13247,6 +13576,11 @@ get-folder-size@^2.0.0: gar "^1.0.4" tiny-each-async "2.0.3" +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -13346,6 +13680,11 @@ git-url-parse@^11.1.2: dependencies: git-up "^4.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + gl-mat4@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/gl-mat4/-/gl-mat4-1.1.4.tgz#1e895b55892e56a896867abd837d38f37a178086" @@ -14819,7 +15158,7 @@ interpret@^2.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.0.0.tgz#b783ffac0b8371503e9ab39561df223286aa5433" integrity sha512-e0/LknJ8wpMMhTiWcjivB+ESwIuvHnBSlBbmP/pSb8CQJldoj1p2qv7xGZ/+BtbTziYRFSz8OsvdbiX45LtYQA== -invariant@2.2.4, invariant@^2.0.0, invariant@^2.1.0, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: +invariant@2, invariant@2.2.4, invariant@^2.0.0, invariant@^2.1.0, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -19111,6 +19450,11 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -19246,7 +19590,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp-classic@^0.5.2: +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== @@ -19707,6 +20051,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + napi-macros@~1.8.1: version "1.8.2" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-1.8.2.tgz#299265c1d8aa401351ad0675107d751228c03eda" @@ -19828,11 +20177,28 @@ nock@^9.0.14: qs "^6.5.1" semver "^5.3.0" +node-abi@^2.18.0, node-abi@^2.21.0, node-abi@^2.7.0: + version "2.30.1" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf" + integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== + dependencies: + semver "^5.4.1" + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== +node-addon-api@^3.0.2: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + +node-addon-api@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87" + integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q== + node-dir@^0.1.10: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -19876,6 +20242,11 @@ node-gyp-build@^4.2.0, node-gyp-build@^4.2.3: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739" integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg== +node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + node-gyp-build@~3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" @@ -19907,6 +20278,25 @@ node-gyp@^7.1.0: tar "^6.0.2" which "^2.0.2" +node-hid@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-1.3.0.tgz#346a468505cee13d69ccd760052cbaf749f66a41" + integrity sha512-BA6G4V84kiNd1uAChub/Z/5s/xS3EHBCxotQ0nyYrUG65mXewUDHE1tWOSqA2dp3N+mV0Ffq9wo2AW9t4p/G7g== + dependencies: + bindings "^1.5.0" + nan "^2.14.0" + node-abi "^2.18.0" + prebuild-install "^5.3.4" + +node-hid@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-2.1.1.tgz#f83c8aa0bb4e6758b5f7383542477da93f67359d" + integrity sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw== + dependencies: + bindings "^1.5.0" + node-addon-api "^3.0.2" + prebuild-install "^6.0.0" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -20047,6 +20437,11 @@ nonce-tracker@^1.0.0: await-semaphore "^0.1.3" ethjs-query "^0.3.8" +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -20156,7 +20551,7 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -npmlog@^4.0.2, npmlog@^4.1.2: +npmlog@^4.0.1, npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -21389,6 +21784,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + pause-stream@0.0.11: version "0.0.11" resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" @@ -21963,6 +22363,46 @@ postmsg-rpc@^2.4.0: dependencies: shortid "^2.2.8" +prebuild-install@^5.3.4: + version "5.3.6" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.6.tgz#7c225568d864c71d89d07f8796042733a3f54291" + integrity sha512-s8Aai8++QQGi4sSbs/M1Qku62PFK49Jm1CbgXklGz4nmHveDq0wzJkg7Na5QbnO1uNH8K7iqx2EQ/mV0MZEmOg== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + +prebuild-install@^6.0.0: + version "6.1.4" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" + integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.21.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + precinct@^8.0.0: version "8.1.0" resolved "https://registry.yarnpkg.com/precinct/-/precinct-8.1.0.tgz#6b8f2389ba2ca61c466731390b0d7e25da3fd996" @@ -24303,6 +24743,13 @@ rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4: dependencies: bn.js "^4.11.1" +rlp@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" + integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== + dependencies: + bn.js "^5.2.0" + rn-host-detect@^1.1.5: version "1.2.0" resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.2.0.tgz#8b0396fc05631ec60c1cb8789e5070cdb04d0da0" @@ -24411,6 +24858,13 @@ rx-lite@^3.1.2: resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= +rxjs@6: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" @@ -25016,6 +25470,15 @@ simple-get@^2.7.0: once "^1.3.1" simple-concat "^1.0.0" +simple-get@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-peer@^9.3.0: version "9.5.0" resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.5.0.tgz#67ba8bd4b54efc3acf19aceafdc118b27e24fcbc" @@ -26296,6 +26759,16 @@ tape@^4.6.3, tape@^4.8.0: string.prototype.trim "~1.1.2" through "~2.3.8" +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + tar-stream@^2.0.0, tar-stream@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" @@ -26307,6 +26780,17 @@ tar-stream@^2.0.0, tar-stream@^2.0.1: inherits "^2.0.3" readable-stream "^3.1.1" +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + tar@6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39" @@ -26989,7 +27473,7 @@ type-detect@0.1.1: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" integrity sha1-C6XsKohWQORw6k6FBZcZANrFiCI= -type-detect@4.0.8, type-detect@^4.0.8: +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -27076,6 +27560,11 @@ typical@^5.0.0: resolved "https://registry.yarnpkg.com/typical/-/typical-5.1.0.tgz#7116ca103caf2574985fc84fbaa8fd0ee5ea1684" integrity sha512-t5Ik8UAwBal1P1XzuVE4dc+RYQZicLUGJdvqr/vdqsED7SQECgsGBylldSsfWZL7RQjxT3xhQcKHWhLaVSR6YQ== +u2f-api@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720" + integrity sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg== + uint8arrays@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-1.1.0.tgz#d034aa65399a9fd213a1579e323f0b29f67d0ed2" @@ -27464,6 +27953,14 @@ ursa-optional@~0.9.10: bindings "^1.3.0" nan "^2.11.1" +usb@^1.6.3: + version "1.8.0" + resolved "https://registry.yarnpkg.com/usb/-/usb-1.8.0.tgz#aec44c61558e618c699a2cbd31c86e3dc7f64d87" + integrity sha512-lA0q2tjDEAq1YUsW6nQ+asw92TtFrQ8rhMd11jAoFhK3xItZUupJ7npZDSmVOpQqQhhdFmX/YciqyywupA/wOQ== + dependencies: + node-addon-api "^4.2.0" + node-gyp-build "^4.3.0" + use-composed-ref@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" @@ -28458,6 +28955,11 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + which-typed-array@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff"