diff --git a/.circleci/config.yml b/.circleci/config.yml index 01b0b2827..de5455c9e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -122,6 +122,8 @@ jobs: prep-build: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + environment: + NODE_OPTIONS: --max_old_space_size=1024 steps: - checkout - attach_workspace: @@ -141,6 +143,8 @@ jobs: prep-build-test: docker: - image: circleci/node@sha256:e16740707de2ebed45c05d507f33ef204902349c7356d720610b5ec6a35d3d88 + environment: + NODE_OPTIONS: --max_old_space_size=1024 steps: - checkout - attach_workspace: diff --git a/.circleci/scripts/release-create-release-pr b/.circleci/scripts/release-create-release-pr index f209422cd..a1d05c777 100755 --- a/.circleci/scripts/release-create-release-pr +++ b/.circleci/scripts/release-create-release-pr @@ -45,6 +45,7 @@ install_github_cli printf '%s\n' "Creating a Pull Request for $version on GitHub" if ! hub pull-request \ + --draft \ --message "${CIRCLE_BRANCH/-/ } RC" --message ':package: :rocket:' \ --base "$CIRCLE_PROJECT_USERNAME:$base_branch" \ --head "$CIRCLE_PROJECT_USERNAME:$CIRCLE_BRANCH"; diff --git a/.eslintrc.js b/.eslintrc.js index e4fa4e948..68392f022 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,6 @@ module.exports = { root: true, - parser: 'babel-eslint', + parser: '@babel/eslint-parser', parserOptions: { 'sourceType': 'module', 'ecmaVersion': 2017, @@ -39,7 +39,7 @@ module.exports = { ], plugins: [ - 'babel', + '@babel', 'react', 'import', ], @@ -82,10 +82,16 @@ module.exports = { }], 'no-invalid-this': 'off', - 'babel/no-invalid-this': 'error', + '@babel/no-invalid-this': 'error', - 'babel/semi': ['error', 'never'], + '@babel/semi': ['error', 'never'], 'mocha/no-setup-in-describe': 'off', + 'node/no-process-env': 'off', + + // TODO: re-enable these rules + 'node/no-sync': 'off', + 'node/no-unpublished-import': 'off', + 'node/no-unpublished-require': 'off', }, overrides: [{ @@ -108,7 +114,7 @@ module.exports = { 'app/scripts/migrations/*.js', ], rules: { - 'global-require': 'off', + 'node/global-require': 'off', }, }, { files: [ @@ -117,7 +123,7 @@ module.exports = { ], rules: { // Mocha will re-assign `this` in a test context - 'babel/no-invalid-this': 'off', + '@babel/no-invalid-this': 'off', }, }, { files: [ @@ -126,7 +132,8 @@ module.exports = { 'test/helper.js', ], rules: { - 'no-process-exit': 'off', + 'node/no-process-exit': 'off', + 'node/shebang': 'off', }, }, { files: [ diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index b56d08d95..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..4cd184317 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,8 @@ +Fixes: # + +Explanation: + +Manual testing steps: + - + - + - \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..d35290252 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-name: "@metamask/*" + - dependency-name: "eth-contract-metadata" + versioning-strategy: "lockfile-only" diff --git a/CHANGELOG.md b/CHANGELOG.md index c2d1ff61c..a8f60149e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,25 @@ # Changelog ## Current Develop Branch +- [#9612](https://github.com/MetaMask/metamask-extension/pull/9612): Update main-quote-summary designs/styles + +## 8.1.3 Mon Oct 26 2020 +- [#9642](https://github.com/MetaMask/metamask-extension/pull/9642) Prevent excessive overflow from swap dropdowns +- [#9658](https://github.com/MetaMask/metamask-extension/pull/9658): Fix sorting Quote Source column of quote sort list +- [#9667](https://github.com/MetaMask/metamask-extension/pull/9667): Fix adding contact with QR code +- [#9674](https://github.com/MetaMask/metamask-extension/pull/9674): Fix ENS resolution of `.eth` URLs with query strings +- [#9691](https://github.com/MetaMask/metamask-extension/pull/9691): Bump @metamask/inpage-provider from 6.1.0 to 6.3.0 +- [#9700](https://github.com/MetaMask/metamask-extension/pull/9700): Provide image sizing so there's no jump when opening the swaps token search +- [#9568](https://github.com/MetaMask/metamask-extension/pull/9568): Add ses lockdown to build system +- [#9705](https://github.com/MetaMask/metamask-extension/pull/9705): Prevent memory leak from selected account copy tooltip +- [#9671](https://github.com/MetaMask/metamask-extension/pull/9671): Prevent old fetches from polluting the swap state +- [#9702](https://github.com/MetaMask/metamask-extension/pull/9702): Keyboard navigation for swaps dropdowns +- [#9646](https://github.com/MetaMask/metamask-extension/pull/9646): Switch from Matomo to Segment +- [#9745](https://github.com/MetaMask/metamask-extension/pull/9745): Fix fetching swaps when initial network not Mainnet +- [#9621](https://github.com/MetaMask/metamask-extension/pull/9621): Include aggregator fee as part of displayed network fees +- [#9736](https://github.com/MetaMask/metamask-extension/pull/9736): Bump eth-contract-metadata from 1.16.0 to 1.17.0 +- [#9743](https://github.com/MetaMask/metamask-extension/pull/9743): Fix "+-" prefix on swap token amount +- [#9715](https://github.com/MetaMask/metamask-extension/pull/9715): Focus on wallet address in buy workflow ## 8.1.2 Mon Oct 19 2020 - [#9608](https://github.com/MetaMask/metamask-extension/pull/9608): Ensure QR code scanner works diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index a4710ccbf..427f29078 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -82,6 +82,9 @@ "affirmAgree": { "message": "I Agree" }, + "aggregatorFeeCost": { + "message": "Aggregator network fee" + }, "alertDisableTooltip": { "message": "This can be changed in \"Settings > Alerts\"" }, @@ -129,6 +132,9 @@ "message": "MetaMask", "description": "The name of the application" }, + "approvalAndAggregatorTxFeeCost": { + "message": "Approval and aggregator network fee" + }, "approvalTxGasCost": { "message": "Approval Tx Gas Cost" }, @@ -1685,9 +1691,6 @@ "swapFinalizing": { "message": "Finalizing..." }, - "swapGasFeeSummary": { - "message": "The gas fee covers the cost of processing your swap and storing it on the Ethereum network. MetaMask does not profit from this fee." - }, "swapGetQuotes": { "message": "Get quotes" }, @@ -1736,6 +1739,9 @@ "message": "$1 quotes available", "description": "$1 is the number of quotes that the user can select from when opening the list of quotes on the 'view quote' screen" }, + "swapNetworkFeeSummary": { + "message": "The network fee covers the cost of processing your swap and storing it on the Ethereum network. MetaMask does not profit from this fee." + }, "swapNewQuoteIn": { "message": "New quotes in $1", "description": "Tells the user the amount of time until the currently displayed quotes are update. $1 is a time that is counting down from 1:00 to 0:00" diff --git a/app/manifest/_base.json b/app/manifest/_base.json index f32d4e9bb..499b2893b 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -68,6 +68,6 @@ "notifications" ], "short_name": "__MSG_appName__", - "version": "8.1.2", + "version": "8.1.3", "web_accessible_resources": ["inpage.js", "phishing.html"] } diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index 40980990c..26e8cd081 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -86,6 +86,7 @@ export default class DetectTokensController { this.interval = DEFAULT_INTERVAL } + /* eslint-disable accessor-pairs */ /** * @type {Number} */ @@ -162,4 +163,5 @@ export default class DetectTokensController { get isActive () { return this.isOpen && this.isUnlocked } + /* eslint-enable accessor-pairs */ } diff --git a/app/scripts/controllers/ens/index.js b/app/scripts/controllers/ens/index.js index d900bf4e6..26fde22c6 100644 --- a/app/scripts/controllers/ens/index.js +++ b/app/scripts/controllers/ens/index.js @@ -1,4 +1,4 @@ -import punycode from 'punycode' +import punycode from 'punycode/punycode' import ethUtil from 'ethereumjs-util' import ObservableStore from 'obs-store' import log from 'loglevel' diff --git a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js index ec5066b9c..a89d74632 100644 --- a/app/scripts/controllers/permissions/permissionsMethodMiddleware.js +++ b/app/scripts/controllers/permissions/permissionsMethodMiddleware.js @@ -111,7 +111,7 @@ export default function createPermissionsMethodMiddleware ({ } // when this promise resolves, the response is on its way back - // eslint-disable-next-line callback-return + // eslint-disable-next-line node/callback-return await next() if (responseHandler) { diff --git a/app/scripts/controllers/swaps.js b/app/scripts/controllers/swaps.js index 682eff4aa..e19185498 100644 --- a/app/scripts/controllers/swaps.js +++ b/app/scripts/controllers/swaps.js @@ -12,6 +12,7 @@ import { DEFAULT_ERC20_APPROVE_GAS, QUOTES_EXPIRED_ERROR, QUOTES_NOT_AVAILABLE_ERROR, + SWAPS_FETCH_ORDER_CONFLICT, } from '../../../ui/app/helpers/constants/swaps' import { fetchTradesInfo as defaultFetchTradesInfo, @@ -69,6 +70,7 @@ const initialState = { export default class SwapsController { constructor ({ getBufferedGasLimit, + networkController, provider, getProviderConfig, tokenRatesStore, @@ -88,7 +90,16 @@ export default class SwapsController { this.pollCount = 0 this.getProviderConfig = getProviderConfig + this.indexOfNewestCallInFlight = 0 + this.ethersProvider = new ethers.providers.Web3Provider(provider) + this._currentNetwork = networkController.store.getState().network + networkController.on('networkDidChange', (network) => { + if (network !== 'loading' && network !== this._currentNetwork) { + this._currentNetwork = network + this.ethersProvider = new ethers.providers.Web3Provider(provider) + } + }) this._setupSwapsLivenessFetching() } @@ -124,6 +135,10 @@ export default class SwapsController { if (!isPolledRequest) { this.setSwapsErrorKey('') } + + const indexOfCurrentCall = this.indexOfNewestCallInFlight + 1 + this.indexOfNewestCallInFlight = indexOfCurrentCall + let newQuotes = await this._fetchTradesInfo(fetchParams) newQuotes = mapValues(newQuotes, (quote) => ({ @@ -175,19 +190,27 @@ export default class SwapsController { if (Object.values(newQuotes).length === 0) { this.setSwapsErrorKey(QUOTES_NOT_AVAILABLE_ERROR) } else { - const topAggData = await this._findTopQuoteAggId(newQuotes) + const topQuoteData = await this._findTopQuoteAndCalculateSavings(newQuotes) - if (topAggData.topAggId) { - topAggId = topAggData.topAggId - newQuotes[topAggId].isBestQuote = topAggData.isBest + if (topQuoteData.topAggId) { + topAggId = topQuoteData.topAggId + newQuotes[topAggId].isBestQuote = topQuoteData.isBest + newQuotes[topAggId].savings = topQuoteData.savings } } + // If a newer call has been made, don't update state with old information + // Prevents timing conflicts between fetches + if (this.indexOfNewestCallInFlight !== indexOfCurrentCall) { + throw new Error(SWAPS_FETCH_ORDER_CONFLICT) + } + const { swapsState } = this.store.getState() let { selectedAggId } = swapsState if (!newQuotes[selectedAggId]) { selectedAggId = null } + this.store.updateState({ swapsState: { ...swapsState, @@ -394,48 +417,61 @@ export default class SwapsController { return ethersGasPrice.toHexString() } - async _findTopQuoteAggId (quotes) { + async _findTopQuoteAndCalculateSavings (quotes = {}) { const tokenConversionRates = this.tokenRatesStore.getState() .contractExchangeRates const { swapsState: { customGasPrice }, } = this.store.getState() - if (!Object.values(quotes).length) { + const numQuotes = Object.keys(quotes).length + if (!numQuotes) { return {} } const usedGasPrice = customGasPrice || await this._getEthersGasPrice() let topAggId = '' - let ethValueOfTradeForBestQuote = null + let ethTradeValueOfBestQuote = null + let ethFeeForBestQuote = null + const allEthTradeValues = [] + const allEthFees = [] Object.values(quotes).forEach((quote) => { const { + aggregator, + approvalNeeded, + averageGas, destinationAmount = 0, destinationToken, destinationTokenInfo, - trade, - approvalNeeded, - averageGas, gasEstimate, - aggregator, + sourceAmount, + sourceToken, + trade, } = quote + const tradeGasLimitForCalculation = gasEstimate ? new BigNumber(gasEstimate, 16) : new BigNumber(averageGas || MAX_GAS_LIMIT, 10) + const totalGasLimitForCalculation = tradeGasLimitForCalculation .plus(approvalNeeded?.gas || '0x0', 16) .toString(16) + const gasTotalInWeiHex = calcGasTotal( totalGasLimitForCalculation, usedGasPrice, ) - const totalEthCost = new BigNumber(gasTotalInWeiHex, 16).plus( - trade.value, - 16, - ) - const ethFee = conversionUtil(totalEthCost, { + + // trade.value is a sum of different values depending on the transaction. + // It always includes any external fees charged by the quote source. In + // addition, if the source asset is ETH, trade.value includes the amount + // of swapped ETH. + const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16) + .plus(trade.value, 16) + + const totalEthCost = conversionUtil(totalWeiCost, { fromCurrency: 'ETH', fromDenomination: 'WEI', toDenomination: 'ETH', @@ -443,10 +479,26 @@ export default class SwapsController { numberOfDecimals: 6, }) + // The total fee is aggregator/exchange fees plus gas fees. + // If the swap is from ETH, subtract the sourceAmount from the total cost. + // Otherwise, the total fee is simply trade.value plus gas fees. + const ethFee = sourceToken === ETH_SWAPS_TOKEN_ADDRESS + ? conversionUtil( + totalWeiCost.minus(sourceAmount, 10), // sourceAmount is in wei + { + fromCurrency: 'ETH', + fromDenomination: 'WEI', + toDenomination: 'ETH', + fromNumericBase: 'BN', + numberOfDecimals: 6, + }, + ) + : totalEthCost + const tokenConversionRate = tokenConversionRates[destinationToken] const ethValueOfTrade = - destinationTokenInfo.symbol === 'ETH' - ? calcTokenAmount(destinationAmount, 18).minus(ethFee, 10) + destinationToken === ETH_SWAPS_TOKEN_ADDRESS + ? calcTokenAmount(destinationAmount, 18).minus(totalEthCost, 10) : new BigNumber(tokenConversionRate || 1, 10) .times( calcTokenAmount( @@ -455,22 +507,51 @@ export default class SwapsController { ), 10, ) - .minus(tokenConversionRate ? ethFee.toString(10) : 0, 10) + .minus(tokenConversionRate ? totalEthCost : 0, 10) + + // collect values for savings calculation + allEthTradeValues.push(ethValueOfTrade) + allEthFees.push(ethFee) if ( - ethValueOfTradeForBestQuote === null || - ethValueOfTrade.gt(ethValueOfTradeForBestQuote) + ethTradeValueOfBestQuote === null || + ethValueOfTrade.gt(ethTradeValueOfBestQuote) ) { topAggId = aggregator - ethValueOfTradeForBestQuote = ethValueOfTrade + ethTradeValueOfBestQuote = ethValueOfTrade + ethFeeForBestQuote = ethFee } }) const isBest = - quotes[topAggId]?.destinationTokenInfo?.symbol === 'ETH' || + quotes[topAggId].destinationToken === ETH_SWAPS_TOKEN_ADDRESS || Boolean(tokenConversionRates[quotes[topAggId]?.destinationToken]) - return { topAggId, isBest } + let savings = null + + if (isBest) { + savings = {} + // Performance savings are calculated as: + // valueForBestTrade - medianValueOfAllTrades + savings.performance = ethTradeValueOfBestQuote.minus( + getMedian(allEthTradeValues), + 10, + ) + + // Performance savings are calculated as: + // medianFeeOfAllTrades - feeForBestTrade + savings.fee = getMedian(allEthFees).minus( + ethFeeForBestQuote, + 10, + ) + + // Total savings are the sum of performance and fee savings + savings.total = savings.performance.plus(savings.fee, 10).toString(10) + savings.performance = savings.performance.toString(10) + savings.fee = savings.fee.toString(10) + } + + return { topAggId, isBest, savings } } async _getERC20Allowance (contractAddress, walletAddress) { @@ -563,5 +644,39 @@ export default class SwapsController { this.setSwapsLiveness(swapsFeatureIsLive) } } - +} + +/** + * Calculates the median of a sample of BigNumber values. + * + * @param {import('bignumber.js').BigNumber[]} values - A sample of BigNumber + * values. The array will be sorted in place. + * @returns {import('bignumber.js').BigNumber} The median of the sample. + */ +function getMedian (values) { + if (!Array.isArray(values) || values.length === 0) { + throw new Error('Expected non-empty array param.') + } + + values.sort((a, b) => { + if (a.equals(b)) { + return 0 + } + return a.lessThan(b) ? -1 : 1 + }) + + if (values.length % 2 === 1) { + // return middle value + return values[(values.length - 1) / 2] + } + + // return mean of middle two values + const upperIndex = values.length / 2 + return values[upperIndex] + .plus(values[upperIndex - 1]) + .dividedBy(2) +} + +export const utils = { + getMedian, } diff --git a/app/scripts/controllers/token-rates.js b/app/scripts/controllers/token-rates.js index bbc4ad778..c3e872ca2 100644 --- a/app/scripts/controllers/token-rates.js +++ b/app/scripts/controllers/token-rates.js @@ -46,6 +46,7 @@ export default class TokenRatesController { this.store.putState({ contractExchangeRates }) } + /* eslint-disable accessor-pairs */ /** * @type {Object} */ @@ -68,6 +69,7 @@ export default class TokenRatesController { this._tokens = tokens this.updateExchangeRates() } + /* eslint-enable accessor-pairs */ start (interval = DEFAULT_INTERVAL) { this._handle && clearInterval(this._handle) diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 4406672b2..4ec69ff46 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -76,7 +76,7 @@ export default class TransactionController extends EventEmitter { this.blockTracker = opts.blockTracker this.signEthTx = opts.signTransaction this.inProcessOfSigning = new Set() - this._trackSegmentEvent = opts.trackSegmentEvent + this._trackMetaMetricsEvent = opts.trackMetaMetricsEvent this._getParticipateInMetrics = opts.getParticipateInMetrics this.memStore = new ObservableStore({}) @@ -829,13 +829,13 @@ export default class TransactionController extends EventEmitter { _trackSwapsMetrics (txMeta, approvalTxMeta) { if (this._getParticipateInMetrics() && txMeta.swapMetaData) { if (txMeta.txReceipt.status === '0x0') { - this._trackSegmentEvent({ + this._trackMetaMetricsEvent({ event: 'Swap Failed', category: 'swaps', excludeMetaMetricsId: false, }) - this._trackSegmentEvent({ + this._trackMetaMetricsEvent({ event: 'Swap Failed', properties: { ...txMeta.swapMetaData }, category: 'swaps', @@ -860,18 +860,18 @@ export default class TransactionController extends EventEmitter { const estimatedVsUsedGasRatio = `${ (new BigNumber(txMeta.txReceipt.gasUsed, 16)) - .div(txMeta.swapMetaData.estimated_gas, 16) + .div(txMeta.swapMetaData.estimated_gas, 10) .times(100) .round(2) }%` - this._trackSegmentEvent({ + this._trackMetaMetricsEvent({ event: 'Swap Completed', category: 'swaps', excludeMetaMetricsId: false, }) - this._trackSegmentEvent({ + this._trackMetaMetricsEvent({ event: 'Swap Completed', category: 'swaps', properties: { diff --git a/app/scripts/lib/background-metametrics.js b/app/scripts/lib/background-metametrics.js deleted file mode 100644 index 7af1125c1..000000000 --- a/app/scripts/lib/background-metametrics.js +++ /dev/null @@ -1,14 +0,0 @@ -import { getBackgroundMetaMetricState } from '../../../ui/app/selectors' -import { sendMetaMetricsEvent } from '../../../ui/app/helpers/utils/metametrics.util' - -export default function backgroundMetaMetricsEvent (metaMaskState, version, eventData) { - const stateEventData = getBackgroundMetaMetricState({ metamask: metaMaskState }) - if (stateEventData.participateInMetaMetrics) { - sendMetaMetricsEvent({ - ...stateEventData, - ...eventData, - version, - currentPath: '/background', - }) - } -} diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index e543a2d66..92968d28d 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -1,4 +1,3 @@ -import urlUtil from 'url' import extension from 'extensionizer' import resolveEnsToIpfsContentId from './resolver' @@ -26,8 +25,7 @@ export default function setupEnsIpfsResolver ({ provider, getCurrentNetwork, get return } // parse ens name - const urlData = urlUtil.parse(url) - const { hostname: name, path, search, hash: fragment } = urlData + const { hostname: name, pathname, search, hash: fragment } = new URL(url) const domainParts = name.split('.') const topLevelDomain = domainParts[domainParts.length - 1] // if unsupported TLD, abort @@ -35,17 +33,17 @@ export default function setupEnsIpfsResolver ({ provider, getCurrentNetwork, get return } // otherwise attempt resolve - attemptResolve({ tabId, name, path, search, fragment }) + attemptResolve({ tabId, name, pathname, search, fragment }) } - async function attemptResolve ({ tabId, name, path, search, fragment }) { + async function attemptResolve ({ tabId, name, pathname, search, fragment }) { const ipfsGateway = getIpfsGateway() extension.tabs.update(tabId, { url: `loading.html` }) let url = `https://app.ens.domains/name/${name}` try { const { type, hash } = await resolveEnsToIpfsContentId({ provider, name }) if (type === 'ipfs-ns' || type === 'ipns-ns') { - const resolvedUrl = `https://${hash}.${type.slice(0, 4)}.${ipfsGateway}${path}${search || ''}${fragment || ''}` + const resolvedUrl = `https://${hash}.${type.slice(0, 4)}.${ipfsGateway}${pathname}${search || ''}${fragment || ''}` try { // check if ipfs gateway has result const response = await window.fetch(resolvedUrl, { method: 'HEAD' }) @@ -56,11 +54,11 @@ export default function setupEnsIpfsResolver ({ provider, getCurrentNetwork, get console.warn(err) } } else if (type === 'swarm-ns') { - url = `https://swarm-gateways.net/bzz:/${hash}${path}${search || ''}${fragment || ''}` + url = `https://swarm-gateways.net/bzz:/${hash}${pathname}${search || ''}${fragment || ''}` } else if (type === 'onion' || type === 'onion3') { - url = `http://${hash}.onion${path}${search || ''}${fragment || ''}` + url = `http://${hash}.onion${pathname}${search || ''}${fragment || ''}` } else if (type === 'zeronet') { - url = `http://127.0.0.1:43110/${hash}${path}${search || ''}${fragment || ''}` + url = `http://127.0.0.1:43110/${hash}${pathname}${search || ''}${fragment || ''}` } } catch (err) { console.warn(err) diff --git a/app/scripts/lib/enums.js b/app/scripts/lib/enums.js index b54c7069e..543e8db36 100644 --- a/app/scripts/lib/enums.js +++ b/app/scripts/lib/enums.js @@ -1,3 +1,12 @@ +/** + * A string representing the type of environment the application is currently running in + * popup - When the user click's the icon in their browser's extension bar; the default view + * notification - When the extension opens due to interaction with a Web3 enabled website + * fullscreen - When the user clicks 'expand view' to open the extension in a new tab + * background - The background process that powers the extension + * @typedef {'popup' | 'notification' | 'fullscreen' | 'background'} EnvironmentType + */ + const ENVIRONMENT_TYPE_POPUP = 'popup' const ENVIRONMENT_TYPE_NOTIFICATION = 'notification' const ENVIRONMENT_TYPE_FULLSCREEN = 'fullscreen' diff --git a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js index e493aeffe..91e4e60c2 100644 --- a/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js +++ b/app/scripts/lib/rpc-method-middleware/handlers/log-web3-usage.js @@ -50,7 +50,12 @@ function logWeb3UsageHandler ( event: `Website Accessed window.web3`, category: 'inpage_provider', properties: { action, web3Property: name }, - referrerUrl: origin, + eventContext: { + referrer: { + url: origin, + }, + }, + excludeMetaMetricsId: true, }) } diff --git a/app/scripts/lib/segment.js b/app/scripts/lib/segment.js deleted file mode 100644 index 7093b0ac1..000000000 --- a/app/scripts/lib/segment.js +++ /dev/null @@ -1,112 +0,0 @@ -import Analytics from 'analytics-node' - -const inDevelopment = process.env.METAMASK_DEBUG || process.env.IN_TEST - -const flushAt = inDevelopment ? 1 : undefined - -const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' - -const segmentNoop = { - track () { - // noop - }, - page () { - // noop - }, - identify () { - // noop - }, -} - -// We do not want to track events on development builds unless specifically -// provided a SEGMENT_WRITE_KEY. This also holds true for test environments and -// E2E, which is handled in the build process by never providing the SEGMENT_WRITE_KEY -// which process.env.IN_TEST is true -const segment = process.env.SEGMENT_WRITE_KEY - ? new Analytics(process.env.SEGMENT_WRITE_KEY, { flushAt }) - : segmentNoop - -/** - * Returns a function for tracking Segment events. - * - * @param {string} metamaskVersion - The current version of the MetaMask - * extension. - * @param {Function} getParticipateInMetrics - A function that returns - * whether the user participates in MetaMetrics. - * @param {Function} getMetricsState - A function for getting state relevant - * to MetaMetrics/Segment. - */ -export function getTrackSegmentEvent ( - metamaskVersion, - getParticipateInMetrics, - getMetricsState, -) { - const version = process.env.METAMASK_ENVIRONMENT === 'production' - ? metamaskVersion - : `${metamaskVersion}-${process.env.METAMASK_ENVIRONMENT}` - - const segmentContext = { - app: { - name: 'MetaMask Extension', - version, - }, - page: { - path: '/background-process', - title: 'Background Process', - url: '/background-process', - }, - userAgent: window.navigator.userAgent, - } - - /** - * Tracks a Segment event per the given arguments. - * - * @param {string} event - The event name. - * @param {string} category - The event category. - * @param {Object} [properties] - The event properties. - * @param {string} [referrerUrl] - The event's referrer URL, if relevant. - * @param {boolean} [excludeMetaMetricsId] - `true` if the user's MetaMetrics id should - * not be included, and `false` otherwise. Default: `true` - */ - return function trackSegmentEvent ({ - event, - category, - properties = {}, - excludeMetaMetricsId = true, - referrerUrl, - }) { - if (!event || !category) { - throw new Error('Must specify event and category.') - } - - if (!getParticipateInMetrics()) { - return - } - - const { currentLocale, metaMetricsId } = getMetricsState() - - const trackOptions = { - event, - category, - context: { - ...segmentContext, - locale: currentLocale.replace('_', '-'), - }, - properties, - } - - if (excludeMetaMetricsId) { - trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID - } else { - trackOptions.userId = metaMetricsId - } - - if (referrerUrl) { - trackOptions.context.referrer = { - url: referrerUrl, - } - } - - segment.track(trackOptions) - } -} diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index f66091d80..a72780c91 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -24,6 +24,8 @@ import { CurrencyRateController, PhishingController, } from '@metamask/controllers' +import { getTrackMetaMetricsEvent } from '../../shared/modules/metametrics' +import { getBackgroundMetaMetricState } from '../../ui/app/selectors' import ComposableObservableStore from './lib/ComposableObservableStore' import AccountTracker from './lib/account-tracker' import createLoggerMiddleware from './lib/createLoggerMiddleware' @@ -55,9 +57,7 @@ import getRestrictedMethods from './controllers/permissions/restrictedMethods' import nodeify from './lib/nodeify' import accountImporter from './account-import-strategies' import seedPhraseVerifier from './lib/seed-phrase-verifier' -import { getTrackSegmentEvent } from './lib/segment' - -import backgroundMetaMetricsEvent from './lib/background-metametrics' +import { ENVIRONMENT_TYPE_BACKGROUND } from './lib/enums' export default class MetamaskController extends EventEmitter { @@ -115,16 +115,32 @@ export default class MetamaskController extends EventEmitter { migrateAddressBookState: this.migrateAddressBookState.bind(this), }) - // This depends on preferences controller state - this.trackSegmentEvent = getTrackSegmentEvent( + this.trackMetaMetricsEvent = getTrackMetaMetricsEvent( this.platform.getVersion(), - () => this.preferencesController.getParticipateInMetaMetrics(), () => { + const participateInMetaMetrics = this.preferencesController.getParticipateInMetaMetrics() const { currentLocale, metaMetricsId, } = this.preferencesController.store.getState() - return { currentLocale, metaMetricsId } + const chainId = this.networkController.getCurrentChainId() + const provider = this.networkController.getProviderConfig() + const network = provider.type === 'rpc' ? provider.rpcUrl : provider.type + return { + participateInMetaMetrics, + metaMetricsId, + environmentType: ENVIRONMENT_TYPE_BACKGROUND, + chainId, + network, + context: { + page: { + path: '/background-process', + title: 'Background Process', + url: '/background-process', + }, + locale: currentLocale.replace('_', '-'), + }, + } }, ) @@ -252,7 +268,7 @@ export default class MetamaskController extends EventEmitter { signTransaction: this.keyringController.signTransaction.bind(this.keyringController), provider: this.provider, blockTracker: this.blockTracker, - trackSegmentEvent: this.trackSegmentEvent, + trackMetaMetricsEvent: this.trackMetaMetricsEvent, getParticipateInMetrics: () => this.preferencesController.getParticipateInMetaMetrics(), }) this.txController.on('newUnapprovedTx', () => opts.showUnapprovedTx()) @@ -295,6 +311,7 @@ export default class MetamaskController extends EventEmitter { this.swapsController = new SwapsController({ getBufferedGasLimit: this.txController.txGasUtil.getBufferedGasLimit.bind(this.txController.txGasUtil), + networkController: this.networkController, provider: this.provider, getProviderConfig: this.networkController.getProviderConfig.bind(this.networkController), tokenRatesStore: this.tokenRatesController.store, @@ -1671,7 +1688,7 @@ export default class MetamaskController extends EventEmitter { })) engine.push(createMethodMiddleware({ origin, - sendMetrics: this.trackSegmentEvent, + sendMetrics: this.trackMetaMetricsEvent, })) // filter and subscription polyfills engine.push(filterMiddleware) @@ -1876,19 +1893,18 @@ export default class MetamaskController extends EventEmitter { } const metamaskState = await this.getState() - const version = this.platform.getVersion() - backgroundMetaMetricsEvent( - metamaskState, - version, - { - customVariables, - eventOpts: { - action, - category: 'Background', - name, - }, + const additionalProperties = getBackgroundMetaMetricState(metamaskState) + + this.trackMetaMetricsEvent({ + event: name, + category: 'Background', + matomoEvent: true, + properties: { + action, + ...additionalProperties, + ...customVariables, }, - ) + }) } /** @@ -2146,6 +2162,7 @@ export default class MetamaskController extends EventEmitter { } // TODO: Replace isClientOpen methods with `controllerConnectionChanged` events. + /* eslint-disable accessor-pairs */ /** * A method for recording whether the MetaMask user interface is open or not. * @private @@ -2155,6 +2172,7 @@ export default class MetamaskController extends EventEmitter { this._isClientOpen = open this.detectTokensController.isOpen = open } + /* eslint-enable accessor-pairs */ /** * Creates RPC engine middleware for processing eth_signTypedData requests diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index a3dc86e29..b10848db1 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -1,9 +1,3 @@ -/* The migrator has two methods the user should be concerned with: - * - * getData(), which returns the app-consumable data object - * saveData(), which persists the app-consumable data object. - */ - // Migrations must start at version 1 or later. // They are objects with a `version` number // and a `migrate` function. diff --git a/development/build/index.js b/development/build/index.js index 0a9f519f8..21efa88b1 100755 --- a/development/build/index.js +++ b/development/build/index.js @@ -3,6 +3,10 @@ // // run any task with "yarn build ${taskName}" // +global.globalThis = global // eslint-disable-line node/no-unsupported-features/es-builtins +require('lavamoat-core/lib/ses.umd.js') + +lockdown() // eslint-disable-line no-undef const livereload = require('gulp-livereload') const { createTask, composeSeries, composeParallel, detectAndRunEntryTask } = require('./task') diff --git a/development/build/manifest.js b/development/build/manifest.js index 1ea9e5ad5..1b24e6398 100644 --- a/development/build/manifest.js +++ b/development/build/manifest.js @@ -1,4 +1,5 @@ const { promises: fs } = require('fs') +const path = require('path') const { merge, cloneDeep } = require('lodash') const baseManifest = require('../../app/manifest/_base.json') @@ -16,11 +17,11 @@ function createManifestTasks ({ browserPlatforms }) { // merge base manifest with per-platform manifests const prepPlatforms = async () => { return Promise.all(browserPlatforms.map(async (platform) => { - const platformModifications = await readJson(`${__dirname}/../../app/manifest/${platform}.json`) + const platformModifications = await readJson(path.join(__dirname, '..', '..', 'app', 'manifest', `${platform}.json`)) const result = merge(cloneDeep(baseManifest), platformModifications) - const dir = `./dist/${platform}` + const dir = path.join('.', 'dist', platform) await fs.mkdir(dir, { recursive: true }) - await writeJson(result, `${dir}/manifest.json`) + await writeJson(result, path.join(dir, 'manifest.json')) })) } @@ -75,10 +76,10 @@ function createManifestTasks ({ browserPlatforms }) { function createTaskForModifyManifestForEnvironment (transformFn) { return () => { return Promise.all(browserPlatforms.map(async (platform) => { - const path = `./dist/${platform}/manifest.json` - const manifest = await readJson(path) + const manifestPath = path.join('.', 'dist', platform, 'manifest.json') + const manifest = await readJson(manifestPath) transformFn(manifest) - await writeJson(manifest, path) + await writeJson(manifest, manifestPath) })) } } @@ -86,11 +87,11 @@ function createManifestTasks ({ browserPlatforms }) { } // helper for reading and deserializing json from fs -async function readJson (path) { - return JSON.parse(await fs.readFile(path, 'utf8')) +async function readJson (file) { + return JSON.parse(await fs.readFile(file, 'utf8')) } // helper for serializing and writing json to fs -async function writeJson (obj, path) { - return fs.writeFile(path, JSON.stringify(obj, null, 2)) +async function writeJson (obj, file) { + return fs.writeFile(file, JSON.stringify(obj, null, 2)) } diff --git a/development/build/scripts.js b/development/build/scripts.js index 7dc8d2d95..c6b9734d5 100644 --- a/development/build/scripts.js +++ b/development/build/scripts.js @@ -18,6 +18,7 @@ const { makeStringTransform } = require('browserify-transform-tools') const conf = require('rc')('metamask', { INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID, SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY, + SEGMENT_LEGACY_WRITE_KEY: process.env.SEGMENT_LEGACY_WRITE_KEY, }) const packageJSON = require('../../package.json') @@ -324,6 +325,7 @@ function createScriptTasks ({ browserPlatforms, livereload }) { // inflating event volume. const SEGMENT_PROD_WRITE_KEY = opts.testing ? undefined : process.env.SEGMENT_PROD_WRITE_KEY const SEGMENT_DEV_WRITE_KEY = opts.testing ? undefined : conf.SEGMENT_WRITE_KEY + const SEGMENT_LEGACY_WRITE_KEY = opts.testing ? undefined : conf.SEGMENT_LEGACY_WRITE_KEY // Inject variables into bundle bundler.transform(envify({ @@ -343,6 +345,7 @@ function createScriptTasks ({ browserPlatforms, livereload }) { : conf.INFURA_PROJECT_ID ), SEGMENT_WRITE_KEY: environment === 'production' ? SEGMENT_PROD_WRITE_KEY : SEGMENT_DEV_WRITE_KEY, + SEGMENT_LEGACY_WRITE_KEY: environment === 'production' ? process.env.SEGMENT_LEGACY_WRITE_KEY : SEGMENT_LEGACY_WRITE_KEY, }), { global: true, }) diff --git a/development/build/styles.js b/development/build/styles.js index d6f3a7855..4be766673 100644 --- a/development/build/styles.js +++ b/development/build/styles.js @@ -50,26 +50,29 @@ function createStyleTasks ({ livereload }) { livereload.changed(event.path) }) } - await buildScss(devMode) + await buildScss() } async function buildScss () { - await pump(...[ - // pre-process - gulp.src(src), - devMode && sourcemaps.init(), - sass().on('error', sass.logError), - devMode && sourcemaps.write(), - autoprefixer(), - // standard - gulp.dest(dest), - // right-to-left - rtlcss(), - rename({ suffix: '-rtl' }), - devMode && sourcemaps.write(), - gulp.dest(dest), - ].filter(Boolean)) + await Promise.all([ + buildScssPipeline(src, dest, devMode, false), + buildScssPipeline(src, dest, devMode, true), + ]) } } } + +async function buildScssPipeline (src, dest, devMode, rtl) { + await pump(...[ + // pre-process + gulp.src(src), + devMode && sourcemaps.init(), + sass().on('error', sass.logError), + autoprefixer(), + rtl && rtlcss(), + rtl && rename({ suffix: '-rtl' }), + devMode && sourcemaps.write(), + gulp.dest(dest), + ].filter(Boolean)) +} diff --git a/development/build/task.js b/development/build/task.js index 879ab1c97..6988696d7 100644 --- a/development/build/task.js +++ b/development/build/task.js @@ -1,5 +1,5 @@ const EventEmitter = require('events') -const { spawn } = require('child_process') +const spawn = require('cross-spawn') const tasks = {} const taskEvents = new EventEmitter() diff --git a/development/verify-locale-strings.js b/development/verify-locale-strings.js index 1d4c6e3a7..a26e421c8 100644 --- a/development/verify-locale-strings.js +++ b/development/verify-locale-strings.js @@ -97,7 +97,6 @@ async function getLocale (code) { log.error(`Error opening your locale ("${code}") file: `, e) } process.exit(1) - return undefined } } @@ -112,7 +111,6 @@ async function writeLocale (code, locale) { log.error(`Error writing your locale ("${code}") file: `, e) } process.exit(1) - return undefined } } diff --git a/docs/creating-metrics-events.md b/docs/creating-metrics-events.md deleted file mode 100644 index 26fd8a6bb..000000000 --- a/docs/creating-metrics-events.md +++ /dev/null @@ -1,72 +0,0 @@ -## Creating Metrics Events - -The `metricsEvent` method is made available to all components via context. This is done in `metamask-extension/ui/app/helpers/higher-order-components/metametrics/metametrics.provider.js`. As such, it can be called in all components by first adding it to the context proptypes: - -``` -static contextTypes = { - t: PropTypes.func, - metricsEvent: PropTypes.func, -} -``` - -and then accessing it on `this.context`. - -Below is an example of a metrics event call: - -``` -this.context.metricsEvent({ - eventOpts: { - category: 'Navigation', - action: 'Main Menu', - name: 'Switched Account', - }, -}) -``` - -### Base Schema - -Every `metricsEvent` call is passed an object that must have an `eventOpts` property. This property is an object that itself must have three properties: -- category: categorizes events according to the schema we have set up in our matomo.org instance -- action: usually describes the page on which the event takes place, or sometimes a significant subsections of a page -- name: a very specific descriptor of the event - -### Implicit properties - -All metrics events send the following data when called: -- network -- environmentType -- activeCurrency -- accountType -- numberOfTokens -- numberOfAccounts -- version - -These are added to the metrics event via the metametrics provider. - -### Custom Variables - -Metrics events can include custom variables. These are included within the `customVariables` property that is a first-level property within first param passed to `metricsEvent`. - -For example: -``` -this.context.metricsEvent({ - eventOpts: { - category: 'Settings', - action: 'Custom RPC', - name: 'Error', - }, - customVariables: { - networkId: newRpc, - chainId, - }, -}) -``` - -Custom variables can have custom property names and values can be strings or numbers. - -**To include a custom variable, there are a set of necessary steps you must take.** - -1. First you must declare a constant equal to the desired name of the custom variable property in `metamask-extension/ui/app/helpers/utils/metametrics.util.js` under `//Custom Variable Declarations` -1. Then you must add that name to the `customVariableNameIdMap` declaration - 1. The id must be between 1 and 5 - 1. There can be no more than 5 custom variables assigned ids on a given url diff --git a/package.json b/package.json index 2ed8e593a..457ba244a 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dapp-forwarder": "concurrently -k -n forwarder,dapp -p '[{time}][{name}]' 'yarn forwarder' 'yarn dapp'", "sendwithprivatedapp": "node development/static-server.js test/e2e/send-eth-with-private-key-test --port 8080", "test:unit": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/*.js\" \"ui/app/**/*.test.js\"", - "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive mocha test/unit-global/*", + "test:unit:global": "mocha --exit --require test/env.js --require test/setup.js --recursive test/unit-global/*", "test:unit:lax": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/{,**/!(permissions)}/*.js\" \"ui/app/**/*.test.js\"", "test:unit:strict": "mocha --exit --require test/env.js --require test/setup.js --recursive \"test/unit/**/permissions/*.js\"", "test:unit:path": "mocha --exit --require test/env.js --require test/setup.js --recursive", @@ -61,9 +61,7 @@ "3box/ipfs/ipld-zcash/zcash-bitcore-lib/elliptic": "^6.5.3", "3box/**/libp2p-crypto/node-forge": "^0.10.0", "3box/**/libp2p-keychain/node-forge": "^0.10.0", - "browserify-derequire/derequire": "^2.1.1", - "ganache-core/lodash": "^4.17.19", - "ganache-core/websocket": "^1.0.32" + "browserify-derequire/derequire": "^2.1.1" }, "dependencies": { "3box": "^1.10.2", @@ -175,7 +173,9 @@ "web3-stream-provider": "^4.0.0" }, "devDependencies": { - "@babel/core": "^7.5.5", + "@babel/core": "^7.12.1", + "@babel/eslint-parser": "^7.12.1", + "@babel/eslint-plugin": "^7.12.1", "@babel/plugin-proposal-class-properties": "^7.5.5", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", "@babel/plugin-proposal-object-rest-spread": "^7.5.5", @@ -184,9 +184,9 @@ "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/register": "^7.5.5", - "@metamask/eslint-config": "^3.2.0", + "@metamask/eslint-config": "^4.1.0", "@metamask/forwarder": "^1.1.0", - "@metamask/test-dapp": "^3.1.0", + "@metamask/test-dapp": "^3.2.0", "@sentry/cli": "^1.58.0", "@storybook/addon-actions": "^5.3.14", "@storybook/addon-backgrounds": "^5.3.14", @@ -196,8 +196,8 @@ "@storybook/storybook-deployer": "^2.8.6", "@testing-library/react": "^10.4.8", "@testing-library/react-hooks": "^3.2.1", + "@types/react": "^16.9.53", "addons-linter": "1.14.0", - "babel-eslint": "^10.1.0", "babel-loader": "^8.0.6", "babelify": "^10.0.0", "brfs": "^2.0.2", @@ -210,24 +210,25 @@ "concurrently": "^5.2.0", "copy-webpack-plugin": "^6.0.3", "coveralls": "^3.0.0", + "cross-spawn": "^7.0.3", "css-loader": "^2.1.1", "del": "^3.0.0", "deps-dump": "^1.1.0", "envify": "^4.1.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.15.1", - "eslint": "^6.8.0", - "eslint-plugin-babel": "^5.3.0", + "eslint": "^7.7.0", "eslint-plugin-import": "^2.22.0", - "eslint-plugin-mocha": "^6.3.0", - "eslint-plugin-react": "^7.18.3", + "eslint-plugin-mocha": "^8.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-react": "~7.20.0", "eslint-plugin-react-hooks": "^4.0.4", "fancy-log": "^1.3.3", "fast-glob": "^3.2.2", "file-loader": "^1.1.11", "fs-extra": "^8.1.0", - "ganache-cli": "^6.9.1", - "ganache-core": "^2.10.2", + "ganache-cli": "^6.12.1", + "ganache-core": "^2.13.1", "geckodriver": "^1.19.1", "get-port": "^5.1.0", "gulp": "^4.0.2", @@ -248,6 +249,7 @@ "gulp-zip": "^4.0.0", "jsdom": "^11.2.0", "koa": "^2.7.0", + "lavamoat-core": "^6.1.0", "lockfile-lint": "^4.0.0", "mocha": "^7.2.0", "nock": "^9.0.14", @@ -287,7 +289,7 @@ "webpack": "^4.41.6" }, "engines": { - "node": "^10.16.0", + "node": "^10.18.1", "yarn": "^1.16.0" } } diff --git a/shared/modules/metametrics.js b/shared/modules/metametrics.js new file mode 100644 index 000000000..e0fc186f0 --- /dev/null +++ b/shared/modules/metametrics.js @@ -0,0 +1,251 @@ +import Analytics from 'analytics-node' +import { omit, pick } from 'lodash' + +// flushAt controls how many events are collected in the queue before they +// are sent to segment. I recommend a queue size of one due to an issue with +// detecting and flushing events in an extension beforeunload doesn't work in +// a notification context. Because notification windows are opened and closed +// in reaction to the very events we want to track, it is problematic to cache +// at all. +const flushAt = 1 + +export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' + +const segmentNoop = { + track (_, callback = () => undefined) { + // Need to call the callback so that environments without a segment id still + // resolve the promise from trackMetaMetricsEvent + return callback() + }, + page () { + // noop + }, + identify () { + // noop + }, +} + +/** + * Used to determine whether or not to attach a user's metametrics id + * to events that include on-chain data. This helps to prevent identifying + * a user by being able to trace their activity on etherscan/block exploring + */ +const trackableSendCounts = { + 1: true, + 10: true, + 30: true, + 50: true, + 100: true, + 250: true, + 500: true, + 1000: true, + 2500: true, + 5000: true, + 10000: true, + 25000: true, +} + +export function sendCountIsTrackable (sendCount) { + return Boolean(trackableSendCounts[sendCount]) +} + +// We do not want to track events on development builds unless specifically +// provided a SEGMENT_WRITE_KEY. This also holds true for test environments and +// E2E, which is handled in the build process by never providing the SEGMENT_WRITE_KEY +// when process.env.IN_TEST is truthy +export const segment = process.env.SEGMENT_WRITE_KEY + ? new Analytics(process.env.SEGMENT_WRITE_KEY, { flushAt }) + : segmentNoop + +export const segmentLegacy = process.env.SEGMENT_LEGACY_WRITE_KEY + ? new Analytics(process.env.SEGMENT_LEGACY_WRITE_KEY, { flushAt }) + : segmentNoop + +/** + * We attach context to every meta metrics event that help to qualify our analytics. + * This type has all optional values because it represents a returned object from a + * method call. Ideally app and userAgent are defined on every event. This is confirmed + * in the getTrackMetaMetricsEvent function, but still provides the consumer a way to + * override these values if necessary. + * @typedef {Object} MetaMetricsContext + * @property {Object} app + * @property {string} app.name - the name of the application tracking the event + * @property {string} app.version - the version of the application + * @property {string} userAgent - the useragent string of the user + * @property {string} locale - the locale string for the user + * @property {Object} [page] - an object representing details of the current page + * @property {string} [page.path] - the path of the current page (e.g /home) + * @property {string} [page.title] - the title of the current page (e.g 'home') + * @property {string} [page.url] - the fully qualified url of the current page + * @property {Object} [referrer] - for metamask, this is the dapp that triggered an interaction + * @property {string} [referrer.url] - the origin of the dapp issuing the notification + */ + +/** + * page and referrer from the MetaMetricsContext are very dynamic in nature and may be + * provided as part of the initial context payload when creating the trackMetaMetricsEvent function, + * or at the event level when calling the trackMetaMetricsEvent function. + * @typedef {Pick} MetaMetricsDynamicContext + */ + +/** + * @typedef {import('../../app/scripts/lib/enums').EnvironmentType} EnvironmentType + */ + +/** + * @typedef {Object} MetaMetricsRequiredState + * @property {bool} participateInMetaMetrics - has the user opted into metametrics + * @property {string} [metaMetricsId] - the user's metaMetricsId, if they have opted in + * @property {MetaMetricsDynamicContext} context - context about the event + * @property {string} chainId - the chain id of the current network + * @property {string} locale - the locale string of the current user + * @property {string} network - the name of the current network + * @property {EnvironmentType} environmentType - environment that the event happened in + * @property {string} [metaMetricsSendCount] - number of transactions sent, used to add metametricsId + * intermittently to events with onchain data attached to them used to protect identity of users. + */ + +/** + * @typedef {Object} MetaMetricsEventPayload + * @property {string} event - event name to track + * @property {string} category - category to associate event to + * @property {boolean} [isOptIn] - happened during opt in/out workflow + * @property {object} [properties] - object of custom values to track, snake_case + * @property {number} [revenue] - amount of currency that event creates in revenue for MetaMask + * @property {string} [currency] - ISO 4127 format currency for events with revenue, defaults to US dollars + * @property {number} [value] - Abstract "value" that this event has for MetaMask. + * @property {boolean} [excludeMetaMetricsId] - whether to exclude the user's metametrics id for anonymity + * @property {string} [metaMetricsId] - an override for the metaMetricsId in the event one is created as part + * of an asynchronous workflow, such as awaiting the result of the metametrics opt-in function that generates the + * user's metametrics id. + * @property {boolean} [matomoEvent] - is this event a holdover from matomo that needs further migration? + * when true, sends the data to a special segment source that marks the event data as not conforming to our + * ideal schema + * @property {MetaMetricsDynamicContext} [eventContext] - additional context to attach to event + */ + +/** + * Returns a function for tracking Segment events. + * + * @param {string} metamaskVersion - The current version of the MetaMask extension. + * @param {() => MetaMetricsRequiredState} getDynamicState - A function returning required fields + * @returns {(payload: MetaMetricsEventPayload) => Promise} - function to track an event + */ +export function getTrackMetaMetricsEvent ( + metamaskVersion, + getDynamicState, +) { + const version = process.env.METAMASK_ENVIRONMENT === 'production' + ? metamaskVersion + : `${metamaskVersion}-${process.env.METAMASK_ENVIRONMENT}` + + return function trackMetaMetricsEvent ({ + event, + category, + isOptIn, + properties = {}, + revenue, + currency, + value, + metaMetricsId: metaMetricsIdOverride, + excludeMetaMetricsId: excludeId, + matomoEvent = false, + eventContext = {}, + }) { + if (!event || !category) { + throw new Error('Must specify event and category.') + } + const { + participateInMetaMetrics, + context: providedContext, + metaMetricsId, + environmentType, + chainId, + locale, + network, + metaMetricsSendCount, + } = getDynamicState() + + let excludeMetaMetricsId = excludeId ?? false + + // This is carried over from the old implementation, and will likely need + // to be updated to work with the new tracking plan. I think we should use + // a config setting for this instead of trying to match the event name + const isSendFlow = Boolean(event.match(/^send|^confirm/u)) + if (isSendFlow && metaMetricsSendCount && !sendCountIsTrackable(metaMetricsSendCount + 1)) { + excludeMetaMetricsId = true + } + + if (!participateInMetaMetrics && !isOptIn) { + return Promise.resolve() + } + + /** @type {MetaMetricsContext} */ + const context = { + app: { + name: 'MetaMask Extension', + version, + }, + locale, + userAgent: window.navigator.userAgent, + ...pick(providedContext, ['page', 'referrer']), + ...pick(eventContext, ['page', 'referrer']), + } + + const trackOptions = { + event, + properties: { + // These values are omitted from properties because they have special meaning + // in segment. https://segment.com/docs/connections/spec/track/#properties. + // to avoid accidentally using these inappropriately, you must add them as top + // level properties on the event payload. + ...omit(properties, ['revenue', 'currency', 'value']), + revenue, + value, + currency, + category, + network, + chain_id: chainId, + environment_type: environmentType, + }, + context, + } + + // If we are tracking sensitive data we will always use the anonymousId property + // as well as our METAMETRICS_ANONYMOUS_ID. This prevents us from associating potentially + // identifiable information with a specific id. During the opt in flow we will track all + // events, but do so with the anonymous id. The one exception to that rule is after the + // user opts in to MetaMetrics. When that happens we receive back the user's new MetaMetrics + // id before it is fully persisted to state. To avoid a race condition we explicitly pass the + // new id to the track method. In that case we will track the opt in event to the user's id. + // In all other cases we use the metaMetricsId from state. + if (excludeMetaMetricsId) { + trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID + } else if (isOptIn && metaMetricsIdOverride) { + trackOptions.userId = metaMetricsIdOverride + } else if (isOptIn) { + trackOptions.anonymousId = METAMETRICS_ANONYMOUS_ID + } else { + trackOptions.userId = metaMetricsId + } + + return new Promise((resolve, reject) => { + // This is only safe to do because we are no longer batching events through segment. + // If flushAt is greater than one the callback won't be triggered until after a number + // of events have been queued equal to the flushAt value OR flushInterval passes. The + // default flushInterval is ten seconds + const callback = (err) => { + if (err) { + return reject(err) + } + return resolve() + } + + if (matomoEvent === true) { + segmentLegacy.track(trackOptions, callback) + } else { + segment.track(trackOptions, callback) + } + }) + } +} diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index b06efb3ec..26047550d 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -10,7 +10,7 @@ const largeDelayMs = regularDelayMs * 2 const dappPort = 8080 -async function withFixtures (options, callback) { +async function withFixtures (options, testSuite) { const { dapp, fixtures, ganacheOptions, driverOptions, title } = options const fixtureServer = new FixtureServer() const ganacheServer = new Ganache() @@ -33,8 +33,7 @@ async function withFixtures (options, callback) { const { driver } = await buildWebDriver(driverOptions) webDriver = driver - // eslint-disable-next-line callback-return - await callback({ + await testSuite({ driver, }) diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 88e7be305..4ef3b056f 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -676,7 +676,7 @@ describe('MetaMask', function () { await driver.switchToWindow(extension) await driver.delay(largeDelayMs * 2) - await driver.findElements(By.css('.transaction-list-item')) + await driver.findElements(By.css('.transaction-list-item--unconfirmed')) const txListValue = await driver.findClickableElement(By.css('.transaction-list-item__primary-currency')) await driver.wait(until.elementTextMatches(txListValue, /-4\s*ETH/u), 10000) await txListValue.click() @@ -772,9 +772,8 @@ describe('MetaMask', function () { await driver.delay(regularDelayMs * 2) await driver.clickElement(By.xpath(`//button[contains(text(), 'Create Token')]`)) - await driver.delay(largeDelayMs) + windowHandles = await driver.waitUntilXWindowHandles(3) - windowHandles = await driver.getAllWindowHandles() const popup = windowHandles[2] await driver.switchToWindow(popup) await driver.delay(regularDelayMs) diff --git a/test/e2e/mock-3box/server.js b/test/e2e/mock-3box/server.js index 1ac8a758c..66c4be6bb 100644 --- a/test/e2e/mock-3box/server.js +++ b/test/e2e/mock-3box/server.js @@ -1,5 +1,4 @@ const http = require('http') -const url = require('url') const port = 8889 @@ -20,7 +19,7 @@ const requestHandler = (request, response) => { response.end('ok') }) } else if (request.method === 'GET') { - const { key } = url.parse(request.url, true).query + const key = (new URL(request.url, 'https://example.org/')).searchParams.get('key') response.setHeader('Access-Control-Allow-Headers', '*') response.end(JSON.stringify(database[key] || '')) } else { diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index dcd516e41..c4a551b36 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -124,10 +124,11 @@ class Driver { async waitUntilXWindowHandles (x, delayStep = 1000, timeout = 5000) { let timeElapsed = 0 + let windowHandles = [] while (timeElapsed <= timeout) { - const windowHandles = await this.driver.getAllWindowHandles() + windowHandles = await this.driver.getAllWindowHandles() if (windowHandles.length === x) { - return + return windowHandles } await this.delay(delayStep) timeElapsed += delayStep diff --git a/test/helper.js b/test/helper.js index 8e8f37b2f..cbd47c312 100644 --- a/test/helper.js +++ b/test/helper.js @@ -86,6 +86,6 @@ if (!window.crypto) { window.crypto = {} } if (!window.crypto.getRandomValues) { - // eslint-disable-next-line global-require + // eslint-disable-next-line node/global-require window.crypto.getRandomValues = require('polyfill-crypto.getrandomvalues') } diff --git a/test/stub/provider.js b/test/stub/provider.js index 6cbcb2700..4ff63297a 100644 --- a/test/stub/provider.js +++ b/test/stub/provider.js @@ -31,6 +31,9 @@ export function createTestProviderTools (opts = {}) { // handle block tracker methods engine.push(providerAsMiddleware(GanacheCore.provider({ mnemonic: getTestSeed(), + network_id: opts.networkId, + _chainId: opts.chainId, + _chainIdRpc: opts.chainId, }))) // wrap in standard provider interface const provider = providerFromEngine(engine) diff --git a/test/unit/actions/tx_test.js b/test/unit/actions/tx_test.js index c5be5d031..a21824688 100644 --- a/test/unit/actions/tx_test.js +++ b/test/unit/actions/tx_test.js @@ -29,7 +29,7 @@ describe('tx confirmation screen', function () { it('creates COMPLETED_TX with the cancelled transaction ID', async function () { actions._setBackgroundConnection({ approveTransaction (_, cb) { - cb('An error!') + cb(new Error('An error!')) }, cancelTransaction (_, cb) { cb() diff --git a/test/unit/app/controllers/swaps-test.js b/test/unit/app/controllers/swaps-test.js index 60395403c..9707b34e6 100644 --- a/test/unit/app/controllers/swaps-test.js +++ b/test/unit/app/controllers/swaps-test.js @@ -4,8 +4,9 @@ import sinon from 'sinon' import { ethers } from 'ethers' import BigNumber from 'bignumber.js' import ObservableStore from 'obs-store' +import { ROPSTEN_NETWORK_ID, MAINNET_NETWORK_ID } from '../../../../app/scripts/controllers/network/enums' import { createTestProviderTools } from '../../../stub/provider' -import SwapsController from '../../../../app/scripts/controllers/swaps' +import SwapsController, { utils } from '../../../../app/scripts/controllers/swaps' const MOCK_FETCH_PARAMS = { slippage: 3, @@ -17,32 +18,11 @@ const MOCK_FETCH_PARAMS = { exchangeList: 'zeroExV1', } -const TEST_AGG_ID = 'zeroExV1' -const MOCK_QUOTES = { - [TEST_AGG_ID]: { - trade: { - data: '0x00', - from: '0x7F18BB4Dd92CF2404C54CBa1A9BE4A1153bdb078', - value: '0x17647444f166000', - gas: '0xe09c0', - gasPrice: undefined, - to: '0x881d40237659c251811cec9c364ef91dc08d300c', - }, - sourceAmount: '1000000000000000000000000000000000000', - destinationAmount: '396493201125465', - error: null, - sourceToken: '0x6b175474e89094c44da98b954eedeac495271d0f', - destinationToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', - approvalNeeded: null, - maxGas: 920000, - averageGas: 312510, - estimatedRefund: 343090, - fetchTime: 559, - aggregator: TEST_AGG_ID, - aggType: 'AGG', - slippage: 3, - }, -} +const TEST_AGG_ID_1 = 'TEST_AGG_1' +const TEST_AGG_ID_2 = 'TEST_AGG_2' +const TEST_AGG_ID_BEST = 'TEST_AGG_BEST' +const TEST_AGG_ID_APPROVAL = 'TEST_AGG_APPROVAL' + const MOCK_APPROVAL_NEEDED = { 'data': '0x095ea7b300000000000000000000000095e6f48254609a6ee006f7d493c8e5fb97094cef0000000000000000000000000000000000000000004a817c7ffffffdabf41c00', 'to': '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', @@ -51,8 +31,9 @@ const MOCK_APPROVAL_NEEDED = { 'gas': '12', 'gasPrice': '34', } + const MOCK_QUOTES_APPROVAL_REQUIRED = { - [TEST_AGG_ID]: { + [TEST_AGG_ID_APPROVAL]: { trade: { data: '0x00', from: '0x7F18BB4Dd92CF2404C54CBa1A9BE4A1153bdb078', @@ -70,12 +51,13 @@ const MOCK_QUOTES_APPROVAL_REQUIRED = { averageGas: 312510, estimatedRefund: 343090, fetchTime: 559, - aggregator: TEST_AGG_ID, + aggregator: TEST_AGG_ID_APPROVAL, aggType: 'AGG', slippage: 3, approvalNeeded: MOCK_APPROVAL_NEEDED, }, } + const MOCK_FETCH_METADATA = { destinationTokenInfo: { symbol: 'FOO', @@ -94,6 +76,19 @@ const MOCK_GET_BUFFERED_GAS_LIMIT = async () => ({ simulationFails: undefined, }) +function getMockNetworkController () { + return { + store: { + getState: () => { + return { + network: ROPSTEN_NETWORK_ID, + } + }, + }, + on: sinon.stub().withArgs('networkDidChange').callsArgAsync(1), + } +} + const EMPTY_INIT_STATE = { swapsState: { quotes: {}, @@ -123,6 +118,7 @@ describe('SwapsController', function () { const getSwapsController = () => { return new SwapsController({ getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, + networkController: getMockNetworkController(), provider, getProviderConfig: MOCK_GET_PROVIDER_CONFIG, tokenRatesStore: MOCK_TOKEN_RATES_STORE, @@ -138,7 +134,7 @@ describe('SwapsController', function () { // by default, all accounts are external accounts (not contracts) eth_getCode: '0x', } - provider = createTestProviderTools({ scaffold: providerResultStub }) + provider = createTestProviderTools({ scaffold: providerResultStub, networkId: 1, chainId: 1 }) .provider }) @@ -160,6 +156,78 @@ describe('SwapsController', function () { MOCK_GET_PROVIDER_CONFIG, ) }) + + it('should replace ethers instance when network changes', function () { + const networkController = getMockNetworkController() + const swapsController = new SwapsController({ + getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, + networkController, + provider, + getProviderConfig: MOCK_GET_PROVIDER_CONFIG, + tokenRatesStore: MOCK_TOKEN_RATES_STORE, + fetchTradesInfo: fetchTradesInfoStub, + fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + }) + const currentEthersInstance = swapsController.ethersProvider + const onNetworkDidChange = networkController.on.getCall(0).args[1] + + onNetworkDidChange(MAINNET_NETWORK_ID) + + const newEthersInstance = swapsController.ethersProvider + assert.notStrictEqual( + currentEthersInstance, + newEthersInstance, + 'Ethers provider should be replaced', + ) + }) + + it('should not replace ethers instance when network changes to loading', function () { + const networkController = getMockNetworkController() + const swapsController = new SwapsController({ + getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, + networkController, + provider, + getProviderConfig: MOCK_GET_PROVIDER_CONFIG, + tokenRatesStore: MOCK_TOKEN_RATES_STORE, + fetchTradesInfo: fetchTradesInfoStub, + fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + }) + const currentEthersInstance = swapsController.ethersProvider + const onNetworkDidChange = networkController.on.getCall(0).args[1] + + onNetworkDidChange('loading') + + const newEthersInstance = swapsController.ethersProvider + assert.strictEqual( + currentEthersInstance, + newEthersInstance, + 'Ethers provider should not be replaced', + ) + }) + + it('should not replace ethers instance when network changes to the same network', function () { + const networkController = getMockNetworkController() + const swapsController = new SwapsController({ + getBufferedGasLimit: MOCK_GET_BUFFERED_GAS_LIMIT, + networkController, + provider, + getProviderConfig: MOCK_GET_PROVIDER_CONFIG, + tokenRatesStore: MOCK_TOKEN_RATES_STORE, + fetchTradesInfo: fetchTradesInfoStub, + fetchSwapsFeatureLiveness: fetchSwapsFeatureLivenessStub, + }) + const currentEthersInstance = swapsController.ethersProvider + const onNetworkDidChange = networkController.on.getCall(0).args[1] + + onNetworkDidChange(ROPSTEN_NETWORK_ID) + + const newEthersInstance = swapsController.ethersProvider + assert.strictEqual( + currentEthersInstance, + newEthersInstance, + 'Ethers provider should not be replaced', + ) + }) }) describe('API', function () { @@ -233,14 +301,14 @@ describe('SwapsController', function () { }) it('should set initial gas estimate', async function () { - const initialAggId = TEST_AGG_ID + const initialAggId = TEST_AGG_ID_1 const baseGasEstimate = 10 - const { maxGas, estimatedRefund } = MOCK_QUOTES[TEST_AGG_ID] + const { maxGas, estimatedRefund } = getMockQuotes()[TEST_AGG_ID_1] const { swapsState } = swapsController.store.getState() // Set mock quotes in order to have data for the test agg swapsController.store.updateState({ - swapsState: { ...swapsState, quotes: MOCK_QUOTES }, + swapsState: { ...swapsState, quotes: getMockQuotes() }, }) await swapsController.setInitialGasEstimate( @@ -272,6 +340,19 @@ describe('SwapsController', function () { }) }) + describe('_findTopQuoteAndCalculateSavings', function () { + it('returns empty object if passed undefined or empty object', async function () { + assert.deepStrictEqual( + await swapsController._findTopQuoteAndCalculateSavings(), + {}, + ) + assert.deepStrictEqual( + await swapsController._findTopQuoteAndCalculateSavings({}), + {}, + ) + }) + }) + describe('fetchAndSetQuotes', function () { it('returns null if fetchParams is not provided', async function () { const quotes = await swapsController.fetchAndSetQuotes(undefined) @@ -279,7 +360,7 @@ describe('SwapsController', function () { }) it('calls fetchTradesInfo with the given fetchParams and returns the correct quotes', async function () { - fetchTradesInfoStub.resolves(MOCK_QUOTES) + fetchTradesInfoStub.resolves(getMockQuotes()) // Make it so approval is not required sandbox @@ -291,8 +372,8 @@ describe('SwapsController', function () { MOCK_FETCH_METADATA, ) - assert.deepStrictEqual(newQuotes[TEST_AGG_ID], { - ...MOCK_QUOTES[TEST_AGG_ID], + assert.deepStrictEqual(newQuotes[TEST_AGG_ID_BEST], { + ...getMockQuotes()[TEST_AGG_ID_BEST], sourceTokenInfo: undefined, destinationTokenInfo: { symbol: 'FOO', @@ -301,7 +382,12 @@ describe('SwapsController', function () { isBestQuote: true, // TODO: find a way to calculate these values dynamically gasEstimate: 2000000, - gasEstimateWithRefund: '8cd8e', + gasEstimateWithRefund: 'b8cae', + savings: { + fee: '0', + performance: '6', + total: '6', + }, }) assert.strictEqual( @@ -311,7 +397,7 @@ describe('SwapsController', function () { }) it('performs the allowance check', async function () { - fetchTradesInfoStub.resolves(MOCK_QUOTES) + fetchTradesInfoStub.resolves(getMockQuotes()) // Make it so approval is not required const allowanceStub = sandbox @@ -358,7 +444,7 @@ describe('SwapsController', function () { }) it('marks the best quote', async function () { - fetchTradesInfoStub.resolves(MOCK_QUOTES) + fetchTradesInfoStub.resolves(getMockQuotes()) // Make it so approval is not required sandbox @@ -370,7 +456,7 @@ describe('SwapsController', function () { MOCK_FETCH_METADATA, ) - assert.strictEqual(topAggId, TEST_AGG_ID) + assert.strictEqual(topAggId, TEST_AGG_ID_BEST) assert.strictEqual(newQuotes[topAggId].isBestQuote, true) }) @@ -379,15 +465,15 @@ describe('SwapsController', function () { // Clone the existing mock quote and increase destination amount const bestQuote = { - ...MOCK_QUOTES[TEST_AGG_ID], + ...getMockQuotes()[TEST_AGG_ID_1], aggregator: bestAggId, destinationAmount: ethers.BigNumber.from( - MOCK_QUOTES[TEST_AGG_ID].destinationAmount, + getMockQuotes()[TEST_AGG_ID_1].destinationAmount, ) - .add(1) + .add((100e18).toString()) .toString(), } - const quotes = { ...MOCK_QUOTES, [bestAggId]: bestQuote } + const quotes = { ...getMockQuotes(), [bestAggId]: bestQuote } fetchTradesInfoStub.resolves(quotes) // Make it so approval is not required @@ -405,7 +491,7 @@ describe('SwapsController', function () { }) it('does not mark as best quote if no conversion rate exists for destination token', async function () { - fetchTradesInfoStub.resolves(MOCK_QUOTES) + fetchTradesInfoStub.resolves(getMockQuotes()) // Make it so approval is not required sandbox @@ -762,4 +848,150 @@ describe('SwapsController', function () { }) }) }) + + describe('utils', function () { + describe('getMedian', function () { + const { getMedian } = utils + + it('calculates median correctly with uneven sample', function () { + const values = [3, 2, 6].map((value) => new BigNumber(value)) + const median = getMedian(values) + + assert.strictEqual( + median.toNumber(), 3, + 'should have returned correct median', + ) + }) + + it('calculates median correctly with even sample', function () { + const values = [3, 2, 2, 6].map((value) => new BigNumber(value)) + const median = getMedian(values) + + assert.strictEqual( + median.toNumber(), 2.5, + 'should have returned correct median', + ) + }) + + it('throws on empty or non-array sample', function () { + assert.throws( + () => getMedian([]), + 'should throw on empty array', + ) + + assert.throws( + () => getMedian(), + 'should throw on non-array param', + ) + + assert.throws( + () => getMedian({}), + 'should throw on non-array param', + ) + }) + }) + }) }) + +function getMockQuotes () { + return { + [TEST_AGG_ID_1]: { + 'trade': { + 'from': '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc', + 'value': '0x0', + 'gas': '0x61a80', // 4e5 + 'to': '0x881D40237659C251811CEC9c364ef91dC08D300C', + }, + 'sourceAmount': '10000000000000000000', // 10e18 + 'destinationAmount': '20000000000000000000', // 20e18 + 'error': null, + 'sourceToken': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'destinationToken': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'approvalNeeded': null, + 'maxGas': 600000, + 'averageGas': 120000, + 'estimatedRefund': 80000, + 'fetchTime': 607, + 'aggregator': TEST_AGG_ID_1, + 'aggType': 'AGG', + 'slippage': 2, + 'sourceTokenInfo': { + 'address': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'symbol': 'DAI', + 'decimals': 18, + 'iconUrl': 'https://foo.bar/logo.png', + }, + 'destinationTokenInfo': { + 'address': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'symbol': 'USDC', + 'decimals': 18, + }, + }, + + [TEST_AGG_ID_BEST]: { + 'trade': { + 'from': '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc', + 'value': '0x0', + 'gas': '0x61a80', + 'to': '0x881D40237659C251811CEC9c364ef91dC08D300C', + }, + 'sourceAmount': '10000000000000000000', + 'destinationAmount': '25000000000000000000', // 25e18 + 'error': null, + 'sourceToken': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'destinationToken': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'approvalNeeded': null, + 'maxGas': 1100000, + 'averageGas': 411000, + 'estimatedRefund': 343090, + 'fetchTime': 1003, + 'aggregator': TEST_AGG_ID_BEST, + 'aggType': 'AGG', + 'slippage': 2, + 'sourceTokenInfo': { + 'address': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'symbol': 'DAI', + 'decimals': 18, + 'iconUrl': 'https://foo.bar/logo.png', + }, + 'destinationTokenInfo': { + 'address': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'symbol': 'USDC', + 'decimals': 18, + }, + }, + + [TEST_AGG_ID_2]: { + 'trade': { + 'from': '0xe18035bf8712672935fdb4e5e431b1a0183d2dfc', + 'value': '0x0', + 'gas': '0x61a80', + 'to': '0x881D40237659C251811CEC9c364ef91dC08D300C', + }, + 'sourceAmount': '10000000000000000000', + 'destinationAmount': '22000000000000000000', // 22e18 + 'error': null, + 'sourceToken': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'destinationToken': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'approvalNeeded': null, + 'maxGas': 368000, + 'averageGas': 197000, + 'estimatedRefund': 18205, + 'fetchTime': 1354, + 'aggregator': TEST_AGG_ID_2, + 'aggType': 'AGG', + 'slippage': 2, + 'sourceTokenInfo': { + 'address': '0x6b175474e89094c44da98b954eedeac495271d0f', + 'symbol': 'DAI', + 'decimals': 18, + 'iconUrl': 'https://foo.bar/logo.png', + }, + 'destinationTokenInfo': { + 'address': '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + 'symbol': 'USDC', + 'decimals': 18, + }, + }, + } +} diff --git a/ui/app/components/app/connected-status-indicator/connected-status-indicator.component.js b/ui/app/components/app/connected-status-indicator/connected-status-indicator.component.js index d000aaf7a..232f15262 100644 --- a/ui/app/components/app/connected-status-indicator/connected-status-indicator.component.js +++ b/ui/app/components/app/connected-status-indicator/connected-status-indicator.component.js @@ -19,7 +19,7 @@ export default class ConnectedStatusIndicator extends Component { static defaultProps = { status: STATUS_NOT_CONNECTED, - onClick: null, + onClick: undefined, } renderStatusCircle = () => { diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 249b29ca7..58aa30a87 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -53,7 +53,7 @@ export default class GasModalPageContainer extends Component { customTotalSupplement: PropTypes.string, isSwap: PropTypes.bool, value: PropTypes.string, - conversionRate: PropTypes.string, + conversionRate: PropTypes.number, minimumGasLimit: PropTypes.number.isRequired, } diff --git a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js index ff6dd9390..4651b70f8 100644 --- a/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/app/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -124,7 +124,7 @@ export function setTickPosition (axis, n, newPosition, secondNewPosition) { .style('visibility', 'visible') } -/* eslint-disable babel/no-invalid-this */ +/* eslint-disable @babel/no-invalid-this */ export function appendOrUpdateCircle ({ data, itemIndex, cx, cy, cssId, appendOnly }) { const circle = this.main .select(`.c3-selected-circles${this.getTargetSelectorSuffix(data.id)}`) @@ -145,7 +145,7 @@ export function appendOrUpdateCircle ({ data, itemIndex, cx, cy, cssId, appendOn .attr('cy', cy) } } -/* eslint-enable babel/no-invalid-this */ +/* eslint-enable @babel/no-invalid-this */ export function setSelectedCircle ({ chart, diff --git a/ui/app/components/app/selected-account/selected-account.component.js b/ui/app/components/app/selected-account/selected-account.component.js index ff2dd17c9..c1756b5ee 100644 --- a/ui/app/components/app/selected-account/selected-account.component.js +++ b/ui/app/components/app/selected-account/selected-account.component.js @@ -18,6 +18,17 @@ class SelectedAccount extends Component { selectedIdentity: PropTypes.object.isRequired, } + componentDidMount () { + this.copyTimeout = null + } + + componentWillUnmount () { + if (this.copyTimeout) { + clearTimeout(this.copyTimeout) + this.copyTimeout = null + } + } + render () { const { t } = this.context const { selectedIdentity } = this.props @@ -34,7 +45,7 @@ class SelectedAccount extends Component { className="selected-account__clickable" onClick={() => { this.setState({ copied: true }) - setTimeout(() => this.setState({ copied: false }), 3000) + this.copyTimeout = setTimeout(() => this.setState({ copied: false }), 3000) copyToClipboard(checksummedAddress) }} > diff --git a/ui/app/components/ui/info-tooltip/info-tooltip.js b/ui/app/components/ui/info-tooltip/info-tooltip.js index 42b8af75d..7e04c3822 100644 --- a/ui/app/components/ui/info-tooltip/info-tooltip.js +++ b/ui/app/components/ui/info-tooltip/info-tooltip.js @@ -36,7 +36,7 @@ export default function InfoTooltip ({ } InfoTooltip.propTypes = { - contentText: PropTypes.string, + contentText: PropTypes.node, position: PropTypes.oneOf(['top', 'left', 'bottom', 'right']), wide: PropTypes.bool, containerClassName: PropTypes.string, diff --git a/ui/app/components/ui/loading-screen/loading-screen.component.js b/ui/app/components/ui/loading-screen/loading-screen.component.js index e7f754acc..457f2dcbd 100644 --- a/ui/app/components/ui/loading-screen/loading-screen.component.js +++ b/ui/app/components/ui/loading-screen/loading-screen.component.js @@ -16,18 +16,18 @@ class LoadingScreen extends Component { renderMessage () { const { loadingMessage } = this.props - if (isValidElement(loadingMessage)) { - return loadingMessage + + if (!loadingMessage) { + return null } - return loadingMessage - ? {loadingMessage} - : null + + return isValidElement(loadingMessage) ? loadingMessage : {loadingMessage} } render () { return (
- {this.props.header && this.props.header} + {this.props.header}
{this.props.showLoadingSpinner && } {this.renderMessage()} diff --git a/ui/app/components/ui/qr-code/qr-code.js b/ui/app/components/ui/qr-code/qr-code.js index 53a0d85d5..c00885341 100644 --- a/ui/app/components/ui/qr-code/qr-code.js +++ b/ui/app/components/ui/qr-code/qr-code.js @@ -59,6 +59,7 @@ function QrCodeView (props) { />
diff --git a/ui/app/components/ui/readonly-input/readonly-input.js b/ui/app/components/ui/readonly-input/readonly-input.js index eba6fd6c2..b3e86c9c6 100644 --- a/ui/app/components/ui/readonly-input/readonly-input.js +++ b/ui/app/components/ui/readonly-input/readonly-input.js @@ -9,6 +9,7 @@ export default function ReadOnlyInput (props) { value, textarea, onClick, + autoFocus = false, } = props const InputType = textarea ? 'textarea' : 'input' @@ -21,6 +22,7 @@ export default function ReadOnlyInput (props) { readOnly onFocus={(event) => event.target.select()} onClick={onClick} + autoFocus={autoFocus} />
) @@ -32,4 +34,5 @@ ReadOnlyInput.propTypes = { value: PropTypes.string, textarea: PropTypes.bool, onClick: PropTypes.func, + autoFocus: PropTypes.bool, } diff --git a/ui/app/contexts/metametrics.js b/ui/app/contexts/metametrics.js index 111622587..eb0c8e476 100644 --- a/ui/app/contexts/metametrics.js +++ b/ui/app/contexts/metametrics.js @@ -1,4 +1,4 @@ -import React, { Component, createContext, useEffect, useCallback, useState } from 'react' +import React, { Component, createContext, useEffect, useCallback, useState, useMemo } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' import { useHistory } from 'react-router-dom' @@ -9,16 +9,15 @@ import { getAccountType, getNumberOfAccounts, getNumberOfTokens, + getCurrentChainId, } from '../selectors/selectors' import { getSendToken } from '../selectors/send' import { txDataSelector, } from '../selectors/confirm-transaction' import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { - sendMetaMetricsEvent, - sendCountIsTrackable, -} from '../helpers/utils/metametrics.util' +import { getTrackMetaMetricsEvent } from '../../../shared/modules/metametrics' +import { getCurrentLocale } from '../ducks/metamask/metamask' export const MetaMetricsContext = createContext(() => { captureException( @@ -30,6 +29,8 @@ export function MetaMetricsProvider ({ children }) { const txData = useSelector(txDataSelector) || {} const network = useSelector(getCurrentNetworkId) const environmentType = getEnvironmentType() + const chainId = useSelector(getCurrentChainId) + const locale = useSelector(getCurrentLocale) const activeCurrency = useSelector(getSendToken)?.symbol const accountType = useSelector(getAccountType) const confirmTransactionOrigin = txData.origin @@ -44,7 +45,7 @@ export function MetaMetricsProvider ({ children }) { previousPath: '', })) - const { previousPath, currentPath } = state + const { currentPath } = state useEffect(() => { const unlisten = history.listen(() => setState((prevState) => ({ @@ -55,45 +56,63 @@ export function MetaMetricsProvider ({ children }) { return unlisten }, [history]) + /** + * track a metametrics event + * + * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} - payload for event + * @returns undefined + */ + const trackEvent = useMemo(() => { + const referrer = confirmTransactionOrigin ? { url: confirmTransactionOrigin } : undefined + const page = { + path: currentPath, + } + return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ + context: { + referrer, + page, + }, + environmentType, + locale: locale.replace('_', '-'), + network, + chainId, + participateInMetaMetrics, + metaMetricsId, + metaMetricsSendCount, + })) + }, [network, chainId, locale, environmentType, participateInMetaMetrics, currentPath, confirmTransactionOrigin, metaMetricsId, metaMetricsSendCount]) + const metricsEvent = useCallback((config = {}, overrides = {}) => { const { eventOpts = {} } = config - const { name = '' } = eventOpts - const { currentPath: overrideCurrentPath = '' } = overrides - const isSendFlow = Boolean(name.match(/^send|^confirm/u) || overrideCurrentPath.match(/send|confirm/u)) - if (participateInMetaMetrics || config.isOptIn) { - return sendMetaMetricsEvent({ - network, - environmentType, - activeCurrency, - accountType, - confirmTransactionOrigin, - metaMetricsId, - numberOfTokens, - numberOfAccounts, - version: global.platform.getVersion(), - ...config, - previousPath, - currentPath, - excludeMetaMetricsId: isSendFlow && !sendCountIsTrackable(metaMetricsSendCount + 1), - ...overrides, - }) - } - - return undefined + return trackEvent({ + event: eventOpts.name, + category: eventOpts.category, + isOptIn: config.isOptIn, + excludeMetaMetricsId: eventOpts.excludeMetaMetricsId ?? overrides.excludeMetaMetricsId ?? false, + metaMetricsId: config.metaMetricsId, + matomoEvent: true, + properties: { + action: eventOpts.action, + number_of_tokens: numberOfTokens, + number_of_accounts: numberOfAccounts, + active_currency: activeCurrency, + account_type: accountType, + is_new_visit: config.is_new_visit, + // the properties coming from this key will not match our standards for + // snake_case on properties, and they may be redundant and/or not in the + // proper location (origin not as a referrer, for example). This is a temporary + // solution to not lose data, and the entire event system will be reworked in + // forthcoming PRs to deprecate the old Matomo events in favor of the new schema. + ...config.customVariables, + }, + }) }, [ - network, - environmentType, - activeCurrency, accountType, - confirmTransactionOrigin, - participateInMetaMetrics, - previousPath, - metaMetricsId, + activeCurrency, numberOfTokens, numberOfAccounts, - currentPath, - metaMetricsSendCount, + trackEvent, ]) return ( diff --git a/ui/app/contexts/metametrics.new.js b/ui/app/contexts/metametrics.new.js index 1d5587ebb..2afbb712a 100644 --- a/ui/app/contexts/metametrics.new.js +++ b/ui/app/contexts/metametrics.new.js @@ -3,26 +3,19 @@ * MetaMetrics is our own brand, and should remain aptly named regardless of the underlying * metrics system. This file implements Segment analytics tracking. */ -import React, { useRef, Component, createContext, useEffect, useCallback } from 'react' +import React, { useRef, Component, createContext, useEffect, useMemo } from 'react' import { useSelector } from 'react-redux' import PropTypes from 'prop-types' import { useLocation, matchPath, useRouteMatch } from 'react-router-dom' import { captureException, captureMessage } from '@sentry/browser' import { omit } from 'lodash' -import { - getCurrentNetworkId, -} from '../selectors/selectors' import { getEnvironmentType } from '../../../app/scripts/lib/util' -import { - sendCountIsTrackable, - segment, - METAMETRICS_ANONYMOUS_ID, -} from '../helpers/utils/metametrics.util' import { PATH_NAME_MAP } from '../helpers/constants/routes' import { getCurrentLocale } from '../ducks/metamask/metamask' -import { txDataSelector } from '../selectors' +import { getCurrentChainId, getMetricsNetworkIdentifier, txDataSelector } from '../selectors' +import { getTrackMetaMetricsEvent, METAMETRICS_ANONYMOUS_ID, segment } from '../../../shared/modules/metametrics' export const MetaMetricsContext = createContext(() => { captureException( @@ -34,7 +27,6 @@ const PATHS_TO_CHECK = Object.keys(PATH_NAME_MAP) function useSegmentContext () { const match = useRouteMatch({ path: PATHS_TO_CHECK, exact: true, strict: true }) - const locale = useSelector(getCurrentLocale) const txData = useSelector(txDataSelector) || {} const confirmTransactionOrigin = txData.origin @@ -42,11 +34,6 @@ function useSegmentContext () { url: confirmTransactionOrigin, } : undefined - let version = global.platform.getVersion() - if (process.env.METAMASK_ENVIRONMENT !== 'production') { - version = `${version}-${process.env.METAMASK_ENVIRONMENT}` - } - const page = match ? { path: match.path, title: PATH_NAME_MAP[match.path], @@ -54,24 +41,39 @@ function useSegmentContext () { } : undefined return { - app: { - version, - name: 'MetaMask Extension', - }, - locale: locale.replace('_', '-'), page, referrer, - userAgent: window.navigator.userAgent, } } export function MetaMetricsProvider ({ children }) { - const network = useSelector(getCurrentNetworkId) const metaMetricsId = useSelector((state) => state.metamask.metaMetricsId) const participateInMetaMetrics = useSelector((state) => state.metamask.participateInMetaMetrics) const metaMetricsSendCount = useSelector((state) => state.metamask.metaMetricsSendCount) + const locale = useSelector(getCurrentLocale) const location = useLocation() const context = useSegmentContext() + const network = useSelector(getMetricsNetworkIdentifier) + const chainId = useSelector(getCurrentChainId) + + /** + * track a metametrics event + * + * @param {import('../../../shared/modules/metametrics').MetaMetricsEventPayload} - payload for event + * @returns undefined + */ + const trackEvent = useMemo(() => { + return getTrackMetaMetricsEvent(global.platform.getVersion(), () => ({ + context, + locale: locale.replace('_', '-'), + environmentType: getEnvironmentType(), + chainId, + network, + participateInMetaMetrics, + metaMetricsId, + metaMetricsSendCount, + })) + }, [network, participateInMetaMetrics, locale, metaMetricsId, metaMetricsSendCount, chainId, context]) // Used to prevent double tracking page calls const previousMatch = useRef() @@ -131,72 +133,6 @@ export function MetaMetricsProvider ({ children }) { } }, [location, context, network, metaMetricsId, participateInMetaMetrics]) - /** - * track a metametrics event using segment - * e.g metricsEvent({ event: 'Unlocked MetaMask', category: 'Navigation' }) - * - * @param {object} config - configuration object for the event to track - * @param {string} config.event - event name to track - * @param {string} config.category - category to associate event to - * @param {boolean} [config.isOptIn] - happened during opt in/out workflow - * @param {object} [config.properties] - object of custom values to track, snake_case - * @param {number} [config.revenue] - amount of currency that event creates in revenue for MetaMask - * @param {string} [config.currency] - ISO 4127 format currency for events with revenue, defaults to US dollars - * @param {number} [config.value] - Abstract "value" that this event has for MetaMask. - * @return {undefined} - */ - const trackEvent = useCallback( - (config = {}) => { - const { event, category, isOptIn = false, properties = {}, revenue, value, currency } = config - if (!event) { - // Event name is required for tracking an event - throw new Error('MetaMetrics trackEvent function must be provided a payload with an "event" key') - } - if (!category) { - // Category must be supplied for every tracking event - throw new Error('MetaMetrics events must be provided a category') - } - const environmentType = getEnvironmentType() - - let excludeMetaMetricsId = config.excludeMetaMetricsId ?? false - - // This is carried over from the old implementation, and will likely need - // to be updated to work with the new tracking plan. I think we should use - // a config setting for this instead of trying to match the event name - const isSendFlow = Boolean(event.match(/^send|^confirm/u)) - if (isSendFlow && !sendCountIsTrackable(metaMetricsSendCount + 1)) { - excludeMetaMetricsId = true - } - const idTrait = excludeMetaMetricsId ? 'anonymousId' : 'userId' - const idValue = excludeMetaMetricsId ? METAMETRICS_ANONYMOUS_ID : metaMetricsId - - if (participateInMetaMetrics || isOptIn) { - segment.track({ - [idTrait]: idValue, - event, - properties: { - ...omit(properties, ['revenue', 'currency', 'value']), - revenue, - value, - currency, - category, - network, - environment_type: environmentType, - }, - context, - }) - } - - return undefined - }, [ - context, - network, - metaMetricsId, - metaMetricsSendCount, - participateInMetaMetrics, - ], - ) - return ( {children} diff --git a/ui/app/css/design-system/typography.scss b/ui/app/css/design-system/typography.scss index 70cc4bef4..1d6e1a522 100644 --- a/ui/app/css/design-system/typography.scss +++ b/ui/app/css/design-system/typography.scss @@ -69,11 +69,22 @@ $fa-font-path: 'fonts/fontawesome'; $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; +$font-size-h1: 2.5rem; +$font-size-h2: 2rem; +$font-size-h3: 1.5rem; +$font-size-h4: 1.125rem; +$font-size-h5: 1rem; +$font-size-h6: 0.875rem; +$font-size-paragraph: 1rem; +$font-size-h7: 0.75rem; +$font-size-h8: 0.625rem; +$font-size-h9: 0.5rem; + // Typography @mixin H1 { font-style: normal; font-weight: normal; - font-size: 2.5rem; + font-size: $font-size-h1; font-family: $font-family; line-height: 140%; } @@ -82,7 +93,7 @@ $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; @mixin H2 { font-style: normal; font-weight: normal; - font-size: 2rem; + font-size: $font-size-h2; font-family: $font-family; line-height: 140%; } @@ -90,7 +101,7 @@ $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; @mixin H3 { font-style: normal; font-weight: normal; - font-size: 1.5rem; + font-size: $font-size-h3; font-family: $font-family; line-height: 140%; } @@ -98,7 +109,7 @@ $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; @mixin H4 { font-style: normal; font-weight: normal; - font-size: 1.125rem; + font-size: $font-size-h4; font-family: $font-family; line-height: 140%; } @@ -106,46 +117,41 @@ $font-family: Euclid, Roboto, Helvetica, Arial, sans-serif; @mixin H5 { font-style: normal; font-weight: normal; - font-size: 1rem; - font-family: $font-family; + font-size: $font-size-h5; line-height: 140%; } @mixin H6 { font-style: normal; font-weight: normal; - font-size: 0.875rem; // 14px @default + font-size: $font-size-h6; // 14px @default line-height: 140%; } @mixin Paragraph { font-style: normal; font-weight: normal; - font-size: 1rem; - font-family: $font-family; + font-size: $font-size-paragraph; line-height: 140%; } @mixin H7 { font-style: normal; font-weight: normal; - font-size: 0.75rem; - font-family: $font-family; + font-size: $font-size-h7; line-height: 140%; } @mixin H8 { font-style: normal; font-weight: normal; - font-size: 0.625rem; - font-family: $font-family; + font-size: $font-size-h8; line-height: 140%; } @mixin H9 { font-style: normal; font-weight: normal; - font-size: 0.5rem; - font-family: $font-family; + font-size: $font-size-h9; line-height: 140%; } diff --git a/ui/app/ducks/swaps/swaps.js b/ui/app/ducks/swaps/swaps.js index 60f6ab9d0..94c2d2af2 100644 --- a/ui/app/ducks/swaps/swaps.js +++ b/ui/app/ducks/swaps/swaps.js @@ -23,7 +23,7 @@ import { import { AWAITING_SWAP_ROUTE, BUILD_QUOTE_ROUTE, LOADING_QUOTES_ROUTE, SWAPS_ERROR_ROUTE, SWAPS_MAINTENANCE_ROUTE } from '../../helpers/constants/routes' import { fetchSwapsFeatureLiveness } from '../../pages/swaps/swaps.util' import { calcGasTotal } from '../../pages/send/send.utils' -import { decimalToHex, getValueFromWeiHex, hexMax, decGWEIToHexWEI, hexToDecimal } from '../../helpers/utils/conversions.util' +import { decimalToHex, getValueFromWeiHex, hexMax, decGWEIToHexWEI, hexToDecimal, hexWEIToDecGWEI } from '../../helpers/utils/conversions.util' import { calcTokenAmount } from '../../helpers/utils/token-util' import { getFastPriceEstimateInHexWEI, @@ -36,6 +36,7 @@ import { QUOTES_NOT_AVAILABLE_ERROR, ETH_SWAPS_TOKEN_OBJECT, SWAP_FAILED_ERROR, + SWAPS_FETCH_ORDER_CONFLICT, } from '../../helpers/constants/swaps' import { SWAP, SWAP_APPROVAL } from '../../helpers/constants/transactions' import { fetchBasicGasAndTimeEstimates, fetchGasEstimates, resetCustomGasState } from '../gas/gas.duck' @@ -50,7 +51,6 @@ const initialState = { quotesFetchStartTime: null, topAssets: {}, toToken: null, - metamaskFeeAmount: null, } const slice = createSlice({ @@ -89,9 +89,6 @@ const slice = createSlice({ setToToken: (state, action) => { state.toToken = action.payload }, - setMetamaskFeeAmount: (state, action) => { - state.metamaskFeeAmount = action.payload - }, }, }) @@ -111,8 +108,6 @@ export const getTopAssets = (state) => state.swaps.topAssets export const getToToken = (state) => state.swaps.toToken -export const getMetaMaskFeeAmount = (state) => state.swaps.metamaskFeeAmount - export const getFetchingQuotes = (state) => state.swaps.fetchingQuotes export const getQuotesFetchStartTime = (state) => state.swaps.quotesFetchStartTime @@ -200,7 +195,6 @@ const { setQuotesFetchStartTime, setTopAssets, setToToken, - setMetamaskFeeAmount, } = actions export { @@ -212,7 +206,6 @@ export { setQuotesFetchStartTime as setSwapQuotesFetchStartTime, setTopAssets, setToToken as setSwapToToken, - setMetamaskFeeAmount, } export const navigateBackToBuildQuote = (history) => { @@ -407,6 +400,13 @@ export const fetchQuotesAndSetQuoteState = (history, inputValue, maxSlippage, me dispatch(setInitialGasEstimate(selectedAggId)) } } catch (e) { + // A newer swap request is running, so simply bail and let the newer request respond + if (e.message === SWAPS_FETCH_ORDER_CONFLICT) { + log.debug(`Swap fetch order conflict detected; ignoring older request`) + return + } + // TODO: Check for any errors we should expect to occur in production, and report others to Sentry + log.error(`Error fetching quotes: `, e) dispatch(setSwapsErrorKey(ERROR_FETCHING_QUOTES)) } @@ -462,6 +462,7 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { conversionRate, numberOfDecimals: 6, }) + const swapMetaData = { token_from: sourceTokenInfo.symbol, token_from_amount: String(swapTokenValue), @@ -474,7 +475,10 @@ export const signAndSendTransactions = (history, metaMetricsEvent) => { other_quote_selected: usedQuote.aggregator !== getTopQuote(state)?.aggregator, other_quote_selected_source: usedQuote.aggregator === getTopQuote(state)?.aggregator ? '' : usedQuote.aggregator, gas_fees: formatCurrency(gasEstimateTotalInEth, 'usd')?.slice(1), - estimated_gas: estimatedGasLimit.toString(16), + estimated_gas: estimatedGasLimit.toString(10), + suggested_gas_price: hexWEIToDecGWEI(usedGasPrice), + used_gas_price: hexWEIToDecGWEI(fastGasEstimate), + average_savings: usedQuote.savings?.performance, } const metaMetricsConfig = { diff --git a/ui/app/helpers/constants/swaps.js b/ui/app/helpers/constants/swaps.js index f9ccc5a78..a20000a0c 100644 --- a/ui/app/helpers/constants/swaps.js +++ b/ui/app/helpers/constants/swaps.js @@ -14,6 +14,7 @@ export const SWAP_FAILED_ERROR = 'swap-failed-error' export const ERROR_FETCHING_QUOTES = 'error-fetching-quotes' export const QUOTES_NOT_AVAILABLE_ERROR = 'quotes-not-avilable' export const OFFLINE_FOR_MAINTENANCE = 'offline-for-maintenance' +export const SWAPS_FETCH_ORDER_CONFLICT = 'swaps-fetch-order-conflict' // A gas value for ERC20 approve calls that should be sufficient for all ERC20 approve implementations export const DEFAULT_ERC20_APPROVE_GAS = '0x1d4c0' diff --git a/ui/app/helpers/utils/conversions.util.test.js b/ui/app/helpers/utils/conversions.util.test.js index 5f344e3e5..5a32ceff4 100644 --- a/ui/app/helpers/utils/conversions.util.test.js +++ b/ui/app/helpers/utils/conversions.util.test.js @@ -2,40 +2,42 @@ import assert from 'assert' import { ETH } from '../constants/common' import * as utils from './conversions.util' -describe('getWeiHexFromDecimalValue', function () { - it('should correctly convert 0 in ETH', function () { - const weiValue = utils.getWeiHexFromDecimalValue({ - value: '0', - fromCurrency: ETH, - fromDenomination: ETH, +describe('conversion utils', function () { + describe('getWeiHexFromDecimalValue', function () { + it('should correctly convert 0 in ETH', function () { + const weiValue = utils.getWeiHexFromDecimalValue({ + value: '0', + fromCurrency: ETH, + fromDenomination: ETH, + }) + assert.equal(weiValue, '0') + }) + }) + + describe('decETHToDecWEI', function () { + it('should correctly convert 1 ETH to WEI', function () { + const weiValue = utils.decETHToDecWEI('1') + assert.equal(weiValue, '1000000000000000000') + }) + + it('should correctly convert 0.000000000000000001 ETH to WEI', function () { + const weiValue = utils.decETHToDecWEI('0.000000000000000001') + assert.equal(weiValue, '1') + }) + + it('should correctly convert 1000000.000000000000000001 ETH to WEI', function () { + const weiValue = utils.decETHToDecWEI('1000000.000000000000000001') + assert.equal(weiValue, '1000000000000000000000001') + }) + + it('should correctly convert 9876.543210 ETH to WEI', function () { + const weiValue = utils.decETHToDecWEI('9876.543210') + assert.equal(weiValue, '9876543210000000000000') + }) + + it('should correctly convert 1.0000000000000000 ETH to WEI', function () { + const weiValue = utils.decETHToDecWEI('1.0000000000000000') + assert.equal(weiValue, '1000000000000000000') }) - assert.equal(weiValue, '0') - }) -}) - -describe('decETHToDecWEI', function () { - it('should correctly convert 1 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1') - assert.equal(weiValue, '1000000000000000000') - }) - - it('should correctly convert 0.000000000000000001 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('0.000000000000000001') - assert.equal(weiValue, '1') - }) - - it('should correctly convert 1000000.000000000000000001 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1000000.000000000000000001') - assert.equal(weiValue, '1000000000000000000000001') - }) - - it('should correctly convert 9876.543210 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('9876.543210') - assert.equal(weiValue, '9876543210000000000000') - }) - - it('should correctly convert 1.0000000000000000 ETH to WEI', function () { - const weiValue = utils.decETHToDecWEI('1.0000000000000000') - assert.equal(weiValue, '1000000000000000000') }) }) diff --git a/ui/app/helpers/utils/metametrics.util.js b/ui/app/helpers/utils/metametrics.util.js deleted file mode 100644 index 9dc16dc7e..000000000 --- a/ui/app/helpers/utils/metametrics.util.js +++ /dev/null @@ -1,259 +0,0 @@ -/* eslint camelcase: 0 */ - -import ethUtil from 'ethereumjs-util' -import Analytics from 'analytics-node' - -const inDevelopment = process.env.METAMASK_DEBUG || process.env.IN_TEST - -let projectId = process.env.METAMETRICS_PROJECT_ID -if (!projectId) { - projectId = inDevelopment ? 1 : 2 -} - -const METAMETRICS_BASE_URL = 'https://chromeextensionmm.innocraft.cloud/piwik.php' -const METAMETRICS_REQUIRED_PARAMS = `?idsite=${projectId}&rec=1&apiv=1` -const METAMETRICS_BASE_FULL = METAMETRICS_BASE_URL + METAMETRICS_REQUIRED_PARAMS - -const METAMETRICS_TRACKING_URL = inDevelopment - ? 'http://www.metamask.io/metametrics' - : 'http://www.metamask.io/metametrics-prod' - -/** ***************Custom variables*************** **/ -// Custom variable declarations -const METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE = 'gasLimitChange' -const METAMETRICS_CUSTOM_GAS_PRICE_CHANGE = 'gasPriceChange' -const METAMETRICS_CUSTOM_FUNCTION_TYPE = 'functionType' -const METAMETRICS_CUSTOM_RECIPIENT_KNOWN = 'recipientKnown' -const METAMETRICS_REQUEST_ORIGIN = 'origin' -const METAMETRICS_CUSTOM_FROM_NETWORK = 'fromNetwork' -const METAMETRICS_CUSTOM_TO_NETWORK = 'toNetwork' -const METAMETRICS_CUSTOM_ERROR_FIELD = 'errorField' -const METAMETRICS_CUSTOM_ERROR_MESSAGE = 'errorMessage' -const METAMETRICS_CUSTOM_RPC_NETWORK_ID = 'networkId' -const METAMETRICS_CUSTOM_RPC_CHAIN_ID = 'chainId' -const METAMETRICS_CUSTOM_GAS_CHANGED = 'gasChanged' -const METAMETRICS_CUSTOM_ASSET_SELECTED = 'assetSelected' - -const customVariableNameIdMap = { - [METAMETRICS_CUSTOM_FUNCTION_TYPE]: 1, - [METAMETRICS_CUSTOM_RECIPIENT_KNOWN]: 2, - [METAMETRICS_REQUEST_ORIGIN]: 3, - [METAMETRICS_CUSTOM_GAS_LIMIT_CHANGE]: 4, - [METAMETRICS_CUSTOM_GAS_PRICE_CHANGE]: 5, - - [METAMETRICS_CUSTOM_FROM_NETWORK]: 1, - [METAMETRICS_CUSTOM_TO_NETWORK]: 2, - - [METAMETRICS_CUSTOM_RPC_NETWORK_ID]: 1, - [METAMETRICS_CUSTOM_RPC_CHAIN_ID]: 2, - - [METAMETRICS_CUSTOM_ERROR_FIELD]: 3, - [METAMETRICS_CUSTOM_ERROR_MESSAGE]: 4, - - [METAMETRICS_CUSTOM_GAS_CHANGED]: 1, - [METAMETRICS_CUSTOM_ASSET_SELECTED]: 2, -} - -/** ********************************************************** **/ - -const METAMETRICS_CUSTOM_NETWORK = 'network' -const METAMETRICS_CUSTOM_ENVIRONMENT_TYPE = 'environmentType' -const METAMETRICS_CUSTOM_ACTIVE_CURRENCY = 'activeCurrency' -const METAMETRICS_CUSTOM_ACCOUNT_TYPE = 'accountType' -const METAMETRICS_CUSTOM_NUMBER_OF_ACCOUNTS = 'numberOfAccounts' -const METAMETRICS_CUSTOM_NUMBER_OF_TOKENS = 'numberOfTokens' -const METAMETRICS_CUSTOM_VERSION = 'version' - -const customDimensionsNameIdMap = { - [METAMETRICS_CUSTOM_NETWORK]: 5, - [METAMETRICS_CUSTOM_ENVIRONMENT_TYPE]: 6, - [METAMETRICS_CUSTOM_ACTIVE_CURRENCY]: 7, - [METAMETRICS_CUSTOM_ACCOUNT_TYPE]: 8, - [METAMETRICS_CUSTOM_NUMBER_OF_ACCOUNTS]: 9, - [METAMETRICS_CUSTOM_NUMBER_OF_TOKENS]: 10, - [METAMETRICS_CUSTOM_VERSION]: 11, -} - -export const METAMETRICS_ANONYMOUS_ID = '0x0000000000000000' - -function composeUrlRefParamAddition (previousPath, confirmTransactionOrigin) { - const externalOrigin = confirmTransactionOrigin && confirmTransactionOrigin !== 'metamask' - return `&urlref=${externalOrigin ? 'EXTERNAL' : encodeURIComponent(`${METAMETRICS_TRACKING_URL}${previousPath}`)}` -} - -// composes query params of the form &dimension[0-999]=[value] -function composeCustomDimensionParamAddition (customDimensions) { - const customDimensionParamStrings = Object.keys(customDimensions).reduce((acc, name) => { - return [...acc, `dimension${customDimensionsNameIdMap[name]}=${customDimensions[name]}`] - }, []) - return `&${customDimensionParamStrings.join('&')}` -} - -// composes query params in form: &cvar={[id]:[[name],[value]]} -// Example: &cvar={"1":["OS","iphone 5.0"],"2":["Matomo Mobile Version","1.6.2"],"3":["Locale","en::en"],"4":["Num Accounts","2"]} -function composeCustomVarParamAddition (customVariables) { - const customVariableIdValuePairs = Object.keys(customVariables).reduce((acc, name) => { - return { - [customVariableNameIdMap[name]]: [name, customVariables[name]], - ...acc, - } - }, {}) - return `&cvar=${encodeURIComponent(JSON.stringify(customVariableIdValuePairs))}` -} - -function composeParamAddition (paramValue, paramName) { - return paramValue !== 0 && !paramValue - ? '' - : `&${paramName}=${paramValue}` -} - -/** - * @name composeUrl - * @param {Object} config - configuration object for composing the metametrics url - * @property {object} config.eventOpts Object containing event category, action and name descriptors - * @property {object} config.customVariables Object containing custom properties with values relevant to a specific event - * @property {object} config.pageOpts Objects containing information about a page/route the event is dispatched from - * @property {number} config.network The selected network of the user when the event occurs - * @property {string} config.environmentType The "environment" the user is using the app from: 'popup', 'notification' or 'fullscreen' - * @property {string} config.activeCurrency The current the user has select as their primary currency at the time of the event - * @property {string} config.accountType The account type being used at the time of the event: 'hardware', 'imported' or 'default' - * @property {number} config.numberOfTokens The number of tokens that the user has added at the time of the event - * @property {number} config.numberOfAccounts The number of accounts the user has added at the time of the event - * @property {string} config.version The current version of the MetaMask extension - * @property {string} config.previousPath The pathname of the URL the user was on prior to the URL they are on at the time of the event - * @property {string} config.currentPath The pathname of the URL the user is on at the time of the event - * @property {string} config.metaMetricsId A random id assigned to a user at the time of opting in to metametrics. A hexadecimal number - * @property {string} config.confirmTransactionOrigin The origin on a transaction - * @property {boolean} config.excludeMetaMetricsId Whether or not the tracked event data should be associated with a metametrics id - * @property {boolean} config.isNewVisit Whether or not the event should be tracked as a new visit/user sessions - * @returns {string} - Returns a url to be passed to fetch to make the appropriate request to matomo. - * Example: https://chromeextensionmm.innocraft.cloud/piwik.php?idsite=1&rec=1&apiv=1&e_c=Navigation&e_a=Home&e_n=Clicked%20Send:%20Eth&urlref=http%3A%2F%2Fwww.metamask.io%2Fmetametrics%2Fhome.html%23send&dimension5=3&dimension6=fullscreen&dimension7=ETH&dimension8=default&dimension9=0&dimension10=3&url=http%3A%2F%2Fwww.metamask.io%2Fmetametrics%2Fhome.html%23&_id=49c10aff19795e9a&rand=7906028754863992&pv_id=53acad&uid=49c1 - */ -function composeUrl (config) { - const { - eventOpts = {}, - customVariables = '', - pageOpts = '', - network, - environmentType, - activeCurrency, - accountType, - numberOfTokens, - numberOfAccounts, - version, - previousPath = '', - currentPath, - metaMetricsId, - confirmTransactionOrigin, - excludeMetaMetricsId, - isNewVisit, - } = config - const base = METAMETRICS_BASE_FULL - - const e_c = composeParamAddition(eventOpts.category, 'e_c') - const e_a = composeParamAddition(eventOpts.action, 'e_a') - const e_n = composeParamAddition(eventOpts.name, 'e_n') - const new_visit = isNewVisit ? `&new_visit=1` : '' - - const cvar = (customVariables && composeCustomVarParamAddition(customVariables)) || '' - - const action_name = '' - - const urlref = previousPath && composeUrlRefParamAddition(previousPath, confirmTransactionOrigin) - - const dimensions = pageOpts.hideDimensions - ? '' - : ( - composeCustomDimensionParamAddition({ - network, - environmentType, - activeCurrency, - accountType, - version, - numberOfTokens: (customVariables && customVariables.numberOfTokens) || numberOfTokens, - numberOfAccounts: (customVariables && customVariables.numberOfAccounts) || numberOfAccounts, - }) - ) - const url = currentPath ? `&url=${encodeURIComponent(`${METAMETRICS_TRACKING_URL}${currentPath}`)}` : '' - const _id = metaMetricsId && !excludeMetaMetricsId ? `&_id=${metaMetricsId.slice(2, 18)}` : '' - const rand = `&rand=${String(Math.random()).slice(2)}` - const pv_id = currentPath ? `&pv_id=${ethUtil.bufferToHex(ethUtil.sha3(currentPath)).slice(2, 8)}` : '' - - let uid = '' - if (excludeMetaMetricsId) { - uid = '&uid=0000000000000000' - } else if (metaMetricsId) { - uid = `&uid=${metaMetricsId.slice(2, 18)}` - } - - return [base, e_c, e_a, e_n, cvar, action_name, urlref, dimensions, url, _id, rand, pv_id, uid, new_visit].join('') -} - -export function sendMetaMetricsEvent (config) { - return window.fetch(composeUrl(config), { - 'headers': {}, - 'method': 'GET', - }) -} - -export function verifyUserPermission (config, props) { - const { - eventOpts = {}, - } = config - const { userPermissionPreferences } = props - const { - allowAll, - allowNone, - allowSendMetrics, - } = userPermissionPreferences - - if (allowNone) { - return false - } else if (allowAll) { - return true - } else if (allowSendMetrics && eventOpts.name === 'send') { - return true - } - return false -} - -const trackableSendCounts = { - 1: true, - 10: true, - 30: true, - 50: true, - 100: true, - 250: true, - 500: true, - 1000: true, - 2500: true, - 5000: true, - 10000: true, - 25000: true, -} - -export function sendCountIsTrackable (sendCount) { - return Boolean(trackableSendCounts[sendCount]) -} - -const flushAt = inDevelopment ? 1 : undefined - -const segmentNoop = { - track () { - // noop - }, - page () { - // noop - }, - identify () { - // noop - }, -} - -// We do not want to track events on development builds unless specifically -// provided a SEGMENT_WRITE_KEY. This also holds true for test environments and -// E2E, which is handled in the build process by never providing the SEGMENT_WRITE_KEY -// which process.env.IN_TEST is true -export const segment = process.env.SEGMENT_WRITE_KEY - ? new Analytics(process.env.SEGMENT_WRITE_KEY, { flushAt }) - : segmentNoop diff --git a/ui/app/helpers/utils/token-util.js b/ui/app/helpers/utils/token-util.js index cacfe6af2..700f5f9c8 100644 --- a/ui/app/helpers/utils/token-util.js +++ b/ui/app/helpers/utils/token-util.js @@ -148,7 +148,7 @@ export function calcTokenValue (value, decimals) { * @returns {string | undefined} A lowercase address string. */ export function getTokenAddressParam (tokenData = {}) { - const value = tokenData?.args?.['_to'] || tokenData?.args?.[0] + const value = tokenData?.args?._to || tokenData?.args?.[0] return value?.toString().toLowerCase() } @@ -160,7 +160,7 @@ export function getTokenAddressParam (tokenData = {}) { * @returns {string | undefined} A decimal string value. */ export function getTokenValueParam (tokenData = {}) { - return tokenData?.args?.['_value']?.toString() + return tokenData?.args?._value?.toString() } export function getTokenValue (tokenParams = []) { diff --git a/ui/app/helpers/utils/util.js b/ui/app/helpers/utils/util.js index ba5c07867..8cf64947d 100644 --- a/ui/app/helpers/utils/util.js +++ b/ui/app/helpers/utils/util.js @@ -1,4 +1,4 @@ -import punycode from 'punycode' +import punycode from 'punycode/punycode' import abi from 'human-standard-token-abi' import BigNumber from 'bignumber.js' import ethUtil from 'ethereumjs-util' diff --git a/ui/app/hooks/useSwappedTokenValue.js b/ui/app/hooks/useSwappedTokenValue.js index b7027d4af..8357d8749 100644 --- a/ui/app/hooks/useSwappedTokenValue.js +++ b/ui/app/hooks/useSwappedTokenValue.js @@ -44,6 +44,11 @@ export function useSwappedTokenValue (transactionGroup, currentAsset) { decimals, ) : transactionCategory === SWAP && primaryTransaction.swapTokenValue + + const isNegative = typeof swapTokenValue === 'string' + ? Math.sign(swapTokenValue) === -1 + : false + const _swapTokenFiatAmount = useTokenFiatAmount( address, swapTokenValue || '', @@ -52,5 +57,5 @@ export function useSwappedTokenValue (transactionGroup, currentAsset) { const swapTokenFiatAmount = ( swapTokenValue && isViewingReceivedTokenFromSwap && _swapTokenFiatAmount ) - return { swapTokenValue, swapTokenFiatAmount, isViewingReceivedTokenFromSwap } + return { swapTokenValue, swapTokenFiatAmount, isViewingReceivedTokenFromSwap, isNegative } } diff --git a/ui/app/hooks/useTransactionDisplayData.js b/ui/app/hooks/useTransactionDisplayData.js index de027d41e..c41fcaf99 100644 --- a/ui/app/hooks/useTransactionDisplayData.js +++ b/ui/app/hooks/useTransactionDisplayData.js @@ -115,7 +115,7 @@ export function useTransactionDisplayData (transactionGroup) { // The primary title of the Tx that will be displayed in the activity list let title - const { swapTokenValue, swapTokenFiatAmount, isViewingReceivedTokenFromSwap } = useSwappedTokenValue(transactionGroup, currentAsset) + const { swapTokenValue, isNegative, swapTokenFiatAmount, isViewingReceivedTokenFromSwap } = useSwappedTokenValue(transactionGroup, currentAsset) // There are seven types of transaction entries that are currently differentiated in the design // 1. Signature request @@ -145,8 +145,13 @@ export function useTransactionDisplayData (transactionGroup) { : initialTransaction.sourceTokenSymbol primaryDisplayValue = swapTokenValue secondaryDisplayValue = swapTokenFiatAmount - prefix = isViewingReceivedTokenFromSwap ? '+' : '-' - + if (isNegative) { + prefix = '' + } else if (isViewingReceivedTokenFromSwap) { + prefix = '+' + } else { + prefix = '-' + } } else if (transactionCategory === SWAP_APPROVAL) { category = TRANSACTION_CATEGORY_APPROVAL title = t('swapApproval', [primaryTransaction.sourceTokenSymbol]) diff --git a/ui/app/pages/add-token/token-search/token-search.component.js b/ui/app/pages/add-token/token-search/token-search.component.js index ed8c41354..2cca26e84 100644 --- a/ui/app/pages/add-token/token-search/token-search.component.js +++ b/ui/app/pages/add-token/token-search/token-search.component.js @@ -56,7 +56,7 @@ export default class TokenSearch extends Component { position="start" style={{ marginRight: '12px' }} > - + ) } diff --git a/ui/app/pages/routes/routes.component.js b/ui/app/pages/routes/routes.component.js index 37bb13f40..e5c3e74de 100644 --- a/ui/app/pages/routes/routes.component.js +++ b/ui/app/pages/routes/routes.component.js @@ -101,12 +101,6 @@ export default class Routes extends Component { this.props.history.listen((locationObj, action) => { if (action === 'PUSH') { pageChanged(locationObj.pathname) - this.context.metricsEvent({}, { - currentPath: locationObj.pathname, - pageOpts: { - hideDimensions: true, - }, - }) } }) } diff --git a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js index ccbfed356..5c02e2654 100644 --- a/ui/app/pages/send/send-content/add-recipient/ens-input.component.js +++ b/ui/app/pages/send/send-content/add-recipient/ens-input.component.js @@ -33,6 +33,7 @@ export default class EnsInput extends Component { onReset: PropTypes.func, onValidAddressTyped: PropTypes.func, contact: PropTypes.object, + value: PropTypes.string, } state = { @@ -53,20 +54,33 @@ export default class EnsInput extends Component { } } - // If an address is sent without a nickname, meaning not from ENS or from - // the user's own accounts, a default of a one-space string is used. componentDidUpdate (prevProps) { const { input, } = this.state const { network, + value, } = this.props + let newValue + + // Set the value of our input based on QR code provided by parent + const newProvidedValue = input !== value && prevProps.value !== value + if (newProvidedValue) { + newValue = value + } + if (prevProps.network !== network) { const provider = global.ethereumProvider this.ens = new ENS({ provider, network }) - this.onChange({ target: { value: input } }) + if (!newProvidedValue) { + newValue = input + } + } + + if (newValue !== undefined) { + this.onChange({ target: { value: newValue } }) } } diff --git a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js index 12f420186..632ad1b4e 100644 --- a/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js +++ b/ui/app/pages/settings/contact-list-tab/add-contact/add-contact.component.js @@ -52,6 +52,7 @@ export default class AddContact extends PureComponent { validate = (address) => { const valid = isValidAddress(address) const validEnsAddress = isValidDomainName(address) + if (valid || validEnsAddress || address === '') { this.setState({ error: '', ethAddress: address }) } else { @@ -73,6 +74,7 @@ export default class AddContact extends PureComponent { this.setState({ ensAddress: address, error: '', ensError: '' }) }} updateEnsResolutionError={(message) => this.setState({ ensError: message })} + value={this.state.ethAddress || ''} /> ) } diff --git a/ui/app/pages/swaps/actionable-message/actionable-message.js b/ui/app/pages/swaps/actionable-message/actionable-message.js index 84cade2ec..9805914d8 100644 --- a/ui/app/pages/swaps/actionable-message/actionable-message.js +++ b/ui/app/pages/swaps/actionable-message/actionable-message.js @@ -38,7 +38,7 @@ export default function ActionableMessage ({ } ActionableMessage.propTypes = { - message: PropTypes.string.isRequired, + message: PropTypes.node.isRequired, primaryAction: PropTypes.shape({ label: PropTypes.string, onClick: PropTypes.func, diff --git a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js index 1ddb5252f..d44348424 100644 --- a/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js +++ b/ui/app/pages/swaps/awaiting-swap/awaiting-swap.js @@ -31,7 +31,7 @@ import { import { SUBMITTED_STATUS } from '../../../helpers/constants/transactions' import { ASSET_ROUTE, DEFAULT_ROUTE } from '../../../helpers/constants/routes' -import { getRenderableGasFeesForQuote } from '../swaps.util' +import { getRenderableNetworkFeesForQuote } from '../swaps.util' import SwapsFooter from '../swaps-footer' import SwapFailureIcon from './swap-failure-icon' import SwapSuccessIcon from './swap-success-icon' @@ -41,7 +41,6 @@ import ViewOnEtherScanLink from './view-on-ether-scan-link' export default function AwaitingSwap ({ swapComplete, errorKey, - symbol, txHash, networkId, tokensReceived, @@ -71,8 +70,17 @@ export default function AwaitingSwap ({ let feeinFiat if (usedQuote && tradeTxParams) { - const renderableGasFees = getRenderableGasFeesForQuote(usedQuote.gasEstimateWithRefund || usedQuote.averageGas, approveTxParams?.gas || '0x0', tradeTxParams.gasPrice, currentCurrency, conversionRate) - feeinFiat = renderableGasFees.feeinFiat?.slice(1) + const renderableNetworkFees = getRenderableNetworkFeesForQuote( + usedQuote.gasEstimateWithRefund || usedQuote.averageGas, + approveTxParams?.gas || '0x0', + tradeTxParams.gasPrice, + currentCurrency, + conversionRate, + tradeTxParams.value, + sourceTokenInfo?.symbol, + usedQuote.sourceAmount, + ) + feeinFiat = renderableNetworkFees.feeinFiat?.slice(1) } const quotesExpiredEvent = useNewMetricEvent({ @@ -119,7 +127,14 @@ export default function AwaitingSwap ({ let countdownText if (timeRemainingIsNumber && !timeRemainingExpired && tradeTxData?.submittedTime) { - countdownText = + countdownText = ( + + ) } else if (tradeTxData?.submittedTime) { countdownText = t('swapsAlmostDone') } else { @@ -182,7 +197,7 @@ export default function AwaitingSwap ({ headerText = t('swapProcessing') statusImage = submitText = t('swapsViewInActivity') - descriptionText = t('swapOnceTransactionHasProcess', [{symbol}]) + descriptionText = t('swapOnceTransactionHasProcess', [{destinationTokenInfo.symbol}]) content = ( <>
- submitText = t('swapViewToken', [symbol]) - descriptionText = t('swapTokenAvailable', [{`${tokensReceived || ''} ${symbol}`}]) + submitText = t('swapViewToken', [destinationTokenInfo.symbol]) + descriptionText = t('swapTokenAvailable', [{`${tokensReceived || ''} ${destinationTokenInfo.symbol}`}]) content = blockExplorerUrl && ( ( -
- -
-) - -export const swapComplete = () => ( -
- -
-) - -export const swapError = () => ( -
- -
-) diff --git a/ui/app/pages/swaps/build-quote/build-quote.js b/ui/app/pages/swaps/build-quote/build-quote.js index 8ca56c3af..31131ff83 100644 --- a/ui/app/pages/swaps/build-quote/build-quote.js +++ b/ui/app/pages/swaps/build-quote/build-quote.js @@ -241,22 +241,23 @@ export default function BuildQuote ({
{t('swapSwapTo')}
- +
+ +
{ diff --git a/ui/app/pages/swaps/build-quote/index.scss b/ui/app/pages/swaps/build-quote/index.scss index 7b0592ba8..8c97ff36a 100644 --- a/ui/app/pages/swaps/build-quote/index.scss +++ b/ui/app/pages/swaps/build-quote/index.scss @@ -118,4 +118,9 @@ max-height: 276px; } } + + /* Prevents the swaps "Swap to" field from overflowing */ + .dropdown-input-pair__to .dropdown-search-list { + width: 100%; + } } diff --git a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js index 5628640d9..cd48e5189 100644 --- a/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js +++ b/ui/app/pages/swaps/dropdown-search-list/dropdown-search-list.js @@ -29,12 +29,16 @@ export default function DropdownSearchList ({ const t = useContext(I18nContext) const [isOpen, setIsOpen] = useState(false) const [selectedItem, setSelectedItem] = useState(startingItem) + const close = useCallback(() => { + setIsOpen(false) + onClose && onClose() + }, [onClose]) + const onClickItem = useCallback((item) => { onSelect && onSelect(item) setSelectedItem(item) - setIsOpen(false) - onClose && onClose() - }, [onClose, onSelect]) + close() + }, [onSelect, close]) const onClickSelector = useCallback(() => { if (!isOpen) { @@ -57,10 +61,20 @@ export default function DropdownSearchList ({ } }, [externallySelectedItem, selectedItem, prevExternallySelectedItem]) + const onKeyUp = (e) => { + if (e.key === 'Escape') { + close() + } else if (e.key === 'Enter') { + onClickSelector(e) + } + } + return (
{!isOpen && (
-

{ t('swapGasFeeSummary') }

+

{ t('swapNetworkFeeSummary') }

{ t('swapEstimatedNetworkFeeSummary', [ { t('swapEstimatedNetworkFee') } diff --git a/ui/app/pages/swaps/index.js b/ui/app/pages/swaps/index.js index ea38f53b7..f35060b2d 100644 --- a/ui/app/pages/swaps/index.js +++ b/ui/app/pages/swaps/index.js @@ -20,7 +20,6 @@ import { getAggregatorMetadata, getBackgroundSwapRouteState, getSwapsErrorKey, - setMetamaskFeeAmount, getSwapsFeatureLiveness, prepareToLeaveSwaps, fetchAndSetSwapsGasPriceInfo, @@ -49,7 +48,7 @@ import { useNewMetricEvent } from '../../hooks/useMetricEvent' import { getValueFromWeiHex } from '../../helpers/utils/conversions.util' import FeatureToggledRoute from '../../helpers/higher-order-components/feature-toggled-route' -import { fetchTokens, fetchTopAssets, getSwapsTokensReceivedFromTxMeta, fetchAggregatorMetadata, fetchMetaMaskFeeAmount } from './swaps.util' +import { fetchTokens, fetchTopAssets, getSwapsTokensReceivedFromTxMeta, fetchAggregatorMetadata } from './swaps.util' import AwaitingSwap from './awaiting-swap' import LoadingQuote from './loading-swaps-quotes' import BuildQuote from './build-quote' @@ -155,11 +154,6 @@ export default function Swap () { dispatch(setAggregatorMetadata(newAggregatorMetadata)) }) - fetchMetaMaskFeeAmount() - .then((metaMaskFeeAmount) => { - dispatch(setMetamaskFeeAmount(metaMaskFeeAmount)) - }) - dispatch(resetCustomGasState()) dispatch(fetchAndSetSwapsGasPriceInfo()) @@ -304,7 +298,6 @@ export default function Swap () { @@ -366,7 +358,6 @@ export default function Swap () { ? ( { - const [loading, setLoading] = useState(false) - const [loadingComplete, setLoadingComplete] = useState(false) - const [done, setDone] = useState(false) - - useEffect(() => { - if (!done && !loading) { - setLoading(true) - setTimeout(() => { - setLoading(false) - setLoadingComplete(true) - }, 3000) - } - }, [done, loading]) - - return ( -

-
- setDone(true)} - aggregatorMetadata={storiesMetadata} - /> -
-
- ) -} - -export const SlowerThanExpectedCompletion = () => { - const [loading, setLoading] = useState(false) - const [loadingComplete, setLoadingComplete] = useState(false) - const [done, setDone] = useState(false) - - useEffect(() => { - if (!done && !loading) { - setLoading(true) - setTimeout(() => { - setLoading(false) - setLoadingComplete(true) - }, 10000) - } - }, [done, loading]) - - return ( -
-
- setDone(true)} - aggregatorMetadata={storiesMetadata} - /> -
-
- ) -} - -export const FasterThanExpectedCompletionWithError = () => { - const [loading, setLoading] = useState(false) - const [loadingComplete, setLoadingComplete] = useState(false) - const [done, setDone] = useState(false) - - useEffect(() => { - if (!done && !loading) { - setLoading(true) - setTimeout(() => { - setLoading(false) - setLoadingComplete(true) - }, 3000) - } - }, [done, loading]) - - return ( -
-
- setDone(true)} - aggregatorMetadata={storiesMetadata} - /> -
-
- ) -} diff --git a/ui/app/pages/swaps/searchable-item-list/index.scss b/ui/app/pages/swaps/searchable-item-list/index.scss index e5895a265..73eb5b09d 100644 --- a/ui/app/pages/swaps/searchable-item-list/index.scss +++ b/ui/app/pages/swaps/searchable-item-list/index.scss @@ -66,7 +66,8 @@ border-bottom: 1px solid $Grey-100; } - &:hover { + &:hover, + &:focus { background: $Grey-000; } diff --git a/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js b/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js index e7a841e66..6d00e3a80 100644 --- a/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js +++ b/ui/app/pages/swaps/searchable-item-list/item-list/item-list.component.js @@ -34,6 +34,7 @@ export default function ItemList ({ return null } + const onClick = () => onClickItem && onClickItem(result) const { iconUrl, identiconAddress, @@ -47,11 +48,13 @@ export default function ItemList ({ } = result return (
onClickItem && onClickItem(result)} + onClick={onClick} + onKeyUp={(e) => e.key === 'Enter' && onClick()} key={`searchable-item-list-item-${i}`} > {(iconUrl || primaryLabel) && ()} diff --git a/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js b/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js index 7cb93211a..401d660dc 100644 --- a/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js +++ b/ui/app/pages/swaps/searchable-item-list/list-item-search/list-item-search.component.js @@ -10,7 +10,7 @@ const renderAdornment = () => ( position="start" style={{ marginRight: '12px' }} > - + ) diff --git a/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js b/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js index f85aada1f..409fc3196 100644 --- a/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js +++ b/ui/app/pages/swaps/select-quote-popover/mock-quote-data.js @@ -6,8 +6,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '100000000000000000000', isBestQuote: false, - liquiditySource: 'AGG', - metaMaskFee: '1.00 DAI', networkFees: '$15.25', quoteSource: 'AGG', rawNetworkFees: 10.25, @@ -23,8 +21,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '101000000000000000000', isBestQuote: false, - liquiditySource: 'RFQ', - metaMaskFee: '1.01 DAI', networkFees: '$14.26', quoteSource: 'RFQ', rawNetworkFees: 10.26, @@ -40,8 +36,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '102000000000000000000', isBestQuote: false, - liquiditySource: 'DEX', - metaMaskFee: '1.02 DAI', networkFees: '$13.27', quoteSource: 'DEX', rawNetworkFees: 10.27, @@ -57,8 +51,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '150000000000000000000', isBestQuote: true, - liquiditySource: 'AGG', - metaMaskFee: '1.00 DAI', networkFees: '$12.28', quoteSource: 'AGG', rawNetworkFees: 10.28, @@ -74,8 +66,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '104000000000000000000', isBestQuote: false, - liquiditySource: 'RFQ', - metaMaskFee: '1.04 DAI', networkFees: '$11.29', quoteSource: 'RFQ', rawNetworkFees: 10.29, @@ -91,8 +81,6 @@ const quoteDataRows = [ destinationTokenSymbol: 'DAI', destinationTokenValue: '105000000000000000000', isBestQuote: false, - liquiditySource: 'DEX', - metaMaskFee: '1.05 DAI', networkFees: '$10.30', quoteSource: 'DEX', rawNetworkFees: 10.30, diff --git a/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js b/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js index bff69cbb5..5e8d7d8e6 100644 --- a/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js +++ b/ui/app/pages/swaps/select-quote-popover/quote-details/quote-details.js @@ -1,8 +1,6 @@ import React, { useContext } from 'react' import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' import { I18nContext } from '../../../../contexts/i18n' -import { getMetaMaskFeeAmount } from '../../../../ducks/swaps/swaps' import InfoTooltip from '../../../../components/ui/info-tooltip' import ExchangeRateDisplay from '../../exchange-rate-display' @@ -16,9 +14,9 @@ const QuoteDetails = ({ minimumAmountReceived, feeInEth, networkFees, + metaMaskFee, }) => { const t = useContext(I18nContext) - const metaMaskFee = useSelector(getMetaMaskFeeAmount) return (
@@ -105,6 +103,7 @@ QuoteDetails.propTypes = { minimumAmountReceived: PropTypes.string.isRequired, feeInEth: PropTypes.string.isRequired, networkFees: PropTypes.string.isRequired, + metaMaskFee: PropTypes.number.isRequired, } export default QuoteDetails diff --git a/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js b/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js index 27f99be04..b13087139 100644 --- a/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js +++ b/ui/app/pages/swaps/select-quote-popover/select-quote-popover-constants.js @@ -7,8 +7,6 @@ export const QUOTE_DATA_ROWS_PROPTYPES_SHAPE = PropTypes.shape({ destinationTokenSymbol: PropTypes.string.isRequired, destinationTokenValue: PropTypes.string.isRequired, isBestQuote: PropTypes.bool, - liquiditySource: PropTypes.string.isRequired, - metaMaskFee: PropTypes.string.isRequired, networkFees: PropTypes.string.isRequired, quoteSource: PropTypes.string.isRequired, rawNetworkFees: PropTypes.number.isRequired, diff --git a/ui/app/pages/swaps/select-quote-popover/sort-list/sort-list.js b/ui/app/pages/swaps/select-quote-popover/sort-list/sort-list.js index 623020e05..c2bc0ecca 100644 --- a/ui/app/pages/swaps/select-quote-popover/sort-list/sort-list.js +++ b/ui/app/pages/swaps/select-quote-popover/sort-list/sort-list.js @@ -38,7 +38,7 @@ export default function SortList ({ // This sort aims to do the following: // If there is no selected sort column, then the best quotes should be first in the list // If there is no selected sort column, then quotes that are not the best quotes should be in random order, after the first in the list - // If the sort column is 'liquiditySource', sort alphabetically by 'liquiditySource' + // If the sort column is 'quoteSource', sort alphabetically by 'quoteSource' // Otherwise, sort in either ascending or descending numerical order on the selected column const sortedRows = useMemo(() => { return [...quoteDataRows].sort((rowDataA, rowDataB) => { @@ -51,7 +51,7 @@ export default function SortList ({ const aHex = (new BigNumber(rowDataA.destinationTokenValue).toString(16)) const bHex = (new BigNumber(rowDataB.destinationTokenValue).toString(16)) return aHex[aHex.length - 1] < bHex[bHex.length - 1] ? -1 : 1 - } else if (sortColumn === 'liquiditySource') { + } else if (sortColumn === 'quoteSource') { return rowDataA[sortColumn] > rowDataB[sortColumn] ? sortDirection * -1 : sortDirection @@ -94,7 +94,7 @@ export default function SortList ({
onColumnHeaderClick('liquiditySource')} + onClick={() => onColumnHeaderClick('quoteSource')} > {t('swapQuoteSource')}
diff --git a/ui/app/pages/swaps/slippage-buttons/slippage-buttons.js b/ui/app/pages/swaps/slippage-buttons/slippage-buttons.js index 839074f8f..d45530a9f 100644 --- a/ui/app/pages/swaps/slippage-buttons/slippage-buttons.js +++ b/ui/app/pages/swaps/slippage-buttons/slippage-buttons.js @@ -74,7 +74,7 @@ export default function SlippageButtons ({
) diff --git a/ui/app/pages/swaps/swaps-util-test-constants.js b/ui/app/pages/swaps/swaps-util-test-constants.js index a4cd57677..9815ff4be 100644 --- a/ui/app/pages/swaps/swaps-util-test-constants.js +++ b/ui/app/pages/swaps/swaps-util-test-constants.js @@ -1,3 +1,5 @@ +import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps' + export const TRADES_BASE_PROD_URL = 'https://api.metaswap.codefi.network/trades?' export const TOKENS_BASE_PROD_URL = 'https://api.metaswap.codefi.network/tokens' export const AGGREGATOR_METADATA_BASE_PROD_URL = 'https://api.metaswap.codefi.network/aggregatorMetadata' @@ -16,6 +18,7 @@ export const TOKENS = [ { erc20: true, symbol: 'USDT', decimals: 6, address: '0xdAC17F958D2ee523a2206206994597C13D831ec7' }, { erc20: true, symbol: 'WED', decimals: 18, address: '0x7848ae8F19671Dc05966dafBeFbBbb0308BDfAbD' }, { erc20: true, symbol: 'WBTC', decimals: 8, address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599' }, + ETH_SWAPS_TOKEN_OBJECT, ] export const MOCK_TRADE_RESPONSE_1 = [ diff --git a/ui/app/pages/swaps/swaps.util.js b/ui/app/pages/swaps/swaps.util.js index 32974d5b6..14f9204d2 100644 --- a/ui/app/pages/swaps/swaps.util.js +++ b/ui/app/pages/swaps/swaps.util.js @@ -2,9 +2,11 @@ import log from 'loglevel' import BigNumber from 'bignumber.js' import abi from 'human-standard-token-abi' import { isValidAddress } from 'ethereumjs-util' +import { ETH_SWAPS_TOKEN_OBJECT } from '../../helpers/constants/swaps' import { calcTokenValue, calcTokenAmount } from '../../helpers/utils/token-util' import { constructTxParams, toPrecisionWithoutTrailingZeros } from '../../helpers/utils/util' import { decimalToHex, getValueFromWeiHex } from '../../helpers/utils/conversions.util' + import { subtractCurrencies } from '../../helpers/utils/conversion-util' import { formatCurrency } from '../../helpers/utils/confirm-tx.util' import fetchWithCache from '../../helpers/utils/fetch-with-cache' @@ -27,8 +29,6 @@ const getBaseApi = function (type) { return `https://api.metaswap.codefi.network/featureFlag` case 'aggregatorMetadata': return `https://api.metaswap.codefi.network/aggregatorMetadata` - case 'feeAmount': - return `https://api.metaswap.codefi.network/fee` default: throw new Error('getBaseApi requires an api call type') } @@ -214,7 +214,10 @@ export async function fetchTradesInfo ({ export async function fetchTokens () { const tokenUrl = getBaseApi('tokens') const tokens = await fetchWithCache(tokenUrl, { method: 'GET' }, { cacheRefreshTime: CACHE_REFRESH_ONE_HOUR }) - const filteredTokens = tokens.filter((token) => validateData(TOKEN_VALIDATORS, token, tokenUrl)) + const filteredTokens = tokens.filter((token) => { + return validateData(TOKEN_VALIDATORS, token, tokenUrl) && (token.address !== ETH_SWAPS_TOKEN_OBJECT.address) + }) + filteredTokens.push(ETH_SWAPS_TOKEN_OBJECT) return filteredTokens } @@ -247,11 +250,6 @@ export async function fetchSwapsFeatureLiveness () { return status?.active } -export async function fetchMetaMaskFeeAmount () { - const response = await fetchWithCache(getBaseApi('feeAmount'), { method: 'GET' }, { cacheRefreshTime: 600000 }) - return response?.fee -} - export async function fetchTokenPrice (address) { const query = `contract_addresses=${address}&vs_currencies=eth` @@ -268,17 +266,34 @@ export async function fetchTokenBalance (address, userAddress) { return usersToken } -export function getRenderableGasFeesForQuote (tradeGas, approveGas, gasPrice, currentCurrency, conversionRate) { +export function getRenderableNetworkFeesForQuote ( + tradeGas, + approveGas, + gasPrice, + currentCurrency, + conversionRate, + tradeValue, + sourceSymbol, + sourceAmount, +) { const totalGasLimitForCalculation = (new BigNumber(tradeGas || '0x0', 16)).plus(approveGas || '0x0', 16).toString(16) const gasTotalInWeiHex = calcGasTotal(totalGasLimitForCalculation, gasPrice) + const nonGasFee = new BigNumber(tradeValue, 16) + .minus(sourceSymbol === 'ETH' ? sourceAmount : 0, 10) + .toString(16) + + const totalWeiCost = new BigNumber(gasTotalInWeiHex, 16) + .plus(nonGasFee, 16) + .toString(16) + const ethFee = getValueFromWeiHex({ - value: gasTotalInWeiHex, + value: totalWeiCost, toDenomination: 'ETH', numberOfDecimals: 5, }) const rawNetworkFees = getValueFromWeiHex({ - value: gasTotalInWeiHex, + value: totalWeiCost, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2, @@ -289,12 +304,25 @@ export function getRenderableGasFeesForQuote (tradeGas, approveGas, gasPrice, cu rawEthFee: ethFee, feeInFiat: formattedNetworkFee, feeInEth: `${ethFee} ETH`, + nonGasFee, } } -export function quotesToRenderableData (quotes, gasPrice, conversionRate, currentCurrency, approveGas, tokenConversionRates, customGasLimit) { +export function quotesToRenderableData (quotes, gasPrice, conversionRate, currentCurrency, approveGas, tokenConversionRates) { return Object.values(quotes).map((quote) => { - const { destinationAmount = 0, sourceAmount = 0, sourceTokenInfo, destinationTokenInfo, slippage, aggType, aggregator, gasEstimateWithRefund, averageGas } = quote + const { + destinationAmount = 0, + sourceAmount = 0, + sourceTokenInfo, + destinationTokenInfo, + slippage, + aggType, + aggregator, + gasEstimateWithRefund, + averageGas, + fee, + trade, + } = quote const sourceValue = calcTokenAmount(sourceAmount, sourceTokenInfo.decimals || 18).toString(10) const destinationValue = calcTokenAmount(destinationAmount, destinationTokenInfo.decimals || 18).toPrecision(8) @@ -303,9 +331,8 @@ export function quotesToRenderableData (quotes, gasPrice, conversionRate, curren rawNetworkFees, rawEthFee, feeInEth, - } = getRenderableGasFeesForQuote( + } = getRenderableNetworkFeesForQuote( ( - customGasLimit || gasEstimateWithRefund || decimalToHex(averageGas || 800000) ), @@ -313,6 +340,9 @@ export function quotesToRenderableData (quotes, gasPrice, conversionRate, curren gasPrice, currentCurrency, conversionRate, + trade.value, + sourceTokenInfo.symbol, + sourceAmount, ) const slippageMultiplier = (new BigNumber(100 - slippage)).div(100) @@ -358,6 +388,7 @@ export function quotesToRenderableData (quotes, gasPrice, conversionRate, curren sourceTokenValue: sourceValue, ethValueOfTrade, minimumAmountReceived, + metaMaskFee: fee, } }) } diff --git a/ui/app/pages/swaps/view-quote/view-quote.js b/ui/app/pages/swaps/view-quote/view-quote.js index da08f7615..a658abfe2 100644 --- a/ui/app/pages/swaps/view-quote/view-quote.js +++ b/ui/app/pages/swaps/view-quote/view-quote.js @@ -22,7 +22,6 @@ import { getBalanceError, getCustomSwapsGas, getDestinationTokenInfo, - getMetaMaskFeeAmount, getSwapsTradeTxParams, getTopQuote, navigateBackToBuildQuote, @@ -68,7 +67,7 @@ import MainQuoteSummary from '../main-quote-summary' import { calcGasTotal } from '../../send/send.utils' import { getCustomTxParamsData } from '../../confirm-approve/confirm-approve.util' import ActionableMessage from '../actionable-message' -import { quotesToRenderableData, getRenderableGasFeesForQuote } from '../swaps.util' +import { quotesToRenderableData, getRenderableNetworkFeesForQuote } from '../swaps.util' import { useTokenTracker } from '../../../hooks/useTokenTracker' import { QUOTES_EXPIRED_ERROR } from '../../../helpers/constants/swaps' import CountdownTimer from '../countdown-timer' @@ -100,7 +99,7 @@ export default function ViewQuote () { // Select necessary data const tradeTxParams = useSelector(getSwapsTradeTxParams) - const { gasPrice } = tradeTxParams || {} + const { gasPrice, value: tradeValue } = tradeTxParams || {} const customMaxGas = useSelector(getCustomSwapsGas) const tokenConversionRates = useSelector(getTokenExchangeRates) const memoizedTokenConversionRates = useEqualityCheck(tokenConversionRates) @@ -163,12 +162,6 @@ export default function ViewQuote () { calcTokenAmount(approveValue, selectedFromToken.decimals).toFixed(9) ) const approveGas = approveTxParams?.gas - const approveGasTotal = calcGasTotal(approveGas || '0x0', gasPrice) - const approveGasTotalInEth = getValueFromWeiHex({ - value: approveGasTotal, - toDenomination: 'ETH', - numberOfDecimals: 4, - }) const renderablePopoverData = useMemo(() => { return quotesToRenderableData( @@ -203,23 +196,30 @@ export default function ViewQuote () { sourceTokenValue, } = renderableDataForUsedQuote - const { feeInFiat, feeInEth } = getRenderableGasFeesForQuote( + const { feeInFiat, feeInEth } = getRenderableNetworkFeesForQuote( usedGasLimit, approveGas, gasPrice, currentCurrency, conversionRate, + tradeValue, + sourceTokenSymbol, + usedQuote.sourceAmount, ) const { feeInFiat: maxFeeInFiat, feeInEth: maxFeeInEth, - } = getRenderableGasFeesForQuote( + nonGasFee, + } = getRenderableNetworkFeesForQuote( maxGasLimit, approveGas, gasPrice, currentCurrency, conversionRate, + tradeValue, + sourceTokenSymbol, + usedQuote.sourceAmount, ) const tokenCost = (new BigNumber(usedQuote.sourceAmount)) @@ -341,7 +341,7 @@ export default function ViewQuote () { } }, [sourceTokenSymbol, sourceTokenValue, destinationTokenSymbol, destinationTokenValue, fetchParams, topQuote, numberOfQuotes, feeInFiat, bestQuoteReviewedEvent, anonymousBestQuoteReviewedEvent]) - const metaMaskFee = useSelector(getMetaMaskFeeAmount) + const metaMaskFee = usedQuote.fee const onFeeCardTokenApprovalClick = () => { anonymousEditSpendLimitOpened() @@ -378,6 +378,26 @@ export default function ViewQuote () { })) } + const nonGasFeeIsPositive = (new BigNumber(nonGasFee, 16)).gt(0) + const approveGasTotal = calcGasTotal(approveGas || '0x0', gasPrice) + const extraNetworkFeeTotalInHexWEI = (new BigNumber(nonGasFee, 16)) + .plus(approveGasTotal, 16) + .toString(16) + const extraNetworkFeeTotalInEth = getValueFromWeiHex({ + value: extraNetworkFeeTotalInHexWEI, + toDenomination: 'ETH', + numberOfDecimals: 4, + }) + + let extraInfoRowLabel = '' + if (approveGas && nonGasFeeIsPositive) { + extraInfoRowLabel = t('approvalAndAggregatorTxFeeCost') + } else if (approveGas) { + extraInfoRowLabel = t('approvalTxGasCost') + } else if (nonGasFeeIsPositive) { + extraInfoRowLabel = t('aggregatorFeeCost') + } + const onFeeCardMaxRowClick = () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', txData: { txParams: { ...tradeTxParams, gas: maxGasLimit } }, @@ -389,10 +409,10 @@ export default function ViewQuote () { ), customTotalSupplement: approveGasTotal, extraInfoRow: ( - approveGas + extraInfoRowLabel ? { - label: t('approvalTxGasCost'), - value: t('amountInEth', [approveGasTotalInEth]), + label: extraInfoRowLabel, + value: t('amountInEth', [extraNetworkFeeTotalInEth]), } : null ), diff --git a/ui/app/selectors/permissions.js b/ui/app/selectors/permissions.js index 32f4e0be1..dc5821b6b 100644 --- a/ui/app/selectors/permissions.js +++ b/ui/app/selectors/permissions.js @@ -210,7 +210,7 @@ export function getAccountToConnectToActiveTab (state) { export function getOrderedConnectedAccountsForActiveTab (state) { const { activeTab, metamask: { permissionsHistory } } = state - const permissionsHistoryByAccount = permissionsHistory[activeTab.origin]?.['eth_accounts']?.accounts + const permissionsHistoryByAccount = permissionsHistory[activeTab.origin]?.eth_accounts?.accounts const orderedAccounts = getMetaMaskAccountsOrdered(state) const connectedAccounts = getPermittedAccountsForCurrentTab(state) diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 7a2d1882a..a998dd2a7 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -14,6 +14,16 @@ export function getNetworkIdentifier (state) { return nickname || rpcUrl || type } +export function getMetricsNetworkIdentifier (state) { + const { provider } = state.metamask + return provider.type === 'rpc' ? provider.rpcUrl : provider.type +} + +export function getCurrentChainId (state) { + const { chainId } = state.metamask.provider + return chainId +} + export function getCurrentKeyring (state) { const identity = getSelectedIdentity(state) @@ -156,7 +166,7 @@ export function getAssetImages (state) { } export function getAddressBook (state) { - const { chainId } = state.metamask.provider + const chainId = getCurrentChainId(state) if (!state.metamask.addressBook[chainId]) { return [] } diff --git a/yarn.lock b/yarn.lock index c6dc9e22f..760517163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -61,19 +61,19 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/core@>=7.9.0", "@babel/core@^7.4.3", "@babel/core@^7.5.5", "@babel/core@^7.7.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.5.tgz#1f15e2cca8ad9a1d78a38ddba612f5e7cdbbd330" - integrity sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w== +"@babel/core@>=7.9.0", "@babel/core@^7.12.1", "@babel/core@^7.4.3", "@babel/core@^7.7.5": + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" + integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.5" - "@babel/helper-module-transforms" "^7.10.5" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.10.5" + "@babel/generator" "^7.12.1" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.1" + "@babel/parser" "^7.12.3" "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.5" - "@babel/types" "^7.10.5" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -83,12 +83,28 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.10.4", "@babel/generator@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.5.tgz#1b903554bc8c583ee8d25f1e8969732e6b829a69" - integrity sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig== +"@babel/eslint-parser@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.12.1.tgz#b3ae38e6174d2d0d2d00d2dcd919b4086b6bb8f0" + integrity sha512-cc7WQHnHQY3++/bghgbDtPx+5bf6xTsokyGzV6Qzh65NLz/unv+mPQuACkQ9GFhIhcTFv6yqwNaEcfX7EkOEsg== dependencies: - "@babel/types" "^7.10.5" + eslint-scope "5.1.0" + eslint-visitor-keys "^1.3.0" + semver "^6.3.0" + +"@babel/eslint-plugin@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/eslint-plugin/-/eslint-plugin-7.12.1.tgz#67626a16312dfe7c5dd7685a1a8af7b03c43985b" + integrity sha512-rOjrD5yupTYCO4x0kEbQmi/NsaD+VGOD/9Cvso64WMVPY2y6o5Nvw2sqFWdeSEBdR1Dsa07YjplBs067x5YbXg== + dependencies: + eslint-rule-composer "^0.3.0" + +"@babel/generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468" + integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg== + dependencies: + "@babel/types" "^7.12.1" jsesc "^2.5.1" source-map "^0.5.0" @@ -176,19 +192,19 @@ dependencies: "@babel/types" "^7.4.4" -"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.8.3": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz#172f56e7a63e78112f3a04055f24365af702e7ee" - integrity sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA== +"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" + integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== dependencies: - "@babel/types" "^7.10.5" + "@babel/types" "^7.12.1" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" + integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.1" "@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": version "7.4.4" @@ -202,17 +218,19 @@ "@babel/types" "^7.4.4" lodash "^4.17.11" -"@babel/helper-module-transforms@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz#120c271c0b3353673fcdfd8c053db3c544a260d6" - integrity sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA== +"@babel/helper-module-transforms@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" + integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-replace-supers" "^7.12.1" + "@babel/helper-simple-access" "^7.12.1" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/helper-validator-identifier" "^7.10.4" "@babel/template" "^7.10.4" - "@babel/types" "^7.10.5" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" lodash "^4.17.19" "@babel/helper-optimise-call-expression@^7.0.0", "@babel/helper-optimise-call-expression@^7.8.3": @@ -267,15 +285,15 @@ "@babel/traverse" "^7.8.3" "@babel/types" "^7.8.3" -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== +"@babel/helper-replace-supers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9" + integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.12.1" "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" "@babel/helper-simple-access@^7.1.0": version "7.1.0" @@ -285,20 +303,19 @@ "@babel/template" "^7.1.0" "@babel/types" "^7.0.0" -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== +"@babel/helper-simple-access@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" + integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1" - integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg== +"@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.11.0" "@babel/helper-validator-identifier@^7.10.4": version "7.10.4" @@ -315,14 +332,14 @@ "@babel/traverse" "^7.1.0" "@babel/types" "^7.2.0" -"@babel/helpers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== +"@babel/helpers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" + integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== dependencies: "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" "@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4": version "7.10.4" @@ -333,15 +350,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.7.0", "@babel/parser@^7.7.5": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.4.tgz#9eedf27e1998d87739fb5028a5120557c06a1a64" - integrity sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA== - -"@babel/parser@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.5.tgz#e7c6bf5a7deff957cec9f04b551e2762909d826b" - integrity sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ== +"@babel/parser@^7.10.1", "@babel/parser@^7.10.4", "@babel/parser@^7.12.1", "@babel/parser@^7.12.3", "@babel/parser@^7.7.5": + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" + integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.2.0" @@ -1056,62 +1068,36 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.4.tgz#e642e5395a3b09cc95c8e74a27432b484b697818" - integrity sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.1", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.4", "@babel/traverse@^7.7.4", "@babel/traverse@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" + integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.4" + "@babel/generator" "^7.12.1" "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - "@babel/parser" "^7.10.4" - "@babel/types" "^7.10.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.13" - -"@babel/traverse@^7.10.4", "@babel/traverse@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.5.tgz#77ce464f5b258be265af618d8fddf0536f20b564" - integrity sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.10.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.10.4" - "@babel/parser" "^7.10.5" - "@babel/types" "^7.10.5" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.12.1" + "@babel/types" "^7.12.1" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.7.0", "@babel/types@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee" - integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@babel/types@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.5.tgz#d88ae7e2fde86bfbfe851d4d81afa70a997b5d15" - integrity sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q== +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.12.1", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.8.3": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" + integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== dependencies: "@babel/helper-validator-identifier" "^7.10.4" lodash "^4.17.19" to-fast-properties "^2.0.0" -"@babel/types@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== +"@choojs/findup@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@choojs/findup/-/findup-0.2.1.tgz#ac13c59ae7be6e1da64de0779a0a7f03d75615a3" + integrity sha512-YstAqNb0MCN8PjdLCDfRsBcGVRN41f3vgLvaI0IrIcBp4AqILRSS0DeWNGkicC+f/zRIPJLc+9RURVSepwvfBw== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" + commander "^2.15.1" "@download/blockies@^1.0.3": version "1.0.3" @@ -1317,6 +1303,37 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@eslint/eslintrc@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.1.3.tgz#7d1a2b2358552cc04834c0979bd4275362e37085" + integrity sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^12.1.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + lodash "^4.17.19" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@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" + integrity sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg== + dependencies: + "@ethersproject/address" ">=5.0.0-beta.128" + "@ethersproject/bignumber" ">=5.0.0-beta.130" + "@ethersproject/bytes" ">=5.0.0-beta.129" + "@ethersproject/constants" ">=5.0.0-beta.128" + "@ethersproject/hash" ">=5.0.0-beta.128" + "@ethersproject/keccak256" ">=5.0.0-beta.127" + "@ethersproject/logger" ">=5.0.0-beta.129" + "@ethersproject/properties" ">=5.0.0-beta.131" + "@ethersproject/strings" ">=5.0.0-beta.130" + "@ethersproject/abi@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.2.tgz#7fe8f080aa1483fe32cd27bb5b8f2019266af1e2" @@ -1345,6 +1362,19 @@ "@ethersproject/transactions" "^5.0.0" "@ethersproject/web" "^5.0.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" + integrity sha512-i/CjElAkzV7vQBAeoz+IpjGfcFYEP9eD7j3fzZ0fzTq03DO7PPnR+xkEZ1IoDXGwDS+55aLM1xvLDwB/Lx6IOQ== + dependencies: + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/networks" "^5.0.3" + "@ethersproject/properties" "^5.0.3" + "@ethersproject/transactions" "^5.0.5" + "@ethersproject/web" "^5.0.6" + "@ethersproject/abstract-signer@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.2.tgz#5776f888fda816de1d08ddb0e74778ecb9590f69" @@ -1356,6 +1386,29 @@ "@ethersproject/logger" "^5.0.0" "@ethersproject/properties" "^5.0.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" + integrity sha512-8W8gy/QutEL60EoMEpvxZ8MFAEWs/JvH5nmZ6xeLXoZvmBCasGmxqHdYjo2cxg0nevkPkq9SeenSsBBZSCx+SQ== + dependencies: + "@ethersproject/abstract-provider" "^5.0.4" + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.3" + +"@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" + integrity sha512-DpkQ6rwk9jTefrRsJzEm6nhRiJd9pvhn1xN0rw5N/jswXG5r7BLk/GVA0mMAVWAsYfvi2xSc5L41FMox43RYEA== + dependencies: + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/keccak256" "^5.0.3" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/rlp" "^5.0.3" + bn.js "^4.4.0" + "@ethersproject/address@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.2.tgz#80d0ddfb7d4bd0d32657747fa4bdd2defef2e00a" @@ -1375,6 +1428,13 @@ dependencies: "@ethersproject/bytes" "^5.0.0" +"@ethersproject/base64@^5.0.3": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.4.tgz#b0d8fdbf3dda977cf546dcd35725a7b1d5256caa" + integrity sha512-4KRykQ7BQMeOXfvio1YITwHjxwBzh92UoXIdzxDE1p53CK28bbHPdsPNYo0wl0El7lJAMpT2SOdL0hhbWRnyIA== + dependencies: + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/basex@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.0.2.tgz#13029ce0ad63674f4d4dbebf6763181fb22f0e6d" @@ -1383,6 +1443,15 @@ "@ethersproject/bytes" "^5.0.0" "@ethersproject/properties" "^5.0.0" +"@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" + integrity sha512-KXFVAFKS1jdTXYN8BE5Oj+ZfPMh28iRdFeNGBVT6cUFdtiPVqeXqc0ggvBqA3A1VoFFGgM7oAeaagA393aORHA== + dependencies: + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + bn.js "^4.4.0" + "@ethersproject/bignumber@^5.0.0": version "5.0.5" resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.5.tgz#31bd7e75aad46ace345fae69b1f5bb120906af1b" @@ -1392,6 +1461,13 @@ "@ethersproject/logger" "^5.0.0" bn.js "^4.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" + integrity sha512-IEj9HpZB+ACS6cZ+QQMTqmu/cnUK2fYNE6ms/PVxjoBjoxc6HCraLpam1KuRvreMy0i523PLmjN8OYeikRdcUQ== + dependencies: + "@ethersproject/logger" "^5.0.5" + "@ethersproject/bytes@^5.0.0": version "5.0.3" resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.3.tgz#b3769963ae0188a35713d343890a903bda20af9c" @@ -1399,6 +1475,13 @@ dependencies: "@ethersproject/logger" "^5.0.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" + integrity sha512-foaQVmxp2+ik9FrLUCtVrLZCj4M3Ibgkqvh+Xw/vFRSerkjVSYePApaVE5essxhoSlF1U9oXfWY09QI2AXtgKA== + dependencies: + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/constants@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.2.tgz#f7ac0b320e2bbec1a5950da075015f8bc4e8fed1" @@ -1421,6 +1504,20 @@ "@ethersproject/logger" "^5.0.0" "@ethersproject/properties" "^5.0.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" + integrity sha512-Gvh57v6BWhwnud6l7tMfQm32PRQ2DYx2WaAAQmAxAfYvmzUkpQCBstnGeNMXIL8/2wdkvcB2u+WZRWaZtsFuUQ== + dependencies: + "@ethersproject/abstract-signer" "^5.0.6" + "@ethersproject/address" "^5.0.5" + "@ethersproject/bignumber" "^5.0.8" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/keccak256" "^5.0.3" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.4" + "@ethersproject/strings" "^5.0.4" + "@ethersproject/hash@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.2.tgz#6d69558786961836d530b8b4a8714eac5388aec7" @@ -1468,6 +1565,14 @@ aes-js "3.0.0" scrypt-js "3.0.1" +"@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" + integrity sha512-GNpiOUm9PGUxFNqOxYKDQBM0u68bG9XC9iOulEQ8I0tOx/4qUpgVzvgXL6ugxr0RY554Gz/NQsVqknqPzUcxpQ== + dependencies: + "@ethersproject/bytes" "^5.0.4" + js-sha3 "0.5.7" + "@ethersproject/keccak256@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.2.tgz#7ed4a95bb45ee502cf4532223833740a83602797" @@ -1476,6 +1581,11 @@ "@ethersproject/bytes" "^5.0.0" js-sha3 "0.5.7" +"@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" + integrity sha512-FrX0Vnb3JZ1md/7GIZfmJ06XOAA8r3q9Uqt9O5orr4ZiksnbpXKlyDzQtlZ5Yv18RS8CAUbiKH9vwidJg1BPmQ== + "@ethersproject/logger@^5.0.0": version "5.0.4" resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.4.tgz#09fa4765b5691233e3afb6617cb38a700f9dd2e4" @@ -1488,6 +1598,13 @@ dependencies: "@ethersproject/logger" "^5.0.0" +"@ethersproject/networks@^5.0.3": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.4.tgz#6d320a5e15a0cda804f5da88be0ba846156f6eec" + integrity sha512-/wHDTRms5mpJ09BoDrbNdFWINzONe05wZRgohCXvEv39rrH/Gd/yAnct8wC0RsW3tmFOgjgQxuBvypIxuUynTw== + dependencies: + "@ethersproject/logger" "^5.0.5" + "@ethersproject/pbkdf2@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.0.2.tgz#d12c5f434bbdf6f52401eddb7d753a713dd9e4ea" @@ -1496,6 +1613,13 @@ "@ethersproject/bytes" "^5.0.0" "@ethersproject/sha2" "^5.0.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" + integrity sha512-UdyX3GqBxFt15B0uSESdDNmhvEbK3ACdDXl2soshoPcneXuTswHDeA0LoPlnaZzhbgk4p6jqb4GMms5C26Qu6A== + dependencies: + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.2.tgz#2facb62d2f2d968c7b3d0befa5bcc884cc565d3b" @@ -1541,6 +1665,14 @@ "@ethersproject/bytes" "^5.0.0" "@ethersproject/logger" "^5.0.0" +"@ethersproject/rlp@^5.0.3": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.4.tgz#0090a0271e84ea803016a112a79f5cfd80271a77" + integrity sha512-5qrrZad7VTjofxSsm7Zg/7Dr4ZOln4S2CqiDdOuTv6MBKnXj0CiBojXyuDy52M8O3wxH0CyE924hXWTDV1PQWQ== + dependencies: + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/sha2@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.0.2.tgz#baefc78c071be8729b180759eb29267129314252" @@ -1560,6 +1692,16 @@ "@ethersproject/properties" "^5.0.0" elliptic "6.5.3" +"@ethersproject/signing-key@^5.0.4": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.5.tgz#acfd06fc05a14180df7e027688bbd23fc4baf782" + integrity sha512-Z1wY7JC1HVO4CvQWY2TyTTuAr8xK3bJijZw1a9G92JEmKdv1j255R/0YLBBcFTl2J65LUjtXynNJ2GbArPGi5g== + dependencies: + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.3" + elliptic "6.5.3" + "@ethersproject/solidity@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.0.2.tgz#431cee341ec51e022bd897b93fef04521f414756" @@ -1571,6 +1713,15 @@ "@ethersproject/sha2" "^5.0.0" "@ethersproject/strings" "^5.0.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" + integrity sha512-JED6WaIV00xM/gvj8vSnd+0VWtDYdidTmavFRCTQakqfz+4tDo6Jz5LHgG+dd45h7ah7ykCHW0C7ZXWEDROCXQ== + dependencies: + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/constants" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/strings@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.2.tgz#1753408c3c889813fd0992abd76393e3e47a2619" @@ -1595,6 +1746,21 @@ "@ethersproject/rlp" "^5.0.0" "@ethersproject/signing-key" "^5.0.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" + integrity sha512-htsFhOD+NMBxx676A8ehSuwVV49iqpSB+CkjPZ02tpNew0K6p8g0CZ46Z1ZP946gIHAU80xQ0NACHYrjIUaCFA== + dependencies: + "@ethersproject/address" "^5.0.4" + "@ethersproject/bignumber" "^5.0.7" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/constants" "^5.0.4" + "@ethersproject/keccak256" "^5.0.3" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.3" + "@ethersproject/rlp" "^5.0.3" + "@ethersproject/signing-key" "^5.0.4" + "@ethersproject/units@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.0.2.tgz#de1461ff3ad2587e57bf367d056b6b72cfceda78" @@ -1636,6 +1802,17 @@ "@ethersproject/properties" "^5.0.0" "@ethersproject/strings" "^5.0.0" +"@ethersproject/web@^5.0.6": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.9.tgz#b08f8295f4bfd4777c8723fe9572f5453b9f03cb" + integrity sha512-//QNlv1MSkOII1hv3+HQwWoiVFS+BMVGI0KYeUww4cyrEktnx1QIez5bTSab9s9fWTFaWKNmQNBwMbxAqPuYDw== + dependencies: + "@ethersproject/base64" "^5.0.3" + "@ethersproject/bytes" "^5.0.4" + "@ethersproject/logger" "^5.0.5" + "@ethersproject/properties" "^5.0.3" + "@ethersproject/strings" "^5.0.4" + "@ethersproject/wordlists@^5.0.0": version "5.0.2" resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.0.2.tgz#eded47314509c8608373fc2b22879ee2b71b7c7c" @@ -2057,9 +2234,9 @@ react-is "^16.8.0" "@metamask/controllers@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-3.1.0.tgz#e56e599b5f35cf9c46e44a1e99381698cfbb87bf" - integrity sha512-K8t5EXnksMsR2pcyK3zST2H36xnu60aCKpLGcDlq39cAv6LwDhXH8ktS57A8BYzHngD08recC7NVX6X1HoLknQ== + version "3.2.0" + resolved "https://registry.yarnpkg.com/@metamask/controllers/-/controllers-3.2.0.tgz#8ad2e63f7953d294712d9b5bacaea1c5261ce588" + integrity sha512-Nysutcny5ddsr4eP4XvYuNMAwMqvCO/krughnNUzT69LljslutJyxS2MnT0MnWyKYNa6+CBaV9gxdV+Mm6fAFA== dependencies: await-semaphore "^0.1.3" eth-contract-metadata "^1.11.0" @@ -2084,10 +2261,10 @@ web3 "^0.20.7" web3-provider-engine "^16.0.1" -"@metamask/eslint-config@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-3.2.0.tgz#66b9b2bea1616821506501e76de4ac991f34914f" - integrity sha512-WKfB81fD5NZBFbj/UqMyfNss/b25XrukVC3j2mcaIEF0uzSKzh1b/yy7aXxcfXshWemHz28MOwZT9Bin5KV37w== +"@metamask/eslint-config@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-4.1.0.tgz#ace2357af2d9c7d04da40a337fc7f4a81a048921" + integrity sha512-oc4ONdFB1h2yxBebVj4ACYzGzArB8ZQKiFVNCDlYiTCyeQ/GR4+EUwg0KvlO33LlXCRbAhO3CX0nChbvIB8hEw== "@metamask/eth-ledger-bridge-keyring@^0.2.6": version "0.2.6" @@ -2124,15 +2301,15 @@ integrity sha512-Hggj4y0QIjDzKGTXzarhEPIQyFSB2bi2y6YLJNwaT4JmP30UB5Cj6gqoY0M4pj3QT57fzp0BUuGp7F/AUe28tw== "@metamask/inpage-provider@^6.1.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@metamask/inpage-provider/-/inpage-provider-6.1.0.tgz#6a4ec9437169b6d6f2b439dd7a2e604ebcfc2fca" - integrity sha512-Sgl+kHyJCTkyWzNKIX18/O+CJUMWlc5jWB27p3NBfA/r1ldr87n7wdJhK9VnHrKZ2GMJtwBmtuE9Do+mLIKHXA== + version "6.3.0" + resolved "https://registry.yarnpkg.com/@metamask/inpage-provider/-/inpage-provider-6.3.0.tgz#92d965e20912c24adbf973efbd07dbf339547741" + integrity sha512-n7E06+8hWdYKmgJo84WFvgX6/BSqaOQEOMIrcbrP48LdkkZNEAChx6D8oUb2lYDQiWgahR+f20jsJoN4WmOjxw== dependencies: - eth-json-rpc-errors "^2.0.2" + eth-rpc-errors "^2.1.1" fast-deep-equal "^2.0.1" - json-rpc-engine "^5.1.5" + is-stream "^2.0.0" + json-rpc-engine "^5.2.0" json-rpc-middleware-stream "^2.1.1" - loglevel "^1.6.1" obj-multiplex "^1.0.0" obs-store "^4.0.3" pump "^3.0.0" @@ -2154,10 +2331,10 @@ gl-mat4 "1.1.4" gl-vec3 "1.0.3" -"@metamask/test-dapp@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-3.1.0.tgz#25560ff260bcf6611b30a26b09c915013576210c" - integrity sha512-pUKiWgEzD9+IcfYJSyz1wrNSBNMwJGynUBLfc/RE39sDw+4I3PRc4z27rn7oYGa1C65OsgrrwZ02QW7/UtTX2A== +"@metamask/test-dapp@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-3.2.0.tgz#b0fb8b75519585b38fec8ecd527fa54257e6411d" + integrity sha512-FLhImScxbkI+SuhF7o9D3J2yxYUBTHrg+erlHqBA8lYZelSWDPczgGuIO8XzLIpj+p5a6BT6hM+0IFWmOP14mA== "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -2913,14 +3090,7 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" integrity sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A== -"@types/bignumber.js@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" - integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== - dependencies: - bignumber.js "*" - -"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.4": +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.5": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== @@ -3016,11 +3186,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@^10.12.18": - version "10.17.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.6.tgz#1aaabd6f6470a6ac3824ab1e94d731ca1326d93d" - integrity sha512-0a2X6cgN3RdPBL2MIlR6Lt0KlM7fOFsutuXcdglcOq6WvLnYXgPQSh0Mx6tO1KCAE8MxbHSOSTWDoUxRq+l3DA== - "@types/node@^10.3.2": version "10.14.14" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.14.tgz#a47955df2acf76ba7f0ac3b205d325da193dc9ad" @@ -3031,10 +3196,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== -"@types/node@^12.6.1": - version "12.12.38" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.38.tgz#58841a382f231ad005dbb935c36d44aa1118a26b" - integrity sha512-75eLjX0pFuTcUXnnWmALMzzkYorjND0ezNEycaKesbUBg9eGZp4GHPuDmkRc4mQQvIpe29zrzATNRA6hkYqwmA== +"@types/node@^12.12.6": + version "12.19.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.1.tgz#303f74c8a2b35644594139e948b2be470ae1186f" + integrity sha512-/xaVmBBjOGh55WCqumLAHXU9VhjGtmyTGqJzFBXRWZzByOXI5JAJNx9xPVGEsNizrNwcec92fQMj458MWfjN1A== "@types/node@^8.10.11": version "8.10.48" @@ -3056,11 +3221,23 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/pbkdf2@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" + integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== + dependencies: + "@types/node" "*" + "@types/prettier@^2.1.0": version "2.1.1" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.1.tgz#be148756d5480a84cde100324c03a86ae5739fb5" integrity sha512-2zs+O+UkDsJ1Vcp667pd3f8xearMdopz/z54i99wtRDI5KLmngk7vlrYZD0ZjKHaROR03EznlBbVY9PfAEyJIQ== +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" @@ -3116,6 +3293,14 @@ dependencies: csstype "^2.2.0" +"@types/react@^16.9.53": + version "16.9.53" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.53.tgz#40cd4f8b8d6b9528aedd1fff8fcffe7a112a3d23" + integrity sha512-4nW60Sd4L7+WMXH1D6jCdVftuW7j4Za6zdp6tJ33Rqv0nk1ZAmQKML9ZLD4H0dehA3FZxXR/GM8gXplf82oNGw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + "@types/redux@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@types/redux/-/redux-3.6.0.tgz#f1ebe1e5411518072e4fdfca5c76e16e74c1399a" @@ -3123,6 +3308,13 @@ dependencies: redux "*" +"@types/secp256k1@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4" + integrity sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog== + dependencies: + "@types/node" "*" + "@types/testing-library__react-hooks@^3.0.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@types/testing-library__react-hooks/-/testing-library__react-hooks-3.2.0.tgz#52f3a109bef06080e3b1e3ae7ea1c014ce859897" @@ -3170,25 +3362,6 @@ dependencies: "@types/yargs-parser" "*" -"@web3-js/scrypt-shim@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@web3-js/scrypt-shim/-/scrypt-shim-0.1.0.tgz#0bf7529ab6788311d3e07586f7d89107c3bea2cc" - integrity sha512-ZtZeWCc/s0nMcdx/+rZwY1EcuRdemOK9ag21ty9UsHkFxsNb/AaoucUz0iPuyGe0Ku+PFuRmWZG7Z7462p9xPw== - dependencies: - scryptsy "^2.1.0" - semver "^6.3.0" - -"@web3-js/websocket@^1.0.29": - version "1.0.30" - resolved "https://registry.yarnpkg.com/@web3-js/websocket/-/websocket-1.0.30.tgz#9ea15b7b582cf3bf3e8bc1f4d3d54c0731a87f87" - integrity sha512-fDwrD47MiDrzcJdSeTLF75aCcxVVt8B1N74rA+vh2XCAvFy4tEWJjtnUtj2QG7/zlQ6g9cQ88bZFBxwd9/FmtA== - dependencies: - debug "^2.2.0" - es5-ext "^0.10.50" - nan "^2.14.0" - typedarray-to-buffer "^3.1.5" - yaeti "^0.0.6" - "@webassemblyjs/ast@1.8.5": version "1.8.5" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" @@ -3535,10 +3708,10 @@ acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.7, acorn@^6.2.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== -acorn@^7.0.0, acorn@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" - integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== +acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== addons-linter@1.14.0: version "1.14.0" @@ -3718,12 +3891,7 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= -ajv-keywords@^3.1.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" - integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== - -ajv-keywords@^3.4.1: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== @@ -3764,10 +3932,10 @@ ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.9.1: - version "6.12.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" - integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.9.1: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -3831,6 +3999,11 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-cyan@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" @@ -3951,7 +4124,7 @@ ansi-wrap@0.1.0, ansi-wrap@^0.1.0: resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= -any-promise@1.3.0, any-promise@^1.1.0: +any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= @@ -4308,13 +4481,13 @@ array.prototype.flat@^1.2.1, array.prototype.flat@^1.2.3: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -array.prototype.flatmap@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz#3103cd4826ef90019c9b0a4839b2535fa6faf4e9" - integrity sha512-i18e2APdsiezkcqDyZor78Pbfjfds3S94dG6dgIV2ZASJaUf1N0dz2tGdrmwrmlZuNUgxH+wz6Z0zYVH2c5xzQ== +array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz#1c13f84a178566042dd63de4414440db9222e443" + integrity sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg== dependencies: - define-properties "^1.1.2" - es-abstract "^1.10.0" + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" function-bind "^1.1.1" arraybuffer.slice@~0.0.7: @@ -4720,18 +4893,6 @@ babel-core@^6.0.14, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.7" -babel-eslint@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" - integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" @@ -5643,11 +5804,6 @@ big.js@^5.1.2, big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -bignumber.js@*, bignumber.js@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - bignumber.js@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" @@ -5658,6 +5814,11 @@ bignumber.js@^8.0.1, bignumber.js@^8.0.2, bignumber.js@^8.1.1: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.1.1.tgz#4b072ae5aea9c20f6730e4e5d529df1271c4d885" integrity sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ== +bignumber.js@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" + integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== + "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git": version "2.0.7" resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" @@ -5873,11 +6034,6 @@ bn.js@4.11.6: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha1-UzRK2xRhehP26N0s4okF0cC6MhU= -bn.js@4.11.8, bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.7, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: - version "4.11.8" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" - integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== - bn.js@=2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-2.0.4.tgz#220a7cd677f7f1bfa93627ff4193776fe7819480" @@ -5888,6 +6044,16 @@ bn.js@^1.0.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-1.3.0.tgz#0db4cbf96f8f23b742f5bcb9d1aa7a9994a05e83" integrity sha1-DbTL+W+PI7dC9by50ap6mZSgXoM= +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.7, bn.js@^4.11.8, bn.js@^4.4.0, bn.js@^4.8.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +bn.js@^4.11.9: + version "4.11.9" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" + integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + body-parser@1.19.0, body-parser@^1.15.0, body-parser@^1.16.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -7379,11 +7545,6 @@ colors@^1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -colors@~0.6.0-1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" - integrity sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w= - columnify@1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" @@ -7443,16 +7604,16 @@ commander@^2.15.0, commander@^2.16.0, commander@^2.19.0, commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== +commander@^2.15.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + commander@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== -commander@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.1.0.tgz#d121bbae860d9992a3d517ba96f56588e47c6781" - integrity sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E= - commander@~2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -7963,10 +8124,10 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" - integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -8160,6 +8321,11 @@ csstype@^2.5.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.5.tgz#1cd1dff742ebf4d7c991470ae71e12bb6751e034" integrity sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA== +csstype@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.3.tgz#2b410bbeba38ba9633353aff34b05d9755d065f8" + integrity sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag== + currency-formatter@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/currency-formatter/-/currency-formatter-1.4.2.tgz#9da20b3706f7a42daf73b356b09a2a2b76ff3870" @@ -8181,6 +8347,11 @@ cyclist@~0.2.2: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= +cytoplasm@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/cytoplasm/-/cytoplasm-3.3.1.tgz#6d10099e536b12c642e8375b47cbffac66656a4b" + integrity sha512-38swm2Lr7cmTh0KRYtiUOCT5PT2TPp31Lpp3wcAIm3iGT4KdGGewyTydkFhBEDrKik/umgmG2hVoG5A1fKQY+g== + d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0: version "1.2.4" resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f" @@ -9482,7 +9653,7 @@ element-resize-detector@^1.2.1: dependencies: batch-processor "1.0.0" -elliptic@6.3.3, elliptic@6.5.3, elliptic@=3.0.3, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.3: +elliptic@6.3.3, elliptic@6.5.3, elliptic@=3.0.3, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.4.1, elliptic@^6.5.2, elliptic@^6.5.3: version "6.5.3" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== @@ -9613,6 +9784,13 @@ enhanced-resolve@^4.1.0: memory-fs "^0.4.0" tapable "^1.0.0" +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" @@ -9744,86 +9922,40 @@ error@^7.0.0: string-template "~0.2.1" xtend "~4.0.0" -es-abstract@^1.10.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0, es-abstract@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" - integrity sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ== - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - -es-abstract@^1.11.0, es-abstract@^1.12.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" - integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-keys "^1.0.12" - -es-abstract@^1.13.0, es-abstract@^1.5.0: - version "1.14.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497" - integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg== - dependencies: - es-to-primitive "^1.2.0" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.0" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-inspect "^1.6.0" - object-keys "^1.1.1" - string.prototype.trimleft "^2.0.0" - string.prototype.trimright "^2.0.0" - -es-abstract@^1.15.0: - version "1.16.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.2.tgz#4e874331645e9925edef141e74fc4bd144669d34" - integrity sha512-jYo/J8XU2emLXl3OLwfwtuFfuF2w6DYPs+xy9ZfVyPkDcrauu6LYrw/q2TyCtrbc/KUdCiC5e9UajRhgNkVopA== +es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.13.0, es-abstract@^1.15.0, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5, es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0, es-abstract@^1.9.0: + version "1.17.7" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" + integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-inspect "^1.7.0" + is-callable "^1.2.2" + is-regex "^1.1.1" + object-inspect "^1.8.0" object-keys "^1.1.1" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== +es-abstract@^1.18.0-next.0: + version "1.18.0-next.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" + integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" - object-inspect "^1.7.0" + is-callable "^1.2.2" + is-negative-zero "^2.0.0" + is-regex "^1.1.1" + object-inspect "^1.8.0" object-keys "^1.1.1" - object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" - -es-to-primitive@^1.1.1, es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" + object.assign "^4.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -9991,12 +10123,13 @@ eslint-module-utils@^2.6.0: debug "^2.6.9" pkg-dir "^2.0.0" -eslint-plugin-babel@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-5.3.0.tgz#2e7f251ccc249326da760c1a4c948a91c32d0023" - integrity sha512-HPuNzSPE75O+SnxHIafbW5QB45r2w78fxqwK3HmjqIUoPfPzVrq6rD+CINU3yzoDSzEhUkX07VUphbF73Lth/w== +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== dependencies: - eslint-rule-composer "^0.3.0" + eslint-utils "^2.0.0" + regexpp "^3.0.0" eslint-plugin-import@^2.22.0: version "2.22.0" @@ -10017,13 +10150,13 @@ eslint-plugin-import@^2.22.0: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-plugin-mocha@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz#72bfd06a5c4323e17e30ef41cd726030e8cdb8fd" - integrity sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg== +eslint-plugin-mocha@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-8.0.0.tgz#7ec5d228bcb3735301701dfbc3376320a1ca3791" + integrity sha512-n67etbWDz6NQM+HnTwZHyBwz/bLlYPOxUbw7bPuCyFujv7ZpaT/Vn6KTAbT02gf7nRljtYIjWcTxK/n8a57rQQ== dependencies: - eslint-utils "^2.0.0" - ramda "^0.27.0" + eslint-utils "^2.1.0" + ramda "^0.27.1" eslint-plugin-no-unsafe-innerhtml@1.0.16: version "1.0.16" @@ -10032,25 +10165,38 @@ eslint-plugin-no-unsafe-innerhtml@1.0.16: dependencies: eslint "^3.7.1" +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + eslint-plugin-react-hooks@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.4.tgz#aed33b4254a41b045818cacb047b81e6df27fa58" integrity sha512-equAdEIsUETLFNCmmCkiCGq6rkSK5MoJhXFPFYeUebcjKgBmWWcgVOqZyQC8Bv1BwVCnTq9tBxgJFgAJTWoJtA== -eslint-plugin-react@^7.18.3: - version "7.18.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.18.3.tgz#8be671b7f6be095098e79d27ac32f9580f599bc8" - integrity sha512-Bt56LNHAQCoou88s8ViKRjMB2+36XRejCQ1VoLj716KI1MoE99HpTVvIThJ0rvFmG4E4Gsq+UgToEjn+j044Bg== +eslint-plugin-react@~7.20.0: + version "7.20.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz#4d7845311a93c463493ccfa0a19c9c5d0fd69f60" + integrity sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg== dependencies: array-includes "^3.1.1" + array.prototype.flatmap "^1.2.3" doctrine "^2.1.0" has "^1.0.3" - jsx-ast-utils "^2.2.3" - object.entries "^1.1.1" + jsx-ast-utils "^2.4.1" + object.entries "^1.1.2" object.fromentries "^2.0.2" object.values "^1.1.1" prop-types "^15.7.2" - resolve "^1.14.2" + resolve "^1.17.0" string.prototype.matchall "^4.0.2" eslint-rule-composer@^0.3.0: @@ -10058,6 +10204,14 @@ eslint-rule-composer@^0.3.0: resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== +eslint-scope@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" + integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -10066,22 +10220,22 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-utils@^1.3.1, eslint-utils@^1.4.3: +eslint-utils@^1.3.1: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^2.0.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -10093,6 +10247,16 @@ eslint-visitor-keys@1.1.0, eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1. resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== +eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" + integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + eslint@5.16.0: version "5.16.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.16.0.tgz#a1e3ac1aae4a3fbd8296fcf8f7ab7314cbb6abea" @@ -10176,22 +10340,24 @@ eslint@^3.7.1: text-table "~0.2.0" user-home "^2.0.0" -eslint@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== +eslint@^7.7.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.11.0.tgz#aaf2d23a0b5f1d652a08edacea0c19f7fadc0b3b" + integrity sha512-G9+qtYVCHaDi1ZuWzBsOWo2wSwd70TXnU6UHA3cTYHp7gCTXZcpggWFoUVAMRarg68qtPoNfFbzPh+VdOgmwmw== dependencies: "@babel/code-frame" "^7.0.0" + "@eslint/eslintrc" "^0.1.3" ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" + chalk "^4.0.0" + cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + enquirer "^2.3.5" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.0" + esquery "^1.2.0" esutils "^2.0.2" file-entry-cache "^5.0.1" functional-red-black-tree "^1.0.1" @@ -10200,21 +10366,19 @@ eslint@^6.8.0: ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" is-glob "^4.0.0" js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" + levn "^0.4.1" + lodash "^4.17.19" minimatch "^3.0.4" - mkdirp "^0.5.1" natural-compare "^1.4.0" - optionator "^0.8.3" + optionator "^0.9.1" progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" table "^5.2.3" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -10245,14 +10409,14 @@ espree@^5.0.1: acorn-jsx "^5.0.0" eslint-visitor-keys "^1.0.0" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.0.tgz#dc30437cf67947cf576121ebd780f15eeac72348" + integrity sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw== dependencies: - acorn "^7.1.1" + acorn "^7.4.0" acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + eslint-visitor-keys "^1.3.0" esprima@3.x.x: version "3.1.3" @@ -10276,6 +10440,13 @@ esquery@^1.0.0, esquery@^1.0.1: dependencies: estraverse "^4.0.0" +esquery@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.3.1.tgz#b78b5828aa8e214e29fb74c4d5b752e1c033da57" + integrity sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" @@ -10284,11 +10455,23 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + estree-is-function@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" @@ -10330,9 +10513,9 @@ eth-block-tracker@^4.4.2: safe-event-emitter "^1.0.1" eth-contract-metadata@^1.11.0, eth-contract-metadata@^1.16.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.16.0.tgz#a7d643795ba5318f86ce1aae9c4522888aa92d78" - integrity sha512-WnwYkkIl0RbDQgnV/4V6E8a84fVkP/qmYCUde1UKLQekOFeZXhs/7KgPBAWdZ7otJRo0bPQf4UjAOfESAV3gtw== + version "1.17.0" + resolved "https://registry.yarnpkg.com/eth-contract-metadata/-/eth-contract-metadata-1.17.0.tgz#96d4b056ac9a7175eeba091dbabd0713cfd4c703" + integrity sha512-vlw4OiW3+9J3kJfEtPCyiSW9fhdWTqrAhXcvdMY2CevGxbhvOd5Lz59DeWerSTV3IoSXttghDurPA76dAeTV+A== eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: version "2.0.8" @@ -10364,7 +10547,7 @@ eth-hd-keyring@^3.5.0: events "^1.1.1" xtend "^4.0.1" -eth-json-rpc-errors@^2.0.1, eth-json-rpc-errors@^2.0.2: +eth-json-rpc-errors@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/eth-json-rpc-errors/-/eth-json-rpc-errors-2.0.2.tgz#c1965de0301fe941c058e928bebaba2e1285e3c4" integrity sha512-uBCRM2w2ewusRHGxN8JhcuOb2RN3ueAOYH/0BhqdFmQkZx5lj5+fLKTz0mIVOzd4FG5/kUksCzCD7eTEim6gaA== @@ -10470,10 +10653,10 @@ eth-keyring-controller@^6.1.0: loglevel "^1.5.0" obs-store "^4.0.3" -eth-lib@0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.7.tgz#2f93f17b1e23aec3759cd4a3fe20c1286a3fc1ca" - integrity sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco= +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== dependencies: bn.js "^4.11.6" elliptic "^6.4.0" @@ -10521,6 +10704,13 @@ eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: json-rpc-random-id "^1.0.0" xtend "^4.0.1" +eth-rpc-errors@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-2.1.1.tgz#00a7d6c8a9c864a8ab7d0356be20964e5bee4b13" + integrity sha512-MY3zAa5ZF8hvgQu1HOF9agaK5GgigBRGpTJ8H0oVlE0NqMu13CW6syyjLXdeIDCGQTbUeHliU1z9dVmvMKx1Tg== + dependencies: + fast-safe-stringify "^2.0.6" + eth-rpc-errors@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz#d7b22653c70dbf9defd4ef490fd08fe70608ca10" @@ -10528,18 +10718,6 @@ eth-rpc-errors@^3.0.0: dependencies: fast-safe-stringify "^2.0.6" -eth-sig-util@2.3.0, eth-sig-util@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.3.0.tgz#c54a6ac8e8796f7e25f59cf436982a930e645231" - integrity sha512-ugD1AvaggvKaZDgnS19W5qOfepjGc7qHrt7TrAaL54gJw9SHvgIXJ3r2xOMW30RWJZNP+1GlTOy5oye7yXA4xA== - dependencies: - buffer "^5.2.1" - elliptic "^6.4.0" - ethereumjs-abi "0.6.5" - ethereumjs-util "^5.1.1" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - eth-sig-util@^1.4.0, eth-sig-util@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" @@ -10548,7 +10726,19 @@ eth-sig-util@^1.4.0, eth-sig-util@^1.4.2: ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" ethereumjs-util "^5.1.1" -eth-sig-util@^2.4.4, eth-sig-util@^2.5.0: +eth-sig-util@^2.0.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.3.tgz#6938308b38226e0b3085435474900b03036abcbe" + integrity sha512-KpXbCKmmBUNUTGh9MRKmNkIPietfhzBqqYqysDavLseIiMUGl95k6UcPEkALAZlj41e9E6yioYXc1PC333RKqw== + dependencies: + buffer "^5.2.1" + elliptic "^6.4.0" + ethereumjs-abi "0.6.5" + ethereumjs-util "^5.1.1" + tweetnacl "^1.0.0" + tweetnacl-util "^0.15.0" + +eth-sig-util@^2.3.0, eth-sig-util@^2.4.4, eth-sig-util@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.0.tgz#1018cf8bef2fe275ecbd526cf3248757b0880053" integrity sha512-ahApxr+e1cls/GwcFSGsgRLrMqG6D6cBnK9CRHhx97O/s9ow+URIxbPvov8jfE70ZnNBdHMircoSCpi1b4QHjA== @@ -10627,6 +10817,27 @@ ethereum-common@^0.0.18: resolved "https://registry.yarnpkg.com/ethereum-common/-/ethereum-common-0.0.18.tgz#2fdc3576f232903358976eb39da783213ff9523f" integrity sha1-L9w1dvIykDNYl26znaeDIT/5Uj8= +ethereum-cryptography@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" + integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== + dependencies: + "@types/pbkdf2" "^3.0.0" + "@types/secp256k1" "^4.0.1" + blakejs "^1.1.0" + browserify-aes "^1.2.0" + bs58check "^2.1.2" + create-hash "^1.2.0" + create-hmac "^1.1.7" + hash.js "^1.1.7" + keccak "^3.0.0" + pbkdf2 "^3.0.17" + randombytes "^2.1.0" + safe-buffer "^5.1.2" + scrypt-js "^3.0.0" + secp256k1 "^4.0.1" + setimmediate "^1.0.5" + ethereum-ens-network-map@^1.0.0, ethereum-ens-network-map@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/ethereum-ens-network-map/-/ethereum-ens-network-map-1.0.2.tgz#4e27bad18dae7bd95d84edbcac2c9e739fc959b9" @@ -10640,7 +10851,15 @@ ethereumjs-abi@0.6.5, ethereumjs-abi@^0.6.4, ethereumjs-abi@^0.6.5: bn.js "^4.10.0" ethereumjs-util "^4.3.0" -ethereumjs-abi@0.6.7, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": +ethereumjs-abi@0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== + dependencies: + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" + +"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": version "0.6.7" resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#8431eab7b3384e65e8126a4602520b78031666fb" dependencies: @@ -10753,31 +10972,18 @@ ethereumjs-util@5.1.0: rlp "^2.0.0" secp256k1 "^3.0.1" -ethereumjs-util@6.1.0, ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@~6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" - integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== - dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "0.1.6" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - -ethereumjs-util@6.2.0, ethereumjs-util@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz#23ec79b2488a7d041242f01e25f24e5ad0357960" - integrity sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ== +ethereumjs-util@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== dependencies: "@types/bn.js" "^4.11.3" bn.js "^4.11.0" create-hash "^1.1.2" + elliptic "^6.5.2" + ethereum-cryptography "^0.1.3" ethjs-util "0.1.6" - keccak "^2.0.0" rlp "^2.2.3" - secp256k1 "^3.0.1" ethereumjs-util@^4.0.1, ethereumjs-util@^4.3.0, ethereumjs-util@^4.4.0: version "4.5.0" @@ -10803,10 +11009,36 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum safe-buffer "^5.1.1" secp256k1 "^3.0.1" -ethereumjs-vm@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.1.3.tgz#dc8eb45f47d775da9f0b2437d5e20896fdf66f37" - integrity sha512-RTrD0y7My4O6Qr1P2ZIsMfD6RzL6kU/RhBZ0a5XrPzAeR61crBS7or66ohDrvxDI/rDBxMi+6SnsELih6fzalw== +ethereumjs-util@^6.0.0, ethereumjs-util@^6.1.0, ethereumjs-util@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.0.tgz#23ec79b2488a7d041242f01e25f24e5ad0357960" + integrity sha512-vb0XN9J2QGdZGIEKG2vXM+kUdEivUfU6Wmi5y0cg+LRhDYKnXIZ/Lz7XjFbHRR9VIKq2lVGLzGBkA++y2nOdOQ== + dependencies: + "@types/bn.js" "^4.11.3" + bn.js "^4.11.0" + create-hash "^1.1.2" + ethjs-util "0.1.6" + keccak "^2.0.0" + rlp "^2.2.3" + secp256k1 "^3.0.1" + +ethereumjs-util@~6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" + integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + ethjs-util "0.1.6" + keccak "^1.0.2" + rlp "^2.0.0" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + +ethereumjs-vm@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-vm/-/ethereumjs-vm-4.2.0.tgz#e885e861424e373dbc556278f7259ff3fca5edab" + integrity sha512-X6qqZbsY33p5FTuZqCnQ4+lo957iUJMM6Mpa6bL4UW0dxM6WmDSHuI4j/zOp1E2TDKImBGCJA9QPfc08PaNubA== dependencies: async "^2.1.2" async-eventemitter "^0.2.2" @@ -10841,7 +11073,7 @@ ethereumjs-vm@^2.1.0, ethereumjs-vm@^2.3.4, ethereumjs-vm@^2.6.0: rustbn.js "~0.2.0" safe-buffer "^5.1.1" -ethereumjs-wallet@0.6.0, ethereumjs-wallet@^0.6.0: +ethereumjs-wallet@0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz#82763b1697ee7a796be7155da9dfb49b2f98cfdb" integrity sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s= @@ -10854,7 +11086,22 @@ ethereumjs-wallet@0.6.0, ethereumjs-wallet@^0.6.0: utf8 "^2.1.1" uuid "^2.0.1" -ethereumjs-wallet@0.6.3: +ethereumjs-wallet@0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz#685e9091645cee230ad125c007658833991ed474" + integrity sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA== + dependencies: + aes-js "^3.1.1" + bs58check "^2.1.2" + ethereum-cryptography "^0.1.3" + ethereumjs-util "^6.0.0" + randombytes "^2.0.6" + safe-buffer "^5.1.2" + scryptsy "^1.2.1" + utf8 "^3.0.0" + uuid "^3.3.2" + +ethereumjs-wallet@^0.6.0: version "0.6.3" resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.3.tgz#b0eae6f327637c2aeb9ccb9047b982ac542e6ab1" integrity sha512-qiXPiZOsStem+Dj/CQHbn5qex+FVkuPmGH7SvSnA9F3tdRDt8dLMyvIj3+U05QzVZNPYh4HXEdnzoYI4dZkr9w== @@ -10869,22 +11116,6 @@ ethereumjs-wallet@0.6.3: utf8 "^3.0.0" uuid "^3.3.2" -ethers@4.0.0-beta.3: - version "4.0.0-beta.3" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.0-beta.3.tgz#15bef14e57e94ecbeb7f9b39dd0a4bd435bc9066" - integrity sha512-YYPogooSknTwvHg3+Mv71gM/3Wcrx+ZpCzarBj3mqs9njjRkrOo2/eufzhHloOCo3JSoNI4TQJJ6yU5ABm3Uog== - dependencies: - "@types/node" "^10.3.2" - aes-js "3.0.0" - bn.js "^4.4.0" - elliptic "6.3.3" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.3" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - ethers@^4.0.20, ethers@^4.0.28: version "4.0.33" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.33.tgz#f7b88d2419d731a39aefc37843a3f293e396f918" @@ -11018,18 +11249,6 @@ ethjs-format@0.2.2: number-to-bn "1.7.0" strip-hex-prefix "1.0.0" -ethjs-format@0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.5.tgz#44f30abee17b074d7162d2c886abffd065828925" - integrity sha1-RPMKvuF7B01xYtLIhqv/0GWCiSU= - dependencies: - bn.js "4.11.6" - ethjs-schema "0.2.0" - ethjs-util "0.1.3" - is-hex-prefixed "1.0.0" - number-to-bn "1.7.0" - strip-hex-prefix "1.0.0" - ethjs-format@0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/ethjs-format/-/ethjs-format-0.2.7.tgz#20c92f31c259a381588d069830d838b489774b86" @@ -11058,7 +11277,7 @@ ethjs-query@0.3.7: ethjs-rpc "0.2.0" promise-to-callback "^1.0.0" -ethjs-query@0.3.8, ethjs-query@^0.3.7, ethjs-query@^0.3.8: +ethjs-query@0.3.8, ethjs-query@^0.3.4, ethjs-query@^0.3.7, ethjs-query@^0.3.8: version "0.3.8" resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.8.tgz#aa5af02887bdd5f3c78b3256d0f22ffd5d357490" integrity sha512-/J5JydqrOzU8O7VBOwZKUWXxHDGr46VqNjBCJgBVNNda+tv7Xc8Y2uJc6aMHHVbeN3YOQ7YRElgIc0q1CI02lQ== @@ -11076,24 +11295,11 @@ ethjs-query@^0.2.4: ethjs-format "0.2.2" ethjs-rpc "0.1.5" -ethjs-query@^0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/ethjs-query/-/ethjs-query-0.3.4.tgz#068a8b268fe045acd2dfdf167bb740b12e596bc3" - integrity sha512-RkeLtBwuXJkBIf/U+Az0GOT203UiBLmN7WA6WZIwSTbmhH2yNicggwaWKvN3TOtpErOsXnzYTZp82mElHdORUQ== - dependencies: - ethjs-format "0.2.5" - ethjs-rpc "0.1.9" - ethjs-rpc@0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.5.tgz#099e22f27dc4c18b6978a485fc36b1b0f7969080" integrity sha1-CZ4i8n3EwYtpeKSF/DaxsPeWkIA= -ethjs-rpc@0.1.9: - version "0.1.9" - resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.1.9.tgz#389dcd61be52e72bc47111a75805f8e45882faea" - integrity sha512-KJqT7cgTeCJQ2RY1AlVmTZVnKIUXMPg+niPN5VJKwRSzpjgfr3LTVHlGbkRCqZtOMDi0ogB2vHZaRQiZBXZTUg== - ethjs-rpc@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/ethjs-rpc/-/ethjs-rpc-0.2.0.tgz#3d0011e32cfff156ed6147818c6fb8f801701b4c" @@ -11106,11 +11312,6 @@ ethjs-schema@0.1.5: resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.1.5.tgz#59740e3b3977bcdbb9b11bc3068201e8aceabb0d" integrity sha1-WXQOOzl3vNu5sRvDBoIB6Kzquw0= -ethjs-schema@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.2.0.tgz#07b46d4f55b792a846c90a79f330d31d112cca38" - integrity sha1-B7RtT1W3kqhGyQp58zDTHREsyjg= - ethjs-schema@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/ethjs-schema/-/ethjs-schema-0.2.1.tgz#47e138920421453617069034684642e26bb310f4" @@ -11198,7 +11399,12 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter3@3.1.2, eventemitter3@^3.1.0: +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +eventemitter3@^3.1.0: version "3.1.2" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== @@ -11585,7 +11791,7 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= @@ -11927,6 +12133,14 @@ find-versions@^3.0.0: array-uniq "^2.1.0" semver-regex "^2.0.0" +find-yarn-workspace-root@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" + integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== + dependencies: + fs-extra "^4.0.3" + micromatch "^3.1.4" + findup-sync@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" @@ -11947,14 +12161,6 @@ findup-sync@^3.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" -findup@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/findup/-/findup-0.1.5.tgz#8ad929a3393bac627957a7e5de4623b06b0e2ceb" - integrity sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs= - dependencies: - colors "~0.6.0-1" - commander "~2.1.0" - fined@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476" @@ -12222,7 +12428,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^4.0.2: +fs-extra@^4.0.2, fs-extra@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== @@ -12231,6 +12437,15 @@ fs-extra@^4.0.2: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -12371,19 +12586,19 @@ fuse.js@^3.4.6: resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.6.tgz#545c3411fed88bf2e27c457cab6e73e7af697a45" integrity sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg== -ganache-cli@^6.9.1: - version "6.9.1" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.9.1.tgz#1e13eee098fb9f19b031a191ec3f62ae926ea8b3" - integrity sha512-VPBumkNUZzXDRQwVOby5YyQpd5t1clkr06xMgB28lZdEIn5ht1GMwUskOTFOAxdkQ4J12IWP0gdeacVRGowqbA== +ganache-cli@^6.12.1: + version "6.12.1" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.1.tgz#148cf6541494ef1691bd68a77e4414981910cb3e" + integrity sha512-zoefZLQpQyEJH9jgtVYgM+ENFLAC9iwys07IDCsju2Ieq9KSTLH89RxSP4bhizXKV/h/+qaWpfyCBGWnBfqgIQ== dependencies: - ethereumjs-util "6.1.0" + ethereumjs-util "6.2.1" source-map-support "0.5.12" yargs "13.2.4" -ganache-core@^2.10.2: - version "2.10.2" - resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.10.2.tgz#17c171c6c0195b6734a0dd741a9d2afd4f74e292" - integrity sha512-4XEO0VsqQ1+OW7Za5fQs9/Kk7o8M0T1sRfFSF8h9NeJ2ABaqMO5waqxf567ZMcSkRKaTjUucBSz83xNfZv1HDg== +ganache-core@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.1.tgz#bf60399a2dd084e1090db91cbbc7ed3885dc01e4" + integrity sha512-Ewg+kNcDqXtOohe7jCcP+ZUv9EMzOx2MoqOYYP3BCfxrDh3KjBXXaKK+Let7li0TghAs9lxmBgevZku35j5YzA== dependencies: abstract-leveldown "3.0.0" async "2.6.2" @@ -12392,27 +12607,30 @@ ganache-core@^2.10.2: clone "2.1.2" debug "3.2.6" encoding-down "5.0.4" - eth-sig-util "2.3.0" - ethereumjs-abi "0.6.7" + eth-sig-util "^2.0.0" + ethereumjs-abi "0.6.8" ethereumjs-account "3.0.0" ethereumjs-block "2.2.2" ethereumjs-common "1.5.0" ethereumjs-tx "2.1.2" - ethereumjs-util "6.2.0" - ethereumjs-vm "4.1.3" + ethereumjs-util "6.2.1" + ethereumjs-vm "4.2.0" heap "0.2.6" + keccak "3.0.1" level-sublevel "6.6.4" levelup "3.1.1" - lodash "4.17.14" - merkle-patricia-tree "2.3.2" + lodash "4.17.20" + lru-cache "5.1.1" + merkle-patricia-tree "3.0.0" + patch-package "6.2.2" seedrandom "3.0.1" source-map-support "0.5.12" tmp "0.1.0" web3-provider-engine "14.2.1" - websocket "1.0.29" + websocket "1.0.32" optionalDependencies: - ethereumjs-wallet "0.6.3" - web3 "1.2.4" + ethereumjs-wallet "0.6.5" + web3 "1.2.11" gar@^1.0.4: version "1.0.4" @@ -13553,6 +13771,14 @@ hash.js@1.1.3, hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" +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== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hasha@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.1.0.tgz#dd05ccdfcfe7dab626247ce2a58efe461922f4ca" @@ -14113,7 +14339,7 @@ import-fresh@^3.0.0: parent-module "^1.0.0" resolve-from "^4.0.0" -import-fresh@^3.1.0: +import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== @@ -15063,10 +15289,10 @@ is-callable@^1.1.3, is-callable@^1.1.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== -is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-callable@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" + integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== is-ci@^1.0.10: version "1.2.1" @@ -15087,6 +15313,13 @@ is-circular@^1.0.2: resolved "https://registry.yarnpkg.com/is-circular/-/is-circular-1.0.2.tgz#2e0ab4e9835f4c6b0ea2b9855a84acd501b8366c" integrity sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA== +is-core-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.0.0.tgz#58531b70aed1db7c0e8d4eb1a0a2d1ddd64bd12d" + integrity sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -15343,6 +15576,11 @@ is-negated-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= +is-negative-zero@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" + integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -15513,12 +15751,12 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== +is-regex@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9" + integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg== dependencies: - has "^1.0.3" + has-symbols "^1.0.1" is-regexp@^1.0.0: version "1.0.0" @@ -16040,17 +16278,7 @@ json-rpc-engine@^3.4.0, json-rpc-engine@^3.6.0: promise-to-callback "^1.0.0" safe-event-emitter "^1.0.1" -json-rpc-engine@^5.1.5: - version "5.1.8" - resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.1.8.tgz#5ba0147ce571899bbaa7133ffbc05317c34a3c7f" - integrity sha512-vTBSDEPJV1fPAsbm2g5sEuPjsgLdiab2f1CTn2PyRr8nxggUpA996PDlNQDsM0gnrA99F8KIBLq2nIKrOFl1Mg== - dependencies: - async "^2.0.1" - eth-json-rpc-errors "^2.0.1" - promise-to-callback "^1.0.0" - safe-event-emitter "^1.0.1" - -json-rpc-engine@^5.3.0: +json-rpc-engine@^5.2.0, json-rpc-engine@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.3.0.tgz#7dc7291766b28766ebda33eb6d3f4c6301c44ff4" integrity sha512-+diJ9s8rxB+fbJhT7ZEf8r8spaLRignLd8jTgQ/h5JSGppAHGtNMZtCoabipCaleR1B3GTGxbXBOqhaJSGmPGQ== @@ -16290,12 +16518,12 @@ jss@^10.0.3, jss@^10.3.0: is-in-browser "^1.1.3" tiny-warning "^1.0.2" -jsx-ast-utils@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" - integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== +jsx-ast-utils@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e" + integrity sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w== dependencies: - array-includes "^3.0.3" + array-includes "^3.1.1" object.assign "^4.1.0" jszip@^3.1.5: @@ -16372,6 +16600,14 @@ k-bucket@^5.0.0: dependencies: randombytes "^2.0.3" +keccak@3.0.1, keccak@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff" + integrity sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + keccak@^1.0.2: version "1.4.0" resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" @@ -16462,6 +16698,13 @@ kind-of@^6.0.0, kind-of@^6.0.1, kind-of@^6.0.2, kind-of@^6.0.3: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + klaw@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" @@ -16585,6 +16828,25 @@ latest-version@^5.0.0: dependencies: package-json "^6.3.0" +lavamoat-core@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/lavamoat-core/-/lavamoat-core-6.2.0.tgz#ff1e39c0407f4bf5b94847c5dfaf5b09f28ac77a" + integrity sha512-sY0ddwWou2WGnpEFG/8CGguo6XKq2hc5etIDQ47TYUEJB9BaWGuWulekcrTsTQ0f7EN5r0Y2QtV5ZxxM0fMm8w== + dependencies: + cytoplasm "^3.3.1" + fromentries "^1.2.0" + json-stable-stringify "^1.0.1" + lavamoat-tofu "^5.1.1" + resolve "^1.15.1" + +lavamoat-tofu@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lavamoat-tofu/-/lavamoat-tofu-5.1.1.tgz#67d3c5775b587dd439c426f1cd86650b10443760" + integrity sha512-LIZTifbbTATA5UClVGI7YGMTOjUXjrVCBOz0DaeUicldLonLlwG81/53/vTIfPM1xV/KA85MIzGPHz4pDdiVkA== + dependencies: + "@babel/parser" "^7.10.1" + "@babel/traverse" "^7.10.1" + lazy-cache@^0.2.3: version "0.2.7" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" @@ -16879,6 +17141,14 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + libp2p-bootstrap@~0.9.3: version "0.9.7" resolved "https://registry.yarnpkg.com/libp2p-bootstrap/-/libp2p-bootstrap-0.9.7.tgz#eabedab24775a6175f07ce035b716e8114d84a76" @@ -17678,7 +17948,12 @@ lodash.uniqby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= -lodash@4.17.14, lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: +lodash@4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + +lodash@=3.10.1, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.2, lodash@~4.17.4: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -17722,11 +17997,6 @@ loglevel@^1.4.1, loglevel@^1.5.0: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.0.tgz#ae0caa561111498c5ba13723d6fb631d24003934" integrity sha1-rgyqVhERSYxboTcj1vtjHSQAOTQ= -loglevel@^1.6.1: - version "1.6.8" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.8.tgz#8a25fb75d092230ecd4457270d80b54e28011171" - integrity sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA== - logplease@^1.2.14, logplease@~1.2.14, logplease@~1.2.15: version "1.2.15" resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.15.tgz#3da442e93751a5992cc19010a826b08d0293c48a" @@ -17830,6 +18100,13 @@ lru-cache@4.1.x, lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +lru-cache@5.1.1, lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-3.2.0.tgz#71789b3b7f5399bec8565dda38aa30d2a097efee" @@ -17837,13 +18114,6 @@ lru-cache@^3.2.0: dependencies: pseudomap "^1.0.1" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -18225,7 +18495,20 @@ merkle-lib@^2.0.10: resolved "https://registry.yarnpkg.com/merkle-lib/-/merkle-lib-2.0.10.tgz#82b8dbae75e27a7785388b73f9d7725d0f6f3326" integrity sha1-grjbrnXieneFOItz+ddyXQ9vMyY= -merkle-patricia-tree@2.3.2, merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: +merkle-patricia-tree@3.0.0, merkle-patricia-tree@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" + integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== + dependencies: + async "^2.6.1" + ethereumjs-util "^5.2.0" + level-mem "^3.0.1" + level-ws "^1.0.0" + readable-stream "^3.0.6" + rlp "^2.0.0" + semaphore ">=1.0.1" + +merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz#982ca1b5a0fde00eed2f6aeed1f9152860b8208a" integrity sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g== @@ -18239,19 +18522,6 @@ merkle-patricia-tree@2.3.2, merkle-patricia-tree@^2.1.2, merkle-patricia-tree@^2 rlp "^2.0.0" semaphore ">=1.0.1" -merkle-patricia-tree@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/merkle-patricia-tree/-/merkle-patricia-tree-3.0.0.tgz#448d85415565df72febc33ca362b8b614f5a58f8" - integrity sha512-soRaMuNf/ILmw3KWbybaCjhx86EYeBbD8ph0edQCTed0JN/rxDt1EBN52Ajre3VyGo+91f8+/rfPIRQnnGMqmQ== - dependencies: - async "^2.6.1" - ethereumjs-util "^5.2.0" - level-mem "^3.0.1" - level-ws "^1.0.0" - readable-stream "^3.0.6" - rlp "^2.0.0" - semaphore ">=1.0.1" - mersenne-twister@^1.0.1, mersenne-twister@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mersenne-twister/-/mersenne-twister-1.1.0.tgz#f916618ee43d7179efcf641bec4531eb9670978a" @@ -18440,7 +18710,7 @@ mini-css-extract-plugin@^0.7.0: schema-utils "^1.0.0" webpack-sources "^1.1.0" -minimalistic-assert@^1.0.0: +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== @@ -19087,6 +19357,11 @@ nock@^9.0.14: qs "^6.5.1" semver "^5.3.0" +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-dir@^0.1.10: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -19125,6 +19400,11 @@ node-forge@^0.10.0, node-forge@^0.7.1, node-forge@^0.7.5, node-forge@~0.7.6: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-gyp-build@^4.2.0: + version "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@~3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" @@ -19587,6 +19867,11 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== +object-inspect@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + object-inspect@~1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d" @@ -19624,7 +19909,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@4.1.0, object.assign@^4.0.4, object.assign@^4.1.0: +object.assign@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== @@ -19634,6 +19919,16 @@ object.assign@4.1.0, object.assign@^4.0.4, object.assign@^4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" +object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" + integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.18.0-next.0" + has-symbols "^1.0.1" + object-keys "^1.1.1" + object.defaults@^1.0.0, object.defaults@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" @@ -19664,14 +19959,13 @@ object.entries@^1.1.0: function-bind "^1.1.1" has "^1.0.3" -object.entries@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" - integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== +object.entries@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" + integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA== dependencies: define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.17.5" has "^1.0.3" "object.fromentries@^2.0.0 || ^1.0.0": @@ -19897,17 +20191,17 @@ optionator@^0.8.1, optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" options@>=0.0.5: version "0.0.6" @@ -20599,6 +20893,24 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= +patch-package@6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" + integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^2.4.2" + cross-spawn "^6.0.5" + find-yarn-workspace-root "^1.2.1" + fs-extra "^7.0.1" + is-ci "^2.0.0" + klaw-sync "^6.0.0" + minimist "^1.2.0" + rimraf "^2.6.3" + semver "^5.6.0" + slash "^2.0.0" + tmp "^0.0.33" + path-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" @@ -20730,6 +21042,17 @@ pause-stream@0.0.11: dependencies: through "~2.3" +pbkdf2@^3.0.17: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" + integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -21247,7 +21570,7 @@ postcss@^6.0.1, postcss@^6.0.19: source-map "^0.6.1" supports-color "^5.2.0" -postcss@^6.0.14: +postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== @@ -21286,6 +21609,11 @@ precond@0.2: resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -22018,10 +22346,10 @@ ramda@^0.21.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" integrity sha1-oAGr7bP/YQd9T/HVd9RN536NCjU= -ramda@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.0.tgz#915dc29865c0800bf3f69b8fd6c279898b59de43" - integrity sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA== +ramda@^0.27.1: + version "0.27.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" + integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== randexp@0.4.6: version "0.4.6" @@ -22969,6 +23297,11 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== +regexpp@^3.0.0, regexpp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" + integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -23443,13 +23776,21 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: +resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" +resolve@^1.10.1, resolve@^1.15.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.18.1.tgz#018fcb2c5b207d2a6424aee361c5a266da8f4130" + integrity sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== + dependencies: + is-core-module "^2.0.0" + path-parse "^1.0.6" + resolve@~1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" @@ -23638,14 +23979,14 @@ rst-selector-parser@^2.2.3: nearley "^2.7.10" rtlcss@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-2.4.0.tgz#482ea28f2b9fe06dd0ab3057997be9af13da84c1" - integrity sha512-hdjFhZ5FCI0ABOfyXOMOhBtwPWtANLCG7rOiOcRf+yi5eDdxmDjqBruWouEnwVdzfh/TWF6NNncIEsigOCFZOA== + version "2.6.1" + resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-2.6.1.tgz#e65d07bd6c23e13438a3e4c81d38ab000a796dc5" + integrity sha512-WoKAYLxT123Gh/9dAPeMY0YWBx6D7IjORJhTbmmq8UJI4zaSxsA0uqPWsXEqGgZT2HEGtxWkhkIZ6g1IvOQ+eg== dependencies: - chalk "^2.3.0" - findup "^0.1.5" + "@choojs/findup" "^0.2.1" + chalk "^2.4.2" mkdirp "^0.5.1" - postcss "^6.0.14" + postcss "^6.0.23" strip-json-comments "^2.0.0" run-async@^0.1.0: @@ -23919,17 +24260,12 @@ scrollbarwidth@^0.1.3: resolved "https://registry.yarnpkg.com/scrollbarwidth/-/scrollbarwidth-0.1.3.tgz#1b0de64e288c38c427f4a01fe00a462a04b94fdf" integrity sha1-Gw3mTiiMOMQn9KAf4ApGKgS5T98= -scrypt-js@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.3.tgz#bb0040be03043da9a012a2cea9fc9f852cfc87d4" - integrity sha1-uwBAvgMEPamgEqLOqfyfhSz8h9Q= - scrypt-js@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== -scrypt-js@3.0.1: +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== @@ -23965,11 +24301,6 @@ scryptsy@^1.2.1: dependencies: pbkdf2 "^3.0.3" -scryptsy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.1.0.tgz#8d1e8d0c025b58fdd25b6fa9a0dc905ee8faa790" - integrity sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w== - scss-tokenizer@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" @@ -23992,6 +24323,15 @@ secp256k1@^3.0.1, secp256k1@^3.6.1, secp256k1@^3.6.2: nan "^2.14.0" safe-buffer "^5.1.2" +secp256k1@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.2.tgz#15dd57d0f0b9fdb54ac1fa1694f40e5e9a54f4a1" + integrity sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg== + dependencies: + elliptic "^6.5.2" + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + seedrandom@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083" @@ -24060,7 +24400,7 @@ semver-truncate@^1.1.2: resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg== -semver@6.3.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@6.3.0, semver@^6.1.1, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -24080,7 +24420,7 @@ semver@^6.0.0, semver@^6.1.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b" integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ== -semver@^7.3.2: +semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -24461,6 +24801,11 @@ slash@^1.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -25207,37 +25552,21 @@ string.prototype.trim@~1.1.2: es-abstract "^1.5.0" function-bind "^1.0.2" -string.prototype.trimleft@^2.0.0, string.prototype.trimleft@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" - integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== dependencies: define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.0.0, string.prototype.trimright@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" - integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" + es-abstract "^1.17.5" string_decoder@0.10, string_decoder@~0.10.x: version "0.10.31" @@ -25401,7 +25730,7 @@ strip-json-comments@2.0.1, strip-json-comments@^2.0.0, strip-json-comments@^2.0. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -strip-json-comments@^3.0.1: +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -25643,14 +25972,13 @@ swappable-obj-proxy@^1.1.0: resolved "https://registry.yarnpkg.com/swappable-obj-proxy/-/swappable-obj-proxy-1.1.0.tgz#fe23c60a0df22499e85d94b71297d9c39ff05fa4" integrity sha512-bXbKO85b0YNbZi/61TjRAbNtY49ABKu7rQ4k2+RFXPL7TA2mphttfqAqCeJ+lrlKlkYc5pvm6erFk6vOWJSpdw== -swarm-js@0.1.39: - version "0.1.39" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.39.tgz#79becb07f291d4b2a178c50fee7aa6e10342c0e8" - integrity sha512-QLMqL2rzF6n5s50BptyD6Oi0R1aWlJC5Y17SRIVXRj6OR1DRIPM7nepvrxxkjA1zNzFz6mUOMjfeqeDaWB7OOg== +swarm-js@^0.1.40: + version "0.1.40" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99" + integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA== dependencies: bluebird "^3.5.0" buffer "^5.0.5" - decompress "^4.0.0" eth-lib "^0.1.26" fs-extra "^4.0.2" got "^7.1.0" @@ -25659,7 +25987,7 @@ swarm-js@0.1.39: mock-fs "^4.1.0" setimmediate "^1.0.5" tar "^4.0.2" - xhr-request-promise "^0.1.2" + xhr-request "^1.0.1" symbol-observable@1.0.1: version "1.0.1" @@ -26453,6 +26781,13 @@ tweetnacl@^1.0.0, tweetnacl@^1.0.1: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.1.tgz#2594d42da73cd036bd0d2a54683dd35a6b55ca17" integrity sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A== +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -27094,7 +27429,7 @@ uuid@3.2.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" integrity sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA== -uuid@3.3.2, uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2: +uuid@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== @@ -27104,7 +27439,7 @@ uuid@^2.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= -uuid@^3.3.2, uuid@^3.3.3: +uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.2.2, uuid@^3.3.2, uuid@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== @@ -27388,180 +27723,180 @@ web-namespaces@^1.1.2: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.3.tgz#9bbf5c99ff0908d2da031f1d732492a96571a83f" integrity sha512-r8sAtNmgR0WKOKOxzuSgk09JsHlpKlB+uHi937qypOu3PZ17UxPrierFKDye/uNHjNTTEshu5PId8rojIPj/tA== -web3-bzz@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.4.tgz#a4adb7a8cba3d260de649bdb1f14ed359bfb3821" - integrity sha512-MqhAo/+0iQSMBtt3/QI1rU83uvF08sYq8r25+OUZ+4VtihnYsmkkca+rdU0QbRyrXY2/yGIpI46PFdh0khD53A== +web3-bzz@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f" + integrity sha512-XGpWUEElGypBjeFyUhTkiPXFbDVD6Nr/S5jznE3t8cWUA0FxRf1n3n/NuIZeb0H9RkN2Ctd/jNma/k8XGa3YKg== dependencies: - "@types/node" "^10.12.18" + "@types/node" "^12.12.6" got "9.6.0" - swarm-js "0.1.39" + swarm-js "^0.1.40" underscore "1.9.1" -web3-core-helpers@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.4.tgz#ffd425861f4d66b3f38df032afdb39ea0971fc0f" - integrity sha512-U7wbsK8IbZvF3B7S+QMSNP0tni/6VipnJkB0tZVEpHEIV2WWeBHYmZDnULWcsS/x/jn9yKhJlXIxWGsEAMkjiw== +web3-core-helpers@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.2.11.tgz#84c681ed0b942c0203f3b324a245a127e8c67a99" + integrity sha512-PEPoAoZd5ME7UfbnCZBdzIerpe74GEvlwT4AjOmHeCVZoIFk7EqvOZDejJHt+feJA6kMVTdd0xzRNN295UhC1A== dependencies: underscore "1.9.1" - web3-eth-iban "1.2.4" - web3-utils "1.2.4" + web3-eth-iban "1.2.11" + web3-utils "1.2.11" -web3-core-method@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.4.tgz#a0fbc50b8ff5fd214021435cc2c6d1e115807aed" - integrity sha512-8p9kpL7di2qOVPWgcM08kb+yKom0rxRCMv6m/K+H+yLSxev9TgMbCgMSbPWAHlyiF3SJHw7APFKahK5Z+8XT5A== +web3-core-method@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.2.11.tgz#f880137d1507a0124912bf052534f168b8d8fbb6" + integrity sha512-ff0q76Cde94HAxLDZ6DbdmKniYCQVtvuaYh+rtOUMB6kssa5FX0q3vPmixi7NPooFnbKmmZCM6NvXg4IreTPIw== + dependencies: + "@ethersproject/transactions" "^5.0.0-beta.135" + underscore "1.9.1" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-utils "1.2.11" + +web3-core-promievent@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.11.tgz#51fe97ca0ddec2f99bf8c3306a7a8e4b094ea3cf" + integrity sha512-il4McoDa/Ox9Agh4kyfQ8Ak/9ABYpnF8poBLL33R/EnxLsJOGQG2nZhkJa3I067hocrPSjEdlPt/0bHXsln4qA== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.11.tgz#fe6eb603fbaee18530293a91f8cf26d8ae28c45a" + integrity sha512-oFhBtLfOiIbmfl6T6gYjjj9igOvtyxJ+fjS+byRxiwFJyJ5BQOz4/9/17gWR1Cq74paTlI7vDGxYfuvfE/mKvA== dependencies: underscore "1.9.1" - web3-core-helpers "1.2.4" - web3-core-promievent "1.2.4" - web3-core-subscriptions "1.2.4" - web3-utils "1.2.4" + web3-core-helpers "1.2.11" + web3-providers-http "1.2.11" + web3-providers-ipc "1.2.11" + web3-providers-ws "1.2.11" -web3-core-promievent@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.2.4.tgz#75e5c0f2940028722cdd21ba503ebd65272df6cb" - integrity sha512-gEUlm27DewUsfUgC3T8AxkKi8Ecx+e+ZCaunB7X4Qk3i9F4C+5PSMGguolrShZ7Zb6717k79Y86f3A00O0VAZw== - dependencies: - any-promise "1.3.0" - eventemitter3 "3.1.2" - -web3-core-requestmanager@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.2.4.tgz#0a7020a23fb91c6913c611dfd3d8c398d1e4b4a8" - integrity sha512-eZJDjyNTDtmSmzd3S488nR/SMJtNnn/GuwxnMh3AzYCqG3ZMfOylqTad2eYJPvc2PM5/Gj1wAMQcRpwOjjLuPg== +web3-core-subscriptions@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.11.tgz#beca908fbfcb050c16f45f3f0f4c205e8505accd" + integrity sha512-qEF/OVqkCvQ7MPs1JylIZCZkin0aKK9lDxpAtQ1F8niEDGFqn7DT8E/vzbIa0GsOjL2fZjDhWJsaW+BSoAW1gg== dependencies: + eventemitter3 "4.0.4" underscore "1.9.1" - web3-core-helpers "1.2.4" - web3-providers-http "1.2.4" - web3-providers-ipc "1.2.4" - web3-providers-ws "1.2.4" + web3-core-helpers "1.2.11" -web3-core-subscriptions@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.2.4.tgz#0dc095b5cfd82baa527a39796e3515a846b21b99" - integrity sha512-3D607J2M8ymY9V+/WZq4MLlBulwCkwEjjC2U+cXqgVO1rCyVqbxZNCmHyNYHjDDCxSEbks9Ju5xqJxDSxnyXEw== +web3-core@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.11.tgz#1043cacc1becb80638453cc5b2a14be9050288a7" + integrity sha512-CN7MEYOY5ryo5iVleIWRE3a3cZqVaLlIbIzDPsvQRUfzYnvzZQRZBm9Mq+ttDi2STOOzc1MKylspz/o3yq/LjQ== dependencies: - eventemitter3 "3.1.2" + "@types/bn.js" "^4.11.5" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-requestmanager "1.2.11" + web3-utils "1.2.11" + +web3-eth-abi@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.11.tgz#a887494e5d447c2926d557a3834edd66e17af9b0" + integrity sha512-PkRYc0+MjuLSgg03QVWqWlQivJqRwKItKtEpRUaxUAeLE7i/uU39gmzm2keHGcQXo3POXAbOnMqkDvOep89Crg== + dependencies: + "@ethersproject/abi" "5.0.0-beta.153" underscore "1.9.1" - web3-core-helpers "1.2.4" + web3-utils "1.2.11" -web3-core@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.2.4.tgz#2df13b978dcfc59c2abaa887d27f88f21ad9a9d6" - integrity sha512-CHc27sMuET2cs1IKrkz7xzmTdMfZpYswe7f0HcuyneTwS1yTlTnHyqjAaTy0ZygAb/x4iaVox+Gvr4oSAqSI+A== +web3-eth-accounts@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.11.tgz#a9e3044da442d31903a7ce035a86d8fa33f90520" + integrity sha512-6FwPqEpCfKIh3nSSGeo3uBm2iFSnFJDfwL3oS9pyegRBXNsGRVpgiW63yhNzL0796StsvjHWwQnQHsZNxWAkGw== dependencies: - "@types/bignumber.js" "^5.0.0" - "@types/bn.js" "^4.11.4" - "@types/node" "^12.6.1" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-requestmanager "1.2.4" - web3-utils "1.2.4" - -web3-eth-abi@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.2.4.tgz#5b73e5ef70b03999227066d5d1310b168845e2b8" - integrity sha512-8eLIY4xZKoU3DSVu1pORluAw9Ru0/v4CGdw5so31nn+7fR8zgHMgwbFe0aOqWQ5VU42PzMMXeIJwt4AEi2buFg== - dependencies: - ethers "4.0.0-beta.3" - underscore "1.9.1" - web3-utils "1.2.4" - -web3-eth-accounts@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.2.4.tgz#ada6edc49542354328a85cafab067acd7f88c288" - integrity sha512-04LzT/UtWmRFmi4hHRewP5Zz43fWhuHiK5XimP86sUQodk/ByOkXQ3RoXyGXFMNoRxdcAeRNxSfA2DpIBc9xUw== - dependencies: - "@web3-js/scrypt-shim" "^0.1.0" - any-promise "1.3.0" crypto-browserify "3.12.0" - eth-lib "0.2.7" + eth-lib "0.2.8" ethereumjs-common "^1.3.2" ethereumjs-tx "^2.1.1" + scrypt-js "^3.0.1" underscore "1.9.1" uuid "3.3.2" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-utils "1.2.4" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" -web3-eth-contract@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.4.tgz#68ef7cc633232779b0a2c506a810fbe903575886" - integrity sha512-b/9zC0qjVetEYnzRA1oZ8gF1OSSUkwSYi5LGr4GeckLkzXP7osEnp9lkO/AQcE4GpG+l+STnKPnASXJGZPgBRQ== +web3-eth-contract@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.2.11.tgz#917065902bc27ce89da9a1da26e62ef663663b90" + integrity sha512-MzYuI/Rq2o6gn7vCGcnQgco63isPNK5lMAan2E51AJLknjSLnOxwNY3gM8BcKoy4Z+v5Dv00a03Xuk78JowFow== dependencies: - "@types/bn.js" "^4.11.4" + "@types/bn.js" "^4.11.5" underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-promievent "1.2.4" - web3-core-subscriptions "1.2.4" - web3-eth-abi "1.2.4" - web3-utils "1.2.4" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-promievent "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-utils "1.2.11" -web3-eth-ens@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.4.tgz#b95b3aa99fb1e35c802b9e02a44c3046a3fa065e" - integrity sha512-g8+JxnZlhdsCzCS38Zm6R/ngXhXzvc3h7bXlxgKU4coTzLLoMpgOAEz71GxyIJinWTFbLXk/WjNY0dazi9NwVw== +web3-eth-ens@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.2.11.tgz#26d4d7f16d6cbcfff918e39832b939edc3162532" + integrity sha512-dbW7dXP6HqT1EAPvnniZVnmw6TmQEKF6/1KgAxbo8iBBYrVTMDGFQUUnZ+C4VETGrwwaqtX4L9d/FrQhZ6SUiA== dependencies: + content-hash "^2.5.2" eth-ens-namehash "2.0.8" underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-promievent "1.2.4" - web3-eth-abi "1.2.4" - web3-eth-contract "1.2.4" - web3-utils "1.2.4" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-promievent "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-contract "1.2.11" + web3-utils "1.2.11" -web3-eth-iban@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.4.tgz#8e0550fd3fd8e47a39357d87fe27dee9483ee476" - integrity sha512-D9HIyctru/FLRpXakRwmwdjb5bWU2O6UE/3AXvRm6DCOf2e+7Ve11qQrPtaubHfpdW3KWjDKvlxV9iaFv/oTMQ== +web3-eth-iban@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.2.11.tgz#f5f73298305bc7392e2f188bf38a7362b42144ef" + integrity sha512-ozuVlZ5jwFC2hJY4+fH9pIcuH1xP0HEFhtWsR69u9uDIANHLPQQtWYmdj7xQ3p2YT4bQLq/axKhZi7EZVetmxQ== dependencies: - bn.js "4.11.8" - web3-utils "1.2.4" + bn.js "^4.11.9" + web3-utils "1.2.11" -web3-eth-personal@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.4.tgz#3224cca6851c96347d9799b12c1b67b2a6eb232b" - integrity sha512-5Russ7ZECwHaZXcN3DLuLS7390Vzgrzepl4D87SD6Sn1DHsCZtvfdPIYwoTmKNp69LG3mORl7U23Ga5YxqkICw== +web3-eth-personal@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.2.11.tgz#a38b3942a1d87a62070ce0622a941553c3d5aa70" + integrity sha512-42IzUtKq9iHZ8K9VN0vAI50iSU9tOA1V7XU2BhF/tb7We2iKBVdkley2fg26TxlOcKNEHm7o6HRtiiFsVK4Ifw== dependencies: - "@types/node" "^12.6.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-net "1.2.4" - web3-utils "1.2.4" + "@types/node" "^12.12.6" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" -web3-eth@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.4.tgz#24c3b1f1ac79351bbfb808b2ab5c585fa57cdd00" - integrity sha512-+j+kbfmZsbc3+KJpvHM16j1xRFHe2jBAniMo1BHKc3lho6A8Sn9Buyut6odubguX2AxoRArCdIDCkT9hjUERpA== +web3-eth@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.2.11.tgz#4c81fcb6285b8caf544058fba3ae802968fdc793" + integrity sha512-REvxW1wJ58AgHPcXPJOL49d1K/dPmuw4LjPLBPStOVkQjzDTVmJEIsiLwn2YeuNDd4pfakBwT8L3bz1G1/wVsQ== dependencies: underscore "1.9.1" - web3-core "1.2.4" - web3-core-helpers "1.2.4" - web3-core-method "1.2.4" - web3-core-subscriptions "1.2.4" - web3-eth-abi "1.2.4" - web3-eth-accounts "1.2.4" - web3-eth-contract "1.2.4" - web3-eth-ens "1.2.4" - web3-eth-iban "1.2.4" - web3-eth-personal "1.2.4" - web3-net "1.2.4" - web3-utils "1.2.4" + web3-core "1.2.11" + web3-core-helpers "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-eth-abi "1.2.11" + web3-eth-accounts "1.2.11" + web3-eth-contract "1.2.11" + web3-eth-ens "1.2.11" + web3-eth-iban "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-utils "1.2.11" -web3-net@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.4.tgz#1d246406d3aaffbf39c030e4e98bce0ca5f25458" - integrity sha512-wKOsqhyXWPSYTGbp7ofVvni17yfRptpqoUdp3SC8RAhDmGkX6irsiT9pON79m6b3HUHfLoBilFQyt/fTUZOf7A== +web3-net@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.2.11.tgz#eda68ef25e5cdb64c96c39085cdb74669aabbe1b" + integrity sha512-sjrSDj0pTfZouR5BSTItCuZ5K/oZPVdVciPQ6981PPPIwJJkCMeVjD7I4zO3qDPCnBjBSbWvVnLdwqUBPtHxyg== dependencies: - web3-core "1.2.4" - web3-core-method "1.2.4" - web3-utils "1.2.4" + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-utils "1.2.11" web3-provider-engine@14.2.1: version "14.2.1" @@ -27617,41 +27952,42 @@ web3-provider-engine@^16.0.1: xhr "^2.2.0" xtend "^4.0.1" -web3-providers-http@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.2.4.tgz#514fcad71ae77832c2c15574296282fbbc5f4a67" - integrity sha512-dzVCkRrR/cqlIrcrWNiPt9gyt0AZTE0J+MfAu9rR6CyIgtnm1wFUVVGaxYRxuTGQRO4Dlo49gtoGwaGcyxqiTw== +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" + integrity sha512-psh4hYGb1+ijWywfwpB2cvvOIMISlR44F/rJtYkRmQ5jMvG4FOCPlQJPiHQZo+2cc3HbktvvSJzIhkWQJdmvrA== dependencies: - web3-core-helpers "1.2.4" + web3-core-helpers "1.2.11" xhr2-cookies "1.1.0" -web3-providers-ipc@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.4.tgz#9d6659f8d44943fb369b739f48df09092be459bd" - integrity sha512-8J3Dguffin51gckTaNrO3oMBo7g+j0UNk6hXmdmQMMNEtrYqw4ctT6t06YOf9GgtOMjSAc1YEh3LPrvgIsR7og== +web3-providers-ipc@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.2.11.tgz#d16d6c9be1be6e0b4f4536c4acc16b0f4f27ef21" + integrity sha512-yhc7Y/k8hBV/KlELxynWjJDzmgDEDjIjBzXK+e0rHBsYEhdCNdIH5Psa456c+l0qTEU2YzycF8VAjYpWfPnBpQ== dependencies: oboe "2.1.4" underscore "1.9.1" - web3-core-helpers "1.2.4" + web3-core-helpers "1.2.11" -web3-providers-ws@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.4.tgz#099ee271ee03f6ea4f5df9cfe969e83f4ce0e36f" - integrity sha512-F/vQpDzeK+++oeeNROl1IVTufFCwCR2hpWe5yRXN0ApLwHqXrMI7UwQNdJ9iyibcWjJf/ECbauEEQ8CHgE+MYQ== +web3-providers-ws@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.2.11.tgz#a1dfd6d9778d840561d9ec13dd453046451a96bb" + integrity sha512-ZxnjIY1Er8Ty+cE4migzr43zA/+72AF1myzsLaU5eVgdsfV7Jqx7Dix1hbevNZDKFlSoEyq/3j/jYalh3So1Zg== dependencies: - "@web3-js/websocket" "^1.0.29" + eventemitter3 "4.0.4" underscore "1.9.1" - web3-core-helpers "1.2.4" + web3-core-helpers "1.2.11" + websocket "^1.0.31" -web3-shh@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.4.tgz#5c8ff5ab624a3b14f08af0d24d2b16c10e9f70dd" - integrity sha512-z+9SCw0dE+69Z/Hv8809XDbLj7lTfEv9Sgu8eKEIdGntZf4v7ewj5rzN5bZZSz8aCvfK7Y6ovz1PBAu4QzS4IQ== +web3-shh@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.2.11.tgz#f5d086f9621c9a47e98d438010385b5f059fd88f" + integrity sha512-B3OrO3oG1L+bv3E1sTwCx66injW1A8hhwpknDUbV+sw3fehFazA06z9SGXUefuFI1kVs4q2vRi0n4oCcI4dZDg== dependencies: - web3-core "1.2.4" - web3-core-method "1.2.4" - web3-core-subscriptions "1.2.4" - web3-net "1.2.4" + web3-core "1.2.11" + web3-core-method "1.2.11" + web3-core-subscriptions "1.2.11" + web3-net "1.2.11" web3-stream-provider@^4.0.0: version "4.0.0" @@ -27661,13 +27997,13 @@ web3-stream-provider@^4.0.0: readable-stream "^2.0.5" uuid "^3.3.3" -web3-utils@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.4.tgz#96832a39a66b05bf8862a5b0bdad2799d709d951" - integrity sha512-+S86Ip+jqfIPQWvw2N/xBQq5JNqCO0dyvukGdJm8fEWHZbckT4WxSpHbx+9KLEWY4H4x9pUwnoRkK87pYyHfgQ== +web3-utils@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.2.11.tgz#af1942aead3fb166ae851a985bed8ef2c2d95a82" + integrity sha512-3Tq09izhD+ThqHEaWYX4VOT7dNPdZiO+c/1QMA0s5X2lDFKK/xHJb7cyTRRVzN2LvlHbR7baS1tmQhSua51TcQ== dependencies: - bn.js "4.11.8" - eth-lib "0.2.7" + bn.js "^4.11.9" + eth-lib "0.2.8" ethereum-bloom-filters "^1.0.6" ethjs-unit "0.1.6" number-to-bn "1.7.0" @@ -27675,19 +28011,18 @@ web3-utils@1.2.4: underscore "1.9.1" utf8 "3.0.0" -web3@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.4.tgz#6e7ab799eefc9b4648c2dab63003f704a1d5e7d9" - integrity sha512-xPXGe+w0x0t88Wj+s/dmAdASr3O9wmA9mpZRtixGZxmBexAF0MjfqYM+MS4tVl5s11hMTN3AZb8cDD4VLfC57A== +web3@1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.2.11.tgz#50f458b2e8b11aa37302071c170ed61cff332975" + integrity sha512-mjQ8HeU41G6hgOYm1pmeH0mRAeNKJGnJEUzDMoerkpw7QUQT4exVREgF1MYPvL/z6vAshOXei25LE/t/Bxl8yQ== dependencies: - "@types/node" "^12.6.1" - web3-bzz "1.2.4" - web3-core "1.2.4" - web3-eth "1.2.4" - web3-eth-personal "1.2.4" - web3-net "1.2.4" - web3-shh "1.2.4" - web3-utils "1.2.4" + web3-bzz "1.2.11" + web3-core "1.2.11" + web3-eth "1.2.11" + web3-eth-personal "1.2.11" + web3-net "1.2.11" + web3-shh "1.2.11" + web3-utils "1.2.11" web3@^0.20.7: version "0.20.7" @@ -27806,7 +28141,7 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -websocket@1.0.29, websocket@^1.0.32: +websocket@1.0.32, websocket@^1.0.31: version "1.0.32" resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.32.tgz#1f16ddab3a21a2d929dec1687ab21cfdc6d3dbb1" integrity sha512-i4yhcllSP4wrpoPMU2N0TQ/q0O94LRG/eUQjEAamRltjQ1oT1PFFKOG4i877OlJgCG8rw6LrrowJp+TYCEWF7Q== @@ -27922,7 +28257,7 @@ wif@^2.0.1, wif@^2.0.6: dependencies: bs58check "<3.0.0" -word-wrap@~1.2.3: +word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==