From deb0ad8501cc098d05401295a08a60d9f702259b Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Mon, 31 Aug 2020 18:07:12 -0300 Subject: [PATCH 01/23] Bump new onboard.js version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcb633ca..8ed9be47 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ "async-sema": "^3.1.0", "axios": "0.19.2", "bignumber.js": "9.0.0", - "bnc-onboard": "1.11.1", + "bnc-onboard": "1.12.0", "classnames": "^2.2.6", "concurrently": "^5.2.0", "connected-react-router": "6.8.0", From 878c32c4a38effd98296eb269d749bf452d5d4fc Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Wed, 9 Dec 2020 11:33:22 -0300 Subject: [PATCH 02/23] Collectibles utils --- ...getTransferMethodByContractAddress.test.ts | 68 +++++++++ src/logic/collectibles/utils/index.ts | 143 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/logic/collectibles/utils/__tests__/getTransferMethodByContractAddress.test.ts create mode 100644 src/logic/collectibles/utils/index.ts diff --git a/src/logic/collectibles/utils/__tests__/getTransferMethodByContractAddress.test.ts b/src/logic/collectibles/utils/__tests__/getTransferMethodByContractAddress.test.ts new file mode 100644 index 00000000..7a55a818 --- /dev/null +++ b/src/logic/collectibles/utils/__tests__/getTransferMethodByContractAddress.test.ts @@ -0,0 +1,68 @@ +import { getTransferMethodByContractAddress } from 'src/logic/collectibles/utils' + +jest.mock('src/config', () => { + // Require the original module to not be mocked... + const originalModule = jest.requireActual('src/config') + + return { + __esModule: true, // Use it when dealing with esModules + ...originalModule, + getNetworkId: jest.fn().mockReturnValue(4), + } +}) + +describe('getTransferMethodByContractAddress', () => { + const config = require('src/config') + + afterAll(() => { + jest.unmock('src/config') + }) + + it(`should return "transfer" method, if CK address is provided for MAINNET`, () => { + // Given + config.getNetworkId.mockReturnValue(1) + const contractAddress = '0x06012c8cf97bead5deae237070f9587f8e7a266d' + + // When + const selectedMethod = getTransferMethodByContractAddress(contractAddress) + + // Then + expect(selectedMethod).toBe('transfer') + }) + + it(`should return "transfer" method, if CK address is provided for RINKEBY`, () => { + // Given + config.getNetworkId.mockReturnValue(4) + const contractAddress = '0x16baf0de678e52367adc69fd067e5edd1d33e3bf' + + // When + const selectedMethod = getTransferMethodByContractAddress(contractAddress) + + // Then + expect(selectedMethod).toBe('transfer') + }) + + it(`should return "0x42842e0e" method, if CK address is provided any other network`, () => { + // Given + config.getNetworkId.mockReturnValue(100) + const contractAddress = '0x06012c8cf97bead5deae237070f9587f8e7a266d' + + // When + const selectedMethod = getTransferMethodByContractAddress(contractAddress) + + // Then + expect(selectedMethod).toBe('0x42842e0e') + }) + + it(`should return "0x42842e0e" method, if non-CK address is provided`, () => { + // Given + config.getNetworkId.mockReturnValue(4) + const contractAddress = '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85' + + // When + const selectedMethod = getTransferMethodByContractAddress(contractAddress) + + // Then + expect(selectedMethod).toBe('0x42842e0e') + }) +}) diff --git a/src/logic/collectibles/utils/index.ts b/src/logic/collectibles/utils/index.ts new file mode 100644 index 00000000..8f7b346b --- /dev/null +++ b/src/logic/collectibles/utils/index.ts @@ -0,0 +1,143 @@ +import { getNetworkId, getNetworkInfo } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { nftAssetsListAddressesSelector } from 'src/logic/collectibles/store/selectors' +import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' +import { TOKEN_TRANSFER_METHODS_NAMES } from 'src/logic/safe/store/models/types/transactions.d' +import { getERC721TokenContract, getStandardTokenContract } from 'src/logic/tokens/store/actions/fetchTokens' +import { sameAddress } from 'src/logic/wallets/ethAddresses' +import { CollectibleTx } from 'src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible' +import { store } from 'src/store' +import { sameString } from 'src/utils/strings' + +// CryptoKitties Contract Addresses by network +// This is an exception made for a popular NFT that's not ERC721 standard-compatible, +// so we can allow the user to transfer the assets by using `transferFrom` instead of +// the standard `safeTransferFrom` method. +export const CK_ADDRESS = { + [ETHEREUM_NETWORK.MAINNET]: '0x06012c8cf97bead5deae237070f9587f8e7a266d', + [ETHEREUM_NETWORK.RINKEBY]: '0x16baf0de678e52367adc69fd067e5edd1d33e3bf', +} + +// Note: xDAI ENS is missing, once we have it we need to add it here +const ENS_CONTRACT_ADDRESS = { + [ETHEREUM_NETWORK.MAINNET]: '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85', + [ETHEREUM_NETWORK.RINKEBY]: '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85', + [ETHEREUM_NETWORK.ENERGY_WEB_CHAIN]: '0x0A6d64413c07E10E890220BBE1c49170080C6Ca0', + [ETHEREUM_NETWORK.VOLTA]: '0xd7CeF70Ba7efc2035256d828d5287e2D285CD1ac', +} + +// safeTransferFrom(address,address,uint256) +export const SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH = '42842e0e' + +/** + * Verifies that a tx received by the transaction service is an ERC721 token-related transaction + * @param {TxServiceModel} tx + * @returns boolean + */ +export const isSendERC721Transaction = (tx: TxServiceModel): boolean => { + let hasERC721Transfer = false + + if (tx.dataDecoded && sameString(tx.dataDecoded.method, TOKEN_TRANSFER_METHODS_NAMES.SAFE_TRANSFER_FROM)) { + hasERC721Transfer = tx.dataDecoded.parameters.findIndex((param) => sameString(param.name, 'tokenId')) !== -1 + } + + // Note: this is only valid with our current case (client rendering), if we move to server side rendering we need to refactor this + const state = store.getState() + const knownAssets = nftAssetsListAddressesSelector(state) + return knownAssets.includes(tx.to) || hasERC721Transfer +} + +/** + * Returns the symbol of the provided ERC721 contract + * @param {string} contractAddress + * @returns Promise + */ +export const getERC721Symbol = async (contractAddress: string): Promise => { + let tokenSymbol = 'UNKNOWN' + + try { + const ERC721token = await getERC721TokenContract() + const tokenInstance = await ERC721token.at(contractAddress) + tokenSymbol = await tokenInstance.symbol() + } catch (err) { + // If the contract address is an ENS token contract, we know that the ERC721 standard is not proper implemented + // The method symbol() is missing + if (isENSContract(contractAddress)) { + return 'ENS' + } + console.error(`Failed to retrieve token symbol for ERC721 token ${contractAddress}`) + } + + return tokenSymbol +} + +export const isENSContract = (contractAddress: string): boolean => { + const { id } = getNetworkInfo() + return sameAddress(contractAddress, ENS_CONTRACT_ADDRESS[id]) +} + +/** + * Verifies if the provided contract is a valid ERC721 + * @param {string} contractAddress + * @returns boolean + */ +export const isERC721Contract = async (contractAddress: string): Promise => { + const ERC721Token = await getStandardTokenContract() + let isERC721 = false + + try { + await ERC721Token.at(contractAddress) + isERC721 = true + } catch (error) { + console.warn('Asset not found') + } + + return isERC721 +} + +/** + * Returns a method identifier based on the asset specified and the current network + * @param {string} contractAddress + * @returns string + */ +export const getTransferMethodByContractAddress = (contractAddress: string): string => { + if (sameAddress(contractAddress, CK_ADDRESS[getNetworkId()])) { + // on mainnet `transferFrom` seems to work fine but we can assure that `transfer` will work on both networks + // so that's the reason why we're falling back to `transfer` for CryptoKitties + return 'transfer' + } + + return `0x${SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH}` +} + +/** + * Builds the encodedABI data for the transfer of an NFT token + * @param {CollectibleTx} tx + * @param {string} safeAddress + * @returns Promise + */ +export const generateERC721TransferTxData = async ( + tx: CollectibleTx, + safeAddress: string | undefined, +): Promise => { + if (!safeAddress) { + throw new Error('Failed to build NFT transfer tx data. SafeAddress is not defined.') + } + + const methodToCall = getTransferMethodByContractAddress(tx.assetAddress) + let transferParams = [tx.recipientAddress, tx.nftTokenId] + let NFTTokenContract + + if (methodToCall.includes(SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH)) { + // we add the `from` param for the `safeTransferFrom` method call + transferParams = [safeAddress, ...transferParams] + NFTTokenContract = await getERC721TokenContract() + } else { + // we fallback to an ERC20 Token contract whose ABI implements the `transfer` method + NFTTokenContract = await getStandardTokenContract() + } + + const tokenInstance = await NFTTokenContract.at(tx.assetAddress) + + return tokenInstance.contract.methods[methodToCall](...transferParams).encodeABI() +} From 71375f9d6494e04edfd7eeb8217973a3d4fb96d2 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Mon, 14 Dec 2020 14:53:34 -0300 Subject: [PATCH 03/23] Fix wrong status on txs --- .../store/actions/transactions/utils/transactionHelpers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts index b776b71c..fcc32275 100644 --- a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts +++ b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts @@ -173,12 +173,12 @@ export const calculateTransactionStatus = ( if (tx.isExecuted && tx.isSuccessful) { txStatus = TransactionStatus.SUCCESS + } else if (tx.creationTx) { + txStatus = TransactionStatus.SUCCESS } else if (tx.cancelled || nonce > tx.nonce) { txStatus = TransactionStatus.CANCELLED } else if (tx.confirmations.size === threshold) { txStatus = TransactionStatus.AWAITING_EXECUTION - } else if (tx.creationTx) { - txStatus = TransactionStatus.SUCCESS } else if (!!tx.isPending) { txStatus = TransactionStatus.PENDING } else { From 7c19205e01a56e52f6b21c68d4823eddbee6bed0 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Tue, 15 Dec 2020 18:23:12 -0300 Subject: [PATCH 04/23] (Feature) - Expanded decoded data collapses automatically (#1731) * Adds shouldSafeBeUpdated to avoid updating unnecessary the safe * Fix css typing * Moves equalArrays to utils function Improves how updateSafe is dispatched within checkAndUpdateSafe to avoid unnecessary re renders * Revert some default cases fixes * Adds equalArrays tests * Add test to arrays.test.ts * Improves shouldSafeStoreBeUpdated order and renames it * Adds shouldSafeStoreBeUpdated.test.ts * Uses shouldSafeStoreBeUpdated within safe reducer * Replaces equalArrays with isEqual from lodash * Simplify shouldSafeStoreBeUpdated using isEqual from lodash * Remove lodash to compare Immutable objects correctly Co-authored-by: Daniel Sanchez --- src/logic/safe/store/actions/fetchSafe.ts | 24 +- src/logic/safe/store/reducer/safe.ts | 29 +- .../shouldSafeStoreBeUpdated.test.ts | 369 ++++++++++++++++++ .../safe/utils/shouldSafeStoreBeUpdated.ts | 26 ++ .../Transactions/TxsTable/index.tsx | 14 +- .../components/Transactions/TxsTable/style.ts | 4 +- 6 files changed, 435 insertions(+), 31 deletions(-) create mode 100644 src/logic/safe/utils/__tests__/shouldSafeStoreBeUpdated.test.ts create mode 100644 src/logic/safe/utils/shouldSafeStoreBeUpdated.ts diff --git a/src/logic/safe/store/actions/fetchSafe.ts b/src/logic/safe/store/actions/fetchSafe.ts index 71e2218f..43def162 100644 --- a/src/logic/safe/store/actions/fetchSafe.ts +++ b/src/logic/safe/store/actions/fetchSafe.ts @@ -117,19 +117,17 @@ export const checkAndUpdateSafe = (safeAdd: string) => async (dispatch: Dispatch const modules = await getModules(safeInfo) - dispatch( - updateSafe({ - address: safeAddress, - name: localSafe?.name, - modules, - spendingLimits, - nonce: Number(remoteNonce), - threshold: Number(remoteThreshold), - featuresEnabled: localSafe?.currentVersion - ? enabledFeatures(localSafe?.currentVersion) - : localSafe?.featuresEnabled, - }), - ) + const updatedSafe = { + address: safeAddress, + name: localSafe?.name, + modules, + spendingLimits, + nonce: Number(remoteNonce), + threshold: Number(remoteThreshold), + featuresEnabled: localSafe?.currentVersion ? enabledFeatures(localSafe.currentVersion) : localSafe?.featuresEnabled, + } + + dispatch(updateSafe(updatedSafe)) // If the remote owners does not contain a local address, we remove that local owner localOwners.forEach((localAddress) => { diff --git a/src/logic/safe/store/reducer/safe.ts b/src/logic/safe/store/reducer/safe.ts index 5409c9e5..0d651704 100644 --- a/src/logic/safe/store/reducer/safe.ts +++ b/src/logic/safe/store/reducer/safe.ts @@ -18,6 +18,7 @@ import { checksumAddress } from 'src/utils/checksumAddress' import { SafeReducerMap } from 'src/routes/safe/store/reducer/types/safe' import { ADD_OR_UPDATE_SAFE, buildOwnersFrom } from 'src/logic/safe/store/actions/addOrUpdateSafe' import { sameAddress } from 'src/logic/wallets/ethAddresses' +import { shouldSafeStoreBeUpdated } from 'src/logic/safe/utils/shouldSafeStoreBeUpdated' export const SAFE_REDUCER_ID = 'safes' export const DEFAULT_SAFE_INITIAL_STATE = 'NOT_ASKED' @@ -78,11 +79,15 @@ export default handleActions( const safe = action.payload const safeAddress = safe.address - return state.updateIn( - ['safes', safeAddress], - makeSafe({ name: safe?.name || 'LOADED SAFE', address: safeAddress }), - (prevSafe) => updateSafeProps(prevSafe, safe), - ) + const shouldUpdate = shouldSafeStoreBeUpdated(safe, state.getIn(['safes', safeAddress])) + + return shouldUpdate + ? state.updateIn( + ['safes', safeAddress], + makeSafe({ name: safe?.name || 'LOADED SAFE', address: safeAddress }), + (prevSafe) => updateSafeProps(prevSafe, safe), + ) + : state }, [ACTIVATE_TOKEN_FOR_ALL_SAFES]: (state: SafeReducerMap, action) => { const tokenAddress = action.payload @@ -107,11 +112,15 @@ export default handleActions( return state.setIn(['safes', safe.address], makeSafe(safe)) } - return state.updateIn( - ['safes', safe.address], - makeSafe({ name: safe?.name || 'LOADED SAFE', address: safe.address }), - (prevSafe) => updateSafeProps(prevSafe, safe), - ) + const shouldUpdate = shouldSafeStoreBeUpdated(safe, state.getIn(['safes', safe.safeAddress])) + + return shouldUpdate + ? state.updateIn( + ['safes', safe.address], + makeSafe({ name: safe?.name || 'LOADED SAFE', address: safe.address }), + (prevSafe) => updateSafeProps(prevSafe, safe), + ) + : state }, [REMOVE_SAFE]: (state: SafeReducerMap, action) => { const safeAddress = action.payload diff --git a/src/logic/safe/utils/__tests__/shouldSafeStoreBeUpdated.test.ts b/src/logic/safe/utils/__tests__/shouldSafeStoreBeUpdated.test.ts new file mode 100644 index 00000000..5d029744 --- /dev/null +++ b/src/logic/safe/utils/__tests__/shouldSafeStoreBeUpdated.test.ts @@ -0,0 +1,369 @@ +import { SafeRecordProps } from 'src/logic/safe/store/models/safe' +import { List, Set, Map } from 'immutable' +import { shouldSafeStoreBeUpdated } from 'src/logic/safe/utils/shouldSafeStoreBeUpdated' + +const getMockedOldSafe = ({ + address, + needsUpdate, + balances, + recurringUser, + blacklistedAssets, + blacklistedTokens, + activeAssets, + activeTokens, + owners, + featuresEnabled, + currentVersion, + latestIncomingTxBlock, + ethBalance, + threshold, + name, + nonce, + modules, + spendingLimits, +}: Partial): SafeRecordProps => { + const owner1 = { + name: 'MockedOwner1', + address: '0x3bE3c2dE077FBC409ae50AFFA66a94a9aE669A8d', + } + const owner2 = { + name: 'MockedOwner2', + address: '0xA2366b0c2607de70777d87aCdD1D22F0708fA6a3', + } + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const mockedActiveAssetsAddress1 = '0x503ab2a6A70c6C6ec8b25a4C87C784e1c8f8e8CD' + const mockedActiveAssetsAddress2 = '0xfdd4E685361CB7E89a4D27e03DCd0001448d731F' + const mockedBlacklistedTokenAddress1 = '0xc7d892dca37a244Fb1A7461e6141e58Ead460282' + const mockedBlacklistedAssetAddress1 = '0x0ac539137c4c99001f16Dd132E282F99A02Ddc3F' + + return { + name: name || 'MockedSafe', + address: address || '0xAE173F30ec9A293d37c44BA68d3fCD35F989Ce9F', + threshold: threshold || 2, + ethBalance: ethBalance || '10', + owners: owners || List([owner1, owner2]), + modules: modules || [], + spendingLimits: spendingLimits || [], + activeTokens: activeTokens || Set([mockedActiveTokenAddress1, mockedActiveTokenAddress2]), + activeAssets: activeAssets || Set([mockedActiveAssetsAddress1, mockedActiveAssetsAddress2]), + blacklistedTokens: blacklistedTokens || Set([mockedBlacklistedTokenAddress1]), + blacklistedAssets: blacklistedAssets || Set([mockedBlacklistedAssetAddress1]), + balances: + balances || + Map({ + [mockedActiveTokenAddress1]: '100', + [mockedActiveTokenAddress2]: '10', + }), + nonce: nonce || 2, + latestIncomingTxBlock: latestIncomingTxBlock || 1, + recurringUser: recurringUser || false, + currentVersion: currentVersion || 'v1.1.1', + needsUpdate: needsUpdate || false, + featuresEnabled: featuresEnabled || [], + } +} + +describe('shouldSafeStoreBeUpdated', () => { + it(`Given two equal safes, should return false`, () => { + // given + const oldSafe = getMockedOldSafe({}) + + // When + const expectedResult = shouldSafeStoreBeUpdated(oldSafe, oldSafe) + + // Then + expect(expectedResult).toEqual(false) + }) + it(`Given an old safe and a new address for the safe, should return true`, () => { + // given + const oldAddress = '0x123' + const newAddress = '0x' + const oldSafe = getMockedOldSafe({ address: oldAddress }) + const newSafeProps: Partial = { + address: newAddress, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old safe and a new name for the safe, should return true`, () => { + // given + const oldName = 'oldName' + const newName = 'newName' + const oldSafe = getMockedOldSafe({ name: oldName }) + const newSafeProps: Partial = { + name: newName, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old safe and a new threshold for the safe, should return true`, () => { + // given + const oldThreshold = 1 + const newThreshold = 2 + const oldSafe = getMockedOldSafe({ threshold: oldThreshold }) + const newSafeProps: Partial = { + threshold: newThreshold, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old ethBalance and a new ethBalance for the safe, should return true`, () => { + // given + const oldEthBalance = '1' + const newEthBalance = '2' + const oldSafe = getMockedOldSafe({ ethBalance: oldEthBalance }) + const newSafeProps: Partial = { + ethBalance: newEthBalance, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old owners list and a new owners list for the safe, should return true`, () => { + // given + const owner1 = { + name: 'MockedOwner1', + address: '0x3bE3c2dE077FBC409ae50AFFA66a94a9aE669A8d', + } + const owner2 = { + name: 'MockedOwner2', + address: '0xA2366b0c2607de70777d87aCdD1D22F0708fA6a3', + } + const oldSafe = getMockedOldSafe({ owners: List([owner1, owner2]) }) + const newSafeProps: Partial = { + owners: List([owner1]), + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old modules list and a new modules list for the safe, should return true`, () => { + // given + const oldModulesList = [] + const newModulesList = null + const oldSafe = getMockedOldSafe({ modules: oldModulesList }) + const newSafeProps: Partial = { + modules: newModulesList, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old spendingLimits list and a new spendingLimits list for the safe, should return true`, () => { + // given + const oldSpendingLimitsList = [] + const newSpendingLimitsList = null + const oldSafe = getMockedOldSafe({ spendingLimits: oldSpendingLimitsList }) + const newSafeProps: Partial = { + modules: newSpendingLimitsList, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old activeTokens list and a new activeTokens list for the safe, should return true`, () => { + // given + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const oldActiveTokens = Set([mockedActiveTokenAddress1, mockedActiveTokenAddress2]) + const newActiveTokens = Set([mockedActiveTokenAddress1]) + const oldSafe = getMockedOldSafe({ activeTokens: oldActiveTokens }) + const newSafeProps: Partial = { + activeTokens: newActiveTokens, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old activeAssets list and a new activeAssets list for the safe, should return true`, () => { + // given + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const oldActiveAssets = Set([mockedActiveTokenAddress1, mockedActiveTokenAddress2]) + const newActiveAssets = Set([mockedActiveTokenAddress1]) + const oldSafe = getMockedOldSafe({ activeAssets: oldActiveAssets }) + const newSafeProps: Partial = { + activeAssets: newActiveAssets, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old blacklistedTokens list and a new blacklistedTokens list for the safe, should return true`, () => { + // given + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const oldBlacklistedTokens = Set([mockedActiveTokenAddress1, mockedActiveTokenAddress2]) + const newBlacklistedTokens = Set([mockedActiveTokenAddress1]) + const oldSafe = getMockedOldSafe({ blacklistedTokens: oldBlacklistedTokens }) + const newSafeProps: Partial = { + blacklistedTokens: newBlacklistedTokens, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old blacklistedAssets list and a new blacklistedAssets list for the safe, should return true`, () => { + // given + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const oldBlacklistedAssets = Set([mockedActiveTokenAddress1, mockedActiveTokenAddress2]) + const newBlacklistedAssets = Set([mockedActiveTokenAddress1]) + const oldSafe = getMockedOldSafe({ blacklistedAssets: oldBlacklistedAssets }) + const newSafeProps: Partial = { + blacklistedAssets: newBlacklistedAssets, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old balances list and a new balances list for the safe, should return true`, () => { + // given + const mockedActiveTokenAddress1 = '0x36591cd3DA96b21Ac9ca54cFaf80fe45107294F1' + const mockedActiveTokenAddress2 = '0x92aF97cbF10742dD2527ffaBA70e34C03CFFC2c1' + const oldBalances = Map({ + [mockedActiveTokenAddress1]: '100', + [mockedActiveTokenAddress2]: '10', + }) + const newBalances = Map({ + [mockedActiveTokenAddress1]: '100', + }) + const oldSafe = getMockedOldSafe({ balances: oldBalances }) + const newSafeProps: Partial = { + balances: newBalances, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old nonce and a new nonce for the safe, should return true`, () => { + // given + const oldNonce = 1 + const newNonce = 2 + const oldSafe = getMockedOldSafe({ nonce: oldNonce }) + const newSafeProps: Partial = { + nonce: newNonce, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old newLatestIncomingTxBlock and a new newLatestIncomingTxBlock for the safe, should return true`, () => { + // given + const oldLatestIncomingTxBlock = 1 + const newLatestIncomingTxBlock = 2 + const oldSafe = getMockedOldSafe({ latestIncomingTxBlock: oldLatestIncomingTxBlock }) + const newSafeProps: Partial = { + latestIncomingTxBlock: newLatestIncomingTxBlock, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old recurringUser and a new recurringUser for the safe, should return true`, () => { + // given + const oldRecurringUser = true + const newRecurringUser = false + const oldSafe = getMockedOldSafe({ recurringUser: oldRecurringUser }) + const newSafeProps: Partial = { + recurringUser: newRecurringUser, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old recurringUser and a new recurringUser for the safe, should return true`, () => { + // given + const oldCurrentVersion = '1.1.1' + const newCurrentVersion = '1.0.0' + const oldSafe = getMockedOldSafe({ currentVersion: oldCurrentVersion }) + const newSafeProps: Partial = { + currentVersion: newCurrentVersion, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old needsUpdate and a new needsUpdate for the safe, should return true`, () => { + // given + const oldNeedsUpdate = false + const newNeedsUpdate = true + const oldSafe = getMockedOldSafe({ needsUpdate: oldNeedsUpdate }) + const newSafeProps: Partial = { + needsUpdate: newNeedsUpdate, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) + it(`Given an old featuresEnabled and a new featuresEnabled for the safe, should return true`, () => { + // given + const oldFeaturesEnabled = [] + const newFeaturesEnabled = undefined + const oldSafe = getMockedOldSafe({ featuresEnabled: oldFeaturesEnabled }) + const newSafeProps: Partial = { + featuresEnabled: newFeaturesEnabled, + } + + // When + const expectedResult = shouldSafeStoreBeUpdated(newSafeProps, oldSafe) + + // Then + expect(expectedResult).toEqual(true) + }) +}) diff --git a/src/logic/safe/utils/shouldSafeStoreBeUpdated.ts b/src/logic/safe/utils/shouldSafeStoreBeUpdated.ts new file mode 100644 index 00000000..9247fd48 --- /dev/null +++ b/src/logic/safe/utils/shouldSafeStoreBeUpdated.ts @@ -0,0 +1,26 @@ +import { Map } from 'immutable' + +import { SafeRecordProps } from 'src/logic/safe/store/models/safe' + +// This function checks if an object is a Subset of a Safe State and that they have the same values +const isStateSubset = (superObj, subObj) => { + return Object.keys(subObj).every((key) => { + if (subObj[key] && typeof subObj[key] == 'object') { + if (Map.isMap(subObj[key]) || subObj[key].size >= 0) { + // If type is Immutable Map, List or Object we use Immutable equals + return superObj[key].equals(subObj[key]) + } + return isStateSubset(superObj[key], subObj[key]) + } + return subObj[key] === superObj[key] + }) +} + +export const shouldSafeStoreBeUpdated = ( + newSafeProps: Partial, + oldSafeProps?: SafeRecordProps, +): boolean => { + if (!oldSafeProps) return true + + return !isStateSubset(oldSafeProps, newSafeProps) +} diff --git a/src/routes/safe/components/Transactions/TxsTable/index.tsx b/src/routes/safe/components/Transactions/TxsTable/index.tsx index 9050674b..47dc03ea 100644 --- a/src/routes/safe/components/Transactions/TxsTable/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/index.tsx @@ -3,7 +3,7 @@ import IconButton from '@material-ui/core/IconButton' import TableCell from '@material-ui/core/TableCell' import TableContainer from '@material-ui/core/TableContainer' import TableRow from '@material-ui/core/TableRow' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import ExpandLess from '@material-ui/icons/ExpandLess' import ExpandMore from '@material-ui/icons/ExpandMore' import cn from 'classnames' @@ -25,7 +25,10 @@ import { useAnalytics, SAFE_NAVIGATION_EVENT } from 'src/utils/googleAnalytics' export const TRANSACTION_ROW_TEST_ID = 'transaction-row' -const TxsTable = ({ classes }) => { +const useStyles = makeStyles(styles) + +const TxsTable = (): React.ReactElement => { + const classes = useStyles() const [expandedTx, setExpandedTx] = useState(null) const cancellationTransactions = useSelector(safeCancellationTransactionsSelector) const transactions = useSelector(extendedTransactionsSelector) @@ -95,10 +98,7 @@ const TxsTable = ({ classes }) => { {autoColumns.map((column) => ( { ) } -export default withStyles(styles as any)(TxsTable) +export default TxsTable diff --git a/src/routes/safe/components/Transactions/TxsTable/style.ts b/src/routes/safe/components/Transactions/TxsTable/style.ts index 815ab694..06c73255 100644 --- a/src/routes/safe/components/Transactions/TxsTable/style.ts +++ b/src/routes/safe/components/Transactions/TxsTable/style.ts @@ -1,4 +1,6 @@ -export const styles = () => ({ +import { createStyles } from '@material-ui/core' + +export const styles = createStyles({ container: { marginTop: '56px', }, From f143721c06a34a32fcec670c47a6423193717d9d Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Wed, 16 Dec 2020 22:32:13 +0100 Subject: [PATCH 05/23] Fix typo in ADD_OR_UPDATE_SAFE reducer (#1735) --- src/logic/safe/store/reducer/safe.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/logic/safe/store/reducer/safe.ts b/src/logic/safe/store/reducer/safe.ts index 0d651704..5381b38a 100644 --- a/src/logic/safe/store/reducer/safe.ts +++ b/src/logic/safe/store/reducer/safe.ts @@ -107,17 +107,18 @@ export default handleActions( [ADD_OR_UPDATE_SAFE]: (state: SafeReducerMap, action) => { const { safe } = action.payload + const safeAddress = safe.address - if (!state.hasIn(['safes', safe.address])) { - return state.setIn(['safes', safe.address], makeSafe(safe)) + if (!state.hasIn(['safes', safeAddress])) { + return state.setIn(['safes', safeAddress], makeSafe(safe)) } - const shouldUpdate = shouldSafeStoreBeUpdated(safe, state.getIn(['safes', safe.safeAddress])) + const shouldUpdate = shouldSafeStoreBeUpdated(safe, state.getIn(['safes', safeAddress])) return shouldUpdate ? state.updateIn( - ['safes', safe.address], - makeSafe({ name: safe?.name || 'LOADED SAFE', address: safe.address }), + ['safes', safeAddress], + makeSafe({ name: safe?.name || 'LOADED SAFE', address: safeAddress }), (prevSafe) => updateSafeProps(prevSafe, safe), ) : state From 62232e6dc2444dae2fb8f2fca1377987adc8d119 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 18 Dec 2020 10:34:57 -0300 Subject: [PATCH 06/23] Prevent modal from closing on its own --- .../TxDescription/TransferDescription.tsx | 1 - .../Transactions/TxsTable/ExpandedTx/index.tsx | 12 +++++------- .../safe/components/Transactions/TxsTable/index.tsx | 13 +++++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx index 91a324ca..58a7c2a6 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx @@ -26,7 +26,6 @@ const TransferDescription = ({ }: TransferDescriptionProps): ReactElement | null => { const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, recipient)) const [sendModalOpen, setSendModalOpen] = React.useState(false) - const sendModalOpenHandler = () => { setSendModalOpen(true) } diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx index 22e8de7e..123f8559 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx @@ -73,13 +73,11 @@ const ExpandedModuleTx = ({ tx }: { tx: SafeModuleTransaction }): ReactElement = - {recipient && ( - - )} + diff --git a/src/routes/safe/components/Transactions/TxsTable/index.tsx b/src/routes/safe/components/Transactions/TxsTable/index.tsx index 9050674b..411b8b9a 100644 --- a/src/routes/safe/components/Transactions/TxsTable/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/index.tsx @@ -35,6 +35,10 @@ const TxsTable = ({ classes }) => { trackEvent({ category: SAFE_NAVIGATION_EVENT, action: 'Transactions' }) }, [trackEvent]) + useEffect(() => { + console.log('La coupeeeee') + }, []) + const handleTxExpand = (rowId) => { setExpandedTx((prevRowId) => (prevRowId === rowId ? null : rowId)) } @@ -121,12 +125,9 @@ const TxsTable = ({ classes }) => { colSpan={6} style={{ paddingBottom: 0, paddingTop: 0 }} > - } - in={expandedTx === rowId} - timeout="auto" - unmountOnExit - /> + + + From 2af0fb0cb11cd8b84d99f453408b73dcfaf850e3 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Fri, 18 Dec 2020 10:44:04 -0300 Subject: [PATCH 07/23] Update index.tsx --- src/routes/safe/components/Transactions/TxsTable/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/routes/safe/components/Transactions/TxsTable/index.tsx b/src/routes/safe/components/Transactions/TxsTable/index.tsx index f1a66386..0e5b2687 100644 --- a/src/routes/safe/components/Transactions/TxsTable/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/index.tsx @@ -38,10 +38,6 @@ const TxsTable = (): React.ReactElement => { trackEvent({ category: SAFE_NAVIGATION_EVENT, action: 'Transactions' }) }, [trackEvent]) - useEffect(() => { - console.log('La coupeeeee') - }, []) - const handleTxExpand = (rowId) => { setExpandedTx((prevRowId) => (prevRowId === rowId ? null : rowId)) } From 6ffb7368cdc9e15bbbfdcd936ebe8313ecf9589e Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Mon, 21 Dec 2020 23:06:48 -0300 Subject: [PATCH 08/23] Allow sort for value column --- .../safe/components/Balances/dataFetcher.ts | 62 +++++++++++-------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/routes/safe/components/Balances/dataFetcher.ts b/src/routes/safe/components/Balances/dataFetcher.ts index d2d9b7d8..05b38ff8 100644 --- a/src/routes/safe/components/Balances/dataFetcher.ts +++ b/src/routes/safe/components/Balances/dataFetcher.ts @@ -13,6 +13,25 @@ export const BALANCE_TABLE_VALUE_ID = 'value' const { nativeCoin } = getNetworkInfo() +const getTokenPriceValue = (token: Token, currencyValues?: BalanceCurrencyList, currencyRate?: number): string => { + const currencyValue = currencyValues?.find(({ tokenAddress }) => { + if (token.address === nativeCoin.address && !tokenAddress) { + return true + } + + return token.address === tokenAddress + }) + + if (!currencyValue || !currencyRate) { + return '' + } + + const { balanceInBaseCurrency } = currencyValue + const balance = new BigNumber(balanceInBaseCurrency).times(currencyRate).toFixed(2) + + return formatAmountInUsFormat(balance) +} + const getTokenPriceInCurrency = ( token: Token, currencySelected?: string, @@ -47,6 +66,7 @@ export interface BalanceData { balanceOrder: number fixed: boolean value: string + valueOrder: number } export const getBalanceData = ( @@ -56,19 +76,22 @@ export const getBalanceData = ( currencyRate?: number, ): List => { const { nativeCoin } = getNetworkInfo() - return activeTokens.map((token) => ({ - [BALANCE_TABLE_ASSET_ID]: { - name: token.name, - logoUri: token.logoUri, - address: token.address, - symbol: token.symbol, - }, - assetOrder: token.name, - [BALANCE_TABLE_BALANCE_ID]: `${formatAmountInUsFormat(token.balance?.toString() || '0')} ${token.symbol}`, - balanceOrder: Number(token.balance), - [FIXED]: token.symbol === nativeCoin.symbol, - [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(token, currencySelected, currencyValues, currencyRate), - })) + return activeTokens.map((token) => { + return { + [BALANCE_TABLE_ASSET_ID]: { + name: token.name, + logoUri: token.logoUri, + address: token.address, + symbol: token.symbol, + }, + assetOrder: token.name, + [BALANCE_TABLE_BALANCE_ID]: `${formatAmountInUsFormat(token.balance?.toString() || '0')} ${token.symbol}`, + balanceOrder: Number(token.balance), + [FIXED]: token.symbol === nativeCoin.symbol, + [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(token, currencySelected, currencyValues, currencyRate), + valueOrder: Number(getTokenPriceValue(token, currencyValues, currencyRate)), + } + }) } export const generateColumns = (): List => { @@ -101,21 +124,10 @@ export const generateColumns = (): List => { const value: TableColumn = { id: BALANCE_TABLE_VALUE_ID, - order: false, + order: true, label: 'Value', custom: false, - static: true, disablePadding: false, - style: { - fontSize: '11px', - color: '#5d6d74', - borderBottomWidth: '2px', - width: '125px', - fontFamily: 'Averta', - fontWeight: 'normal', - fontStyle: 'normal', - textAlign: 'right', - }, } return List([assetColumn, balanceColumn, value, actions]) From a00539e8c2d5348d6a110a9d8984cdde400bbff5 Mon Sep 17 00:00:00 2001 From: Mati Dastugue Date: Mon, 28 Dec 2020 14:09:30 -0300 Subject: [PATCH 09/23] Fix token price function to be more generic --- .../safe/components/Balances/dataFetcher.ts | 37 +++++-------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/src/routes/safe/components/Balances/dataFetcher.ts b/src/routes/safe/components/Balances/dataFetcher.ts index 05b38ff8..c7a3f2d4 100644 --- a/src/routes/safe/components/Balances/dataFetcher.ts +++ b/src/routes/safe/components/Balances/dataFetcher.ts @@ -13,7 +13,7 @@ export const BALANCE_TABLE_VALUE_ID = 'value' const { nativeCoin } = getNetworkInfo() -const getTokenPriceValue = (token: Token, currencyValues?: BalanceCurrencyList, currencyRate?: number): string => { +const getTokenValue = (token: Token, currencyValues?: BalanceCurrencyList, currencyRate?: number): string => { const currencyValue = currencyValues?.find(({ tokenAddress }) => { if (token.address === nativeCoin.address && !tokenAddress) { return true @@ -27,36 +27,16 @@ const getTokenPriceValue = (token: Token, currencyValues?: BalanceCurrencyList, } const { balanceInBaseCurrency } = currencyValue - const balance = new BigNumber(balanceInBaseCurrency).times(currencyRate).toFixed(2) + const balance = new BigNumber(balanceInBaseCurrency).times(currencyRate).toString() - return formatAmountInUsFormat(balance) + return balance } -const getTokenPriceInCurrency = ( - token: Token, - currencySelected?: string, - currencyValues?: BalanceCurrencyList, - currencyRate?: number, -): string => { +const getTokenPriceInCurrency = (balance: string, currencySelected?: string): string => { if (!currencySelected) { - return '' + return Number('').toFixed(2) } - const currencyValue = currencyValues?.find(({ tokenAddress }) => { - if (token.address === nativeCoin.address && !tokenAddress) { - return true - } - - return token.address === tokenAddress - }) - - if (!currencyValue || !currencyRate) { - return '' - } - - const { balanceInBaseCurrency } = currencyValue - const balance = new BigNumber(balanceInBaseCurrency).times(currencyRate).toFixed(2) - - return `${formatAmountInUsFormat(balance)} ${currencySelected}` + return `${formatAmountInUsFormat(Number(balance).toFixed(2))} ${currencySelected}` } export interface BalanceData { @@ -77,6 +57,7 @@ export const getBalanceData = ( ): List => { const { nativeCoin } = getNetworkInfo() return activeTokens.map((token) => { + const balance = getTokenValue(token, currencyValues, currencyRate) return { [BALANCE_TABLE_ASSET_ID]: { name: token.name, @@ -88,8 +69,8 @@ export const getBalanceData = ( [BALANCE_TABLE_BALANCE_ID]: `${formatAmountInUsFormat(token.balance?.toString() || '0')} ${token.symbol}`, balanceOrder: Number(token.balance), [FIXED]: token.symbol === nativeCoin.symbol, - [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(token, currencySelected, currencyValues, currencyRate), - valueOrder: Number(getTokenPriceValue(token, currencyValues, currencyRate)), + [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(balance, currencySelected), + valueOrder: Number(balance), } }) } From 186fb347310c182e95e1aeda3e14a43380d88376 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 13:02:04 +0100 Subject: [PATCH 10/23] Bump node-notifier from 8.0.0 to 8.0.1 (#1741) Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/mikaelbr/node-notifier/releases) - [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md) - [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Sanchez --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 606db658..e3b97a37 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13920,9 +13920,9 @@ node-modules-regexp@^1.0.0: integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= node-notifier@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.0.tgz#a7eee2d51da6d0f7ff5094bc7108c911240c1620" - integrity sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA== + version "8.0.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-8.0.1.tgz#f86e89bbc925f2b068784b31f382afdc6ca56be1" + integrity sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA== dependencies: growly "^1.3.0" is-wsl "^2.2.0" From 09b470187f8d66f5687e6b1871f965a6f5f8954e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Jan 2021 14:01:34 +0100 Subject: [PATCH 11/23] Bump axios from 0.21.0 to 0.21.1 (#1754) Bumps [axios](https://github.com/axios/axios) from 0.21.0 to 0.21.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v0.21.0...v0.21.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Sanchez --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7d32b027..d06d533f 100644 --- a/package.json +++ b/package.json @@ -179,7 +179,7 @@ "@sentry/tracing": "^5.28.0", "@truffle/contract": "4.2.30", "async-sema": "^3.1.0", - "axios": "0.21.0", + "axios": "0.21.1", "bignumber.js": "9.0.1", "bnc-onboard": "^1.16.1", "classnames": "^2.2.6", diff --git a/yarn.lock b/yarn.lock index e3b97a37..55eac46a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4586,10 +4586,10 @@ axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf" integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ== -axios@0.21.0: - version "0.21.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca" - integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw== +axios@0.21.1: + version "0.21.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" + integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== dependencies: follow-redirects "^1.10.0" From f1ffb5d147aeea57633ba1838da2bd5811d39c8d Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Tue, 12 Jan 2021 11:39:57 -0300 Subject: [PATCH 12/23] (Fix) - Remove safe fix (#1744) * Avoid displaying notification for non updated owner * Remove old selector usage on welcome page * Remove provider props on WelcomeLayout Fix removing safe behaviour * Fix missing undefined property check on cancelThresholdReached * Removes the default safe when removing the safe marked as default * Remove index * Change react import * Fix relative path for relocate url * Adds removeLocalSafe action Uses removeLocalSafe on onRemoveSafeHandler also removes default safe * Refactor SafeListSidebar uses redux-hooks approach * Disabled save button when the owner name input is pristine --- src/components/App/index.tsx | 6 +- .../{AddresWrapper.tsx => AddressWrapper.tsx} | 13 +- .../SafeListSidebar/SafeList/index.tsx | 10 +- src/components/SafeListSidebar/index.tsx | 28 ++--- .../safe/store/actions/removeLocalSafe.ts | 11 ++ src/logic/safe/store/reducer/safe.ts | 9 +- src/routes/open/components/Layout.tsx | 4 +- .../ManageOwners/EditOwnerModal/index.tsx | 111 +++++++++--------- .../Settings/ManageOwners/index.tsx | 2 +- .../Settings/RemoveSafeModal/index.tsx | 44 +++++-- .../TxsTable/ExpandedTx/index.tsx | 2 +- .../components/{Layout.tsx => index.tsx} | 10 +- src/routes/welcome/container/index.tsx | 14 +-- src/routes/welcome/container/selector.ts | 7 -- 14 files changed, 148 insertions(+), 123 deletions(-) rename src/components/SafeListSidebar/SafeList/{AddresWrapper.tsx => AddressWrapper.tsx} (85%) create mode 100644 src/logic/safe/store/actions/removeLocalSafe.ts rename src/routes/welcome/components/{Layout.tsx => index.tsx} (94%) delete mode 100644 src/routes/welcome/container/selector.ts diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index 8b50ae68..fa9b73f5 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -11,7 +11,7 @@ import ErrorIcon from 'src/assets/icons/error.svg' import InfoIcon from 'src/assets/icons/info.svg' import AppLayout from 'src/components/AppLayout' -import SafeListSidebarProvider, { SafeListSidebarContext } from 'src/components/SafeListSidebar' +import { SafeListSidebar, SafeListSidebarContext } from 'src/components/SafeListSidebar' import CookiesBanner from 'src/components/CookiesBanner' import Notifier from 'src/components/Notifier' import Backdrop from 'src/components/layout/Backdrop' @@ -159,9 +159,9 @@ const App: React.FC = ({ children }) => { } const WrapperAppWithSidebar: React.FC = ({ children }) => ( - + {children} - + ) export default WrapperAppWithSidebar diff --git a/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx b/src/components/SafeListSidebar/SafeList/AddressWrapper.tsx similarity index 85% rename from src/components/SafeListSidebar/SafeList/AddresWrapper.tsx rename to src/components/SafeListSidebar/SafeList/AddressWrapper.tsx index 8bf621a3..f21874aa 100644 --- a/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx +++ b/src/components/SafeListSidebar/SafeList/AddressWrapper.tsx @@ -6,9 +6,10 @@ import { sameAddress } from 'src/logic/wallets/ethAddresses' import DefaultBadge from './DefaultBadge' import { SafeRecordProps } from 'src/logic/safe/store/models/safe' import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' -import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' +import setDefaultSafe from 'src/logic/safe/store/actions/setDefaultSafe' import { makeStyles } from '@material-ui/core/styles' import { getNetworkInfo } from 'src/config' +import { useDispatch } from 'react-redux' const StyledButtonLink = styled(ButtonLink)` visibility: hidden; @@ -46,14 +47,18 @@ const useStyles = makeStyles({ type Props = { safe: SafeRecordProps defaultSafe: DefaultSafe - setDefaultSafe: SetDefaultSafe } const { nativeCoin } = getNetworkInfo() export const AddressWrapper = (props: Props): React.ReactElement => { const classes = useStyles() - const { safe, defaultSafe, setDefaultSafe } = props + const { safe, defaultSafe } = props + const dispatch = useDispatch() + + const setDefaultSafeAction = (safeAddress: string) => { + dispatch(setDefaultSafe(safeAddress)) + } return (
@@ -68,7 +73,7 @@ export const AddressWrapper = (props: Props): React.ReactElement => { className="safeListMakeDefaultButton" textSize="sm" onClick={() => { - setDefaultSafe(safe.address) + setDefaultSafeAction(safe.address) }} color="primary" > diff --git a/src/components/SafeListSidebar/SafeList/index.tsx b/src/components/SafeListSidebar/SafeList/index.tsx index 57b60238..3a664d56 100644 --- a/src/components/SafeListSidebar/SafeList/index.tsx +++ b/src/components/SafeListSidebar/SafeList/index.tsx @@ -6,12 +6,11 @@ import * as React from 'react' import styled from 'styled-components' import { SafeRecord } from 'src/logic/safe/store/models/safe' import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' -import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' import { sameAddress } from 'src/logic/wallets/ethAddresses' import { SAFELIST_ADDRESS } from 'src/routes/routes' -import { AddressWrapper } from './AddresWrapper' +import { AddressWrapper } from 'src/components/SafeListSidebar/SafeList/AddressWrapper' export const SIDEBAR_SAFELIST_ROW_TESTID = 'SIDEBAR_SAFELIST_ROW_TESTID' const StyledIcon = styled(Icon)` @@ -46,10 +45,9 @@ type Props = { defaultSafe: DefaultSafe safes: SafeRecord[] onSafeClick: () => void - setDefaultSafe: SetDefaultSafe } -const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe }: Props): React.ReactElement => { +export const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes }: Props): React.ReactElement => { const classes = useStyles() return ( @@ -67,7 +65,7 @@ const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe ) : (
placeholder
)} - + @@ -76,5 +74,3 @@ const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe ) } - -export default SafeList diff --git a/src/components/SafeListSidebar/index.tsx b/src/components/SafeListSidebar/index.tsx index 8aeeb77b..9846f170 100644 --- a/src/components/SafeListSidebar/index.tsx +++ b/src/components/SafeListSidebar/index.tsx @@ -1,10 +1,10 @@ -import React, { useEffect, useMemo, useState } from 'react' +import React, { useEffect, useMemo, useState, ReactElement } from 'react' import Drawer from '@material-ui/core/Drawer' import SearchIcon from '@material-ui/icons/Search' import SearchBar from 'material-ui-search-bar' -import { connect } from 'react-redux' +import { useSelector } from 'react-redux' -import SafeList from './SafeList' +import { SafeList } from './SafeList' import { sortedSafeListSelector } from './selectors' import useSidebarStyles from './style' @@ -15,11 +15,9 @@ import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' import Row from 'src/components/layout/Row' import { WELCOME_ADDRESS } from 'src/routes/routes' -import setDefaultSafe from 'src/logic/safe/store/actions/setDefaultSafe' import { useAnalytics, SAFE_NAVIGATION_EVENT } from 'src/utils/googleAnalytics' import { defaultSafeSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { AppReduxState } from 'src/store' export const SafeListSidebarContext = React.createContext({ isOpen: false, @@ -34,9 +32,17 @@ const filterBy = (filter, safes) => safe.name.toLowerCase().includes(filter.toLowerCase()), ) -const SafeListSidebar = ({ children, currentSafe, defaultSafe, safes, setDefaultSafeAction }) => { +type Props = { + children: ReactElement +} + +export const SafeListSidebar = ({ children }: Props): ReactElement => { const [isOpen, setIsOpen] = useState(false) const [filter, setFilter] = useState('') + const safes = useSelector(sortedSafeListSelector) + const defaultSafe = useSelector(defaultSafeSelector) + const currentSafe = useSelector(safeParamAddressFromStateSelector) + const classes = useSidebarStyles() const { trackEvent } = useAnalytics() @@ -118,19 +124,9 @@ const SafeListSidebar = ({ children, currentSafe, defaultSafe, safes, setDefault defaultSafe={defaultSafe} onSafeClick={toggleSidebar} safes={filteredSafes} - setDefaultSafe={setDefaultSafeAction} /> {children} ) } - -export default connect( - (state: AppReduxState) => ({ - safes: sortedSafeListSelector(state), - defaultSafe: defaultSafeSelector(state), - currentSafe: safeParamAddressFromStateSelector(state), - }), - { setDefaultSafeAction: setDefaultSafe }, -)(SafeListSidebar) diff --git a/src/logic/safe/store/actions/removeLocalSafe.ts b/src/logic/safe/store/actions/removeLocalSafe.ts new file mode 100644 index 00000000..64bd4284 --- /dev/null +++ b/src/logic/safe/store/actions/removeLocalSafe.ts @@ -0,0 +1,11 @@ +import { Action, Dispatch } from 'redux' +import { loadStoredSafes } from 'src/logic/safe/utils' +import removeSafe from 'src/logic/safe/store/actions/removeSafe' + +export const removeLocalSafe = (safeAddress: string) => async (dispatch: Dispatch): Promise => { + const storedSafes = await loadStoredSafes() + if (storedSafes) { + delete storedSafes[safeAddress] + } + dispatch(removeSafe(safeAddress)) +} diff --git a/src/logic/safe/store/reducer/safe.ts b/src/logic/safe/store/reducer/safe.ts index 5381b38a..b5997f68 100644 --- a/src/logic/safe/store/reducer/safe.ts +++ b/src/logic/safe/store/reducer/safe.ts @@ -126,7 +126,14 @@ export default handleActions( [REMOVE_SAFE]: (state: SafeReducerMap, action) => { const safeAddress = action.payload - return state.deleteIn(['safes', safeAddress]) + const currentDefaultSafe = state.get('defaultSafe') + + let newState = state.deleteIn(['safes', safeAddress]) + if (sameAddress(safeAddress, currentDefaultSafe)) { + newState = newState.set('defaultSafe', DEFAULT_SAFE_INITIAL_STATE) + } + + return newState }, [ADD_SAFE_OWNER]: (state: SafeReducerMap, action) => { const { ownerAddress, ownerName, safeAddress } = action.payload diff --git a/src/routes/open/components/Layout.tsx b/src/routes/open/components/Layout.tsx index 45385f05..2bce3846 100644 --- a/src/routes/open/components/Layout.tsx +++ b/src/routes/open/components/Layout.tsx @@ -17,7 +17,7 @@ import { getOwnerAddressBy, getOwnerNameBy, } from 'src/routes/open/components/fields' -import Welcome from 'src/routes/welcome/components/Layout' +import { WelcomeLayout } from 'src/routes/welcome/components/index' import { history } from 'src/store' import { secondary, sm } from 'src/theme/variables' import { networkSelector, providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors' @@ -138,7 +138,7 @@ export const Layout = (props: LayoutProps): React.ReactElement => { ) : ( - + )} ) diff --git a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx index 26157c4b..914da3c2 100644 --- a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx @@ -40,17 +40,18 @@ type OwnProps = { selectedOwnerName: string } -const EditOwnerComponent = ({ isOpen, onClose, ownerAddress, selectedOwnerName }: OwnProps): React.ReactElement => { +export const EditOwnerModal = ({ isOpen, onClose, ownerAddress, selectedOwnerName }: OwnProps): React.ReactElement => { const classes = useStyles() const dispatch = useDispatch() - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string - const handleSubmit = (values) => { - const { ownerName } = values - - dispatch(editSafeOwner({ safeAddress, ownerAddress, ownerName })) - dispatch(addOrUpdateAddressBookEntry(makeAddressBookEntry({ address: ownerAddress, name: ownerName }))) - dispatch(enqueueSnackbar(NOTIFICATIONS.OWNER_NAME_CHANGE_EXECUTED_MSG)) + const safeAddress = useSelector(safeParamAddressFromStateSelector) + const handleSubmit = ({ ownerName }: { ownerName: string }): void => { + // Update the value only if the ownerName really changed + if (ownerName !== selectedOwnerName) { + dispatch(editSafeOwner({ safeAddress, ownerAddress, ownerName })) + dispatch(addOrUpdateAddressBookEntry(makeAddressBookEntry({ address: ownerAddress, name: ownerName }))) + dispatch(enqueueSnackbar(NOTIFICATIONS.OWNER_NAME_CHANGE_EXECUTED_MSG)) + } onClose() } @@ -71,54 +72,56 @@ const EditOwnerComponent = ({ isOpen, onClose, ownerAddress, selectedOwnerName } - - {() => ( - <> - - - + + {(...args) => { + const pristine = args[2].pristine + return ( + <> + + + + + + + + + {ownerAddress} + + + + + + + + + + - - - - - {ownerAddress} - - - - - - - - - - - - - )} + + ) + }} ) } - -export default EditOwnerComponent diff --git a/src/routes/safe/components/Settings/ManageOwners/index.tsx b/src/routes/safe/components/Settings/ManageOwners/index.tsx index be55767a..df255ca5 100644 --- a/src/routes/safe/components/Settings/ManageOwners/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/index.tsx @@ -9,7 +9,7 @@ import { List } from 'immutable' import RemoveOwnerIcon from '../assets/icons/bin.svg' import AddOwnerModal from './AddOwnerModal' -import EditOwnerModal from './EditOwnerModal' +import { EditOwnerModal } from './EditOwnerModal' import OwnerAddressTableCell from './OwnerAddressTableCell' import RemoveOwnerModal from './RemoveOwnerModal' import ReplaceOwnerModal from './ReplaceOwnerModal' diff --git a/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx b/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx index 5524ecd3..4d2f8b72 100644 --- a/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx +++ b/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx @@ -18,9 +18,16 @@ import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' -import removeSafe from 'src/logic/safe/store/actions/removeSafe' -import { safeNameSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' +import { + defaultSafeSelector, + safeNameSelector, + safeParamAddressFromStateSelector, +} from 'src/logic/safe/store/selectors' import { md, secondary } from 'src/theme/variables' +import { WELCOME_ADDRESS } from 'src/routes/routes' +import { removeLocalSafe } from 'src/logic/safe/store/actions/removeLocalSafe' +import { sameAddress } from 'src/logic/wallets/ethAddresses' +import { saveDefaultSafe } from 'src/logic/safe/utils' const openIconStyle = { height: md, @@ -29,14 +36,33 @@ const openIconStyle = { const useStyles = makeStyles(styles) -const RemoveSafeComponent = ({ isOpen, onClose }) => { +type RemoveSafeModalProps = { + isOpen: boolean + onClose: () => void +} + +export const RemoveSafeModal = ({ isOpen, onClose }: RemoveSafeModalProps): React.ReactElement => { const classes = useStyles() - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string + const safeAddress = useSelector(safeParamAddressFromStateSelector) const safeName = useSelector(safeNameSelector) + const defaultSafe = useSelector(defaultSafeSelector) const dispatch = useDispatch() const explorerInfo = getExplorerInfo(safeAddress) const { url } = explorerInfo() + const onRemoveSafeHandler = async () => { + await dispatch(removeLocalSafe(safeAddress)) + if (sameAddress(safeAddress, defaultSafe)) { + await saveDefaultSafe('') + } + + onClose() + // using native redirect in order to avoid problems in several components + // trying to access references of the removed safe. + const relativePath = window.location.href.split('/#/')[0] + window.location.href = `${relativePath}/#/${WELCOME_ADDRESS}` + } + return ( { + + + + + + + + + + ) +} diff --git a/src/components/AppLayout/MobileStart/assets/phone@2x.png b/src/components/AppLayout/MobileStart/assets/phone@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fdebc6cd8fcb0c8ea29bbef63f0c272b36a11f06 GIT binary patch literal 45883 zcmV*%KsdjNP)Pyg07*naRCodGT?Kqp$JRelLK1=#BmojMNN|U`J5@?usJ`~A>uXE<>hALD^7>w1 zOUtW!kwOc_CAhl<3ljg%e|FDi_HuXk?q)aHBs2MK#_imh|2^l-+!-Qc3M$BR)JehpX^c5{;^}nMnyY<8^GGr9cD$E@}ZSA^;JFCmgnRRX135>((u7eF+0y zO%YX0fxNuDYMuOH2DNJKi`}D(rpXnSwuBq73;@{;8xvMl6bLr}h7r)B0?fh!8kKyQ zm2N{gKr7rp)x3H0O82XhbT!$dhyvTTZ42v!4;Qe70nozQuV5cpbxyL7>#hu7g#uIt zjDj6jCVe<45DMs32H0vMn1u`?m3TlQ*BJ_M1p`=>0jdTK8id@hO3>0|t-%!7yLWHM z+>29i3l-2R0cIihDU?T9m6I-{x`G8QCxGP?sKNnCD_5=zso$YIOp_=2D3G093I^~30b3wI3kJ+W1hPtlcc5n* zG_V9J&=MbX`N05}FK){pU^xM*U_dH0H8toyT4-dvb({hP1qF^LdLV%F2WtKR%_*2g z8<0hE@PB!SBxXaxeRNC8y+`t^gNPaU7*HKO|m4jga{L{2*t2;BSunlCV`CLjwt zZ9v0FO(MtTIt8v^xh*@;@&{JI09Clbr(V5!j_Kue;G1-jr$Aw0VOS?+FaYQe*z7

WAB&%Z- zC@LxnIH7%koIhZ*12iXKRz*M-u+L71K{zL$qq0H;FFVD&mE*DkmoLx?2C%>xZP~IV zVBdD^*by*|(}!Zx)qV;zZQ3;8Bu-CHFSq0Lf(0}yn1u>tVdlmH_TR}U2-l=@R8Ao9 zvJ)4rz!fggvg59NaZ|y9ldp1|JP?zn_ENwJx25;q7s%O_V+A!|+*u$nv+Bz1II=)M z7KBJyX%KS+JUUTr+>XkKG2RfXoVFXhWEQEFewv{_5_^Og2Y(!wFux zjw=}8(!t0Vm!+oxfqVg#FM#4fr0BYP_ijgY(I0|w*BuHpY}imuR*VxnFtZB-b*!Lf z2WVCx({*UU0GU-srgLP`24a<&YytBI177}gUH*Ve7ZY`EO9v!7(9+{EK&*ge2UK=p z$ZIwHzys38n#cI-1_fA$>xkR10-4nhYU!XB2+;I+9n7q{GMyvSflLQ6)NKW_FmPgy z=z_X+6Y50so6jF`p>nI(sDqb3CB4pd>A;0D1-x`%vI3VLrvsK1n5=%3591G*_U+pj z!*5qtLi68Hzz+qO`=XST6rU5;7sy#b%<30F)4@ubA>5fB=LE=f5JOoykVONC#Y+c+ zu>FEppmLmoSFl`{4o*67>EXUW%MP&Yz{)Ni`WqJ)7sCJ=sOz41r1yA?qt;NMw6xSG zDCwPS(xeHzF}~9C*wd3MH$ctT_(KAKnLfUy00At_34oZ)2ZYN@A3z3%Kw&KK7u#Fq!6 zgBJ2hxc*S}0ie5)UI#2YZpsdH?7~nMOj=r+vQd_Dn16MW0>WwS*|W!I|9t_O9}W#jU?mi=hUtDCq^y7@ablx9J0KGfL%eWm z0%STjhIj!o;lvOooEY3NIydHz3kxTR1v|NXrmrk`RhH|r0+$X*x?4Ccoy*d}$d}vo zh+O}Dfs&qAPw&)S+5ArHG3hEt0Uby}DaluUUtp)Fw{z><8QP-*nt+(t{(wwC3}x5> zSu}!JFgh@w;DrwRGET)t$ser9=mfX~v`~kD8S5cD{n3F#cO$(OtPsyXM0t!gk0-+7 zh>eZ))M<$_-Wo)KK+mzPtjsUhCF4a0BXplZ;}E?VKuyvk4cyjz(5Z14qLnU8#yfya z#=DBN`3KPQr5^)`>AEpHy%^Ww(TSmWT`z{Y?~fC+X-?2V!AvNhX?<~DPQgpKFFWuO zkx_ukm$)boN^DR<9;AfHKoA>gbhi#x%tFU-dyqsKJsko94PvKhRN>}dt)@UAKtt!P zX>^cc&W9LCJfNs^YI-_xi!EGNFdUhPmBNkrUS2Dhpm#k~9MX63i;ZwAQ0Z}!54NvxJ&i9niwRy) zEXI2Iji-7j5boz9prrT48YaMoG!iGaaBuobyaf^)sB7mibA>8Ws6^3vaydkXp0%V9sxE?2fWd~%Tf|#8?40Y?`WC$SUlYS^W zWD(LA_k}|J8K(++;kla?GL!{(D6gtb-;pO%7$Cgh?^fM!u*05;&r2! zp@$oH?Vy0u=PLjtz1BeuaTqre2JnKL$D)U;LOt$uYTUxjz#_nA3uclBbqbKd&2t2n zmjQ^0LA_R^ftV+X%k;U$Lg&Pg!Kx4Q6cPqUAb_%s_r-k)fH@T%nX6Id1J%(NAilf- zbj}OFBH#kxLR$EB(9*$650^m(TijOQl5neydhqaJOB~!VRzJdG*ub_k7;qBK{S~LN zYY_!_tay6E$nc31xG@R0 z6DbkKV5;f{h@lPO#Ka8{Ll|?5%9f3;2on(F`Ksa&7D$w2T=Aqudd>I>_bWnrCY)A~ zPp5#Fo&ap5_^sSmsNf|)CLm=4Txvy800y?W0bFjs2Y@gb_<@x2gDPXrO|ka^T4=kJ z54V(K4Ts;8heb_M#p|GjG-C8Oo`e~@_EJE=OfAW13o`;t=(*^pgbD&u03iV;iDLl5 z@lUZl7kEgz#B}!V$4&Volc=bindjLiPG}|`Lj{DNV%Z~f9f*0xlfZ1_ghy(Y9)kc7o02Vke zapOVA59uK?ieErR9xUPoxZuWv=JX}}Fv=P=YLv+BZO9M2Ik%-bm(hsxr7|Oxz`|fm z88T>B&p|-s{I+yqbW@4tpPtS;Mp78Nwo|}8emvdu0+cdqtScGPSYkXAmzlO=9-I4k z?C$3AwT;1T8w1L&?c28>#Q0~hNWi#9Nf_q>d~o9@;lg#n4{l8N!wt?0AclCjg*yW` z1`tEI6HcruxUfS7UbHR@2FQzIe1Vr#A)+Gu;`Rkz0#Zl|w*Z&q!^4vY2wQ-Q-S`-_ z7@*a$W5;Gp{9FdCAqghjEsym z?4HYGecH~QJ7+Chwrmp`&Io&V%cJ{j~SFiqh!-fq7{K0oU=F*@~Q{4f00obH(ZcfbW!*Rq}IWbAE zabccA5&>eE<522bxiHBGJ47xFZMDo&)=TRJ2kW-uz689aEd4VfgxTr6z=;Xxg*2k; zf?L2#Y&-Dc^s!9PSmw53@n9I?59a3P_U+%d@B1mq$scl^hqIU%SH!DC{8mw9Pypq5 zd};+ziH~@*xx`3BnxCOTbc_KRmlZZ<2ODl4#xh#TToYl81K4;z^+`=jdoibL*U#`0 z#|xduei`NoewZ@=F#Pnng(Afd8*>qi1j6CQ4|CNjJt1D^Hry~W_eG6l#RjC&F$Df# zjbi|_ijILQl1589;lALP&RgB^gFvu1Z{7?dD>wWwR`3GxIZdqSy7&PW^JcxIqmMrN zo+gbOjpMh`(F|znp~|YY0w+}}|MQ@jR*f1B?l|Li&kjQm7fM749n@^Vn02=Yejcl? z7caJGD6x);iwY?rF`;k6v<4rH7&h$LHf`E8%g@g*#JrI?;|s)4qyQPt&Jz$rIE)p< zWKILb^ttXz9o+w5u*NZf`D=o#JPN`JcnJbahtRpq%uH33h>q|G_a%S@V&Q@eAs}o! z@X{XyxUSBfJ9p{YrOUs#zMJ_W*2mijz~#ar_XAeXT^_v4j$uw(e!_Ga>@wIDO=G}o zT)M}r8rTZNcp9s5jc4W>=V&_uiwcXFGb@WtOiCKf3jfas_UktSa|N;fKuqQy(&=aC zVUEf?MVtVa)h%;gFhDRtFhVc``GVlWRIiXnj2(a-l1LKkb`X{7*=Wm_Enb^d?Z68J z5&}8}FJ_aEZPl{ne-jcD2fKi)%=0i^51N~yo~rvvt5)G*!y#epcmL^O#$7=lLyPL6 zh26Ns*cHI?JQo!xW7-uDoeAbdVnRa4MopT0c=+()m+acLs|cz5ff(X3|6pTI3Ku3I zhPjJ47@Z-pijuArk@;^2U_sTSBPlWp(hBkl5~EYT&{`@4fxxcn;DtC=3aT)0T<}{t zuMs0goZYxlqqmr_>0p~(th9Q%c!HdRA3xq&DhRgxR1At##+4Fb=4WUS-D3a)mPfG~ ztIDm9Y1csK1Zu#$QnI_axCmoEIk`cDr-lz7elyRvV&wG)V)|UvK@9m|bWsw1eU8iA z7c3BLu;apzS2s?@NJjwXq%die-UxB)h^!;EmHR?^>)nbF9hm^0UGPjqkIoCMFw6Gm zG)PT-9uEc&$TjRLER>1o=n7YkiieJ1HZoaVKJ(vDAUY}F8ojQz*|{r5x9bJ%>4laU zEAXsWiAhaKxqH}SjQ|=4- zfy~lDxUJv??h6DFV!_t+UMR!Lc?}yj?AX)>X-{)hJ@sG!MIf(2Ea9?Lz#$-|o`OnR zk$$05BvcVD5aV)U>ZhcP#Wo9BokTjBYr;(Ea}i-+Gz7%l z)!AD9xG;a1A%*#n{3^P}39TDhy&_SNwGiRHq!Ozw@~$2pi2FiXtLP~Cg_y7*tMj&q zvh?)y)P_x)J`oRE>;a zJ*Mc;D8O$~_vX#Ny)<>ZLVk@MMo3 zJ`POH)*PZj@AF9WsKa^s8^3dq=~>Mx&V~)C9#K-bGGAPnE(i2p3ivF*4-YB9%%bq_b9A?-1Np-It^XVZ;p^eh^dtL3A8Ec);NLNl90h@BxF~ zrh-+Lg7k-qwBlE`doZ{js&`4oXDAT$6kxCdsH&GQUbJo_V_f`VOA60;mjF%xMu7K; zoz$~u&yiRd!<<7tnR^0S2$Oj#Ho^dA_+f6t4`bDZxk4*;=Zn9xcE|u`SFwnXqPUYZ zqP!Qs*gE%xFc3xLZAk+ng8PD>%TGv6NxOqT#7@EvdzT!@79OUDbVyn8)={jqigzVY zZ&K~;2S~0;BQAvki01Kr567EY_LcJ|k)={`Gq(R5^v~UYiVB;s~FNB1W zk%@aOZ&V$DH-_gSR4~Y@NKe6>K)_4t;xaj(CxrwX+fbn9Q-H^{b$t6C>oNymyCfGr zWrA3g%xcxD)df(~VE)P6194e#IqgfzPG3t)Oe z-7Vsy9%kp(J0kHqc)=}%LA)Tmqy-Vhjj!qX4RKW*gOE$c=O}lq^+5rnyub?&7pG4e z@Dg$wyOvTwNf_EVm$~7w-Tl^*cqoCBEfV76FX`H~YdW|voHC3#C_hg^w*zw*bJ*94 zq*d~=>lL$YAVH#7ArS0%khF;D+w2Q&!d>Ce}c_DRd)^hOK`5 zWJFo7(y^b*(6dCp+irA4f2(VC3k3jbLMQD&%aO(6wqphL#-d>&KB9BdL4*rIVB2wD zU}5nVz|t-6S2>HfO~iU0gdz|BbCXHdc3s>Vm@QXCjRP;Hi@Qr8kuin>AyEJzW|cTR zbHiPtYl^r=o6Hxy{p%$rp2Z;MIyj8ef{D-@A#+vcFXpu9vyl$Ue9rI5Vke0q(hfTi zZWSXD=F3?3f%!^zNTI^|`O1JsTUkg+t9MqyV1pnamJkd!6Qhj3qEBZL@W@h}<)w_; z+2VG)AAs8jOCE-Lh+4Q4=hm%T>DOO>C1#_kcW<0H?QIax$M({I0RsTc%8h}+Ct-Le ztc(vM%ZrVyOkpN(Who%zsj}rPT(}TpT#YR$i}y#-@4x>}OO`Cbu5}tXa3Jw&phPR1 z^}kTBc*eC?q}zir*s^6y=$AdwJb%=IhX_C)1i(BA)T@%`5~h%Qyg|a@GJ0oaWp(8? zE#xsC$Bcy6H;%F|4EIbjr&dv%jSCon^Yd+@JVC$`#)NW+k-Q3eNLuK@_;*M+3aIF< zr#P3xm+}miSdw}UF0+$yt!b@(;l5z&ac%`7K3gcx$;s)%K-LmF?(NMGWmo0#gfk&@eZMDF0(_&;; zVa@;%)K~*}VZLw(K#mv6SdvUSjK#n?ylFh1SNy#$(Pa_Pqpt=a>ziA_jd6d&y8WcviLKpB0-I}snzNdT4=w1oT8Z4igk4}%gO4;l}^Wjv2SdF4UK z0}f@-&7VIX1gEE;ewto-=_PvWt+xn(1+EL`gAYC+exSssz2e#`YSye7U31Mfgg0xr zjsErwciE;q=M)HK9HDe<^TEA~7_)p@3f*(hJ&HSm9|k}%Y0@M*_0&^|FPfpbbLXlJ zqgP#Z6^$D=PI2}CFdqMk%em{WyA;5w%r^fnzx;CIdmnIIl^UaxM9m8~YRMdtIG3$p z%)^069CKbn`Rf?pkfaIYh%b*x z>?#c;K3elw!3^A&q+yUq;`rW&vcHnzP+LIk&=~(A{rdG&Z_2B$zM3XZoJhEn4{tWS zIoGaTOJ9BUm2!in2GAXT_~8n~f@z!o7I?=3#Ehvv3IM!<9ZMJ+eAX8I@y8#8@dWN2 zoE63ro~M)t`-vx>P~85bk3Nca4BulD2=g!wWMBXJI(UA!+nm|a@Cuu9F4%2Y0(B?>`loEz=c z#hhSWnTSpJ0kp>wug7@UFtEL1Du6xM2PP#T-$^H(M3-KADRuAOomh0G-+udz@b<$S za^uF0>Pal_4GG)ZLW$2m|2!RY%rUfn z{dy>=6&D6>3_pMje!4mNSSDB7PNb9PAuE3Wi zQ8X%$_{c1#T7|SjZ4gHY1RD>Hxtub7DCtbhCZ!%Z9t3x@y;`r_I!ITD_As<00i7(j zD_sKy5kLuVLVk!!7XfyjkMB`$Qp8D8+j@y1Z4n`+mtol@TO*!H3=(&I%5-5ApFf|XZ1KnXWtzwyQ! z*wWzP;JgyCr*Y%P3gCDSTBDR7pe2%m*piT=I8J)6*gt${q zIfYI<@kBTyYS1rF-vDM2t*!1A?xAfZyMEnu*U^|UWAG8P5+gCDe*E!Aa~pikpQDU@LaFjpRoC}9p<%6*=8ZTMyFQQ$+2 zaJt6)BLEnlff)T^x}S|JN>3z-gS6%15ntIbD8*oa;a8=G`>2tkN~<=N`KJJYM7SUs zC-Nc;b(}DeDDKLC&HiH*aA`@r=8P9`Rd8e6m!{C&fdj6zP3>4Wd)=E;s@ZFZvZa*^sTan;Ppi*)iLZ?93zKXCtTGizUT|Xk z#_`&DZ`Uck)7F&^q-SHp-nj5jP*CJ|^?ZCjBx#wk4F&2Z1!TUU_ntZ9A%!063FJ>B z<2{lQLiIVS&t1u(&vCec0l)%@x7vLFtIs%VT04Kx0Om`9Z&$b;1_i$Ehg&Cr5C)$P zSvocOV76wWB&QgeYQL(>kf&q%jmQ6bKsyJm4a8 zQf$sL#O7=sBI;!ux1oTcK;$W)%|p-D zA-z_84kO&^w_<>vHyrMW0GKH7(Li)SHn4`H!KRFwMFDL3Eh_Rp!>wlZz_eCCOhidx zHhfXWI_IIt_m#G?;j#}bsB-iz6rzj^ssK)`Bef7nY_}r+5EeDqI-I00YE=@9DnzE^%WPY6uWlsrH3AUjxN67 zZ0eoc%||YxjhnX6qffjfi51wvn_*SHQ1^m`1Yp(%LV<4$^W{fp-AX@|L_kYy$!GOTc-ZU`qD|{|(KT5= zQ(nw^>a*_;iZ93amb{mY?fLZ=Qhmy%r#1|w!_u;eeC$Tk+w&by)ZZperIDwdNG+N- zrT=~NBR%)zv(&#|F9u_xu3b7&B5!(~J8vN$pVFQhq^77-EiSn1Z`3X`gKqfSmGso} zZ_oz*=JKsqpQeqQx6ridGpSqGF4U!S2U@pbBY&`4!r$1fp-vsM0PvKTx0nt)Y^dUL zwr<RxGVtwU*{BSV+Bk_MoixnY47-3U!WI-l8ScuP@F!E2o{i zc2n2R9ckC@-L!7~M(Wu;M|ErV>;?44wAu9cyKhtgmX_9l%UZ$cE*70Xn z8T^gtX7!oNjvYJcun~jRsS7K(jjPwJrA=G5(K?QYS-Wln&6+b$mEVE;Z%p)4KxZ_h zwODY&x1HGek57kSFsB&@{DPR|52qdHF3bZ!)(vB_BEXGRX#iGyh#7X!D?ivnhzVdD z(OG<602@Dm5Ppoj%I37}jg8??gp{B2@MnH5!(}K3r&VF@bfv9Zx9-n%9*#O(TfDeh zc5vcDlw&FkND;u4P$~Vfd?L-6IFkyuB~rI_DOA#Ywc?)m%ve4@KbE@B??G+nH=~jT zD{0rk71X?4YpTb8{>-<`ZQ!uC#*NY#9CGO&k32`Eafx)~;X~-*$DXIGtacQi5Kre^ za21_@?ioA)l4;JoJbL@xf76%a-lOh0o$2Hgj;4lbsZ>&0M(2*cns)FRWiP(=9`)>z zL*M@JD?RY=Gqh&)T6*TCw`lE}HT0kVenHDuuH|px8qt}fu4M4qPH(;Yu>y|l_HF5= zTkoZUy#@5_i*L~phYzJY?)e9O_1#Z2d-go~;NM>`aJHeF?-)y0TsoTTd56CF?q@pv zl;c%5XU>{WTefbeTW+|LI(Eq7K}&S*1=rH3b5En?D^}ADH{DCU`}Cxdqpsp>w6@Xf zZ+=9DEG{-_(wI&ec?oUfqg^IVoz9_nhKpKvZEkqfg9)2@}NWu>;R`Pg36wfErlDP*)jrnHt+D z0A9Xpt7HtnBW5j`LQl7RmKOJ&MbEs_n;v+#E7dFF%R=0>7RQ&-WnZ_YXP@a$O%n3y z`9ZJK7t8+5uNnV!7xUyj@0`==r(Y(~FB7Kl(Yy&Pa`m7TerU%ZcNG2j(?t4}!+YoU zWDc#FDhx-jr12*i$;qzIlbSVcOeY?HGy~IkJ_WZ6eemw9bkPOp(3@|6thld1eRAnP zAH7cX>m|{cD=wj@pM02RGN*LlKp{2a(+XaH`6+tm%@^pi&%adz=!(lPqTF6RXy5(= zv|zzv9x$bJ!Kkxn{AVA~uKeA6U}J0M$m-Dy2DIOQpH63=b(*J>iS-g``iwa=`jWrV zd6^fcXb*Uj`Nb8P?q^h+8#xF3D={%dsFDJL+f z6)~q-#GKw9YQS&pYp%YWTDEB6smC~K1_fk`Q)OB!7y-qrm6e90suy z27{>{0}Qy)SbkgL^KPb}2VD4Ea~e1P8+!TGcc>Acn1Ob{;8rJ;q28FBCapm#op9{o z^x7Nm^INfm4jVd9rNckgd(aT(l)n7@J^JM1Hz=b`E85Q=6=TT2F6Or<$^j>dwk9%Q zd>j9wuDHm(!JP zAh_0XJ1DkM48@nl(WaK$=&76DR|pj&~e8cP9J>q8Bg?L>eL~N5}3uFzi1g9dBjjp zPax)9dD;1N{zcbOe-_84PM<}0-F7`4e%KH?XY^Hc$>lfDEEY3ge(n*P^!uO8j=NZI z)P*1MF9!88aBSYTgT`EUE6tcOk4``Bcs|OdC2eOeYv!E!tfS!XO1W*w1C|~jQ_i}+ z64t4mf8H6?d(a8=w`(p@U?h!08kVN{!czuHHZ2&K+h(@nwq8Xk%r(X*G97@c(k3pq zsHl+6J@aH5dES+D5sQqgSnmZr*(w%$A9?IK8a8wQe;nMH8Z}IlYK-lG0z2||@C$Gj zi`|VWGb59qOB`+8ww0#-Ih9op-TCE`;h>b@lJFF)Zv`&+dHi_kx&T-Z8}-upJLVV$ zBb=tJj+oZt!s)i3iIy5f4`vDW>4jcQxG%dzIzkJ9#I~mAN#sHmYeWeC!cBW=*N%-; z(7upo9qZ8e7tg?DX8>HWZl(MH_1kY9mmr~}?PGoK;)pG2~*n4lGwUc--cHTFQ*;(yXXj3rUTSkw``%n z>Vosmq-IT<@M1tVrMGCVxV5+c`7BR{R{U09&SGwoT71wucIFu;($Pl@^8|sz`uM$< zc+$+^1&NMI9BtFOCB4m@70l5`4r5(iSJl>U$A3Ujq)v9GHYSX$6i~lqDg_1&z8#b1xu-edV;W!^ziL@)+ zJ*Pb&CPz?7T3`a}w>& z2k+PSfLU`3kjVjX*7(Z$kNR~W_5Yz2#nxj*bC87rwafXUmBcL8f!z{hW=<{&`QUR# zJ_q_{O!QI!x=5&m(;B2Hb--UU|6;vl5_8Xcn8WYtIcL8r&*^o~RnNv&p&q0xt3FKP zLa`wQ=H=!2oUT<4VA2TzEAfjh;gB6AEL?WOxQ3Lr{veg7#8L^bIy#gf)%J=wX20Ti z8%22=muMKSHkon^1p-kZH6>Lk?9*GMQ~$pGl`!9 z%6qZx>H%}Y`@DRDja?o+4ANb&C$mRvUXj7B{?i(Wr< zHN~@FTFM~iHCZJSc~=YW9z}L-Mg5>^Zy*7v%;Gd1~xYExfP{e z|AGCqY{fFlZl7I!4XnnRL*l@2iXtxKgpp0G{`z1ABC8*Hh4b=P zPG#d-^D51j+!$K0r+`-&9b>ObyQN7H&FZzEKQ3zNvl;n2^J&4t1?p28h{3&cd#lwx zYX$(r#NQ`UZjW5TN)iAGdwZ};8GFVWrZuD<-Fxt7J?m)Ax-}Hfn@3rHpmZPGwr``n z#d*BKSx?Mys>A`olSju^-=Y&S-VEnlMtVv z_LreuSlPlB3w)IT4gg^hV2Z7zF@75gKy<_kCBrpTazpp)iRM4xYD%-wK`jlnc7BmfJhfX=h%9~QRn5I5!!J81uR_xQ6^2ZeZ3}*`!>?=^KMBr`; z_7_mwjJ5;-!FOc*B2WN=56BtRX;A+`_5 z=shrCu`g)t`nA*{tAlNupd&#Uyb|QmlN>BONB}IXULg*@wd>XrfG{pTPF-J*tr?}f zV;=yFyv9^N1=?n|RWA~ZG2BlI4j(Tuyy)-}tO|pdvPcb8QJ<4KLIN=NF|c6+7AFl2 zSDI5PmonpbQ)yu-@u~e(lvu2EVTnbq&6-kAaRPra8CU9Bt>lZsb7Gs)Q3~`Vg|`h5 zf*2@VPNRm6l=ua%1v{pT_*0tBojR)lfHx;Nn!H7MN^Hb#b>v-;w}3zS*~c43Tc}G) z@wNpBVzmj^xuqnhC~gd32w(x{hHo!@8E|rF$MhM~JxTD!Zr8S*x;+{%4uE1QFE%Y- zxm?|O$rlMz>sGFPZU8#yRf z!g9)yK@G)f5}({%pt^jsK9-z3VLX6k_wAB=<7CMek~b0xd}&A=B~rfuN7Kf0573le zvnZw{hKd-hCXARtKOZrje&OGbNBv1Vn(U^8!UW1|x1465x{|t|HiDXv_ns&z6SjO> zE^jCR8cfIRj!FTW%%9ufV^shSmcut}+@Qb;00khyV1$x3t8JG0JcK`(SNR*HHsBAg z+bM9_&8J25?A}wwFJ7`(ed`F$&6m+dKGcDFA?AXk+jn4};ts)W0X(~O>Y|jw;0{p_ z@?z&cz}1-Oq5z(Gm4FwI0o_29gkQEe>2aaB_3t4=$EMn4|D3PKK?i z{5fHZ(K)nvV*$lH9LJo}UV8W3@pLe`h+E2#7>@L@Ak0AeM85Mm^h z_t1g0Y12jl8#p9{K_rF908R-aBt%Jo64-kTYKV>C0>R}W4OXTArT|vFMFC#Wi|yLE ziw^Jy-q5EYFGNeEDd(?5p!Y%^04Kk!tX(z!I!*!1Qzn5I*JS0o;Ai!OR~nscxO){B zNLSWG1i8f zSOG8qY!EN&C)KC<3+5{j0ifYZdc0{DFI}vF2cU#-aBvG3E#%L1R;W#k05gcF07d9T zpwEKRch%}uN_>ptJ#XORP!`I-j&2y_hZu@BLZ`McZ=tHYeY^H5Kg!TKILAaV32QwC zm~$$J?iBiKUR?4CQdL2Shya*0T>p$n!kpU7g+vOwyqXZxD4tS=rPF0J#w(l#d3&As zz}*ZUFj#%OjTJo@D8gZ&gau&fpa3^k0$~OX7<5Q{dV0D7EesZLYcK$uA%li^)d78) z7>KDb*drtcANyKOhwKW)Kfn)4eQ;eOngDc-F%)pZWK<`W!m8k4-AO>u0c+{B!yR1-v*gyCYkJJqyfQL9l)R8tZ(@SeMfxIVI&uRu~=u9gs1G0)_&$g972)a^(eJ zkt7e4&-mCgP#xH60K>W;w5_XI)Zc%&q{{^!TI2F?H%xy8QCX>540^pa~NuL`$M&rkir#tSrLmgjZO^PLJ`cj@ zH=R0lBL1-5noO06bO1-}fagQn_-3BAhonOQIL}3k7V*WfJNUeMKJB7gH^qfY;;mb^ zs&k;kkK={$2?jnB(!WVtwQ3cuUcFlF+DBbzn=yt0;iiCaUKo2-B`NvqLzQu0{u+U} zs@@z2!1(dUA62tXJ@r(&;DQU3d)~ZxN++f~+P`0a{gn@e!ruOA(E+;Pg?w{Ks% z^UgaJ2uV`pKmPdR33109a||7M9k_S3Qs=c zFcgRc1*)4FsTK|_5`+x4%-??dO>sz~_iEi5H&iF8lNrE;4H{JOEfKh>bI(0j0T4db z88Kpn(wohiHH)5n@=3*U!NxV{=bUp6EnT`)9Zq=Si6^RW9U-c|_10VJl!uQ${#YG& z`1$9b)A{G0uRh$yF)3ZUc2(RR$~^D9^Axz9eDcXkF9_YB7_=8$9m4PiglPHGPd}+J zfF*x>O6VIzVVoNU;KetO#uy4zH3i(?K`Ye|-28c9*wsW8Goz||SIzZ(_St8u1^6ny zfB*i36J~q%#36@7Uw!qJ7gzPe4?igI0(iXt{`-nUf?n#3GtMB~fA{_O-zy;c>#x5Q zc%h8P9(#e82ws>s7ibQ>LifV<0x(ci(*~Pfkt_{qe^iggA(>5FwcxCEk;# zPOo_P-FH=4C==#^2OgmL^XDrLaM`kD9-SCCJb)Fr%EupnT-664oik^SE2H^uC{Rrl z@OPj?Wt&tb0OsWTM_r#&*-iz@k1MD!*Uj&`AMI#DFt{fs+4=FTUWL zuV*Mu4crt!1OSHo;Ecq8D+1@0pPx_9JoAi72Y`dl3|toKfB|O*5QHd*qifDQ^Gp>! zckW!3hc^-{-IxmGf8f?KGBT8&3|yFSXDA!(;N@w$@x~j~J%OkL;-oQ#0=1O_Ap;l# zj_s;qO&}Dw6o`8;_)H006@EC{23!`-&4P$0=CspJQ=Ad};D{hzVygvoPtaFEtVBNO zvmnO7eEs#;O4LL;#G_x8#wuc$I`#+WgN0@XzUoJbSNy6dD4Oa~|Ertq^Gh<}ef@`%zO zK|l8M&p*@4FTbp~94N=J;)fq}O(^fvPd`;@p+9@=wbvA|L4*Sc;Rn$C@WT)3mtTJI za80Ol$dDn5qY^*^M+I&UKxMbWskajx-|MfxPEh`T^2sN(aN$D5fnnux(xgeMU*CN5 zP1Nmc)B9lDh60tLKu`b{&Re-F)9A|N1?XUM!vG+lgA%R=;K6;QHEY%=8zLY?OsrS} zRIuq4tAGF`h=C71^pMgqefQmWO02|cBR++?_S$Rdw%cw~+btF>SU^ub^^^iG?Dz+e zb?%H4UR~y*i!M@%c=5xA*a<*`XlXUNn2N&SBt%b~*oqa>(W6HzkrwH7z=Piy zLxD(9fX7Lc_~ z*w1A(*z1K&qT9D`SK=aW06P2Zvz4d@fPs?z@WT&RM>_*RV6b-!E0|aez$zgW=~rHP zC4u{a!L|mN4jnoW_G)3l0_iU0Jzm&12HjbY9()fZZ%_pX2m_7^%6b@`V|(YFcho`x zL{_vF-*58O>vaG9_bWg{8^B=-2Zy#BV<=EtDG-$$7>jFhEDmkox^3Gf$ji~@HZ0mUV;fIy}P5OwEOqWM$n4^XM2pQbYfRa=}4?6( z0@X_aKA==JAY2ksD7`TN77Eo&9zy{`frwMU?l}9gW5;@}bQ%DQ_+u~?7z)%K3OG47 zKAhBuY5sf@@&GKCrngogsLA%hp{$JZIR<_@h5Xt0(4OeU^+p9 zamU5RRq7!HQoS(szA%DUfpBdh608Hh62G-Al!Pg zVCpyWRxs2uX$=MHCY%d5V1_Wp@5-4&7}YX zqOGXvq(_wkFeep+nub?9%J`$?Mr=34N7cp{3K$C1ehTo3EJ1-;Sd{pD986G^S|5W| zhUV=MWqdM2lMdP0A8=eY&WAU~P{5xO+PvhdW_-BkYSeHPVF9pUNasX0=Fbtz`AC^m zPTQW#u7|-{DTEBBfhKKKQUKspR9vL?_~~N-Gbxti5)u;4{=cYva*=IRr2s74C$d_) z%D7ctY6+_`UQ9B1O<{uJj}>|xCZRQ^E7jgmev#3-^=oMLnw2h~(r5@e7cqz4rBe>2 zw`i#jlC1Uy*P#aBYZ~5NUu}arXaM8$tMnHj4$brO*P&-;+f@*wUVH-WFDW9vKbw;H zY_P2d3TRK^0cx4jkWx7AU}<=c$hK`jEenk0eSJH3<id&1}cUo~-sRFyHMIc&#Cmk=<<(u30g%IIX0c5FQl^y(V|N)ZaL2%Qhascr z(vU2DV_+m**KKUuo^WD26FZsMp4d*uwv9<9wr$(CZCkgW_q#u?^%5GT8@4#Mjr#abHYqSTL@3%FO0Y4Jlu!fQSA9~C(7ArtJFD9DqZ19CH%R9 z$MKV7C|9D5X^=N~LWA0~h-|M}U@=@pN8}g6 zPMwpP0OrMdzk~(VP3?M16i(csO4pzwz1Z&9mC#8DI z$x_|*pUI}L5rrxvIu7@yrwd&+95yR0@}S}X0G;Z~5q+kgsn?^P)!}xNH=WH!i=IEm zT*JY3*&>~}=NE^xoQ2R|9_L(O%1dL5LJ~Y}%fhl&>d0&2lJ{pEyBx6pvf5;qDtCxb zg3oD3GSCZ@KKsp3mf$EQD3^-3QZd+7(hAZrOTB{bs3IDf`oXirMoWWRB6$^Uh}5CJ)Bi@srda;>ZF*afQGJjC7cibRp}|u zaJkx^X_vSrL#M`|`V8rOzLv;gtEKSD>ox-veE{pF-nI<1A)wVlpE^32@7(%2IzNHR z(|<$J87Lq&<4u!gIt8nBF7H0Re}5&c$w{|I72 zFapsaRcNbdC~AoA1xGJ&aTF=M4*(-3?sK)ss@mJZMjs{^cni=?8n8P~tZSP$hpNGj z5lF?d-In}|$C+=4OL)QuC1|hSo^AzF9J&#WTN2VdTEt5k75ee(2OkYkh}USlj0Er+ zbEB2*^{46-qm!1i z6>8;wt7}OgO9jQIu91?l5{<@*dcwFcysI5bun1!@G&uj#fU4%#S;AWy^w$Ra2RZ^w z?p!W6QoK%Mwb7oW@5-X|h>J?(_KUb)ezlRq=030cu2)939D4`QO+#_GElK3IV?qdk+!BQH<0iuVQsni9Zyx90ddfC4mT!g)Yl%GrpM&lX7YXDWkeZ!H6ola5}$3(Tu4n?MD zEEZpUhPo!)OCc975MS^ghtJi0AfL|$W2igxgb^LpT;EN<8V5%ehjaSuMwci8m`cz6 z{G!e?zKjQI0q)nEy#QOeZ$TI^K@S9a4q#JZOOBmdJeas$9k zfZzKCw_;|v6qkVk;TykZt4LSN7!dr+Y^w>;*{~T@8XBtVqAnaaxwwn&x2$b32{XR_bpE zK`_X)Kz9;F`K{eNrbtqk$h~|y@ky~*UaiLJ#&k@+fif0~0}~JA<72c~)S#1&a2n!=Ubar-(rz@Bf^Ed&fOKuvp9A$#DlTTkqC zXfOH)!yl|R8PnMqpkjMNbE;{AL>^;PubmCF^txl~!)nCg;CtF{`-6Kj3%+V5-8=a~ z)~GeTpoXB+*dLN?yzCm8`-GQ(jtGsEb+i1?%13NjgfZgq*%2_b-{-U44nQQw4z*r~ z`YawF37)&5(XkIr^fBnl3ZNDmf@{XHzQ^Xq+-3w_05PvaC$>ADgsDp6n^Kwl?|G*JzWO{>t7=-N%rh>!> ze+bk^d6<=}&Tn7SA;^e`F2;SmpQ5HcZvMv|1!M2d9DgveZfO#(GtB1~xSK;Z4M1m0+*T zx`;4|TeJ`W1>@N5)BXLR`^=a+tni0ABXhR@{GwVX%!Asa<|BSjzYo&BN2wlO$MSi% z*ZRASTqcK{NsXaW3TVL?j&oAxaYG#{639NcJ`}#-(azW_iy6BlP?4Oye~2JYo!!EB z7=o6QPJ*eXsHm6?^yHaZ$^Agk89QoMPLB49QYLZ}RVM{CDq+$H#LUXD1R>MKYy6iD zu08LQZQeS$Hd8(vqXZ5S_)Ky>T65VuMZzdc6H6im>VVphXH*n4T4ofk7IU!JEGL;p z+ko}4-6a*gI+N?^s6Q6z{hnc zRq5h^U`7?pj>j=23&|+&x;0K_$nTNcm!YJ0e+NGwl{&NEo&5hGEC;O{08f?cPA>mBfRZSu_ zOL?6~1N_~1`0uIFypXFS$9 z)1~s!>oYbK8#s^Z+t&)&OK9!;KKE5j?f`4M+9)NEy3 z3Ca{kd-_qi9-CjqNmj6#SQW#R%{JllTiRv8=8P{0%)JUnlSV?2Y48%>C+a%32PIBxTJ}rBt^Duvt{7ozAd#DmR?FGJ@Ypd7E8X96Ux3Z3 zOUjA=29Kcb2}Kbvq{c`F2{G#<4ji)G?&^$tt|BPOGgC1u@2%u)fgA=>FB#(g=1cy& zEa3lqRLFegJZD@lHyb?Ax9|E>58CX4dZU+g+nrU_eGU7KOY(Rb@OmftdXG}&QhJZ- z&og1m@iBm@bUA+PKLDT=aA~R4W=*4yw;r9rX;tNFzF$_$eSdU=I9Iv28OGoK{9w7U z=3=#o`3D4VBYvez*VDx~MxE?wBAYeSF3ooM8K0wG{PnSVyC(bEVndFCz-!7Y;mzMEBZpI8xAae?M}HAwg!cY< z&5OVQI~+*7>2{a5*YF-?b^FJ`h}qJgxs*z6J_(`yEb(~&@W3? zK-MHnsmIc)grsv(DK_DGN{FQ30So$#$WXa1ChW-**uF4cbh<4ZOqyp8ZMt5Op9$4OJg0c2 zyf|!d{nRRaAfB-Usnlo;up5+D0co&#=jcNmYq`M$u!ohl@;fEVUp9w#qYBZrdvn}k z;XhW8=XpGzQ_psMb&va%4mWU4T^ zAdUM(KxZ8Hi=rcBz>Xmtesk^w%;6QGZbwx>({bKW4p6y2m}>L})%jd!cMfRlskEXH z{~#2dY`s681L_WvcUN@vZXScZJTs4xC%%qfze9N zzXXHy6;W>~Pb|{ZhL!buy!wqp@gt)XV;8?ZJw4s4-34hIipT0wBI@E5`5dOIU9feBq}wo@2=OkAWj0(LDeo|)#0 zM<=zc=6S#mmj1d3$|K4mXsJm$z`$d%4?`ma&DhzB0#*j4{mmh39J7T+H^Pe$bbgQj z;Q8UmRtV12IB8yOkZP>FH(DQyGK&L^=FFE+|=vgqL?6tKtF=7^-4u|1WlkE0S1(M7f!GDn8E; zO0ox}6al#|mk_WHt&8;PC3*G5WXlpxOOOd^i2uc@Fafw1@G8lMrR~C|62>!-D0RZ| zM6zG7%0>UNO#{@5i#?Qt;V^!;$J7y>7}~T>mh0X_du-KGX4D4MiY^!>3_A%#;t)Lr z_Qv@CaZhq^HxAMQE+)GLl5BP+h;2C^9RIxEpO@Rt=L0E&Mh&P9MEofP+F*#c)Sr*+ zzu1_pcht&35Vn_Y;UpUcNiu7V1O8XhtNp;$bO}^%30DNZJ8=6*sNVu>HpYrkVu7&( z?^p)e^FsbvJ< z5B(2T%ao2Zc`ZKvi@?eGey#-xpSKiOd#_9~$dnLewJj|x4r@YxNCnJ6oRms{>?QCE z-qZBF)uDY|?vop;ol@0}sk6#ADek0{Doz0LA0eo&hO>c}jNB_wT~F|r8zv?y`BKl~ z7mSq#^vrr0J)&Phl}I4L+NOKCxXJ~}A%0z)Al zmzIXZV$|!1;7q};6%;@2%Ss6JpGKuRY~ZtM`yUyomzC6L|Gyutq!+_LDm)e{7TP@* zyW$?Hm33EXM;l*}2BaR#^nYKkF%nGvL1%H*7~Eh{%3HZPSBO5(PxbrHqjq})A;QWi z$?h8xG%UP{I-TFEw$CAAX?6_cnW*XzHYRpvrc+tMPEi$b&65?<3&$ufrcXYcsJS_& zsX&XVsSsAn`=Xs}Gg`z0JiRW58M$jmDk)*j6=KI0{Q`e;Z#4eu6I*CgmFfE3R;$j% z=S%z!@z?dvfz9irM`TY{$XVIo+dr_u=n&5ZpKF0fm*pVa!tvM|Ofv5-j zp5wvU$gWpFs}Vq-e0SLC;I;jyx$5tWbc-se#hiv8sf|g4S z;l)uvsr-Gi6C_4I{B?_Hp@^DxS*l7b<@XnKa!S%{*lytKlcwEp9!t-h!r##&jg!NNP z+HHe9MbC4eA8`2Sc5<|S{cQh$d=kleUj9wH)PfC(aMqMx-thm zl%`sYC0Q(#{KkuZ-@|X)eWNqy4_tWAbXpYhIz9ANsyCJMxap9J6$DfRjN7sQoULh; z-hOWOOn+`TO)E0iHl^F7MM~vC6Z@oy$MPgrb)KQ&IbB{ptRCyvzZ)$sKjL%F9;WIE zk%u4_TvR-HC5Z4<>Ndv%n_!KOdft^ot&t*Q%}Cz;Y`Y%;cphu8&fg-_GlJW1VMN|1 z45~xA&EGk7*ev#k*Ir3$telJWW}JYt+u8=eCRE!&!g)y?qpi5MK}4i<+Paebpi44S zYEz(o-u5?>zrgo}?%9~mzWVmpNY>6Tz~|(%#Yvoh8DZg%oh1%Whqx*wvUg%j5-cim z?eLsAI!FV>o?s_BF;yG$!ymfrTyT*Qr@$Y+m{GtxRjZJ*xIczF6O=X`iI_vk!ECe5 zwdj6|JCWmlu$uMwV78*wW8z9Z!o-ItI6Q(4^3LsGej1%}cI=Q2NUI}0JY`PLFJ1D| zG^-=4y4Y4#{I7ao2lla5P8d6 zDm;Gs`vqSgZX@C7`0%$Bqfzo%?DUu-QuoaN5{>(jPlC`zQ79H7KKs zwKunLh4oeiY_xzcMYQP@UFhJ73?p|=f5u#J{&eoUMq&KO@WF=n`*w+^JhsC6c?3B% zDofgV46TfiPuz-Uf*-jfnb86JaIhy7;3TgN>2 zr_;mIIpYnExsbl^GkoCm>cf*&Rn6PzV>hSRg@5%l|a8ZSnDPZQegLNy|TE2z$Q1x5=5m|3_0vsm$3B zs3Y@zIK(ENg&igq;oNc*lzVl80?L&$1pwcwXY=jQ{Er(}(ujMi4iJ3Fs#~G$Ql$C) z{@~CA(+5K1rAzX+fsu#P*siH5$#TX4hn^rq8B8X=-1@J&V-a%@Jhwslr)5^Qe+Y*V zlQsncc^ak*CMFO7SA(2MFq%3#((oDzb$`y)3P)V%N4Ty4BlK*z{R;lul=4NfUyn3~ z%x13X5DU}7+-S6Qsd|oh-;pdvzO@UqSUsO=7)fO~#C!E$RB@c!A z^)FB9LCiM|ljb7ZKHrgAH?4<7-LrE)=uSt-L*}vdee#n&QL3}O-u|@h)xj^g2WDF? z1RHB~H>TgSDM?o4@2*PSe?SC{(UDD1|y_J3IwTQ*js#82q42VV>cC zycmD@i2N>CfTCH5`!#-JoWk%G+&Y*=g1{kYc(cR9>F`JaG>JZM4``rt zE9DQjKTl|kV{MeC9d0P3%(3xOg(|ppyz4-orLLMpY|D&bJ2tvkQWuXLf_XAXr&fWp z+#wdJAy8n?wWSk5CE~Q&D@BWUW!nws)KlAd_-n3OfpN)`y?|UCVb^~(qs{qBl2gYm zc+LrdXeO1%q&eUJ^KAw-6tR$vhyd8Q6#-z16sXa+J6m9mOxP$Fx+;rS1*eWnUX1Db zI-+_5&PI!yo-b$aNTb%)P4l-0&4*iGfx<)uF12tEw~coc_QT|X{TS|qug6=iw>@8d zhYe=ut<~b++CHtH?}9Mz8S?z6?mWj8$}o{4Gk-siyL0Motx?V=#b@7v?Od9d>q>m* zlWOBqbZt6U|z|E_7F&0z2uosiTyHqb(p^=t392#em}Nm7ZASdfTEQO0B|Fw@ zV1gTf|JyaTT>-NM;rPni0JkT=9*_P_GHmg(>MkVTio217cm)qK1QB+~xQdKK#P?Fx z(9qD0eQSmw5At(q(nlsI%7)sY5Jc@=R5p?8=n1n&$fW&gX#F%E`nnKnGPBHlRh-nq za6P1Td}coQtjUUetj{Hi&!rCQM96>w zKg^Ce!VOdey@cm2k9z11ln{OcHDmlEzxU>p{c*cx@q)$x>^`8s+#IA;S}d1|{93Xh zXU^rE7}>=P6?(XqY&x)@9R!Awyw*HkL0VavZMw#czX)lh3T4n0vlurW{tvu7d)UyD z9Y{>r3xl3}SAuErHFwsDL_NTT{iCV?flB9CXliSsLD3Ayu=Jq(PdzB)4g|kdamQ}% z+DgAO6hP*aO)*D5+ci#!*surv3h!Vt-m7~D@PMda4{#S-)q7eaQgyNsVa=m~ZSB61$3@W7ArGelr z1xiGjFu0Py?&uG4nb|oD)|?I4Q%#Bv|H~+5h5c*5G=N@x;CJc0UZyC~yuSH|z3Hwv zaH9B-0qN_zmYy1*KXsy64*yH%aDXn_LZYAu#~|DmLI2A&fC&s7BpIARE}P_?!J){; z5XXPdE*&F`4IP~sr2jOMJ@{ZnFeOLdf!ILKqS?Z1Q5l4)w(Gsu_vAgtM>%<4I7a*0 zE6%pnxPqsi$RAi>DXjf=&!}p@WzdRi9w?9huWQ>(-@PCG>k_$pPIY-pIF|nrjX1}v zClM?4OyF)H(hGdf8ncPqx0v?6%*w7%pGx+(A@HmtHpZE4+qOub7mGY9J6%Vh@Ywlg zZd0vKeB9PcfHIQ^=bc0!OUu9}?-n1{)(e-jGe{7}B1z*>#|I(}UN;_$oQ*ZKbssu9M z1IAy+G1!Kf>&zf+ph~HG^jXHIq{>BPMI@H5GA5Fc`_828vnuq3r-hLAbLwN$`HI_Y zW}DbO>WES2=jwSBq3U~&{Tw+mTD4qFyy-p@HI;mZZ2j>>5whS%Tvg}O8qfWWoJ3$g zNK5tXagLa-lcV`)-e7~pIERbpEMc>rgjYPc_xTKt=(c#-4EShX*dFLk%DNtWVRaS>%i_Yx& zO_A%N2DY82Jbk_XEpjxxbb*Wua{rvW#xdSy5);qv2ifQs|4jBimRKqUhTjg4s1#wM z?)K2m|0|o~{jBab2T~SEV}bjB-L?x=%hgm}&}F@W6Tc-Ku37WfAqdFYMh#nJ- zSHf74oHjKF=`1)UB0jsR?Zlveqk%kqu?&^Vv@xoFnb*(2wY$RcldEn)S;meJsKJ}n zckSlOf6HI5M4N8Yl}TgI@?%5R8x#V!&!rE~@5Duva+!{=Qc3Ii_}-tFj1M>a)4z?3 z(6$Q>+GdMsM^6n3&x*ea$=1bGn_|S$h@rM<`ru*if-_o@sY~##+ zyBXxIT8PWUql=dD=2!w9dz@LR)VSdQO8JZ+-qWNjE8s2)XJ2hOzF+A+pO5N1ZzuWS zYTT#Kf;8Oh!Qy|N+S+(ZZPpR+2Hl{)p6~6<$D6#`d?p~1R*Tr93EwI7-?ubDHN3pC z+9qEglw&zTu;Th=)BQND%huO3S%(wXSwoXg-0myI9X`BxmE@0+ymAfsiHh0OTns;d8?QwPaRvjXx`DSc5SBOmV`L|_K= z4k10z4pU4fuzxWI=u9*V6wglY?ep{%re|{4ssy5KtdPeFNOuCBi%ciV-dSJjawKq^ z>>twtBlkINWX247#cV)2UlObJv0l)my_j1663@94YX-^C{<_Aq9Ka@zC34|tw0GLz z)bYe+2e!*=HA@$#X8T4B?<%kzMZjxfyH<<|hB0miTlDq>pKsZpKiw+`PNbgtNMxqv zdwySHV`_B0Z1j6My);i8+T<EWT7njD0NpHUqV06?`}xPpzFY zLTBbI1qrqjS0cb=z*+5=S?~w>88bLls$8VF>+gMr5oO)=iW`WSn!iU+AF?X-cA5&C z)a(vx`?JW4Vf{+)mz3SbNs&;B>!lV;Y%(1q(5J|tBdaI*{7Ce2>0+xB;GXB$(|9{Q z<$M-*2wOGHQ$3q64*0PDcNHn#E;LV9KCVuJVG{f!zqvQVl_^`DkpDPaur`0Gts#XZhN^LRcP_;4gy%zFn0n8v-Ybvb8e zdcjp@n5q623(4ZP$q(-r=|7l`Gr#7lBrGKYeFv?%aFOy)8_8|z9S>Ghd!ZQd=Z|GQiJi)?mRl^@enw%1YtgNr~T5PqNiFdw*|`*MZEzPFgse5YKN!;x&? zMBm9;wNuuc5iz*TDwiYQAM3=YAmu>sni)v5YEQ@fX#wHJcXSPYutf(qHv z-)@IL;H*JRiM=@V=m}iLEENLZo{EqKK85{PJvvmuj#9V3|8ekj0gjw=t9`SDJ{>)0 zHaf&C&A#;nLcg+<GmvdYHP($7b_dAj2<|FN6T2=#gFB5(M1 zgEjKpUC40~Dv^Xdg6h5$g2$Lo^@&ZW{y^`cOB5tV3%n+7ce@(c!f|2jN7$NnIXrPH z!M7_<6YykUw_5|Y46v(aVch*ZBz!E@nLf5s%Up?;)`>|>s zJ~;xBAdW7RI3W8}G3U8JM_Ik)?9Nj=6b$OUOUA*EaqD?$8wNQmze|=MLCWMDwyR~L zt@#oNza280ZHl1~bbKeW)RBV-~p!6Z$t zDuA?!sbT)b#4EhTXhd=uk|eCM*+fx46yiVAX#9DA0IV^`a4|bjc-?B_xyk#xa4(re zg|!I?*?UMaMoxotAH$`o8WXX-Oc_U%c}i$LRu$;B>;Xft!*fBU^DrA))wa4cbgY40 z-!^ECL{6q`~Bh=_X zcUq|F-BWohzGzCHa41CS5tGdiv0yukQXVM35cs%dpD?`o^aG(ItjS<|`+lkd6DZq1 zC)$&Ti9>-w+1T9N%vG!q$~C7^+K7suri$y`p?)#`pPnn{c1tkk5MPvF89iT=esA{Ce&RdZB0}gZ-JzXd zrvDw;k=^9P`ZIqYGBOe*@rYFm3-2AyeaJ;U?Be+=5P^=W)*r9w()g2CPY!_jh+_QllMfp)OIbG>)azy*3lmCOAnBdjm zR3JB)f-whUJ>FWhc^^hy>2e|#`_pdJvvXbA^ZE1XyXE&`av+Y-7_&8 zT;-Z;F4jSpn?NSB8SD|gUT%|={C6pTukQoQ%lQw^oU z=vhmprC|Oib30#6_niN1^%cq8n+nNW^Id065r@efSXJ_y|xidg~Bw0G|Iu5Dp4x4+=N4g42RPb7{ZPN z{t|v-55lQ`C#+}Ka__LgsUBPk(VxZsK2mlvZ!D4rNhi_Jx8csC2dikI0GK2?T^(2w zw{vck{9(BO$a6PHL5~oc`J;b!*Hsv6_PJ$o2i@PMrF_aeB=E#Bc=zBsi7j*Gb?Vvb z^l;7x`E^g{%d^taywypkr19x$pCb;Tvcs*EyADWc(u~!vm1WZL@9d#j;%p)SgFV9^ zbxxtGXKt#|m8?w?FN20Kg6sHCV%YU4uf+H7cZ>M74*jMYw=o%G^MrqSns%L{q-XmI z%S+xqLA*VEDyz!5?^8)xA&I0@XI!2q4+S&gMrL|DC5@&H&CHN<)_qzA@21~@#Ltgq z0=*VTbVeNP_X;1m15;)Z(qeBF$};V8ytBoskhPq~zJxzkHHPy@CQ}JSRvgyDr}Nk~ zmXlCK{f0FDXf&L)n^A>}q@$y?jra`%bBB%_t`W>;io<`yopdHphhD6>z#`kaapT=m z=EmVfS59pg;=)CgC@MIs`%yk0$ogWMgI(Sj4bwlKtqzH~0cf_iQZqHb=qt8cz~!`^ z`;HnT4Q-4o8EX7`NW50}oZJ=B?`GnaYyP{nJU` zqgE>b@zLZ9JQMz{(FFhxAcpLZRI--ScI}zDelvPpi%y%~@oM^si-Pe06RfG$rgGaS zjr(;GOb25c*DbjV21fyVAhYRRi&?&8_|>N$$6kKg(m}0R@sE~o1YUW_c0!q**FLrZI>d@MleC-cu(=|%kg zgY^3{S3rvFsbUiQIH%2K@Dc?xenJLJk|irK1Ru2|uhkob^+p3?<;rj)wd2pTU$1vZ zYS9k|HH=wG=C%a1O}2{&G<*sB!w&tm*$!2HJwiVExEjnSAKng$c`aph1k%y`R6p0Nw_^XS#(8PtuA(@486+d$|A7}*>S%%V>=@yo^bZ~KonANary zjv6L06W{9~K)bjQ`OUBYM#tcJsM`vHBptJJ`6(r}K}TyJ`nJNc9b3Ep4KrEwS8Kn% zZ4rg=6RK2csO8-snJ5niyq+>~gJ|{&UGVWs_S@K*G8z~wd)({4q3?^f;%`Pe`ZJ}^d`=L8Nt*6ZFlqaaay^DiCy4kP6 z18*g`&9(JUj}Z|<194vjDTD9}oDqct^gS8y@kg{8T0Q0gtWne#zqwp+}=c;`a1&rNIdq?r1c89-E=O?lj@!O>?sB z<{r7H$s0O8ZS_;`Y>_Pfvxv^(D=gDcY^i(B0xRa!K;2+Ye^vE5AN6G%h7a%oF`X?a zv0SaSTihCH|NP}GIunWJbi_iE$i1@u+oB!8_Wf=5cKtE2J&l-hueGQFc9kn%r#qhLq38YFQ~q{txv92d0HeZcOwD zL!-`=UszaVaqp^AA_nMNQ{mpbYlNdrJ0L2j4Z(5s@+vZNaTlHGKE)KMF0F7_D)prv z)%hBogd>>jc&hKEhTZk`d^`R&3FGww<5H%w;|hNv2moU|8N{7L;0|KbqB?*2`X(V6 z_n_G9U8ln&67(nwqlGnAEoRgUnbs8)(?DBJz_sXp2c;fZ2>tueL7_)^;C!|rX1d+| ziy~3|knbvMR>0#5tO6IjeY(Ir+~HCXKoER?^b2O*g<{Dy@SNe&+U9nS1)}%iNQu>A zNwNrbLb9`R{VkTvVBF*nX*Ilhb-9L`_;o|v@cGFybsQaZM>?zP*~bs0XU81@v+}`v z%aOugH2fR!oDv*-|0FPpP)kQ-e9UXXqUOarhg!$glZ%rRxDC0}F8~h@ngxf?7{?~@ zKZ&;MJc%Q28{Glota1k8=MI}&z8L;G6A`HrI*I9n1ez?Raz9#lL@Ja{(ayN9h+_|~ z*IYF@br+Yx3A6Y<5;DXk}?a6#a{hXfp4|8=y`e6{&7+<9$!qbmg zIWgChF{L*;I2x4_0LP0K@`8}mITF>I69T?&5f_&Rgj3=q0$_Gr!pxjt^WW?H&-Gh* zz+t?|fWYcqlt=no_WwSS(X(fq*K7{K29^T@gk=KpF>`{-!2eHJtRH2~OWFxNaP%Ik z0Ke5qVIP<)MsjldQ$rA2L60D&6eg+Di-?O+zPPnP4OMzU2-Z$JFNmv`t^N*3!Tdq& z=%kI+B6{9huR%PM=@i7x_9nAdd|I7Z6R4Zidv2NH17#+Ir7PtzCpsXEqvE%6fF)xd2x$ z)NHp_I>&eGoBL|Z{L|m2)f=fiza=l0by z{d+r%PPYTR_ZxD5EBvxzm5x+lER*wqdlcSmPC*laa?zxi0$SWkZ~ri}=avxy{suI< zPewFkqy3ZZ7W)l}Aea=qTTBXWXYKAS zOL$KDG8vCipKmyS$AHal&d=pJe`mxv+B5`Tcud#+>UBR2a7Gf)FKjT}=MdB6T8ljT zd+XGRaGP)?q(_}G%9a1*$%h0?zCujUV-E*|PD{w+SNk)8D9utMHlgJ2(zW_)`wQIq zIb*F316pYeI*98Ay@wG$Rx^fwT8noo#|!~$jb%!$o{?zZH&0J}^TpH2%PFL~T7_4- z)$(!}MX6YyZ-`nPc43}h$UBmTvBtyl@jV(%8Qp{Crd-I@?bnDE?H;g59f{!)z%4oo zkcrl>@5aJ0nXbFsBWTQ!_S^R`4f_G|YiwY!q$FZcgJc?EadS)+;ooRd8u@w?gRAL~ zaQPUpqm7gqxkfUnl|z-8%}gKddM);^cwLw5I9+bu4)0U^ltxra!X!%ZE*$4)&;l^x z>m1BRB#swB#KrkuuS$H)=%eHDB#y z^XEhmD|osan9_Y;yzUeMjTx9iIuoav^Awgp=djM#dRP0IA&7~DaVXhOTbUpFto%H4 z&go@;x4^B(xb7YWnZlSJ%%* z9xA_sAftpI-Gjg$)Nyw}O60ggJsyo`IvHrBxAjk$;?asesm~Q-vzh`a#yqDOhA%7Y zk1kpa#LMTEZ+4`5mGR5UsI-T+E03(Y&)C2!41!l!`LgXEmTId)HcuommAu3yUNY*( z3G;P_z{zNj?PFQ;OyjW|3;^S!{dk$!iw8y$L0XizOpO7Wc&U__&4g{}iwRSI)>Es| z6&(r*H#jo2dVk!N-$3lzmub6Nr;|w7Q6%Ksj~wGrqviygooynM3OYE!o5{9M1%Xfi z=~aVwJA`uq7TxS0l8j<|XR>^If2L955g`uaJ1B4~*XCbw{s>!3U4XzHdsduvBT$ecP_l}oxtL+63Ap39)Y6?&K-j77Z z(!IFr4KN!)fF9Ub<*zy&&cCmQlD|JLR>JFnH5%+9Iig5}(@ux82alFE$D+g^p^1uN zDjocZ7fbKQOV@(*5FrQ`QV#nV6sZGIPIA9lqsc>_#ApC3ZdY3(MGvP*At!Z%^GW8z z=OdB@a+!D@PG-X|wIVpfJpMF-F+p*uD|sG*hRfOBC7PXRmP;iC9W6!C=j7^B+h<$N zwyUDL>ZuI+y#d^baX*|w6yO_TZ>$i-3{WxDYijBg&xY^bme*6`QwtVJl;t-7SW(te z8?_fh9xAebf6)wU#5L$8Mj4sX?4xVAi*i{mS48bo$?sphj=O)n&`8@CQ77D@$jH!L zta`$XCbZKa(^CyfRdP9ZI(|}SG+l_YwEJ!G^U%^%#?HjPVSKZIwU&;Xvs9~On=9Bz zCVCX#g3S$dlq=OXSU6oc3BWClkyrhhN+P-ovl4^*EPAnB(<@S89_cSJEg>x^PJ|C1 zOz0Ow!sX^m!W}V2{#@LoS57$Kdgwtmv>RBj6DA9fW;Tsqn1yxq%83g%k_D7anT%)P z+VDQ^ZPwLgV5PcCXqe-yIlM6W9=ShUu!_=9k3;-ALO5med_$&IA&JGqqHxyh{2!RH zg29RCscWNDKSdKZ@&xzpeI;er;k(&kc)I`GA7M&{cIA5!2*O*4tYeUx?By;3e7xHX zu09GU_B{xmlinKtgTSCL6c<`vJ+K0Wy2?CUxpD2-NO2VbQ%&l^T*X$5@_e{PR85H<7h zCzMbB$)iN=d_AzWJ^KVE(=a}FqPoUtSqgplYryH4MC)dWBq-M`la7HR#bISdH{!O= z#6icJ?)C}3z?>jWdgOU6kU%BZcRuYNUJ*jZbb1l8wYr0Uhww!@oi2=uz6{t#Og2$} zUFPzZr}z%E_If^G_TYEagEm!(On3BN$mH^6F&q20_2X#JvhHEa4xGFQ@$FSGx+mna z9Tg3)jPFFcP^K(sULrQf;4oye49yiiozN&sMag#Q9JM>@*Io&&mV~7??g(?R>GN+Z< zwJj$jp((g^T{~R0ywud=qur&Y((h)9q(n@1CZ!iz22EZS^Vb$z6&MOP=p(k2%Jru3 z@vvC&;yx+3)jHVc&tZ<3-!|d@(Yi@5RH$SZoQBD$Jf~cv{IR8jwZNGG=FfB8L=RO0}iFA862v0ZpM+{ZA zG|UK30R&c_GF5N9jU?j&U7PIhvj(m_$9Dx15t9^P@J+5|n&ONnnaIp*^h<9sb9W&hY^)dBS&|QS!Krao zL|T8)PfiBpWA!k%6S$JyB?jR!6@%_S4rLBi#hi}TW_yuTTX(c&pRn!DCkDp}w3Zan zMd~`ueO8GoN2+`tX|piwC48zplRix(Y5RxNNpn})o7R%0wX5L1hg&c$TY}E5Jg`e*avLuuzaa;3wIQ^^vle531|F}^l_k9 z=CK>;H<^kGWUtU%d|0xd&gel{K5XkH1_upy85LRYj`Sl9eEDWLcw1)&!}E^~24eKs z-~xfz|6pPli;){JK}^_U-HE(S#}>Lb+iVAptJ~E@2vI0`P!{*eIMBj>sx_aAOcg(~ zBY_$IGdSm}HwX+%vSQ7uzB*)A?GdumI4pEQ#qqNBrq_-G=ptDPHAEz^_(QnrSM zx#nvxtSau>qry}CK6A1w%0t!4?I}goEEDyl{7f|0yhabAUP~qHhm%ueR!dRTI$=K) z$?};@R-Q}N|NW?{4e8{F?ztufN=0QUPx(+KD#=KH9y5Bt2t2eedn3;BO| z%(P#_6cVp>9vfhoEJiljXep7HQUsLD(Ki{+yZ-$0V0XRPsNTZAjNRp9qM2VW5I{C};TRaBf^)TD#EJ3)fGyE_DTcXzko!QI{6 z9fG?CC%8j!clUYo{cCRjH5b!&^lG@ESD)Th_0&Far`zfk3b;5dB_dv9SGLCIZ)a88 zs^#96Me>)??C0I4L?UpsIr7snO%L)}ypii34dnqLZO*0xi4@Zgv7%{Y(w>~0tI9Jc zFb51;A^tuch8U{d(H0@My%)emyyMYI#W!IRdQKo3_3fr|6}A#$VmC%G27Rq@0$ub$ zcQUY|e(jB$eYD7R&CMolN5Co|5*oYB_P~6S;Y!BAw#cP#{d8323iEB&e#Pvh2)^Q% zwDpaJRvna@lKjU560uw+GF8pt+{sBjEe6E~I9fGYjd~vHN`s6UOQ}#8F>Yt8p%^s2 zs>wR0J)?7Gg+lLIBPn!fkKyInwQ^>80wKhJ=^9$Lb|vj%V$+{%#mGm=`Pz-o=>l)d z^PsTPIR2x4BIEJ)wPUb5wV@x4d{Vf&eNr(oR!myG!ccVDmqaCbN+Dv+?Sx$rhG|4- z3xP1ynO5L!qt3A+$Kx#gE>a#5vj%TuCCi6*-l#${vaCc9%LU4ot|IS&uMhuEXgDO?s*MF zU<*q6c5<)ne*HA6?7dmWpF*oEg!(n&dJ9R76V}7^-R+yF&nufTtd~Oa7{eXs(WcpXV`|r@vQ3lUtP_RasWyZer6upKGDJi7CA|*El$?E z6H23SSYCY`-@VF1gP=5={MJxOpA~bsd*afQcU6&noxmd)Lr@5Kd%oRQ8tC>9lrUcW zbsh1m{T@3^THTHjSwC0kGa-%1nP}H+-R+pW+hSAUI4A~(2ZzV)Y>33uqRq*y_{9s? zWGoJG!wWIM%ZbC)nO2FCPzp0MM7^rR@8FC~G$`)ks)F zqSH1sCr!YdSglGY(icpkKx+Z^Xx8V;%j0Rtd{T9Spk;~7F{9bum-dHR!|dLM8H7x? zJo{SvxI}lQdiLrJ!`GO1O08dCrgFM^FJVLqA=w-=`r)aRT1oK1y2>?DmLp6k;ij8> z+M!JhCaj(l(t%iugIbj~w4pe%a#$vp7xI+DPPqWD$y!Z_bI7v8Z!TwmUt%Jc59KSn zotQ1;`*^N7~`9}4o77Nv^A3FMgA}b6F2<*QVgSqWSE7_SWYsID4EczQ2dNhI$vopRNfQ#HPQPH%UyRq7bqw%@8KWn!Uso3KW#Kw$nN4->{(RcX?0JM!U`bu zKMi*kTg1uWUu!skNZ@~6ez zC9%Vcz^j2YAqO`%ahil#_+e%@2lnqq*gaUa2|pHJ*x(%B25~f$al08^Ur1vmY(6Fk zB`w%bT=|B1$C$be2bNQ1av5?y(exZbq8fcxHZ*A7C3s5oN3Px9-ni~ugc4e)uv>62 z9S>b;Iphk{0Yiq{Z=$Z7)AfPaPNyUKZlX697D2U9WLF$X^ieO6$?fjjuh$ALzItCy zCj&HQW{p<~Gjr?6S+dCCHL;R;S#l2n0u@cn#ATn8#{_fP*JJZrK|v?bmUEt;fhy}4 zQ$Jrnj42#GZdC7{+p{xFlhi^&CH_(ji#Ha@hpwtp8=z1m+TbwoAp3v<_O-e!=vje7 zjrth+NG8cwc1N{Nh0S$N$BRx_5pV$yP?V1Qw$o6)&=~3)E3I101ZT|k?`CD#X)ZRa zta=)s<9O%{Sx|O&zT|&SUp!WDv$&mwik0uq_`of(vvgZLL1s(jOpC0ATJA}RkSE`I zWsW=JGe)b3?h2gD#{*2@C&oz=Mj!C_Bj7ESXkv8>@(X4+TIFOttr%MMWt6N)Q#(i7 z22Ij4J9`MR2X$E7=l3SejXd3#(rZZ2K*%_SOvYZ+p|JO2x1nWT*sN2cmfLK}R)4)^ zN&53=A?Es%gvwtTh4&9PMJg6p5TPH6gaiXt9AU&yj8Gq(^bRtD9zNx7%$}t_hv?mp zZ;rPy4E9M>*Ky^fvM-1!c5G=l`<5Um0dVPK(k4&AQ zk&ma7kV4X4yp%{xqk5&)bJdh+%sh6>eg$LDrpJvVh7%L zhpwuxRVa+g{~UeG-zR34;88yT)Pdx#!LCreSLUDTUxHtmS&YI63TlQi7<+(zCr!T+ zS8nm&DbxWyQi0+;Zp%son#g7@r?Xr3&j$Ja1%#!uJ`)(pQ`2wSQIGh$BuNY`z&9C* z7T3ioxFOAsq_sHoNUkgakm79aLg4+B4Kzd?7|-)N^#Awg4cr>z2xswygplg(FNsc0 zbbBkYh(@y5_@wFr1UEa|`1e>n^})W?*$t>+cI!y)Q*pp6%zBkOJiL*~r1Pu84E?fr z;2KM%2^UQHjl*R|Ou!2*y0OYuPOrj%nQgH6@$wN$b=9^T*iNgr9JLzfTXoFl_J&UI z_~rg|Q8-cDHJS4!OcCwx;bADIK5OwWEeKHs5bO1za`Z^9=||PFuB)~RGolEsLk68Z zQf(?#g0Y0L8*ye4)HId0EN)YF^7>o*=ck6A;*;X}p{S6+Y_yZb${0mjy6hBFc|g$6 zE6BS%9Z9A=4IrbAn0l{yQMw|O|#84zgze|O&n3!1M zI0wE;`mMKzvk}<-hv;zy2S!K7BX$%XS3{g2Lx1XhFXY{6IN%!-DG%S3>C{K%b5A&c zlQUm#xn0JNCLU5T1!pYK5aB?ekVfj?nB>$KU7o0BI^B)Bk(gPB8}*kY@2*a3CdIpi5nV!wJpc*mU8myf_OohtJ(Tg zSAef|ss2J0yDX)}!0*d=qNiu7l+n@2ay*?eZl#c~h`AKP55-G5q)GnS8nxON^$EC+ z0h;GdJF$(+*_dTYO<6ZJW2xnV5`EKg{UkVAJ}cnXYWDr(sYIO$_>Kl!j#cljXc_FU zw0+Wo7ZZV@?}8v}61@Cm;s}?a$?N*)=Iw4))iF538sYY_)pb!l`n$$bt!Y z>{h(u@W*h9hKmnd;(}r2)`!hfn=;_xwfc`kXr3p)#a+MCjn`DK@?C;GIlb>lZ=5wK zm;7nSrp=}_LG3XK(PtZsY^VbY#@->LNLNh6V(su%3xPl*z)F?6Kx(L=?D1KBx$X6f zeN9d4se5h#vtFy~A$^5fZCGSgzvul40y=}zm!%rLLkFhpu?j*aPvRoT&&NW@_ZFeI zP~Yr)=rhKRD;|DdYD7c%mRAhj$KOe%4ZrF{t5;PWgRuV6Rdg;Zh6zmstO4EOw+?W2 zs|nH~$wXLX@|Zz+vFXePy0!jZJzykuI*w*}Alcc)@;JX2lt5B~Y^l zb7B&A4Hjjo^Wz|!QE!oR)#-8rlTNJ_8hBZlsS#0kIi5wKD5Gk3m|++hIo&3rNEY>8 z3AfS=gpA$hVs4ypL6>5pKlol9lH(JSFhak*Gc=Ap5*}nqvuM;`gkv$EM?Sp-A)Dzv zW#AhgyYcpU_Y5y)05nilM8v$jv~A373UoUd>Kt#GJr$8vp)GFz}q<+Jyz63Y5W zl|T!ZYBvMmvG6!uerz${(6_p6V3PGLc1nVgt+*uwEfg8r!eg_-_S9re8~Wp4Ce0wD ztP_EG6&NNyQ0jGlYj?GL{3n+_DM4${w>3E3VVf`4qcavN<47Ya_1k}Jn%J!2koc~b znyYWd>CCj7qE+ab2Gm~a-km%nBsf~Ev>AWJctx!(cj$Yw;vA_b<}DXxb<*%VGn9RO z1p#?#wwCze>Dil^C~0 z;3+5E^&W^XiRBfx!Nk?SES2-0v7&vkHfqySmBUdlQ7cEJ zV5-s4i6{I1)=X-PUBVyF?p)>E(>5ICm2_&eT9-|!7Ft2*4n)6gTT5lRc}vNgZi4HV8K*6ZxmQXlI0Jvs`)Tz_|++ zMwLTk^wM(_hJr_%M-qR4Zg^>(Q#t+Y9R2~}AZPTko%3sLTIu!&6aw!0R|@%@zIYJ| zPU~A$8QK$D&qe%Puh!q#$rJoqTHSq|W_qPY7gK~Qua3|yq&1gkIjoj48KP2sNdy+MA3=nAYzc z+*z<*C{lW5z%{#DVs%0nZ>{nlg(Aj59f&<)jl8C zDa*X(cNZjOW(#PC^~9mQkaVa9zfITylr$5STAijZ+1&TT!w73_KaLQp&@@GEyh!U+ z2sV#-Ic@pD?@yLqoWbu2a6$A~Bz1Id^5TE-j8pzQ!RGmgDe5hb-a%? zktpq9xARP9W@H`z=3zYNHxB~&Y|IIo=qtOQ3~TMH8#I~eUdCHHj#W#X#FAv$)um8k zBgtx~L5I9z5< zaAHm*D)Y(YhC@*xC2~20D^`!~%i1G6+LZA!4&2w+)rt2`{1X@l_*I#uD2(R+G>G%% zNi#qd;Q_9^*=Aq62QG-ScyCp}Q$px%0?tf{CZ6*JCjephh7y03gl{K~M$6%7ny9;BCsTb33 z+jc{*1>}H@Fe2zwNra6D^nHuAJaMxuWZhqv1B-tr0&zW9TF;evvHEKMd#aSuIVO#U zw}2h9SQ=rzZ`Ud^jzA&;0h3TN-Q_}cpk<poe0@GG4Tn4 z&KaFzsUY)R#WsYyxvtS~#!s{lVG*DAHvkaVcw;=^0f*ode$*4Gb6fCMwR9zbk+{Pb zd)I}oGHZgZ&|4DeCS-Ra9%ozW{q+6zf`AtTSe^wg$3_)9C;dY-O!uXVNe63v&VI4i z#-Y^r7vX5)I}p;RcLizZ7w45srY}0^hC>lXN!DmY>8L|+B>49v>NP7r0WXk9mRhas z=m87Y(5wU737X6F(C1gKAAYR9c%E(>`uBsugxRy@6OVNT;zT&iGo)Uux!S%<$DnlA z7Q3k}A;ItCF*)j*3G!^PjZX>!Lftrwc|f+@W$m zfe6&2&=72~<95I4-dH+BLD$t!F~n3l{c4r=>T23gxjFt7V}wKh^VTQy!lf-S5PJ&v z>Rikl{+;`;t?`2aITCs5_w$rleK;b1_hO$I{Ao+Gt zL$O#WD907|{v1%zGl@@4)8z?;vTexuy}{#ckLnFH;IH!< zmbUwukZObr&~iXhJ=P3YibGDszZW7?A%ajRqtUaA!P9MLp-T;q`rmXx9A^uxP53N6A;?qn^9d(Qe7)kc>2Jb2oq# zJ!iZU|ILQ~^~oLPY_&;SCGPor%Kc)33|tj%IL^@cTK2HHtT(^kU8LuCvh@ce$ZZ{3pzd?Wx45*5$vWz0kGfJyPdIqQ^q&Hq_$O@ITxDQUcHy~ zjZ8I6)22^LL^<4yDDKA7sIzBnH_heiO7D#);?v*Fw|lSU?qP$Vh{(zNDB@7l>vV!z z&UrGiKY%8Wr3$~Vsv@J}Mkt%p8}Zx6EmWvHogy$L@&UwrCCpP5L)$!@tiz;{OyBBmp9Vt9L07>&tT z5{UBwZ9kma@X=C7WQHbcIV}UER-?ifcVzP-L_FRQ+m45USjV_r@+bwSgy!nZa?VgP zSE{D>M`UCqtEniMvtOCK+Ws7An=o zeIjxW0YxJYP291UbeSMQ-1$mN&&r%^oXZO3%2l4Vy$8(%mROkdH}dd6oEdmFxb)ct z@u6=Q0tgZhNr*oPaDz*RHnv5HGuvMIb?~bweUifn(jj`3}wxhE7%uxg`@qfy1_cnnmQ% zi_yFILa70d8rNUopKSR~!6W_4@K5*BbW7cPzp>0GGg=6fuF-ml*N7}CkMAi&yV|vI zFka0O<0ZEfi<(-X$oLjZxQ~rS7xH0RCdti(W}}HpM-1K~(vtn=uyI1_gm8p`9pMyv zll7d6&&7656e&jHxqiezz~pJl&PmhP@0r8Wrq-XEkH_bqvfwqhDr8UYfWZ>81u{5GT(k4dB*kH#S1_0oD)k+?P%=`PQ^(GAEb~nMX(HL zt(AuMdQNfk@0(0UsuPvT`V0$FJLmRzV{B&$RgGwxdt3r+S3gOAyns65J+z_J(CotL zg6t(=#9Qc;LZ;NNi3Z$~QjtZH)olP_2P!(*g>1(|0d%5qY!*Kp)aDy#EP+J!7>46+ z3-oR-HYD6q!nGp%5oJv)1ZM z@b`})Xgdu2#$uyRQ7*^rNQ)ra%$b>R5E*I3&svxx_)k~pqr`0+x3iY3?pUSV9Xni~ zxK^$H!cZMgR&%TttWlp3y*$H7lqcl%3_>$!_{J6*F}`T`GqMmZhtCg$;vi^aSJ)nk zo+v>heN;J-Xg`0qG`$KJkt>##Vzt#7>Bga0T&d-Y*<<9dbMqy;w5%kR+EB%|fA5=nNE!v> zpwZ|zV9z=< zBtx$0eo-v%CI=C-tvf2=U& z0+)J-86*ho?w~3+KPrFG{}hkz{iFdUWpXBF=$op7mcb=mnfdRKdV)^-3iMoE;c0yZ zPXBKgg1khV!z zhB$bp$+^QFy=LCu?BjPFI3^}W__ev4!Ag_y4_tx**dZnmk#a~`fgY@2-cF{X@3wp2 zGiE1%xarbQ%m6F7I0la=+_5m!_)i@nWnoLio?*CpJ`pyD8K+jurGFMzV}WP#%?ZtL z)GLfcY)(jWw#b<}FaqgV@|hXoGu5x$rhMZVznQO^iQZw*&ljx^sMm^rMIzXKZlE%? zE5{*MrF=oc9cnkQdurB(lF8r&sz6%`xbXG*20yU?co9HXR(kN1r_YBY!x%laQb-x$ z#Ei&mPaS$?S-04sN&~zR9AJ*fKNz6V3q$$>Rubcw0y)m8#}=YnQ^9(d>6#sx)A+c&W^T?_9((dyEFPB}h>1OH=U`aC zNT_@c@6h{C!3phF^cJ6sip=wc)0X(bNeJWLvcxm{;&M_?faP%LFWXfI_0=v{M2SaY zPwt>NB*KvdQ>l6Bb6;7<3pH#LO5NBsI>w>t{i>pxnHL%cM%9X~BytRWE$$LI5l*|G ztfZk2mFJlcL28cc?$!?s1dS^iUqH;;oz+rB9bv0Tp2z)MIzHv?E)TYxkY;qjl2ZnK z2L;Xck0ap3%bqf{It}7DRgXBz#UQpiT%#uUJXUx<#doe`$e?dzXW_-OIYZu^uta4P z*+Kuff}YOp5shTPEtKzx|DM82RiR36&OL|>ASHFLwK;~P3x##&I{m>#thGus%bHq1 z9jh%B(P*Upp0xf;Rhuhrbz^E+ORP;At1F_YR<+Ou?#V6S`W7Hu{t~K^1vY`QQhW9s zK&0XT$o)`Mn{=J)DIzQbXB|O193PaKaNNC$Y2 zhW*^dq+Djlc1U?QaV$rW311IR26|DHKK+dywSzFH$V3(wH3Y6NEy!kNI?bip{ z^olU3lSF{=zwTve(&BobL!-lr-xrSq)R3SC8sKyWg#zi5yZ9KazwX4o^ z!_ajGnmiab)OZ3LSdDI1G`~Fs)Wp|kcWrY@q%(GN{9{bV_aumfRi5p25`mzu7}0x| zHgxL4z{_oNbJBC#>bSv06#0IAqQ48uL84;4Gu+);&EL&5wX}wbtz?aU8S;`s8KWp4 zXY)bB3j^)0fy5%xWM*FF9}dG~U%Nc=ZMWJ8mwr6bj~a&P{Hd9bx_gjA^P+#>>4_GM zIn%5&f2Cd=h$W8i452Wcx2dYGx7MC$wiqii{eC#9Idon2)V$~1=iSC+IAK7xx_zw% z-Xe#w4E$g15o)2Qs*l z&gfVLy2t7jWn}e1`JutNL}$xa7v#A7Ea1CRQ8(7wGRm6A2TYz@ zdw6A1sEoPiq)|0CmzPSgxFm~i7%RH6KN-bumAS|iaeZpb5<1ULn7~830wSZc$3AZi z5YysPAv7&|J`wQt1`_5(B+s+{8ki=26C6z-?<;4)nm6}%xqiQZ>RX(GG^UUdbA?T% zPh$yJ-db_Ix`GjNi6`Y4C0y;aMY?QwjH8j5sES8Uiz{Wn70DBu6NhiTZJ&FH{boRk zRAmuy=Ww8)VCGL;=Hwk%U!xwsZIRMMsl?U3qg2-u;kUwE$G{RCKch&Q&J3iuL4WKA zzF22IY!!%SmqfXC3RdGL$5E)e*(}!~-1A$9?_Ee#R>6kJO7p+?Uk+) zO+b9TI|_@j&8+Mz?nuuE+>dB9CCpJ2gjQ)_=Iubb96DE-_15bHYjT z&IHWu+|Ba-71W=nswOgTqY);qv{%hisXtH%O3W}wjMdn$MGO)u%~rdFr7=XyBp58;d;#s}uLZif%vC?9d>E>iQ_Hr^4b zhh2mj6I85ZKckZHoWp7TvL9ArQ=$>SU2|DB5FgwqB_Zr7BqZkYLp%UAH9KEPm94{6 zYeaK)(-A@EPTw2a7^isGPRi5MY7RL+87GfGDEoS9ZcO}*WuhRjD@jjfNNGs5T^c(4 z)O?uf)G1;3#1=Lhet&05+L~1Qx!j>~^;(tH zfxytdx0oWUWlC#2(-ErIF-9d`UgdBXA{LJgpdXdh=7Lk1{zM(|cVR4bI0h`V?z9($ zEogG$7c5CS5sVDCh8Z?Z>1YjsQ)(hlmdzYcRVMld&TM_mK)tbV`aLW{WYS0sdUP#O zBNhIgOp%R`k8u4r^7yOIL+|sO$ipoz#JBX{x*nt8yd@0yYDOg-b4nDoy>OF->3)0gzeqZ zY3zzR#hmQpmaqFO|JomcXpR;JRJ#xWhQ^)kr_3h_=e;jat2J-|+hilCHQ2oF{pK{Gaq6|5E|! z@drvDJs>&!D*rnF?m+7EaJf_4qx&(t<3qkl3X1F=+;?_%{lbQ;+|Dc7LwTF44IEC@)s|IdH?6UymDqnWF>tr0c|_& = ({ onNewTransactionClick, children, sidebarItems, -}): React.ReactElement => ( - - -

- - - - - - -
{children}
-
- - - -) +}): React.ReactElement => { + const [mobileNotSupportedClosed, setMobileNotSupportedClosed] = useState(false) + + const closeMobileNotSupported = () => setMobileNotSupportedClosed(true) + + return ( + + +
+ + + + + + +
{children}
+
+ + + + {!mobileNotSupportedClosed && } + + ) +} export default Layout diff --git a/yarn.lock b/yarn.lock index 55eac46a..75b132bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16139,6 +16139,13 @@ react-dev-utils@^9.0.0: strip-ansi "5.2.0" text-table "0.2.0" +react-device-detect@^1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/react-device-detect/-/react-device-detect-1.15.0.tgz#5321f94ae3c4d51ef399b0502a6c739e32d0f315" + integrity sha512-ywjtWW04U7vaJK87IAFHhKozZhTPeDVWsfYx5CxQSQCjU5+fnMMxWZt9HnVWaNTqBEn6g8wCNWyqav7sXJrURg== + dependencies: + ua-parser-js "^0.7.23" + react-docgen-typescript-plugin@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.3.tgz#664b22601df083597ecb1e60bd21beca60125fdf" @@ -19246,6 +19253,11 @@ u2f-api@0.2.7: resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720" integrity sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg== +ua-parser-js@^0.7.23: + version "0.7.23" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.23.tgz#704d67f951e13195fbcd3d78818577f5bc1d547b" + integrity sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA== + ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" From 618888ed075aa02f73841f0d3c9a9e07d126383e Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Tue, 12 Jan 2021 22:33:22 +0100 Subject: [PATCH 14/23] Upgrade dependencies (#1767) * Deduplicate dependencies * Upgrade @truffle/contract to latest v4.3.0 * Upgrade dependencies with minor changes * Upgrade electron-builder configuration * Upgrade typescript to latest version * Upgrade safe-apps-sdk to latest version Remove autoprefixer dependency --- package.json | 51 +- public/electron.js | 2 +- .../forms/Field/DebounceValidationField.tsx | 33 - src/components/forms/Field/index.tsx | 2 +- src/logic/contracts/generateBatchRequests.ts | 6 +- yarn.lock | 2189 +++++++++-------- 6 files changed, 1206 insertions(+), 1077 deletions(-) delete mode 100644 src/components/forms/Field/DebounceValidationField.tsx diff --git a/package.json b/package.json index 93d92744..920d5d56 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ }, "productName": "Safe Multisig", "build": { - "appId": "io.gnosis.safe.macos", + "appId": "io.gnosis.safe", "afterSign": "scripts/notarize.js", "extends": null, "productName": "Safe Multisig", @@ -95,19 +95,10 @@ ] }, "files": [ - "**/*", - "!src${/*}", - "!config${/*}", - "!contracts${/*}", - "!migrations${/*}", - "!flow-typed${/*}", - "!apps${/*}", - "!out${/*}", - "!.editorconfig", - "!.gitignore", - "!README.md", - "!yarn-error.log", - "!yarn.lock" + "build/", + "public", + "scripts", + "package.json" ], "directories": { "buildResources": "public/build" @@ -134,12 +125,12 @@ "deleteAppDataOnUninstall": true }, "linux": { + "category": "Finance", "target": [ "AppImage", "deb", "zip" - ], - "icon": "./public/build/safe.png" + ] }, "win": { "target": [ @@ -165,19 +156,19 @@ ] }, "dependencies": { - "@gnosis.pm/safe-apps-sdk": "1.0.0-beta.4", + "@gnosis.pm/safe-apps-sdk": "1.0.2", "@gnosis.pm/safe-apps-sdk-v1": "npm:@gnosis.pm/safe-apps-sdk@0.4.2", "@gnosis.pm/safe-contracts": "1.1.1-dev.2", "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#bf3a84486b7353bd25447ddff39c406f6fafecc6", "@gnosis.pm/util-contracts": "2.0.6", - "@ledgerhq/hw-transport-node-hid-singleton": "5.34.0", + "@ledgerhq/hw-transport-node-hid-singleton": "5.36.0", "@material-ui/core": "^4.11.0", - "@material-ui/icons": "4.9.1", + "@material-ui/icons": "^4.11.0", "@material-ui/lab": "4.0.0-alpha.56", "@openzeppelin/contracts": "3.1.0", "@sentry/react": "^5.28.0", "@sentry/tracing": "^5.28.0", - "@truffle/contract": "4.2.30", + "@truffle/contract": "^4.3.0", "async-sema": "^3.1.0", "axios": "0.21.1", "bignumber.js": "9.0.1", @@ -190,7 +181,7 @@ "date-fns": "2.16.1", "detect-port": "^1.3.0", "electron-is-dev": "^1.2.0", - "electron-log": "4.3.0", + "electron-log": "^4.3.0", "electron-settings": "^4.0.2", "electron-updater": "4.3.5", "eth-sig-util": "^2.5.3", @@ -208,8 +199,8 @@ "lodash.memoize": "^4.1.2", "material-ui-search-bar": "^1.0.0", "notistack": "https://github.com/gnosis/notistack.git#v0.9.4", - "qrcode.react": "1.0.0", - "query-string": "6.13.7", + "qrcode.react": "1.0.1", + "query-string": "6.13.8", "react": "16.13.1", "react-device-detect": "^1.15.0", "react-dom": "16.13.1", @@ -226,7 +217,7 @@ "redux-actions": "^2.6.5", "redux-thunk": "^2.3.0", "reselect": "^4.0.0", - "semver": "7.3.2", + "semver": "^7.3.2", "styled-components": "^5.2.1", "web3": "1.2.11", "web3-core": "^1.2.11", @@ -241,8 +232,8 @@ "@storybook/addons": "^5.3.19", "@storybook/preset-create-react-app": "^3.1.5", "@storybook/react": "^5.3.19", - "@testing-library/jest-dom": "5.11.6", - "@testing-library/react": "11.2.2", + "@testing-library/jest-dom": "^5.11.6", + "@testing-library/react": "^11.2.2", "@typechain/web3-v1": "^2.0.0", "@types/history": "4.6.2", "@types/jest": "^26.0.16", @@ -255,7 +246,6 @@ "@types/styled-components": "^5.1.4", "@typescript-eslint/eslint-plugin": "^4.6.0", "@typescript-eslint/parser": "^4.6.0", - "autoprefixer": "9.8.6", "cross-env": "^7.0.3", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", @@ -263,13 +253,12 @@ "electron-builder": "22.9.1", "electron-notarize": "1.0.0", "eslint": "^7.11.0", - "eslint-config-prettier": "^6.14.0", + "eslint-config-prettier": "^7.0.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.21.5", "eslint-plugin-sort-destructure-keys": "^1.3.5", - "ethereumjs-abi": "0.6.8", "husky": "^4.3.0", "lint-staged": "^10.5.2", "patch-package": "^6.2.2", @@ -277,7 +266,7 @@ "prettier": "^2.2.0", "sass": "^1.29.0", "typechain": "^4.0.0", - "typescript": "4.0.5", - "wait-on": "5.2.0" + "typescript": "4.1.3", + "wait-on": "5.2.1" } } diff --git a/public/electron.js b/public/electron.js index ae9368b8..18a5ba3d 100644 --- a/public/electron.js +++ b/public/electron.js @@ -92,7 +92,7 @@ function createWindow(port = DEFAULT_PORT) { allowRunningInsecureContent: true, nativeWindowOpen: true, // need to be set in order to display modal }, - icon: electron.nativeImage.createFromPath(path.join(__dirname, './build/safe.png')), + icon: electron.nativeImage.createFromPath(path.join(__dirname, '/public/build/safe.png')), }) mainWindow.once('ready-to-show', () => { diff --git a/src/components/forms/Field/DebounceValidationField.tsx b/src/components/forms/Field/DebounceValidationField.tsx deleted file mode 100644 index 7996e59c..00000000 --- a/src/components/forms/Field/DebounceValidationField.tsx +++ /dev/null @@ -1,33 +0,0 @@ -// source: https://github.com/final-form/react-final-form/issues/369#issuecomment-439823584 - -import React from 'react' -import { Field } from 'react-final-form' - -import { trimSpaces } from 'src/utils/strings' - -const DebounceValidationField = ({ debounce = 1000, validate, ...rest }: any) => { - let clearTimeout - - const localValidation = (value, values, fieldState) => { - const url = trimSpaces(value) - - if (fieldState.active) { - return new Promise((resolve) => { - if (clearTimeout) clearTimeout() - const timerId = setTimeout(() => { - resolve(validate(url, values, fieldState)) - }, debounce) - clearTimeout = () => { - clearTimeout(timerId) - resolve() - } - }) - } else { - return validate(url, values, fieldState) - } - } - - return -} - -export default DebounceValidationField diff --git a/src/components/forms/Field/index.tsx b/src/components/forms/Field/index.tsx index 9a2868f4..38f424fb 100644 --- a/src/components/forms/Field/index.tsx +++ b/src/components/forms/Field/index.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import React from 'react' import { Field } from 'react-final-form' // $FlowFixMe diff --git a/src/logic/contracts/generateBatchRequests.ts b/src/logic/contracts/generateBatchRequests.ts index 5c2a4128..a0807afb 100644 --- a/src/logic/contracts/generateBatchRequests.ts +++ b/src/logic/contracts/generateBatchRequests.ts @@ -46,7 +46,7 @@ const generateBatchRequests = ({ return new Promise((resolve) => { const resolver = (error, result) => { if (error) { - resolve() + resolve(undefined) } else { resolve(result) } @@ -58,7 +58,7 @@ const generateBatchRequests = ({ request = web3[type][method].request(...args, resolver) } else { if (address === null) { - resolve() + resolve(undefined) return } request = contractInstance.methods[method](...args).call.request(resolver) @@ -68,7 +68,7 @@ const generateBatchRequests = ({ batch ? batch.add(request) : localBatch.add(request) } catch (e) { console.warn('There was an error trying to batch request from web3.', e) - resolve() + resolve(undefined) } }) }) diff --git a/yarn.lock b/yarn.lock index 75b132bc..74f066ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14,7 +14,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": +"@babel/code-frame@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== @@ -28,6 +28,13 @@ dependencies: "@babel/highlight" "^7.0.0" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + "@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" @@ -54,15 +61,6 @@ semver "^5.4.1" source-map "^0.5.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" - "@babel/generator@^7.12.10": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.10.tgz#2b188fc329fb8e4f762181703beffc0fe6df3460" @@ -72,15 +70,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.12.5": - version "7.12.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" - integrity sha512-m16TQQJ8hPt7E+OS/XVQg/7U184MLXtvuGbCdA7na61vha+ImkyyNM/9DDA0unYCVZn3ZOhng+qz48/KBOT96A== - dependencies: - "@babel/types" "^7.12.5" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" @@ -262,10 +251,10 @@ dependencies: "@babel/types" "^7.11.0" -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== "@babel/helper-validator-option@^7.12.1": version "7.12.1" @@ -300,21 +289,11 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.1", "@babel/parser@^7.7.0": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" - integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== - -"@babel/parser@^7.12.10": +"@babel/parser@^7.1.0", "@babel/parser@^7.12.10", "@babel/parser@^7.12.7", "@babel/parser@^7.7.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.10.tgz#824600d59e96aea26a5a2af5a9d812af05c3ae81" integrity sha512-PJdRPwyoOqFAWfLytxrWwGrAxghCgh/yTNCYciOz8QgjflA7aZhECPZAa2VUedKg2+QMWkI0L9lynh2SNmNEgA== -"@babel/parser@^7.12.7": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" - integrity sha512-oWR02Ubp4xTLCAqPRiNIuMVgNO5Aif/xpXtabhzW2HWUD47XJsAB4Zd/Rg30+XeQA3juXigV7hlquOTmwqLiwg== - "@babel/plugin-proposal-async-generator-functions@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.1.tgz#dc6c1170e27d8aca99ff65f4925bd06b1c90550e" @@ -835,7 +814,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-runtime@7.12.1", "@babel/plugin-transform-runtime@^7.5.5": +"@babel/plugin-transform-runtime@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.1.tgz#04b792057eb460389ff6a4198e377614ea1e7ba5" integrity sha512-Ac/H6G9FEIkS2tXsZjL4RAdS3L3WHxci0usAnz7laPWUmFiGtj7tIASChqKZMHTSQTQY6xDbOq+V1/vIq3QrWg== @@ -845,6 +824,15 @@ resolve "^1.8.1" semver "^5.5.1" +"@babel/plugin-transform-runtime@^7.5.5": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz#af0fded4e846c4b37078e8e5d06deac6cd848562" + integrity sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA== + dependencies: + "@babel/helper-module-imports" "^7.12.5" + "@babel/helper-plugin-utils" "^7.10.4" + semver "^5.5.1" + "@babel/plugin-transform-shorthand-properties@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" @@ -1133,22 +1121,7 @@ "@babel/parser" "^7.12.7" "@babel/types" "^7.12.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": - 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.12.1" - "@babel/helper-function-name" "^7.10.4" - "@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/traverse@^7.12.10": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": version "7.12.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.10.tgz#2d1f4041e8bf42ea099e5b2dc48d6a594c00017a" integrity sha512-6aEtf0IeRgbYWzta29lePeYSk+YAFIC3kyqESeft8o5CkFlYIMX+EQDDWEiAQ9LHOA3d0oHdgrSsID/CKqXJlg== @@ -1163,45 +1136,12 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/traverse@^7.12.5": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.9.tgz#fad26c972eabbc11350e0b695978de6cc8e8596f" - integrity sha512-iX9ajqnLdoU1s1nHt36JDI9KG4k+vmI8WgjK5d+aDTwQbL2fUnzedNedssA645Ede3PM2ma1n8Q4h2ohwXgMXw== +"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.5", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.7" - "@babel/types" "^7.12.7" - 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.10.5", "@babel/types@^7.11.0", "@babel/types@^7.12.1", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - 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.12.10": - version "7.12.10" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.10.tgz#7965e4a7260b26f09c56bcfcb0498af1f6d9b260" - integrity sha512-sf6wboJV5mGyip2hIpDSKsr80RszPinEFjsHTalMxZAZkoQ2/2yQzxlcFN52SJqsyPfLtPmenL4g2KB3KJXPDw== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - -"@babel/types@^7.12.5", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.3.3": - version "7.12.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" - integrity sha512-MNyI92qZq6jrQkXvtIiykvl4WtoRrVV9MPn+ZfsoEENjiWcBQ3ZSHrkxnJWgWtLX3XXqX5hrSQ+X69wkmesXuQ== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" to-fast-properties "^2.0.0" @@ -1390,174 +1330,189 @@ "@ethersproject/properties" ">=5.0.0-beta.131" "@ethersproject/strings" ">=5.0.0-beta.130" -"@ethersproject/abstract-provider@^5.0.4": +"@ethersproject/abi@5.0.7": version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.7.tgz#04ee3bfe43323384e7fecf6c774975b8dec4bdc9" - integrity sha512-NF16JGn6M0zZP5ZS8KtDL2Rh7yHxZbUjBIHLNHMm/0X0BephhjUWy8jqs/Zks6kDJRzNthgmPVy41Ec0RYWPYA== - 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.6": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.9.tgz#238ddc06031aeb9dfceee2add965292d7dd1acbf" - integrity sha512-CM5UNmXQaA03MyYARFDDRjHWBxujO41tVle7glf5kHcQsDDULgqSVpkliLJMtPzZjOKFeCVZBHybTZDEZg5zzg== - 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.8" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.8.tgz#0c551659144a5a7643c6bea337149d410825298f" - integrity sha512-V87DHiZMZR6hmFYmoGaHex0D53UEbZpW75uj8AqPbjYUmi65RB4N2LPRcJXuWuN2R0Y2CxkvW6ArijWychr5FA== - dependencies: - "@ethersproject/bignumber" "^5.0.10" - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/keccak256" "^5.0.3" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/rlp" "^5.0.3" - -"@ethersproject/base64@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.6.tgz#26311ebf29ea3d0b9c300ccf3e1fdc44b7481516" - integrity sha512-HwrGn8YMiUf7bcdVvB4NJ+eWT0BtEFpDtrYxVXEbR7p/XBSJjwiR7DEggIiRvxbualMKg+EZijQWJ3az2li0uw== - dependencies: - "@ethersproject/bytes" "^5.0.4" - -"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.10", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.0.8": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.12.tgz#fe4a78667d7cb01790f75131147e82d6ea7e7cba" - integrity sha512-mbFZjwthx6vFlHG9owXP/C5QkNvsA+xHpDCkPPPdG2n1dS9AmZAL5DI0InNLid60rQWL3MXpEl19tFmtL7Q9jw== - dependencies: - "@ethersproject/bytes" "^5.0.8" - "@ethersproject/logger" "^5.0.5" - bn.js "^4.4.0" - -"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.8": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.8.tgz#cf1246a6a386086e590063a4602b1ffb6cc43db1" - integrity sha512-O+sJNVGzzuy51g+EMK8BegomqNIg+C2RO6vOt0XP6ac4o4saiq69FnjlsrNslaiMFVO7qcEHBsWJ9hx1tj1lMw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.7.tgz#44ff979e5781b17c8c6901266896c3ee745f4e7e" - integrity sha512-cbQK1UpE4hamB52Eg6DLhJoXeQ1plSzekh5Ujir1xdREdwdsZPPXKczkrWqBBR0KyywJZHN/o/hj0w8j7scSGg== - dependencies: - "@ethersproject/bignumber" "^5.0.7" - -"@ethersproject/hash@>=5.0.0-beta.128": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.9.tgz#81252a848185b584aa600db4a1a68cad9229a4d4" - integrity sha512-e8/i2ZDeGSgCxXT0vocL54+pMbw5oX5fNjb2E3bAIvdkh5kH29M7zz1jHu1QDZnptIuvCZepIbhUH8lxKE2/SQ== - 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/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.6.tgz#5b5ba715ef1be86efde5c271f896fa0daf0e1efe" - integrity sha512-eJ4Id/i2rwrf5JXEA7a12bG1phuxjj47mPZgDUbttuNBodhSuZF2nEO5QdpaRjmlphQ8Kt9PNqY/z7lhtJptZg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - js-sha3 "0.5.7" - -"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.8.tgz#135c1903d35c878265f3cbf2b287042c4c20d5d4" - integrity sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A== - -"@ethersproject/networks@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.6.tgz#4d6586bbebfde1c027504ebf6dfb783b29c3803a" - integrity sha512-2Cg1N5109zzFOBfkyuPj+FfF7ioqAsRffmybJ2lrsiB5skphIAE72XNSCs4fqktlf+rwSh/5o/UXRjXxvSktZw== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.4": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.6.tgz#44d82aaa294816fd63333e7def42426cf0e87b3b" - integrity sha512-a9DUMizYhJ0TbtuDkO9iYlb2CDlpSKqGPDr+amvlZhRspQ6jbl5Eq8jfu4SCcGlcfaTbguJmqGnyOGn1EFt6xA== - dependencies: - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/rlp@^5.0.3": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.6.tgz#29f9097348a3c330811997433b7df89ab51cd644" - integrity sha512-M223MTaydfmQSsvqAl0FJZDYFlSqt6cgbhnssLDwqCKYegAHE16vrFyo+eiOapYlt32XAIJm0BXlqSunULzZuQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/signing-key@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.7.tgz#d03bfc5f565efb962bafebf8e6965e70d1c46d31" - integrity sha512-JYndnhFPKH0daPcIjyhi+GMcw3srIHkQ40hGRe6DA0CdGrpMfgyfSYDQ2D8HL2lgR+Xm4SHfEB0qba6+sCyrvg== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - "@ethersproject/properties" "^5.0.3" - elliptic "6.5.3" - -"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4": - version "5.0.7" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.7.tgz#8dc68f794c9e2901f3b75e53b2afbcb6b6c15037" - integrity sha512-a+6T80LvmXGMOOWQTZHtGGQEg1z4v8rm8oX70KNs55YtPXI/5J3LBbVf5pyqCKSlmiBw5IaepPvs5XGalRUSZQ== - dependencies: - "@ethersproject/bytes" "^5.0.4" - "@ethersproject/constants" "^5.0.4" - "@ethersproject/logger" "^5.0.5" - -"@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.5": - version "5.0.8" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.8.tgz#3b4d7041e13b957a9c4f131e0aea9dae7b6f5a23" - integrity sha512-i7NtOXVzUe+YSU6QufzlRrI2WzHaTmULAKHJv4duIZMLqzehCBXGA9lTpFgFdqGYcQJ7vOtNFC2BB2mSjmuXqg== + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.0.7.tgz#79e52452bd3ca2956d0e1c964207a58ad1a0ee7b" + integrity sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw== dependencies: "@ethersproject/address" "^5.0.4" "@ethersproject/bignumber" "^5.0.7" "@ethersproject/bytes" "^5.0.4" "@ethersproject/constants" "^5.0.4" + "@ethersproject/hash" "^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/web@^5.0.6": - version "5.0.11" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.11.tgz#d47da612b958b4439e415782a53c8f8461522d68" - integrity sha512-x03ihbPoN1S8Gsh9WSwxkYxUIumLi02ZEKJku1C43sxBfe+mdprWyvujzYlpuoRNfWRgNhdRDKMP8JbG6MwNGA== - 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/abstract-provider@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.0.8.tgz#880793c29bfed33dff4c2b2be7ecb9ba966d52c0" + integrity sha512-fqJXkewcGdi8LogKMgRyzc/Ls2js07yor7+g9KfPs09uPOcQLg7cc34JN+lk34HH9gg2HU0DIA5797ZR8znkfw== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/networks" "^5.0.7" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/transactions" "^5.0.9" + "@ethersproject/web" "^5.0.12" + +"@ethersproject/abstract-signer@^5.0.10": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.0.10.tgz#0b35359d470f2996823769ec183442352deb4c6c" + integrity sha512-irx7kH7FDAeW7QChDPW19WsxqeB1d3XLyOLSXm0bfPqL1SS07LXWltBJUBUxqC03ORpAOcM3JQj57DU8JnVY2g== + dependencies: + "@ethersproject/abstract-provider" "^5.0.8" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + +"@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.0.9": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.0.9.tgz#347ef30dc8243c682574a3f23ff63f73c8f8cbf1" + integrity sha512-gKkmbZDMyGbVjr8nA5P0md1GgESqSGH7ILIrDidPdNXBl4adqbuA3OAuZx/O2oGpL6PtJ9BDa0kHheZ1ToHU3w== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/rlp" "^5.0.7" + +"@ethersproject/base64@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.0.7.tgz#d5da73699b4a33dc92bd8e5056ad1880b262057d" + integrity sha512-S5oh5DVfCo06xwJXT8fQC68mvJfgScTl2AXvbYMsHNfIBTDb084Wx4iA9MNlEReOv6HulkS+gyrUM/j3514rSw== + dependencies: + "@ethersproject/bytes" "^5.0.9" + +"@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.13", "@ethersproject/bignumber@^5.0.7": + version "5.0.13" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.0.13.tgz#a5466412b3b80104097b9c694f6ae827df4353fe" + integrity sha512-b89bX5li6aK492yuPP5mPgRVgIxxBP7ksaBtKX5QQBsrZTpNOjf/MR4CjcUrAw8g+RQuD6kap9lPjFgY4U1/5A== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + bn.js "^4.4.0" + +"@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.0.9": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.0.9.tgz#2748247402ad20df69f3a3e935dc7b58c0d75c08" + integrity sha512-k+17ZViDtAugC0s7HM6rdsTWEdIYII4RPCDkPEuxKc6i40Bs+m6tjRAtCECX06wKZnrEoR9pjOJRXHJ/VLoOcA== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4", "@ethersproject/constants@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.0.8.tgz#50f2e23f48c0d1d0de3759ea79b68ec3e06435a1" + integrity sha512-sCc73pFBsl59eDfoQR5OCEZCRv5b0iywadunti6MQIr5lt3XpwxK1Iuzd8XSFO02N9jUifvuZRrt0cY0+NBgTg== + dependencies: + "@ethersproject/bignumber" "^5.0.13" + +"@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4": + version "5.0.10" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.0.10.tgz#41bf37428e8ddbc229ffd81c47af667174cb491a" + integrity sha512-Tf0bvs6YFhw28LuHnhlDWyr0xfcDxSXdwM4TcskeBbmXVSKLv3bJQEEEBFUcRX0fJuslR3gCVySEaSh7vuMx5w== + dependencies: + "@ethersproject/abstract-signer" "^5.0.10" + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + +"@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.0.7.tgz#2eedb5e4c160fcdf0079660f8ae362d7855ea943" + integrity sha512-zpUBmofWvx9PGfc7IICobgFQSgNmTOGTGLUxSYqZzY/T+b4y/2o5eqf/GGmD7qnTGzKQ42YlLNo+LeDP2qe55g== + dependencies: + "@ethersproject/bytes" "^5.0.9" + js-sha3 "0.5.7" + +"@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.0.8.tgz#135c1903d35c878265f3cbf2b287042c4c20d5d4" + integrity sha512-SkJCTaVTnaZ3/ieLF5pVftxGEFX56pTH+f2Slrpv7cU0TNpUZNib84QQdukd++sWUp/S7j5t5NW+WegbXd4U/A== + +"@ethersproject/networks@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.0.7.tgz#8d06e41197b27c2404d89a29ca21f741a01acbfc" + integrity sha512-dI14QATndIcUgcCBL1c5vUr/YsI5cCHLN81rF7PU+yS7Xgp2/Rzbr9+YqpC6NBXHFUASjh6GpKqsVMpufAL0BQ== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.0.7.tgz#951d11ba592ff90bbe8ec34c5a03a5157e3b3360" + integrity sha512-812H1Rus2vjw0zbasfDI1GLNPDsoyX1pYqiCgaR1BuyKxUTbwcH1B+214l6VGe1v+F6iEVb7WjIwMjKhb4EUsg== + dependencies: + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/rlp@^5.0.7": + version "5.0.7" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.0.7.tgz#cfa4fa6415960a435b7814e1a29bdfea657e2b6e" + integrity sha512-ulUTVEuV7PT4jJTPpfhRHK57tkLEDEY9XSYJtrSNHOqdwMvH0z7BM2AKIMq4LVDlnu4YZASdKrkFGEIO712V9w== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/signing-key@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.0.8.tgz#156522e542916b9aa9135527b40c5b6f9235af02" + integrity sha512-YKxQM45eDa6WAD+s3QZPdm1uW1MutzVuyoepdRRVmMJ8qkk7iOiIhUkZwqKLNxKzEJijt/82ycuOREc9WBNAKg== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + elliptic "6.5.3" + +"@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4", "@ethersproject/strings@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.0.8.tgz#11a1b0ed1e8417408693789839f0b5f4e323c0c9" + integrity sha512-5IsdXf8tMY8QuHl8vTLnk9ehXDDm6x9FB9S9Og5IA1GYhLe5ZewydXSjlJlsqU2t9HRbfv97OJZV/pX8DVA/Hw== + dependencies: + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/logger" "^5.0.8" + +"@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.0.9": + version "5.0.9" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.0.9.tgz#ccfcc1d395b5e3ce7342545fa28bfe5541182fd6" + integrity sha512-0Fu1yhdFBkrbMjenEr+39tmDxuHmaw0pe9Jb18XuKoItj7Z3p7+UzdHLr2S/okvHDHYPbZE5gtANDdQ3ZL1nBA== + dependencies: + "@ethersproject/address" "^5.0.9" + "@ethersproject/bignumber" "^5.0.13" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/constants" "^5.0.8" + "@ethersproject/keccak256" "^5.0.7" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/rlp" "^5.0.7" + "@ethersproject/signing-key" "^5.0.8" + +"@ethersproject/web@^5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.0.12.tgz#f123397c107f863c31fce5f31a97c66ec155e755" + integrity sha512-gVxS5iW0bgidZ76kr7LsTxj4uzN5XpCLzvZrLp8TP+4YgxHfCeetFyQkRPgBEAJdNrexdSBayvyJvzGvOq0O8g== + dependencies: + "@ethersproject/base64" "^5.0.7" + "@ethersproject/bytes" "^5.0.9" + "@ethersproject/logger" "^5.0.8" + "@ethersproject/properties" "^5.0.7" + "@ethersproject/strings" "^5.0.8" + "@gnosis.pm/safe-apps-sdk-v1@npm:@gnosis.pm/safe-apps-sdk@0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-0.4.2.tgz#ae87b2164931c006cb0efdede3d82ff210df1648" integrity sha512-BwA2dyCebPMdi4JhhTkp6EjkhEM6vAIviKdhqHiHnSmL+sDfxtP1jdOuE8ME2/4+5TiLSS8k8qscYjLSlf1LLw== -"@gnosis.pm/safe-apps-sdk@1.0.0-beta.4": - version "1.0.0-beta.4" - resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-1.0.0-beta.4.tgz#1fc5e02637395d351eec6c65a528ad90eea74327" - integrity sha512-nddg5Ms9v8DGutbxaq99bpd2e5HIsmC1TX1uRJTN0wSnqOe5Yt8wmT3p6zNrZUu3crWGiN9isrZUzFkZKC26Kw== +"@gnosis.pm/safe-apps-sdk@1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@gnosis.pm/safe-apps-sdk/-/safe-apps-sdk-1.0.2.tgz#c1a3e8799a0d36888556e15438a1bbe3b3c586ff" + integrity sha512-bXbD4ri92Ckc8otQBcESCXT5mdynrz7284xWDKNlGAQSnJU2JKimex5W/mpf80QUD3UNnww7YoEvz1h1nNz7+A== dependencies: semver "^7.3.2" web3-core "^1.3.0" @@ -1820,61 +1775,61 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@ledgerhq/cryptoassets@^5.35.1": - version "5.35.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-5.35.1.tgz#daa933d27bfccdbb351139387f5cd85bd6c641b4" - integrity sha512-9Ed+SIj6uQjKMaWYjaAKxq7n5CAKAu1JFb3Tv76q3AstYhko8SDtvzyqyRpCr4tSMHAvLQIohqRcfuHXbjHwIg== +"@ledgerhq/cryptoassets@^5.37.0": + version "5.37.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-5.37.0.tgz#1647aa7bd764a65b99040ecee38e64139c67f826" + integrity sha512-/Xpq3lk7GTcr/+Irrf6WCOtHzVpZm0OzAeI75Pbl6VufDiXw/e7bMIJzdXqmNkhKLDszj0bzF3L+qOXnrkNt+g== dependencies: invariant "2" -"@ledgerhq/devices@^5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.34.0.tgz#4cb073a7bc9528f42f539241fedf44c0c6b451dc" - integrity sha512-oRoZDDfufXAv9KofQdOXc0QztISa9x/YVdiWs55iOlNRQjWYHSPFzeSP6+J+tN0Au/GS9v+wcnTf+tHCtVz27Q== +"@ledgerhq/devices@^5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.36.0.tgz#f4493bea44390325fcc7a2a0d03bba69fc1604ec" + integrity sha512-EwQwLZcz66a2V07Bad0J+Q67LR2afj2NJChJNcA6/gqvzXrtNtJ37u1co9eLU7S5GGll5JGi7KdBqAD9ZTHaaQ== dependencies: - "@ledgerhq/errors" "^5.34.0" - "@ledgerhq/logs" "^5.30.0" + "@ledgerhq/errors" "^5.36.0" + "@ledgerhq/logs" "^5.36.0" rxjs "^6.6.3" -"@ledgerhq/errors@^5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.34.0.tgz#c003b0929f8ca0c74901a11a88b3e3db4b40e4b7" - integrity sha512-8Td60sOP5wzsjmxmj9Q5hjrr1XjCfB3Vdifq+1fiD6rpjyscYLgmoP2y5GYDPceDhalA/GOrKNSf+aIVVmBNOw== +"@ledgerhq/errors@^5.34.0", "@ledgerhq/errors@^5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.36.0.tgz#9d178b54116ae81b1fbdfa80afcd33981453be4c" + integrity sha512-VS6aFzn3IDUmSLaX2kAPg5sQOc5m7IwvswAGvoMc3FCi9/a1dXWwtiYn5rWd1QjDJlTKSfCwmSpvUMp8FKoY2Q== "@ledgerhq/hw-app-eth@^5.21.0": - version "5.35.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-5.35.1.tgz#4bcc4447560ee860ade60a401064688d08078755" - integrity sha512-W+Vsr+y/ckPgyMKAfPfgcomI3gy0lUisSq5ARJZ8or50n4a4hqsRQcn+BP86D3+cLPeFk+X+pW7KMSlSTiKSCQ== + version "5.37.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-5.37.0.tgz#bd01465c78add275f6769e025a2ce4d142f1a10c" + integrity sha512-xkCm3//6R3DiW1Yjtq7O/yP6555E6G6CkQHkHAJ7J/vuHupb3U7ETz1caCrhHHYITcfL8VqzmhKHizP4qDXkiQ== dependencies: - "@ledgerhq/cryptoassets" "^5.35.1" - "@ledgerhq/errors" "^5.34.0" - "@ledgerhq/hw-transport" "^5.34.0" + "@ledgerhq/cryptoassets" "^5.37.0" + "@ledgerhq/errors" "^5.36.0" + "@ledgerhq/hw-transport" "^5.36.0" bignumber.js "^9.0.1" rlp "^2.2.6" -"@ledgerhq/hw-transport-node-hid-noevents@^5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.34.0.tgz#c31cc3e3033f6fbf77b81c3a9c34230aadd6f3cb" - integrity sha512-n5KRdZ6nmDrmsEXFjIipNdx9rhHbEFmZ5YDoUkdShvKFmaDeKVn0h7RCBwblJRITUZl0RfBzBuBRlpNjQsFfqg== +"@ledgerhq/hw-transport-node-hid-noevents@^5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.36.0.tgz#a25bdf0d10f9eac73148040e5887f40ca46f6a93" + integrity sha512-8zwokin0KFJaTzhy7oLVcy4QCNUjMuc49wPLnr3zxLqhO1innMp2crUxjIFNLRGJm/TfDLnlpxTPud6WZoo5zg== dependencies: - "@ledgerhq/devices" "^5.34.0" - "@ledgerhq/errors" "^5.34.0" - "@ledgerhq/hw-transport" "^5.34.0" - "@ledgerhq/logs" "^5.30.0" - node-hid "2.0.0-0" + "@ledgerhq/devices" "^5.36.0" + "@ledgerhq/errors" "^5.36.0" + "@ledgerhq/hw-transport" "^5.36.0" + "@ledgerhq/logs" "^5.36.0" + node-hid "2.1.1" -"@ledgerhq/hw-transport-node-hid-singleton@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-singleton/-/hw-transport-node-hid-singleton-5.34.0.tgz#1bba566a28efe0bbb31c1c2f214ca574a7b69104" - integrity sha512-RMgWafAyHyZtQjVe1dwu90oSsQ4W/4CpSx2ps87u5sDyWyNURti2pdraDZ1kosLhqTEYedU3VfTV4EFJZ5yfuw== +"@ledgerhq/hw-transport-node-hid-singleton@5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-singleton/-/hw-transport-node-hid-singleton-5.36.0.tgz#99cedb773e571642d7f151c3134c5924147bc0d8" + integrity sha512-eKkJGXW0m7PeJY7V/7FDfU4VFLIVSRjxi7PpfJKFYlUrRwx9QndlZT0LD0u3W9dLktgounHhsOuXvuG44uTHYA== dependencies: - "@ledgerhq/devices" "^5.34.0" - "@ledgerhq/errors" "^5.34.0" - "@ledgerhq/hw-transport" "^5.34.0" - "@ledgerhq/hw-transport-node-hid-noevents" "^5.34.0" - "@ledgerhq/logs" "^5.30.0" + "@ledgerhq/devices" "^5.36.0" + "@ledgerhq/errors" "^5.36.0" + "@ledgerhq/hw-transport" "^5.36.0" + "@ledgerhq/hw-transport-node-hid-noevents" "^5.36.0" + "@ledgerhq/logs" "^5.36.0" lodash "^4.17.20" - node-hid "2.0.0-0" + node-hid "2.1.1" usb-detection "^4.10.0" "@ledgerhq/hw-transport-u2f@^5.21.0": @@ -1887,19 +1842,19 @@ "@ledgerhq/logs" "^5.30.0" u2f-api "0.2.7" -"@ledgerhq/hw-transport@^5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.34.0.tgz#b27eb0d9941a2e6220e5af3e3d4f48ce8a993982" - integrity sha512-JxhqU9sBn+WH3CPMus9b70SED7LEeW17xw0VL5aRdxFu4YS5rhy5Xf4Sd5jIQfyDkHik1ouzfJVuQEju8+GGBw== +"@ledgerhq/hw-transport@^5.34.0", "@ledgerhq/hw-transport@^5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.36.0.tgz#b6e951c411182ece59c7b527f948240d1b0a8a51" + integrity sha512-rwLTBUsdGCC3Ka4G99sqGbbyVhkVxXd4eWWeOb8gnuKhrTydZGkkP3JdZSHgWSrVRYTAUmkE1AnUmchbfh361w== dependencies: - "@ledgerhq/devices" "^5.34.0" - "@ledgerhq/errors" "^5.34.0" + "@ledgerhq/devices" "^5.36.0" + "@ledgerhq/errors" "^5.36.0" events "^3.2.0" -"@ledgerhq/logs@^5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.30.0.tgz#76e8d7e5a06a73c9b99da51fa5befd5cfd5309d4" - integrity sha512-wUhg2VTfUrWihjdGqKkH/s7TBzdIM1yyd2LiscYsfTX2I0xYDMnpE+NkMReeGU8PN3QhCPgnlg9/P9V6UWoJBA== +"@ledgerhq/logs@^5.30.0", "@ledgerhq/logs@^5.36.0": + version "5.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.36.0.tgz#78721347162fb834d90effa1123b363dc46e3a52" + integrity sha512-HnD/hByteUL1MsJu1lMinY9bNq8++5mWJ8qHCW9dLC9LbsvWIqwLwmZiGcW0D2tX9p0/C5ESuIpJ9B/d2dReuw== "@material-ui/core@^4.11.0": version "4.11.2" @@ -1919,10 +1874,10 @@ react-is "^16.8.0 || ^17.0.0" react-transition-group "^4.4.0" -"@material-ui/icons@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665" - integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg== +"@material-ui/icons@^4.11.0": + version "4.11.2" + resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.11.2.tgz#b3a7353266519cd743b6461ae9fdfcb1b25eb4c5" + integrity sha512-fQNsKX2TxBmqIGJCSi3tGTO/gZ+eJgWmMJkgDiOfyNaunNaxcklJQFaFogYcFl0qFuaEz1qaXYXboa/bUXVSOQ== dependencies: "@babel/runtime" "^7.4.4" @@ -1983,6 +1938,11 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" +"@metamask/safe-event-emitter@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-2.0.0.tgz#af577b477c683fad17c619a78208cede06f9605c" + integrity sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q== + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" @@ -1991,18 +1951,18 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@nodelib/fs.scandir@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" - integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== +"@nodelib/fs.scandir@2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" + integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA== dependencies: - "@nodelib/fs.stat" "2.0.3" + "@nodelib/fs.stat" "2.0.4" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" - integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== +"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655" + integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q== "@nodelib/fs.stat@^1.1.2": version "1.1.3" @@ -2010,11 +1970,11 @@ integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== "@nodelib/fs.walk@^1.2.3": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" - integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + version "1.2.6" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063" + integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow== dependencies: - "@nodelib/fs.scandir" "2.1.3" + "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" "@npmcli/move-file@^1.0.1": @@ -2029,6 +1989,16 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.1.0.tgz#bcea457ef89069fbe5a617f50b25b6a8272895d5" integrity sha512-dVXDnUKxrAKLzPdCRkz+N8qsVkK1XxJ6kk3zuI6zaQmcKxN7CkizoDP7lXxcs/Mi2I0mxceTRjJBqlzFffLJrQ== +"@pedrouid/iso-crypto@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@pedrouid/iso-crypto/-/iso-crypto-1.0.0.tgz#cf06b40ef3da3d7ca7363bd7a521ed59fa2fd13d" + integrity sha512-gSz/81Cz2n9p1RHalxN8STtOHg6Dqa+l2Phz36GptpneAcAwOzPmty7FSg58htF4u9V44vEXsc7L8V9ze9j4Xg== + dependencies: + aes-js "^3.1.2" + enc-utils "^3.0.0" + hash.js "^1.1.7" + randombytes "^2.1.0" + "@pmmmwh/react-refresh-webpack-plugin@0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.2.tgz#1f9741e0bde9790a0e13272082ed7272a083620d" @@ -2138,20 +2108,20 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@sentry/browser@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.29.0.tgz#a8cab91729c759c456bd2254cef65bafa5cdc4ea" - integrity sha512-kRlt1mE2wrYjspnIupNnPxqsUrRuy02SuXhbpP7J6uu8QasoEmJ78hk0hHz4jOZRmuWwfs2zIXD4tLGgWOKq8A== +"@sentry/browser@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.29.2.tgz#51adb4005511b1a4a70e4571880fc6653d651f91" + integrity sha512-uxZ7y7rp85tJll+RZtXRhXPbnFnOaxZqJEv05vJlXBtBNLQtlczV5iCtU9mZRLVHDtmZ5VVKUV8IKXntEqqDpQ== dependencies: - "@sentry/core" "5.29.0" - "@sentry/types" "5.29.0" - "@sentry/utils" "5.29.0" + "@sentry/core" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" tslib "^1.9.3" "@sentry/cli@^1.59.0": - version "1.60.1" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.60.1.tgz#ec42f84f44e329f6d1da77051afe15284352e06c" - integrity sha512-pShmK+V4jWxSsdM2LPZm5nyaG8sS5m1ukSZiJdmE0jpj4G4aXM4B1pRovv9ePSkoJdAGnpesX+A/zEvISa8FOw== + version "1.61.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.61.0.tgz#98be4cce2d61df91a8cb42afb740b46eba029925" + integrity sha512-pHEhqP1bB4sdO7N5ow/IkRBrPbKT9HZRinq4PhTVIvmG+NW4VVuVZ6k4tlbp+JXmzMcUc/iXynVkTL7zJIlTQw== dependencies: https-proxy-agent "^5.0.0" mkdirp "^0.5.5" @@ -2159,69 +2129,69 @@ progress "^2.0.3" proxy-from-env "^1.1.0" -"@sentry/core@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.0.tgz#4410ca0dc5785abf3df02fa23c18e83ad90d7cda" - integrity sha512-a1sZBJ2u3NG0YDlGvOTwUCWiNjhfmDtAQiKK1o6RIIbcrWy9TlSps7CYDkBP239Y3A4pnvohjEEKEP3v3L3LZQ== +"@sentry/core@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.29.2.tgz#9e05fe197234161d57aabaf52fab336a7c520d81" + integrity sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw== dependencies: - "@sentry/hub" "5.29.0" - "@sentry/minimal" "5.29.0" - "@sentry/types" "5.29.0" - "@sentry/utils" "5.29.0" + "@sentry/hub" "5.29.2" + "@sentry/minimal" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" tslib "^1.9.3" -"@sentry/hub@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.0.tgz#d018b978fdffc6c8261744b0d08e8d25a3f4dc58" - integrity sha512-kcDPQsRG4cFdmqDh+TzjeO7lWYxU8s1dZYAbbl1J4uGKmhNB0J7I4ak4SGwTsXLY6fhbierxr6PRaoNojCxjPw== +"@sentry/hub@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.29.2.tgz#208f10fe6674695575ad74182a1151f71d6df00a" + integrity sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ== dependencies: - "@sentry/types" "5.29.0" - "@sentry/utils" "5.29.0" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" tslib "^1.9.3" -"@sentry/minimal@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.0.tgz#bd8b52f388abcec2234dbbc6d6721ff65aa30e35" - integrity sha512-nhXofdjtO41/caiF1wk1oT3p/QuhOZDYdF/b29DoD2MiAMK9IjhhOXI/gqaRpDKkXlDvd95fDTcx4t/MqqcKXA== +"@sentry/minimal@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.29.2.tgz#420bebac8d03d30980fdb05c72d7b253d8aa541b" + integrity sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw== dependencies: - "@sentry/hub" "5.29.0" - "@sentry/types" "5.29.0" + "@sentry/hub" "5.29.2" + "@sentry/types" "5.29.2" tslib "^1.9.3" "@sentry/react@^5.28.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.29.0.tgz#367bf4113c4abc6477385383013aaaa381668baa" - integrity sha512-caSdAf+XqNrFw5xAj4gyOSd/33IccVhMlu60MuOOs6B6C3YxbMWUBTSuHeyxgK671ufIA+sxvipzMSVYr4VRAQ== + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.29.2.tgz#e0e2055db6f9c7a3957630e726b23d6a0f2d12f2" + integrity sha512-Fvh4l6/wrnO3FWqte7lPUsuWE5o6t3FHwZqVINgCIabpwPMorvOVzm/gwG7uzhuCoyNTP28svR670sl4BnRuTg== dependencies: - "@sentry/browser" "5.29.0" - "@sentry/minimal" "5.29.0" - "@sentry/types" "5.29.0" - "@sentry/utils" "5.29.0" + "@sentry/browser" "5.29.2" + "@sentry/minimal" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" hoist-non-react-statics "^3.3.2" tslib "^1.9.3" "@sentry/tracing@^5.28.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.0.tgz#8ed515b3f9d409137357c38c8622858f9e684e4a" - integrity sha512-2ZITUH7Eur7IkmRAd5gw8Xt2Sfc28btCnT7o2P2J8ZPD65e99ATqjxXPokx0+6zEkTsstIDD3mbyuwkpbuvuTA== + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.29.2.tgz#6012788547d2ab7893799d82c4941bda145dcd47" + integrity sha512-iumYbVRpvoU3BUuIooxibydeaOOjl5ysc+mzsqhRs2NGW/C3uKAsFXdvyNfqt3bxtRQwJEhwJByLP2u3pLThpw== dependencies: - "@sentry/hub" "5.29.0" - "@sentry/minimal" "5.29.0" - "@sentry/types" "5.29.0" - "@sentry/utils" "5.29.0" + "@sentry/hub" "5.29.2" + "@sentry/minimal" "5.29.2" + "@sentry/types" "5.29.2" + "@sentry/utils" "5.29.2" tslib "^1.9.3" -"@sentry/types@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.0.tgz#af5cec98cde54316c14df3121f0e8106e56b578e" - integrity sha512-iDkxT/9sT3UF+Xb+JyLjZ5caMXsgLfRyV9VXQEiR2J6mgpMielj184d9jeF3bm/VMuAf/VFFqrHlcVsVgmrrMw== +"@sentry/types@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.29.2.tgz#ac87383df1222c2d9b9f8f9ed7a6b86ea41a098a" + integrity sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA== -"@sentry/utils@5.29.0": - version "5.29.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.0.tgz#b4c1223ba362a94cf4850e9ca2cb24655b006b53" - integrity sha512-b2B1gshw2u3EHlAi84PuI5sfmLKXW1z9enMMhNuuNT/CoRp+g5kMAcUv/qYTws7UNnYSvTuVGuZG30v1e0hP9A== +"@sentry/utils@5.29.2": + version "5.29.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.29.2.tgz#99a5cdda2ea19d34a41932f138d470adcb3ee673" + integrity sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ== dependencies: - "@sentry/types" "5.29.0" + "@sentry/types" "5.29.2" tslib "^1.9.3" "@sideway/address@^4.1.0": @@ -2862,10 +2832,10 @@ lz-string "^1.4.4" pretty-format "^26.6.2" -"@testing-library/jest-dom@5.11.6": - version "5.11.6" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.11.6.tgz#782940e82e5cd17bc0a36f15156ba16f3570ac81" - integrity sha512-cVZyUNRWwUKI0++yepYpYX7uhrP398I+tGz4zOlLVlUYnZS+Svuxv4fwLeCIy7TnBYKXUaOlQr3vopxL8ZfEnA== +"@testing-library/jest-dom@^5.11.6": + version "5.11.8" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.11.8.tgz#433a84d6f9a089485101b9e112ef03e5c30bcbfc" + integrity sha512-ScyKrWQM5xNcr79PkSewnA79CLaoxVskE+f7knTOhDD9ftZSA1Jw8mj+pneqhEu3x37ncNfW84NUr7lqK+mXjA== dependencies: "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" @@ -2876,7 +2846,7 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react@11.2.2": +"@testing-library/react@^11.2.2": version "11.2.2" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.2.tgz#099c6c195140ff069211143cb31c0f8337bdb7b7" integrity sha512-jaxm0hwUjv+hzC+UFEywic7buDC9JQ1q3cDsrWVSDAPmLotfA6E6kUHlYm/zOeGCac6g48DR36tFHxl7Zb+N5A== @@ -2896,10 +2866,10 @@ optionalDependencies: secp256k1 "^3.8.0" -"@toruslabs/fetch-node-details@^2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@toruslabs/fetch-node-details/-/fetch-node-details-2.3.2.tgz#22d110ccd2543b5665df87c92f18fd6ea8dee598" - integrity sha512-rYtyeoA9s66w3ZgjuNJ5b3kBHc7JWOHXSZjtK4+1EMa5znjG+dz7UCv6EeYX5gtMGIz7K8zQylAxZfsBsssTLw== +"@toruslabs/fetch-node-details@^2.3.3": + version "2.3.3" + resolved "https://registry.yarnpkg.com/@toruslabs/fetch-node-details/-/fetch-node-details-2.3.3.tgz#bfe98e8067cc7a05a7503b08a7cb1d4d0c9e5c84" + integrity sha512-dYiaolDqkGVrVQKfJt1WDAiUGl99nSoNHHYRR37/TQdDonYVDKpQ8Em/j4z8RkMbRfgYYRKtbKaXdQTGA6VieQ== dependencies: web3-eth-contract "^1.3.0" web3-utils "^1.3.0" @@ -2911,40 +2881,40 @@ dependencies: deepmerge "^4.2.2" -"@toruslabs/torus-embed@^1.8.2": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@toruslabs/torus-embed/-/torus-embed-1.9.0.tgz#8b5ad6061f99ea651c097041bcf518615ab703f2" - integrity sha512-aSXttX5p4az0cwbAtjZHaqDdlei5mjBRiU7ndVBSX6Ay0j8HT/oCihZayTP09UTbuEtUdbEt/GFCyLQBFGKnmA== +"@toruslabs/torus-embed@^1.9.2": + version "1.9.2" + resolved "https://registry.yarnpkg.com/@toruslabs/torus-embed/-/torus-embed-1.9.2.tgz#dad0e0472d81ff7ca68a860a0025232cc557697b" + integrity sha512-giePkl3/MiepwJs1aXhwFq7fTE6Eo+U6ggMhWs2IPkWH0A0hL82W7S2e2LcNBxvGPy2nJ8oh/hblKypFTdxjPA== dependencies: "@chaitanyapotti/random-id" "^1.0.3" - "@toruslabs/fetch-node-details" "^2.3.2" + "@toruslabs/fetch-node-details" "^2.3.3" "@toruslabs/http-helpers" "^1.3.5" - "@toruslabs/torus.js" "^2.2.9" + "@toruslabs/torus.js" "^2.2.10" create-hash "^1.2.0" deepmerge "^4.2.2" - eth-rpc-errors "^3.0.0" + eth-rpc-errors "^4.0.2" fast-deep-equal "^3.1.3" is-stream "^2.0.0" - json-rpc-engine "^5.4.0" - json-rpc-middleware-stream "^2.1.1" - loglevel "^1.7.0" + json-rpc-engine "^6.1.0" + json-rpc-middleware-stream "^3.0.0" + loglevel "^1.7.1" obj-multiplex "^1.0.0" obs-store "^4.0.3" post-message-stream "^3.0.0" pump "^3.0.0" safe-event-emitter "^1.0.1" -"@toruslabs/torus.js@^2.2.9": - version "2.2.9" - resolved "https://registry.yarnpkg.com/@toruslabs/torus.js/-/torus.js-2.2.9.tgz#8e196ecd02bfac0c7c4530025b3a94b0641f75f8" - integrity sha512-fwLp5aZKloSIAsgtlCP1hCVVV+eLVf6KDKggs9ilPjrBbYZCDgQXpGTTddtey0LCTOHYGuvE7IX+OGe7gIvypQ== +"@toruslabs/torus.js@^2.2.10": + version "2.2.12" + resolved "https://registry.yarnpkg.com/@toruslabs/torus.js/-/torus.js-2.2.12.tgz#beffc6715f4bf796feea35db814621faa4104663" + integrity sha512-6IpZBLjBRHQgPWQjxPgaxMCKsVIC6m/9tcG41XsvK//g0DsVZ15g8cUFhngBUEavzFV59fF+KHOR47PBpadKSg== dependencies: "@toruslabs/eccrypto" "^1.1.5" "@toruslabs/http-helpers" "^1.3.5" bn.js "^5.1.3" elliptic "^6.5.3" json-stable-stringify "^1.0.1" - loglevel "^1.7.0" + loglevel "^1.7.1" memory-cache "^0.2.0" web3-utils "^1.3.0" @@ -2955,14 +2925,14 @@ dependencies: source-map-support "^0.5.19" -"@truffle/codec@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.9.1.tgz#24fdb3f7f7471592db50756531d47094cae82343" - integrity sha512-U+n5ZYWSJzPVoj4zNMta2glUV4rRVcFNANE4r3SQyogbdZpp/HRioacqkF3wVPXRhX3F0hOcySK4MeuMOSseOg== +"@truffle/codec@^0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.9.4.tgz#738187e6afc74a0a67dc201762b6ccb8121712d5" + integrity sha512-EAx/6Dg8Dj/O6/zqXpp4Q9OtxKmPKItmHWD91FM7bOXvX71wx66XZqIxD7ORjLEzQqYfJj81ttSnOZgpGxj3RA== dependencies: big.js "^5.2.2" bn.js "^4.11.8" - borc "^2.1.2" + cbor "^5.1.0" debug "^4.1.0" lodash.clonedeep "^4.5.0" lodash.escaperegexp "^4.1.2" @@ -2973,23 +2943,23 @@ utf8 "^3.0.0" web3-utils "1.2.9" -"@truffle/contract-schema@^3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.3.2.tgz#6450738c35859ed087760d826031a8247f7bc907" - integrity sha512-PFNUHlcMFh6CDLDXTYCpm1G5rM5EJlneA9ml5y1TbkLgjLMICI2XLilimFZ/DC0THQekHpoQC+W/QMD/OTiTiw== +"@truffle/contract-schema@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.3.3.tgz#3e9567596d5dd9843df195cc3a874b83246c2505" + integrity sha512-4bvcEoGycopJBPoCiqHP5Q72/1t/ixYS/pVHru+Rzvad641BgvoGrkd4YnyJ+E/MVb4ZLrndL7whmdGqV5B7SA== dependencies: ajv "^6.10.0" crypto-js "^3.1.9-1" debug "^4.1.0" -"@truffle/contract@4.2.30": - version "4.2.30" - resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.2.30.tgz#44a2a20e4baa6b40cbb0748a6bce997c22865bcd" - integrity sha512-BXQC+ddH18W9cVoRTlKH7hqnyrOo0HN7/Hyv7UiAgPh4JNpkZVUxFSd+/MLaE5r8NEG2hykDusOVJ3OaR9wvmw== +"@truffle/contract@^4.3.0": + version "4.3.5" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.3.5.tgz#360434b09bbf9a8d34ed2f7075f40d36509b180c" + integrity sha512-08gLSId+spnXqdM/25pOiurNcSBeCBa6KrplCgojy1RvqlG8JbEa9jXHWt1DCACZTtSnCsC2ywSNxAKRb4HqIA== dependencies: "@truffle/blockchain-utils" "^0.0.25" - "@truffle/contract-schema" "^3.3.2" - "@truffle/debug-utils" "^5.0.1" + "@truffle/contract-schema" "^3.3.3" + "@truffle/debug-utils" "^5.0.8" "@truffle/error" "^0.0.11" "@truffle/interface-adapter" "^0.4.18" bignumber.js "^7.2.1" @@ -3002,17 +2972,18 @@ web3-eth-abi "1.2.9" web3-utils "1.2.9" -"@truffle/debug-utils@^5.0.1": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-5.0.4.tgz#4b7bb18bc9434563d014d58956aba18198ce7148" - integrity sha512-iIZB6TVKqqwNDjQDEgzbruU7SGX+tr+d/Il8OiIqEfS2x0inJ6TeRgbsOCecOTdlBa/6F0Cq11rM0H8trC8YGg== +"@truffle/debug-utils@^5.0.8": + version "5.0.8" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-5.0.8.tgz#681c2bb595750c768f9a17f5c47facef19181044" + integrity sha512-2YzZzhhbZnUr+zQSiqkjF9cwwUPBFyMuH2/iGvjR+9l3+gpOm9+psN658dCziLV0qwiME4Tor4pIW7FnOEDegQ== dependencies: - "@truffle/codec" "^0.9.1" - "@trufflesuite/chromafi" "^2.2.1" + "@truffle/codec" "^0.9.4" + "@trufflesuite/chromafi" "^2.2.2" + bn.js "^5.1.3" chalk "^2.4.2" debug "^4.1.0" highlight.js "^10.4.0" - highlightjs-solidity "^1.0.19" + highlightjs-solidity "^1.0.20" "@truffle/error@^0.0.11": version "0.0.11" @@ -3045,7 +3016,7 @@ source-map-support "^0.5.19" web3 "1.2.9" -"@trufflesuite/chromafi@^2.2.1": +"@trufflesuite/chromafi@^2.2.2": version "2.2.2" resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-2.2.2.tgz#d3fc507aa8504faffc50fb892cedcfe98ff57f77" integrity sha512-mItQwVBsb8qP/vaYHQ1kDt2vJLhjoEXJptT6y6fJGvFophMFhOI/NsTVUa0nJL1nyMeFiS6hSYuNVdpQZzB1gA== @@ -3291,9 +3262,9 @@ "@types/istanbul-lib-report" "*" "@types/jest@*", "@types/jest@^26.0.16": - version "26.0.18" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.18.tgz#3c5f9228e9ac15bd42f903f1acf2ad6ea5ed73d9" - integrity sha512-scDPs+mELZgsFetTgBSsIxKGrlitn9t/d2ecP+S1QSIGD+31fkMBEftLfOAX5k3tU06/0PjreJIQ+gWEbbHqpw== + version "26.0.19" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.19.tgz#e6fa1e3def5842ec85045bd5210e9bb8289de790" + integrity sha512-jqHoirTG61fee6v6rwbnEuKhpSKih0tuhqeFbCmMmErhtu3BYlOZaXWjffgOstMM4S/3iQD31lI5bGLTrs97yQ== dependencies: jest-diff "^26.0.0" pretty-format "^26.0.0" @@ -3333,19 +3304,19 @@ "@types/node" "*" "@types/node@*", "@types/node@^14.14.10": - version "14.14.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.11.tgz#fc25a4248a5e8d0837019b1d170146d07334abe0" - integrity sha512-BJ97wAUuU3NUiUCp44xzUFquQEvnk1wu7q4CMEUYKJWjdkr0YWYDsm4RFtAvxYsNjLsKcrFt6RvK8r+mnzMbEQ== + version "14.14.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.20.tgz#f7974863edd21d1f8a494a73e8e2b3658615c340" + integrity sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A== "@types/node@^10.12.18": - version "10.17.48" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.48.tgz#726e7f25d00bf58d79c8f00dd586dd9a10d06a4f" - integrity sha512-Agl6xbYP6FOMDeAsr3QVZ+g7Yzg0uhPHWx0j5g4LFdUBHVtqtU+gH660k/lCEe506jJLOGbEzsnqPDTZGJQLag== + version "10.17.50" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.50.tgz#7a20902af591282aa9176baefc37d4372131c32d" + integrity sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA== "@types/node@^12.0.12", "@types/node@^12.12.6", "@types/node@^12.6.1": - version "12.19.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.8.tgz#efd6d1a90525519fc608c9db16c8a78f7693a978" - integrity sha512-D4k2kNi0URNBxIRCb1khTnkWNHv8KSL1owPmS/K5e5t8B2GzMReY7AsJIY1BnP5KdlgC4rj9jk2IkDMasIE7xg== + version "12.19.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.12.tgz#04793c2afa4ce833a9972e4c476432e30f9df47b" + integrity sha512-UwfL2uIU9arX/+/PRcIkT08/iBadGN2z6ExOROA2Dh5mAuWTBj6iJbQX4nekiV5H8cTrEG569LeX+HRco9Cbxw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -3400,16 +3371,16 @@ "@types/react" "^16" "@types/react-native@*": - version "0.63.37" - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.37.tgz#c43df90c9d3cc082a97a49a53e989de26cb8ab45" - integrity sha512-xr9SZG7tQQBKT6840tAGaWEC65D2gjyxZtuZxz631UgeW1ofItuu9HMVhoyYqot2hRSa6Q4YC8FYkRVUpM53/w== + version "0.63.42" + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.63.42.tgz#d0baf405edc646d15d5a7f8e67983b8701c1ea2a" + integrity sha512-zb7m2Uwfz6MQh/Nq1DDAmzTRO+EQWV7ZyRl9ZZ2QLd1480xjRjPDQqRkp4vuk3gyRlQtwi0v9I3tOh2IxHFujw== dependencies: "@types/react" "*" "@types/react-redux@^7.1.11": - version "7.1.11" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.11.tgz#a18e8ab3651e8e8cc94798934927937c66021217" - integrity sha512-OjaFlmqy0CRbYKBoaWF84dub3impqnLJUrz4u8PRjDzaa4n1A2cVmjMV81shwXyAD5x767efhA8STFGJz/r1Zg== + version "7.1.15" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.15.tgz#19075884db94101be762accef924d266a603fb1b" + integrity sha512-+piY42tUflPfI7y9Vy3UkG6MEMuJlrxfdtgeUcWmd5Z0qB57NXAPG6smkqu1DNXluo/KDyXPeRYhcFzMwt1BEA== dependencies: "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" @@ -3417,18 +3388,18 @@ redux "^4.0.0" "@types/react-router-dom@^5.1.6": - version "5.1.6" - resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.6.tgz#07b14e7ab1893a837c8565634960dc398564b1fb" - integrity sha512-gjrxYqxz37zWEdMVvQtWPFMFj1dRDb4TGOcgyOfSXTrEXdF92L00WE3C471O3TV/RF1oskcStkXsOU0Ete4s/g== + version "5.1.7" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.1.7.tgz#a126d9ea76079ffbbdb0d9225073eb5797ab7271" + integrity sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg== dependencies: "@types/history" "*" "@types/react" "*" "@types/react-router" "*" "@types/react-router@*": - version "5.1.8" - resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.8.tgz#4614e5ba7559657438e17766bb95ef6ed6acc3fa" - integrity sha512-HzOyJb+wFmyEhyfp4D4NYrumi+LQgQL/68HvJO+q6XtuHSDvw6Aqov7sCAhjbNq3bUPgPqbdvjXC5HeB2oEAPg== + version "5.1.9" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.9.tgz#92a5558f22243d45f90e7699812c342bd98ba41e" + integrity sha512-US6C0rq2Wt/7uje1roqO0R++Sr0jqplKaBChDY5sNg5k7GC/79YFK0ZsLEdemqUjW05wq1Y/9YYEUgfNZ8TlvA== dependencies: "@types/history" "*" "@types/react" "*" @@ -3500,9 +3471,9 @@ integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== "@types/styled-components@^5.1.4": - version "5.1.4" - resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.4.tgz#11f167dbde268635c66adc89b5a5db2e69d75384" - integrity sha512-78f5Zuy0v/LTQNOYfpH+CINHpchzMMmAt9amY2YNtSgsk1TmlKm8L2Wijss/mtTrsUAVTm2CdGB8VOM65vA8xg== + version "5.1.5" + resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.5.tgz#a98e2ead1a1c7660b966f3aade4df9c0ec8ed75a" + integrity sha512-VWwoKm39W783a75oILtdCjnNn+FSV8Yh3O9naIudtZCAkk+rRfwLWzuPjf5k/OilENgZqAkxJ9sukSOZTAD86g== dependencies: "@types/hoist-non-react-statics" "*" "@types/react" "*" @@ -3567,34 +3538,47 @@ integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== "@types/yargs@^15.0.0", "@types/yargs@^15.0.5": - version "15.0.11" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c" - integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA== + version "15.0.12" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.12.tgz#6234ce3e3e3fa32c5db301a170f96a599c960d74" + integrity sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.5.0", "@typescript-eslint/eslint-plugin@^4.6.0": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.9.1.tgz#66758cbe129b965fe9c63b04b405d0cf5280868b" - integrity sha512-QRLDSvIPeI1pz5tVuurD+cStNR4sle4avtHhxA+2uyixWGFjKzJ+EaFVRW6dA/jOgjV5DTAjOxboQkRDE8cRlQ== + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.13.0.tgz#5f580ea520fa46442deb82c038460c3dd3524bb6" + integrity sha512-ygqDUm+BUPvrr0jrXqoteMqmIaZ/bixYOc3A4BRwzEPTZPi6E+n44rzNZWaB0YvtukgP+aoj0i/fyx7FkM2p1w== dependencies: - "@typescript-eslint/experimental-utils" "4.9.1" - "@typescript-eslint/scope-manager" "4.9.1" + "@typescript-eslint/experimental-utils" "4.13.0" + "@typescript-eslint/scope-manager" "4.13.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" + lodash "^4.17.15" regexpp "^3.0.0" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.9.1", "@typescript-eslint/experimental-utils@^4.0.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.9.1.tgz#86633e8395191d65786a808dc3df030a55267ae2" - integrity sha512-c3k/xJqk0exLFs+cWSJxIjqLYwdHCuLWhnpnikmPQD2+NGAx9KjLYlBDcSI81EArh9FDYSL6dslAUSwILeWOxg== +"@typescript-eslint/experimental-utils@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.12.0.tgz#372838e76db76c9a56959217b768a19f7129546b" + integrity sha512-MpXZXUAvHt99c9ScXijx7i061o5HEjXltO+sbYfZAAHxv3XankQkPaNi5myy0Yh0Tyea3Hdq1pi7Vsh0GJb0fA== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.9.1" - "@typescript-eslint/types" "4.9.1" - "@typescript-eslint/typescript-estree" "4.9.1" + "@typescript-eslint/scope-manager" "4.12.0" + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/typescript-estree" "4.12.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@4.13.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.13.0.tgz#9dc9ab375d65603b43d938a0786190a0c72be44e" + integrity sha512-/ZsuWmqagOzNkx30VWYV3MNB/Re/CGv/7EzlqZo5RegBN8tMuPaBgNK6vPBCQA8tcYrbsrTdbx3ixMRRKEEGVw== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.13.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/typescript-estree" "4.13.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -3610,32 +3594,45 @@ eslint-utils "^2.0.0" "@typescript-eslint/parser@^4.5.0", "@typescript-eslint/parser@^4.6.0": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.9.1.tgz#2d74c4db5dd5117379a9659081a4d1ec02629055" - integrity sha512-Gv2VpqiomvQ2v4UL+dXlQcZ8zCX4eTkoIW+1aGVWT6yTO+6jbxsw7yQl2z2pPl/4B9qa5JXeIbhJpONKjXIy3g== + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.13.0.tgz#c413d640ea66120cfcc37f891e8cb3fd1c9d247d" + integrity sha512-KO0J5SRF08pMXzq9+abyHnaGQgUJZ3Z3ax+pmqz9vl81JxmTTOUfQmq7/4awVfq09b6C4owNlOgOwp61pYRBSg== dependencies: - "@typescript-eslint/scope-manager" "4.9.1" - "@typescript-eslint/types" "4.9.1" - "@typescript-eslint/typescript-estree" "4.9.1" + "@typescript-eslint/scope-manager" "4.13.0" + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/typescript-estree" "4.13.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.9.1.tgz#cc2fde310b3f3deafe8436a924e784eaab265103" - integrity sha512-sa4L9yUfD/1sg9Kl8OxPxvpUcqxKXRjBeZxBuZSSV1v13hjfEJkn84n0An2hN8oLQ1PmEl2uA6FkI07idXeFgQ== +"@typescript-eslint/scope-manager@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.12.0.tgz#beeb8beca895a07b10c593185a5612f1085ef279" + integrity sha512-QVf9oCSVLte/8jvOsxmgBdOaoe2J0wtEmBr13Yz0rkBNkl5D8bfnf6G4Vhox9qqMIoG7QQoVwd2eG9DM/ge4Qg== dependencies: - "@typescript-eslint/types" "4.9.1" - "@typescript-eslint/visitor-keys" "4.9.1" + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/visitor-keys" "4.12.0" + +"@typescript-eslint/scope-manager@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.13.0.tgz#5b45912a9aa26b29603d8fa28f5e09088b947141" + integrity sha512-UpK7YLG2JlTp/9G4CHe7GxOwd93RBf3aHO5L+pfjIrhtBvZjHKbMhBXTIQNkbz7HZ9XOe++yKrXutYm5KmjWgQ== + dependencies: + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/visitor-keys" "4.13.0" "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== -"@typescript-eslint/types@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.9.1.tgz#a1a7dd80e4e5ac2c593bc458d75dd1edaf77faa2" - integrity sha512-fjkT+tXR13ks6Le7JiEdagnwEFc49IkOyys7ueWQ4O8k4quKPwPJudrwlVOJCUQhXo45PrfIvIarcrEjFTNwUA== +"@typescript-eslint/types@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.12.0.tgz#fb891fe7ccc9ea8b2bbd2780e36da45d0dc055e5" + integrity sha512-N2RhGeheVLGtyy+CxRmxdsniB7sMSCfsnbh8K/+RUIXYYq3Ub5+sukRCjVE80QerrUBvuEvs4fDhz5AW/pcL6g== + +"@typescript-eslint/types@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.13.0.tgz#6a7c6015a59a08fbd70daa8c83dfff86250502f8" + integrity sha512-/+aPaq163oX+ObOG00M0t9tKkOgdv9lq0IQv/y4SqGkAXmhFmCfgsELV7kOCTb2vVU5VOmVwXBXJTDr353C1rQ== "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" @@ -3651,13 +3648,27 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.9.1.tgz#6e5b86ff5a5f66809e1f347469fadeec69ac50bf" - integrity sha512-bzP8vqwX6Vgmvs81bPtCkLtM/Skh36NE6unu6tsDeU/ZFoYthlTXbBmpIrvosgiDKlWTfb2ZpPELHH89aQjeQw== +"@typescript-eslint/typescript-estree@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.12.0.tgz#3963418c850f564bdab3882ae23795d115d6d32e" + integrity sha512-gZkFcmmp/CnzqD2RKMich2/FjBTsYopjiwJCroxqHZIY11IIoN0l5lKqcgoAPKHt33H2mAkSfvzj8i44Jm7F4w== dependencies: - "@typescript-eslint/types" "4.9.1" - "@typescript-eslint/visitor-keys" "4.9.1" + "@typescript-eslint/types" "4.12.0" + "@typescript-eslint/visitor-keys" "4.12.0" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/typescript-estree@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.13.0.tgz#cf6e2207c7d760f5dfd8d18051428fadfc37b45e" + integrity sha512-9A0/DFZZLlGXn5XA349dWQFwPZxcyYyCFX5X88nWs2uachRDwGeyPz46oTsm9ZJE66EALvEns1lvBwa4d9QxMg== + dependencies: + "@typescript-eslint/types" "4.13.0" + "@typescript-eslint/visitor-keys" "4.13.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -3672,12 +3683,20 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.9.1.tgz#d76374a58c4ead9e92b454d186fea63487b25ae1" - integrity sha512-9gspzc6UqLQHd7lXQS7oWs+hrYggspv/rk6zzEMhCbYwPE/sF7oxo7GAjkS35Tdlt7wguIG+ViWCPtVZHz/ybQ== +"@typescript-eslint/visitor-keys@4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.12.0.tgz#a470a79be6958075fa91c725371a83baf428a67a" + integrity sha512-hVpsLARbDh4B9TKYz5cLbcdMIOAoBYgFPCSP9FFS/liSF+b33gVNq8JHY3QGhHNVz85hObvL7BEYLlgx553WCw== dependencies: - "@typescript-eslint/types" "4.9.1" + "@typescript-eslint/types" "4.12.0" + eslint-visitor-keys "^2.0.0" + +"@typescript-eslint/visitor-keys@4.13.0": + version "4.13.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.13.0.tgz#9acb1772d3b3183182b6540d3734143dce9476fe" + integrity sha512-6RoxWK05PAibukE7jElqAtNMq+RWZyqJ6Q/GdIxaiUj2Ept8jh8+FUVlbq9WxMYxkmEOPvCE5cRSyupMpwW31g== + dependencies: + "@typescript-eslint/types" "4.13.0" eslint-visitor-keys "^2.0.0" "@unilogin/provider@^0.6.1": @@ -3688,80 +3707,82 @@ "@restless/sanitizers" "^0.2.5" reactive-properties "^0.1.11" -"@walletconnect/client@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/client/-/client-1.3.1.tgz#5b8160fe15615ca7017a6be1b125d885e39ddf12" - integrity sha512-G3bgGaALxffiZB6HaCAX6BvIRFYSOClvdcCN3fKfczEYYkOHrrgeEksY7oX5GXXZdNNn4s/zt+5yWnySuA+3Zg== +"@walletconnect/client@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/client/-/client-1.3.2.tgz#8f67ac53bc3f7dfa0cff7a86ea6e43b11178d4f4" + integrity sha512-7dIDgZUwmRJEvnDLrnQP3kejRY0BrfDjTGI6k3+Sam+ancfarAazVMiyWgoG0OffzzM8Snq3Mnb5IZriloRXew== dependencies: - "@walletconnect/core" "^1.3.1" - "@walletconnect/iso-crypto" "^1.3.1" - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" + "@walletconnect/core" "^1.3.2" + "@walletconnect/iso-crypto" "^1.3.2" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" -"@walletconnect/core@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.3.1.tgz#7f7c692ad4c7de37544c610ad0d863dddcb23b19" - integrity sha512-v0RAW4RqcMBNRkX2e6VcOVpBl5dX0oT7w3vWMiHUHwuMMnuoRXoXi1oEiib0K8VyqYuXSaeuEaaHUhYUEcvvtQ== +"@walletconnect/core@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.3.2.tgz#ab2c9b21fc57fc598ebf36c75cd6085c8e63f138" + integrity sha512-Pgw/5NCm002ek8tqbXsJn8BiLER4qMBwv1v13tGkaFyb71srFbTJTE203/5zpliqabnVG8h/q3OKRqHg++eyLA== dependencies: - "@walletconnect/socket-transport" "^1.3.1" - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" + "@walletconnect/socket-transport" "^1.3.2" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" -"@walletconnect/http-connection@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/http-connection/-/http-connection-1.3.1.tgz#fd5af6a3cb6014cd99b48ea827a8664b61df7f8a" - integrity sha512-Hyis8FAgtnkhF1k0oKDhe+rgDq/rPFHry/jdQckvQLZZAEwoNZLJ5s0jjWK2Yl9YP3EZybXat3H63VboieZiUA== +"@walletconnect/http-connection@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/http-connection/-/http-connection-1.3.2.tgz#f12e354cdae5af457920210c99d01729a8308433" + integrity sha512-f0JQSOXTkKcj4JGIBm1fdrEMI9OiG6R78uFfo8a/P4humKYMH7o2q1eZ12teBSPcfW2zFvda4SA5PoU/kORUPQ== dependencies: - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" + eventemitter3 "4.0.7" xhr2-cookies "1.1.0" -"@walletconnect/iso-crypto@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/iso-crypto/-/iso-crypto-1.3.1.tgz#fce8d1235a2059728dfb87a8d0dfac205f295937" - integrity sha512-u5YGYsaSQuRBSxX1623220Bc3KZDgqkIwXCt7PV8UyzhuSFp+SQGj6Cux5SoVlaUChr0iWMzkibLrKSof3yStA== +"@walletconnect/iso-crypto@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/iso-crypto/-/iso-crypto-1.3.2.tgz#e2ffdfe5c9b74bcca0f5d9ee1fceaac88b5a2989" + integrity sha512-9dE49nwPIwRDMnFATrG/7Q4044iLBzW3KLa06OErymkLMpD7hWxnWov8qrgKHxnk/eC2teA8QrNeVL/9nWm15Q== dependencies: - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" - eccrypto-js "5.2.0" + "@pedrouid/iso-crypto" "^1.0.0" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" -"@walletconnect/mobile-registry@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/mobile-registry/-/mobile-registry-1.3.1.tgz#9fdea8d7ac4655a63c59a84ed76780530820808d" - integrity sha512-wOGSqf1xCoMRvsLZ7IEYBwCnojtCbsSd+dc6dJCVWkFcRptjmnInIrP7bg7YIllUCSusWhKjPCYyRsyffNYCyQ== +"@walletconnect/mobile-registry@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/mobile-registry/-/mobile-registry-1.3.2.tgz#c258fecd416e27df7f2477323c3aa2ecf141cd7d" + integrity sha512-hb0KtA+OLjcWv49nyFTlWxgYjvqrOpiWhRUK3fgebjxfyfccp4qhqUUfX2MYGqvQcTKn3cj1CtChpuFIb3uMFQ== -"@walletconnect/qrcode-modal@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/qrcode-modal/-/qrcode-modal-1.3.1.tgz#d546531fc5b18431470aeeab071939c861f8e8a2" - integrity sha512-PHwRNgnRtATtBuuxX8nsRGbSrsevB4gMHd4armJFbGM/XmIcJe89L5X0KVapb5Z8HP8qdbJ6/sMqKBPVEezkgQ== +"@walletconnect/qrcode-modal@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/qrcode-modal/-/qrcode-modal-1.3.2.tgz#88e0b3c36eac314b3e24d5b447a611863bc45bfd" + integrity sha512-mYlqV1Zq3wrsOOUQFvcXYbR6B2rsguQXzNdl0QsggFUiiSPsndcbUHf7XqloyFhOLcB4ibgmxaInGa12fL9mNA== dependencies: - "@walletconnect/mobile-registry" "^1.3.1" - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" + "@walletconnect/mobile-registry" "^1.3.2" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" preact "10.4.1" qrcode "1.4.4" -"@walletconnect/socket-transport@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/socket-transport/-/socket-transport-1.3.1.tgz#b3854225fdae9af0d865d002f7e032cd89ae4678" - integrity sha512-JV/ZJbFGmPJaHcT5GpiuoOxdB5xlkY7SW6J0GDqIBxI92mlOoQ5ea6xY5ullI5WUXZJUIvXcgUHf/KpPG9VN/w== +"@walletconnect/socket-transport@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/socket-transport/-/socket-transport-1.3.2.tgz#45cb3398a6dd2b5a24434172bcc9f667afbd4a07" + integrity sha512-0zoSfyueulgw7idt2OrlD9N8zZ2KC5vb3Vo+QwELE1VuMSaVX+phcoZvM5u0Lr2g+oRQHU/SfTbdUJTh8Wqs9g== dependencies: - "@walletconnect/types" "^1.3.1" + "@walletconnect/types" "^1.3.2" ws "7.3.0" -"@walletconnect/types@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.3.1.tgz#fefa3d5cfb2e68c0439d07f7d32134f692775a80" - integrity sha512-lf8hAFT7OIEgyc0FkLZPPjF4bMql+Svg4SNKj1a1oMTCdA+NPlqMUwOqcIJeIolULZbpFl3DkX3omSy8RNIbkg== +"@walletconnect/types@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.3.2.tgz#d6e865baf372ea02df3b8098ae8bc4dc5bfd11ba" + integrity sha512-2eD/wo8XEmJTUzyfOGX1mEDxCyStmiML/cW5LwXuFiS0cdk+A39dsV4YvNxKl/y0KwADpRuJ8eT2GGnv3jr5WA== -"@walletconnect/utils@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.3.1.tgz#88418856d28bdc683d53d0fad2acdc70b5c88528" - integrity sha512-r1pfAeXc6WCNbHf5zgVPenM8au+bQOYot6tdwpSDZAfdP0KtwmZ9Uro2uP8ykRWovTj2gGgKE+GMh9yVVTraaQ== +"@walletconnect/utils@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.3.2.tgz#dbe753e9a03f2d05908bc087206b1b61ce72efa6" + integrity sha512-i0wlo4FbDCIh+UwcBZBNFsY1TW8eqMb/oX+xTEVj0mbFsmdvzfWM2gRi9vu+Z5idA7ZlHyzFc99DG7kekirGgg== dependencies: - "@walletconnect/types" "^1.3.1" + "@walletconnect/types" "^1.3.2" + bn.js "4.11.8" detect-browser "5.1.0" - enc-utils "2.1.0" + enc-utils "3.0.0" js-sha3 "0.8.0" query-string "6.13.5" rpc-payload-id "1.0.0" @@ -3770,16 +3791,16 @@ window-metadata "1.0.0" "@walletconnect/web3-provider@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@walletconnect/web3-provider/-/web3-provider-1.3.1.tgz#031c1cc7a52ea12287f1278929501ee91847e237" - integrity sha512-sOLtEbNLFrD8DgbvE0P/vRrmdPbF6Zufhn3gAo6/lxDQGH0ajHGmkl04sq/qcwMHKK0zHjYKRSFEG2VqNIThHg== + version "1.3.2" + resolved "https://registry.yarnpkg.com/@walletconnect/web3-provider/-/web3-provider-1.3.2.tgz#a7e25bc9d77c0b9a2148d8470d955d0009d5ac9b" + integrity sha512-V9cMGzyT8DCjCER3X+XsPJvewzzrnRNqcfizfAFJUle2KgkJHFb27D+kMjT2sCbO9QdFRw7enqndaGYMERnPPg== dependencies: - "@walletconnect/client" "^1.3.1" - "@walletconnect/http-connection" "^1.3.1" - "@walletconnect/qrcode-modal" "^1.3.1" - "@walletconnect/types" "^1.3.1" - "@walletconnect/utils" "^1.3.1" - web3-provider-engine "15.0.12" + "@walletconnect/client" "^1.3.2" + "@walletconnect/http-connection" "^1.3.2" + "@walletconnect/qrcode-modal" "^1.3.2" + "@walletconnect/types" "^1.3.2" + "@walletconnect/utils" "^1.3.2" + web3-provider-engine "16.0.1" "@webassemblyjs/ast@1.9.0": version "1.9.0" @@ -4019,7 +4040,7 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0= -aes-js@3.1.2, aes-js@^3.1.1: +aes-js@^3.1.1, aes-js@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== @@ -4082,6 +4103,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.3, ajv@^6.12.4, ajv json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-7.0.3.tgz#13ae747eff125cafb230ac504b2406cf371eece2" + integrity sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -4304,6 +4335,11 @@ array-back@^2.0.0: dependencies: typical "^2.6.1" +array-filter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -4324,7 +4360,7 @@ array-flatten@^2.1.0: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.0.3, array-includes@^3.1.1: +array-includes@^3.0.3, array-includes@^3.1.1, array-includes@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" integrity sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw== @@ -4459,11 +4495,6 @@ ast-types@^0.14.2: dependencies: tslib "^2.0.1" -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -4533,10 +4564,10 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -authereum@^0.0.4-beta.157: - version "0.0.4-beta.201" - resolved "https://registry.yarnpkg.com/authereum/-/authereum-0.0.4-beta.201.tgz#ea380efc6d231dc4222dc20cd9395b02318dd0c3" - integrity sha512-9zyS2nDsO5nW/8dD8SbGUbZLX76O5Zrx6Zq4aZG+Waa3Vsn3Bj82tn8HLPdECmd5heSOmaSEi5TNsS/sGBSiGw== +authereum@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/authereum/-/authereum-0.1.12.tgz#63552041f087bd5e74b5f1d115a15d712333e632" + integrity sha512-aAXB8xZkX0cxG/EtapA++gvJjd16b9Y2USNSKaaegm9Q8todpZB0KliamedZ385WWqARWnk41PteWwlfpXUYog== dependencies: async "3.2.0" bn.js "5.1.2" @@ -4553,7 +4584,7 @@ authereum@^0.0.4-beta.157: web3-provider-engine "15.0.4" web3-utils "1.2.1" -autoprefixer@9.8.6, autoprefixer@^9.6.1, autoprefixer@^9.7.2: +autoprefixer@^9.6.1, autoprefixer@^9.7.2: version "9.8.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== @@ -4566,6 +4597,13 @@ autoprefixer@9.8.6, autoprefixer@^9.6.1, autoprefixer@^9.7.2: postcss "^7.0.32" postcss-value-parser "^4.1.0" +available-typed-arrays@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" + integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== + dependencies: + array-filter "^1.0.0" + await-semaphore@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.3.tgz#2b88018cc8c28e06167ae1cdff02504f1f9688d3" @@ -4586,7 +4624,7 @@ axe-core@^4.0.2: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.1.tgz#70a7855888e287f7add66002211a423937063eaf" integrity sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ== -axios@0.21.1: +axios@0.21.1, axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== @@ -4601,13 +4639,6 @@ axios@^0.18.0: follow-redirects "1.5.10" is-buffer "^2.0.2" -axios@^0.19.2: - version "0.19.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" - integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== - dependencies: - follow-redirects "1.5.10" - axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -5612,9 +5643,9 @@ binary-extensions@^1.0.0: integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== binary-extensions@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" - integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== bind-decorator@^1.0.11: version "1.0.11" @@ -5635,6 +5666,11 @@ bip66@^1.1.5: dependencies: safe-buffer "^5.0.1" +bitwise@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/bitwise/-/bitwise-2.0.4.tgz#3b6f95c43d614b83b980331d3b41d78b9c902039" + integrity sha512-ZOByl1Sc8SH2/owfRfR1apaC1ELNqHqAAtfqs1Ixqk/9Bod6VxWz10MiMYXkNiL95RdFAqOGQxm1TCGPf1iFyw== + bl@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" @@ -5687,17 +5723,17 @@ bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.1.3: integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== bnc-onboard@^1.16.1: - version "1.16.1" - resolved "https://registry.yarnpkg.com/bnc-onboard/-/bnc-onboard-1.16.1.tgz#57aa70a8e75790b15adc396c574ef2e407d8666a" - integrity sha512-BNDYPpKrO96ZNqpfJZeqkMiQgchrK9O9ywR1e8FzehPv8NkKghEDF+gjAAlKTetiNF4JYQyYY2Ua96Qbeqr6AA== + version "1.17.1" + resolved "https://registry.yarnpkg.com/bnc-onboard/-/bnc-onboard-1.17.1.tgz#b1178b2501fdabc9858458b6672af92697049dc2" + integrity sha512-moK0trz6bsLvd2ZHjkwJjg6jTZRslA9Q7FYcF3wKpS29Qgb64Xyypwj+6S9LtEptXtmWPPEweONAoAwQkiWcOw== dependencies: "@ledgerhq/hw-app-eth" "^5.21.0" "@ledgerhq/hw-transport-u2f" "^5.21.0" "@portis/web3" "^2.0.0-beta.57" - "@toruslabs/torus-embed" "^1.8.2" + "@toruslabs/torus-embed" "^1.9.2" "@unilogin/provider" "^0.6.1" "@walletconnect/web3-provider" "^1.3.1" - authereum "^0.0.4-beta.157" + authereum "^0.1.12" bignumber.js "^9.0.0" bnc-sdk "^2.1.4" bowser "^2.10.0" @@ -5758,19 +5794,6 @@ boolean@^3.0.1: resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570" integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g== -borc@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/borc/-/borc-2.1.2.tgz#6ce75e7da5ce711b963755117dd1b187f6f8cf19" - integrity sha512-Sy9eoUi4OiKzq7VovMn246iTo17kzuyHJKomCfpWMlI6RpfN1gk95w7d7gH264nApVLg0HZfcpz62/g4VH1Y4w== - dependencies: - bignumber.js "^9.0.0" - buffer "^5.5.0" - commander "^2.15.0" - ieee754 "^1.1.13" - iso-url "~0.4.7" - json-text-sequence "~0.1.0" - readable-stream "^3.6.0" - bowser@^2.10.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" @@ -6033,9 +6056,9 @@ buffer@^5.0.5, buffer@^5.2.1, buffer@^5.4.2, buffer@^5.4.3, buffer@^5.5.0, buffe ieee754 "^1.1.13" bufferutil@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.2.tgz#79f68631910f6b993d870fc77dc0a2894eb96cd5" - integrity sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA== + version "4.0.3" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.3.tgz#66724b756bed23cd7c28c4d306d7994f9943cc6b" + integrity sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw== dependencies: node-gyp-build "^4.2.0" @@ -6184,12 +6207,12 @@ cacheable-request@^6.0.0: responselike "^1.0.2" call-bind@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" - integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.1.tgz#29aca9151f8ddcfd5b9b786898f005f425e88567" + integrity sha512-tvAvUwNcRikl3RVF20X9lsYmmepsovzTWeJiXjO0PkJp15uy/6xKFZOQtuiSULwYW+6ToZBprphCgWXC2dSgcQ== dependencies: function-bind "^1.1.1" - get-intrinsic "^1.0.0" + get-intrinsic "^1.0.2" call-me-maybe@^1.0.1: version "1.0.1" @@ -6273,9 +6296,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000929, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001164: - version "1.0.30001165" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz#32955490d2f60290bb186bb754f2981917fa744f" - integrity sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA== + version "1.0.30001173" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001173.tgz#3c47bbe3cd6d7a9eda7f50ac016d158005569f56" + integrity sha512-R3aqmjrICdGCTAnSXtNyvWYMK3YtV5jwudbq0T7nN9k4kmE4CBuwPqyJ+KBzepSTh0huivV2gLbSMEzTTmfeYw== capture-exit@^2.0.0: version "2.0.0" @@ -6294,6 +6317,14 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +cbor@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" + integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== + dependencies: + bignumber.js "^9.0.1" + nofilter "^1.0.4" + chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -6367,17 +6398,29 @@ checkpoint-store@^1.1.0: dependencies: functional-red-black-tree "^1.0.1" -cheerio@^1.0.0-rc.2: - version "1.0.0-rc.3" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" - integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== +cheerio-select-tmp@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646" + integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ== dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.1" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash "^4.15.0" - parse5 "^3.0.1" + css-select "^3.1.2" + css-what "^4.0.0" + domelementtype "^2.1.0" + domhandler "^4.0.0" + domutils "^2.4.4" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.5" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f" + integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw== + dependencies: + cheerio-select-tmp "^0.1.0" + dom-serializer "~1.2.0" + domhandler "^4.0.0" + entities "~2.1.0" + htmlparser2 "^6.0.0" + parse5 "^6.0.0" + parse5-htmlparser2-tree-adapter "^6.0.0" chokidar@3.4.2: version "3.4.2" @@ -6395,9 +6438,9 @@ chokidar@3.4.2: fsevents "~2.1.2" "chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" - integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.0.tgz#458a4816a415e9d3b3caa4faec2b96a6935a9e65" + integrity sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -6407,7 +6450,7 @@ chokidar@3.4.2: normalize-path "~3.0.0" readdirp "~3.5.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.1" chokidar@^2.0.4, chokidar@^2.1.8: version "2.1.8" @@ -6735,7 +6778,7 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== -commander@^2.15.0, commander@^2.19.0, commander@^2.20.0: +commander@^2.19.0, commander@^2.20.0: 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== @@ -7244,7 +7287,7 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== -css-select@^1.1.0, css-select@~1.2.0: +css-select@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= @@ -7264,6 +7307,17 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== + dependencies: + boolbase "^1.0.0" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" + css-to-react-native@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" @@ -7307,6 +7361,11 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== + css.escape@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" @@ -7690,11 +7749,6 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -delimit-stream@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" - integrity sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs= - depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -7887,13 +7941,14 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" -dom-serializer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== +dom-serializer@^1.0.1, dom-serializer@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" + integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" dom-walk@^0.1.0: version "0.1.2" @@ -7905,12 +7960,12 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: +domelementtype@1, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domelementtype@^2.0.1: +domelementtype@^2.0.1, domelementtype@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== @@ -7929,6 +7984,13 @@ domhandler@^2.3.0: dependencies: domelementtype "1" +domhandler@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e" + integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA== + dependencies: + domelementtype "^2.1.0" + domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" @@ -7945,6 +8007,15 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^2.4.3, domutils@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" + integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -8033,18 +8104,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -eccrypto-js@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/eccrypto-js/-/eccrypto-js-5.2.0.tgz#eb3b36e9978d316fedf50be46492bb0d3e240cf5" - integrity sha512-pPb6CMapJ1LIzjLWxMqlrnfaEFap7qkk9wcO/b4AVSdxBQYlpOqvlPpq5SpUI4FdmfdhVD34AjN47fM8fryC4A== - dependencies: - aes-js "3.1.2" - enc-utils "2.1.0" - hash.js "1.1.7" - js-sha3 "0.8.0" - randombytes "2.1.0" - secp256k1 "3.8.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -8087,10 +8146,10 @@ electron-is-dev@^1.2.0: resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e" integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw== -electron-log@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.3.0.tgz#6e841a5c9af34ed3ca83e5a8a4156fdc39bed464" - integrity sha512-iuJjH/ZEJkDyCbuAMvvFxAjCMDLMXIQ5NqvppETGrbtf4b/007r5P36BSvexdy0UzwDNzDtIuEXLR34vRXWZrg== +electron-log@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.3.1.tgz#1405fef9d4e6964a5fdb8790a69163aa237ffe91" + integrity sha512-S/0CMjYjgyWUsZ3d27VvErPaI5W4oILp4jfeCuN4DhDqrJW6jKRUD2PxFfTdeZEIjM7+fttGg7A61rPcAcZC1w== electron-notarize@1.0.0: version "1.0.0" @@ -8127,9 +8186,9 @@ electron-settings@^4.0.2: write-file-atomic "^3.0.3" electron-to-chromium@^1.3.103, electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.612: - version "1.3.621" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.621.tgz#0bbe2100ef0b28f88d0b1101fbdf433312f69be0" - integrity sha512-FeIuBzArONbAmKmZIsZIFGu/Gc9AVGlVeVbhCq+G2YIl6QkT0TDn2HKN/FMf1btXEB9kEmIuQf3/lBTVAbmFOg== + version "1.3.633" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" + integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== electron-updater@4.3.5: version "4.3.5" @@ -8225,12 +8284,11 @@ emotion-theming@^10.0.19: "@emotion/weak-memoize" "0.2.5" hoist-non-react-statics "^3.3.0" -enc-utils@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/enc-utils/-/enc-utils-2.1.0.tgz#f6c28c3d4bb38fb409a93185848cf361f4fde142" - integrity sha512-VD0eunGDyzhojePzkORWDnW88gi6tIeGb5Z6QVHugux6mMAPiXyw94fb/7WdDQEWhKMSoYRyzFFUebCqeH20PA== +enc-utils@3.0.0, enc-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/enc-utils/-/enc-utils-3.0.0.tgz#65935d2d6a867fa0ae995f05f3a2f055ce764dcf" + integrity sha512-e57t/Z2HzWOLwOp7DZcV0VMEY8t7ptWwsxyp6kM2b2zrk6JqIpXxzkruHAMiBsy5wg9jp/183GdiRXCvBtzsYg== dependencies: - bn.js "4.11.8" is-typedarray "1.0.0" typedarray-to-buffer "3.1.5" @@ -8278,12 +8336,12 @@ enquirer@^2.3.5, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" -entities@^1.1.1, entities@^1.1.2, entities@~1.1.1: +entities@^1.1.1, entities@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== -entities@^2.0.0: +entities@^2.0.0, entities@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== @@ -8294,9 +8352,9 @@ env-paths@^2.2.0: integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== errno@^0.1.3, errno@~0.1.1, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -8331,7 +8389,7 @@ es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: string.prototype.trimend "^1.0.1" string.prototype.trimstart "^1.0.1" -es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: +es-abstract@^1.18.0-next.1: 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== @@ -8465,12 +8523,10 @@ escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.14.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" - integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== - dependencies: - get-stdin "^6.0.0" +eslint-config-prettier@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.1.0.tgz#5402eb559aa94b894effd6bddfa0b1ca051c858f" + integrity sha512-9sm5/PxaFG7qNJvJzTROMM1Bk1ozXVTKI0buKOyb0Bsr1hrwi0H/TzxF/COtf1uxikIK8SwhX7K6zg78jAzbeA== eslint-config-react-app@^6.0.0: version "6.0.0" @@ -8547,9 +8603,9 @@ eslint-plugin-jsx-a11y@^6.3.1: language-tags "^1.0.5" eslint-plugin-prettier@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.2.0.tgz#af391b2226fa0e15c96f36c733f6e9035dbd952c" - integrity sha512-kOUSJnFjAUFKwVxuzy6sA5yyMx6+o9ino4gCdShzBNx4eyFRudWRYKCFolKjoM40PEiuU6Cn7wBLfq3WsGg7qg== + version "3.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7" + integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ== dependencies: prettier-linter-helpers "^1.0.0" @@ -8559,9 +8615,9 @@ eslint-plugin-react-hooks@^4.2.0: integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== eslint-plugin-react@^7.21.5: - version "7.21.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3" - integrity sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g== + version "7.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269" + integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA== dependencies: array-includes "^3.1.1" array.prototype.flatmap "^1.2.3" @@ -8634,9 +8690,9 @@ eslint-webpack-plugin@^2.1.0: schema-utils "^3.0.0" eslint@^7.11.0: - version "7.15.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.15.0.tgz#eb155fb8ed0865fcf5d903f76be2e5b6cd7e0bc7" - integrity sha512-Vr64xFDT8w30wFll643e7cGrIkPEU50yIiI36OdSIDoSGguIeaLzBo0vpGvzo9RECUqq7htURfwEtKqwytkqzA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.17.0.tgz#4ccda5bf12572ad3bf760e6f195886f50569adb0" + integrity sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ== dependencies: "@babel/code-frame" "^7.0.0" "@eslint/eslintrc" "^0.2.2" @@ -8672,7 +8728,7 @@ eslint@^7.11.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^5.2.3" + table "^6.0.4" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -8768,7 +8824,7 @@ eth-json-rpc-errors@^2.0.2: dependencies: fast-safe-stringify "^2.0.6" -eth-json-rpc-filters@^4.0.2, eth-json-rpc-filters@^4.1.1: +eth-json-rpc-filters@^4.0.2, eth-json-rpc-filters@^4.1.1, eth-json-rpc-filters@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eth-json-rpc-filters/-/eth-json-rpc-filters-4.2.1.tgz#82204a13c99927dbf42cbb3962846650c6281f33" integrity sha512-tPfohezq8mSmwa47xvq6PGzBDLZ0njWJMB1J+OPuv+n+1WkWDlf3l3tqJXpq96RxhrzK2q7wiweRS5aGIzpq4Q== @@ -8800,6 +8856,16 @@ eth-json-rpc-infura@^4.0.1: json-rpc-engine "^5.1.3" node-fetch "^2.6.0" +eth-json-rpc-infura@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eth-json-rpc-infura/-/eth-json-rpc-infura-5.1.0.tgz#e6da7dc47402ce64c54e7018170d89433c4e8fb6" + integrity sha512-THzLye3PHUSGn1EXMhg6WTLW9uim7LQZKeKaeYsS9+wOBcamRiCQVGHa6D2/4P0oS0vSaxsBnU/J6qvn0MPdow== + dependencies: + eth-json-rpc-middleware "^6.0.0" + eth-rpc-errors "^3.0.0" + json-rpc-engine "^5.3.0" + node-fetch "^2.6.0" + eth-json-rpc-middleware@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz#5c9d4c28f745ccb01630f0300ba945f4bef9593f" @@ -8928,6 +8994,13 @@ eth-rpc-errors@^3.0.0: dependencies: fast-safe-stringify "^2.0.6" +eth-rpc-errors@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/eth-rpc-errors/-/eth-rpc-errors-4.0.2.tgz#11bc164e25237a679061ac05b7da7537b673d3b7" + integrity sha512-n+Re6Gu8XGyfFy1it0AwbD1x0MUzspQs0D5UiPs1fFPCr6WAwZM+vbIhXheBFrpgosqN9bs5PqlB4Q61U/QytQ== + dependencies: + fast-safe-stringify "^2.0.6" + eth-sig-util@2.5.3, eth-sig-util@^2.5.3: version "2.5.3" resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-2.5.3.tgz#6938308b38226e0b3085435474900b03036abcbe" @@ -9296,7 +9369,7 @@ eventemitter3@4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== -eventemitter3@^4.0.0: +eventemitter3@4.0.7, eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -9572,9 +9645,9 @@ fast-safe-stringify@^2.0.6: integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fastq@^1.6.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.9.0.tgz#e16a72f338eaca48e91b5c23593bcc2ef66b7947" - integrity sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w== + version "1.10.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.0.tgz#74dbefccade964932cdf500473ef302719c652bb" + integrity sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA== dependencies: reusify "^1.0.4" @@ -9781,7 +9854,7 @@ find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -9796,12 +9869,12 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-versions@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-3.2.0.tgz#10297f98030a786829681690545ef659ed1d254e" - integrity sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww== +find-versions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-versions/-/find-versions-4.0.0.tgz#3c57e573bf97769b8cb8df16934b627915da4965" + integrity sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ== dependencies: - semver-regex "^2.0.0" + semver-regex "^3.1.2" find-yarn-workspace-root@^1.2.1: version "1.2.1" @@ -9887,6 +9960,11 @@ for-own@^0.1.3: dependencies: for-in "^1.0.1" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -10067,10 +10145,10 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@^2.1.2, fsevents@^2.1.3: - version "2.2.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.2.1.tgz#1fb02ded2036a8ac288d507a65962bd87b97628d" - integrity sha512-bTLYHSeC0UH/EFXS9KqWnXuOl/wHK5Z/d+ghd5AsFMYN7wIGkUCOJyzy88+wJKkZPGON8u4Z9f6U4FdgURE9qA== +fsevents@^2.1.2, fsevents@^2.1.3, fsevents@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.1.tgz#b209ab14c61012636c8863507edf7fb68cc54e9f" + integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw== fsevents@~2.1.2: version "2.1.3" @@ -10131,10 +10209,10 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.1.tgz#94a9768fcbdd0595a1c9273aacf4c89d075631be" - integrity sha512-ZnWP+AmS1VUaLgTRy47+zKtjTxz+0xMpx3I52i+aalBK1QP19ggLF3Db89KJX7kjfOfP2eoa01qc++GwPgufPg== +get-intrinsic@^1.0.1, get-intrinsic@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -10150,11 +10228,6 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== - get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -10316,7 +10389,7 @@ globalthis@^1.0.0, globalthis@^1.0.1: dependencies: define-properties "^1.1.3" -globby@11.0.1, globby@^11.0.1: +globby@11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== @@ -10341,6 +10414,18 @@ globby@8.0.2: pify "^3.0.0" slash "^1.0.0" +globby@^11.0.1: + version "11.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83" + integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -10402,12 +10487,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== gridplus-sdk@latest: - version "0.6.2" - resolved "https://registry.yarnpkg.com/gridplus-sdk/-/gridplus-sdk-0.6.2.tgz#7cdcd66bffdd30e25e7c35138d732638585853c0" - integrity sha512-iUeA3PyLbsVzvWFEg4nWWh2k8lK9TGokbbw7WAtToLy0XO2REz5URH7bsI8V20KlvmtuHXjnnZekZdA7dDMRxQ== + version "0.7.1" + resolved "https://registry.yarnpkg.com/gridplus-sdk/-/gridplus-sdk-0.7.1.tgz#314619b4f9e7942f5f45b42032249ff6f08b3b67" + integrity sha512-JYsWCJ01zOmgGbsmGjrKcQRQ6MIDmYo7gZmUf2rzHDEPOmLQA9BJJxZ+36R9jHWkdttKCd9g1zFHtAzaulk+Sg== dependencies: aes-js "^3.1.1" bignumber.js "^9.0.1" + bitwise "^2.0.4" bs58 "^4.0.1" bs58check "^2.1.2" buffer "^5.6.0" @@ -10572,7 +10658,7 @@ hash.js@1.1.3: inherits "^2.0.3" minimalistic-assert "^1.0.0" -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: +hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== @@ -10615,19 +10701,19 @@ hex-color-regex@^1.1.0: integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== highlight.js@^10.4.0, highlight.js@^10.4.1: - version "10.4.1" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.4.1.tgz#d48fbcf4a9971c4361b3f95f302747afe19dbad0" - integrity sha512-yR5lWvNz7c85OhVAEAeFhVCc/GV4C30Fjzc/rCP0aCWzc1UUOPUk55dK/qdwTZHBvMZo+eZ2jpk62ndX/xMFlg== + version "10.5.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.5.0.tgz#3f09fede6a865757378f2d9ebdcbc15ba268f98f" + integrity sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw== highlight.js@~9.13.0: version "9.13.1" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== -highlightjs-solidity@^1.0.19: - version "1.0.19" - resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.0.19.tgz#a2f05bcfadd295a8eefb9cc20dcb18a3ba48e49c" - integrity sha512-ZIzMlxZxkcNnzWC1LeOeUjQjywzXnGyDxexOPKzz8hWFqdE2uRvz1BxD0joOkr41z4SU2ABXVGDx6EWlbzTBLQ== +highlightjs-solidity@^1.0.20: + version "1.0.20" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-1.0.20.tgz#37482fd47deda617994e1d1262df5a319c0a8580" + integrity sha512-Ixb87/4huazRJ7mriimL0DP2GvE5zgSk11VdMPGKMQCNwszDe8qK0PySySsuB88iXyDT/H2gdmvC2bgfrOi3qQ== history@4.10.1, history@^4.9.0: version "4.10.1" @@ -10752,7 +10838,7 @@ html-webpack-plugin@4.5.0, html-webpack-plugin@^4.0.0-beta.2: tapable "^1.1.3" util.promisify "1.0.0" -htmlparser2@^3.3.0, htmlparser2@^3.9.1: +htmlparser2@^3.3.0: version "3.10.1" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== @@ -10764,6 +10850,16 @@ htmlparser2@^3.3.0, htmlparser2@^3.9.1: inherits "^2.0.1" readable-stream "^3.1.1" +htmlparser2@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.0.tgz#c2da005030390908ca4c91e5629e418e0665ac01" + integrity sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.4.4" + entities "^2.0.0" + http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -10863,17 +10959,17 @@ human-signals@^1.1.1: integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== husky@^4.3.0: - version "4.3.5" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.5.tgz#ab8d2a0eb6b62fef2853ee3d442c927d89290902" - integrity sha512-E5S/1HMoDDaqsH8kDF5zeKEQbYqe3wL9zJDyqyYqc8I4vHBtAoxkDBGXox0lZ9RI+k5GyB728vZdmnM4bYap+g== + version "4.3.7" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.7.tgz#ca47bbe6213c1aa8b16bbd504530d9600de91e88" + integrity sha512-0fQlcCDq/xypoyYSJvEuzbDPHFf8ZF9IXKJxlrnvxABTSzK1VPT2RKYQKrcgJ+YD39swgoB6sbzywUqFxUiqjw== dependencies: chalk "^4.0.0" ci-info "^2.0.0" compare-versions "^3.6.0" cosmiconfig "^7.0.0" - find-versions "^3.2.0" + find-versions "^4.0.0" opencollective-postinstall "^2.0.2" - pkg-dir "^4.2.0" + pkg-dir "^5.0.0" please-upgrade-node "^3.2.0" slash "^3.0.0" which-pm-runs "^1.0.0" @@ -10992,9 +11088,9 @@ import-fresh@^2.0.0: resolve-from "^3.0.0" import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.2.tgz#fc129c160c5d68235507f4331a6baad186bdbc3e" - integrity sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw== + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -11426,6 +11522,11 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-generator-function@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" + integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== + is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -11636,6 +11737,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.1" +is-typed-array@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.4.tgz#1f66f34a283a3c94a4335434661ca53fff801120" + integrity sha512-ILaRgn4zaSrVNXNGtON6iFNotXW3hAPF3+0fB1usg2jFlWqo5fEDdmJkz0zBfoi7Dgskr8Khi2xZ8cXqZEfXNA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + has-symbols "^1.0.1" + is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -11693,11 +11805,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -iso-url@~0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-0.4.7.tgz#de7e48120dae46921079fe78f325ac9e9217a385" - integrity sha512-27fFRDnPAMnHGLq36bWTpKET+eiXct3ENlCcdcMdk+mjXrb2kw3mhBUg1B7ewAC0kVzlOPhADzQgz1SE6Tglog== - isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" @@ -12235,7 +12342,7 @@ jest@26.6.0: import-local "^3.0.2" jest-cli "^26.6.0" -joi@^17.1.1: +joi@^17.3.0: version "17.3.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.3.0.tgz#f1be4a6ce29bc1716665819ac361dfa139fff5d2" integrity sha512-Qh5gdU6niuYbUIUV5ejbsMiiFmBdw8Kcp8Buj2JntszCkCfxJ9Cz76OtHxOZMPXrt5810iDIXs+n1nNVoquHgg== @@ -12366,7 +12473,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.3, json-rpc-engine@^5.3.0, json-rpc-engine@^5.4.0: +json-rpc-engine@^5.1.3, json-rpc-engine@^5.3.0: version "5.4.0" resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz#75758609d849e1dba1e09021ae473f3ab63161e5" integrity sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g== @@ -12374,6 +12481,14 @@ json-rpc-engine@^5.1.3, json-rpc-engine@^5.3.0, json-rpc-engine@^5.4.0: eth-rpc-errors "^3.0.0" safe-event-emitter "^1.0.1" +json-rpc-engine@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/json-rpc-engine/-/json-rpc-engine-6.1.0.tgz#bf5ff7d029e1c1bf20cb6c0e9f348dcd8be5a393" + integrity sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ== + dependencies: + "@metamask/safe-event-emitter" "^2.0.0" + eth-rpc-errors "^4.0.2" + json-rpc-error@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/json-rpc-error/-/json-rpc-error-2.0.0.tgz#a7af9c202838b5e905c7250e547f1aff77258a02" @@ -12381,13 +12496,13 @@ json-rpc-error@^2.0.0: dependencies: inherits "^2.0.1" -json-rpc-middleware-stream@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json-rpc-middleware-stream/-/json-rpc-middleware-stream-2.1.1.tgz#06e5409e201e7ddeae47bef29f7059eafd4d5325" - integrity sha512-WZheufPN+/RKkjXQP3lK5tFYblqG0n+oYv5qpammwwY2vsJRB7mM4Txhr4ajzvYEZi1UkENnplrmaYiqaqafaA== +json-rpc-middleware-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-rpc-middleware-stream/-/json-rpc-middleware-stream-3.0.0.tgz#8540331d884f36b9e0ad31054cc68ac6b5a89b52" + integrity sha512-JmZmlehE0xF3swwORpLHny/GvW3MZxCsb2uFNBrn8TOqMqivzCfz232NSDLLOtIQlrPlgyEjiYpyzyOPFOzClw== dependencies: + "@metamask/safe-event-emitter" "^2.0.0" readable-stream "^2.3.3" - safe-event-emitter "^1.0.1" json-rpc-random-id@^1.0.0, json-rpc-random-id@^1.0.1: version "1.0.1" @@ -12399,6 +12514,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -12421,13 +12541,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json-text-sequence@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/json-text-sequence/-/json-text-sequence-0.1.1.tgz#a72f217dc4afc4629fff5feb304dc1bd51a2f3d2" - integrity sha1-py8hfcSvxGKf/1/rME3BvVGi89I= - dependencies: - delimit-stream "0.1.0" - json2mq@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a" @@ -12574,12 +12687,12 @@ jss@10.5.0, jss@^10.0.3: tiny-warning "^1.0.2" "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.1.0.tgz#642f1d7b88aa6d7eb9d8f2210e166478444fa891" - integrity sha512-d4/UOjg+mxAWxCiF0c5UTSwyqbchkbqCvK87aBovhnh8GtysTjWmgC63tY0cJx/HzGgm9qnA147jVBdpOiQ2RA== + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" + integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== dependencies: - array-includes "^3.1.1" - object.assign "^4.1.1" + array-includes "^3.1.2" + object.assign "^4.1.2" just-curry-it@^3.1.0: version "3.1.0" @@ -13035,7 +13148,7 @@ lodash.unset@^4.5.2: resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed" integrity sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0= -"lodash@>=3.5 <5", lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5: +"lodash@>=3.5 <5", lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -13062,7 +13175,7 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loglevel@^1.6.8, loglevel@^1.7.0: +loglevel@^1.6.8, loglevel@^1.7.1: version "1.7.1" resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== @@ -13382,22 +13495,17 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -"mime-db@>= 1.43.0 < 2": +mime-db@1.45.0, "mime-db@>= 1.43.0 < 2": version "1.45.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== mime-types@^2.1.12, mime-types@^2.1.16, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + version "2.1.28" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.28.tgz#1160c4757eab2c5363888e005273ecf79d2a0ecd" + integrity sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ== dependencies: - mime-db "1.44.0" + mime-db "1.45.0" mime@1.6.0, mime@^1.4.1: version "1.6.0" @@ -13871,10 +13979,10 @@ node-gyp-build@^4.2.0: 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-hid@2.0.0-0: - version "2.0.0-0" - resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-2.0.0-0.tgz#35daffb4708f27331ca4143af0b8cf338fea9908" - integrity sha512-Ywc4WaMANhvqHDTynRmbuP52ln76WiNRjjAom5l2uLyNY1wixCVjISi+SP4/Rfgcddq9UJM1sR5+lPD0GcvvMg== +node-hid@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-2.1.1.tgz#f83c8aa0bb4e6758b5f7383542477da93f67359d" + integrity sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw== dependencies: bindings "^1.5.0" node-addon-api "^3.0.2" @@ -13936,6 +14044,11 @@ node-releases@^1.1.29, node-releases@^1.1.3, node-releases@^1.1.61, node-release resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== +nofilter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" + integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== + noop-logger@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" @@ -14043,6 +14156,13 @@ nth-check@^1.0.2, nth-check@~1.0.1: dependencies: boolbase "~1.0.0" +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -14094,7 +14214,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.8.0: +object-inspect@^1.8.0, object-inspect@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== @@ -14139,7 +14259,7 @@ object.assign@4.1.0: has-symbols "^1.0.0" object-keys "^1.0.11" -object.assign@^4.1.0, object.assign@^4.1.1: +object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -14564,17 +14684,22 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + parse5@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== -parse5@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== - dependencies: - "@types/node" "*" +parse5@^6.0.0, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" @@ -14779,6 +14904,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + pkg-up@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" @@ -15551,9 +15683,9 @@ preact@10.4.1: integrity sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q== preact@^10.3.3: - version "10.5.7" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.7.tgz#f1d84725539e18f7ccbea937cf3db5895661dbd3" - integrity sha512-4oEpz75t/0UNcwmcsjk+BIcDdk68oao+7kxcpc1hQPNs2Oo3ZL9xFz8UBf350mxk/VEdD41L5b4l2dE3Ug3RYg== + version "10.5.9" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.9.tgz#8caba9288b4db1d593be2317467f8735e43cda0b" + integrity sha512-X4m+4VMVINl/JFQKALOCwa3p8vhMAhBvle0hJ/W44w/WWfNb2TA7RNicDV3K2dNVs57f61GviEnVLiwN+fxiIg== prebuild-install@^5.3.5: version "5.3.6" @@ -15867,10 +15999,10 @@ qr.js@0.0.0: resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8= -qrcode.react@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.0.tgz#7e8889db3b769e555e8eb463d4c6de221c36d5de" - integrity sha512-jBXleohRTwvGBe1ngV+62QvEZ/9IZqQivdwzo9pJM4LQMoCM2VnvNBnKdjvGnKyDZ/l0nCDgsPod19RzlPvm/Q== +qrcode.react@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.1.tgz#2834bb50e5e275ffe5af6906eff15391fe9e38a5" + integrity sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg== dependencies: loose-envify "^1.4.0" prop-types "^15.6.0" @@ -15913,10 +16045,10 @@ query-string@6.13.5: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -query-string@6.13.7: - version "6.13.7" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.7.tgz#af53802ff6ed56f3345f92d40a056f93681026ee" - integrity sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA== +query-string@6.13.8: + version "6.13.8" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.8.tgz#8cf231759c85484da3cf05a851810d8e825c1159" + integrity sha512-jxJzQI2edQPE/NPUOusNjO/ZOGqr1o2OBa/3M00fU76FsLXDVbJDv/p7ng5OdQyorKrkRz1oqfwmbe5MAMePQg== dependencies: decode-uri-component "^0.2.0" split-on-first "^1.0.0" @@ -15976,7 +16108,7 @@ ramda@^0.26.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== -randombytes@2.1.0, randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -16941,7 +17073,7 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.0: +require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== @@ -17029,14 +17161,7 @@ resolve@1.18.1: is-core-module "^2.0.0" path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.8.1, resolve@~1.17.0: - 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.14.2, resolve@^1.18.1: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.8.1: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== @@ -17044,6 +17169,13 @@ resolve@^1.14.2, resolve@^1.18.1: is-core-module "^2.1.0" path-parse "^1.0.6" +resolve@~1.17.0: + 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" + responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -17234,7 +17366,7 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== -rxjs@^6.1.0, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.4, rxjs@^6.5.5, rxjs@^6.6.0, rxjs@^6.6.3: +rxjs@^6.1.0, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.4, rxjs@^6.6.0, rxjs@^6.6.3: version "6.6.3" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== @@ -17319,9 +17451,9 @@ sass-loader@8.0.2, sass-loader@^9.0.0: semver "^7.3.2" sass@^1.29.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.30.0.tgz#60bbbbaf76ba10117e61c6c24f00161c3d60610e" - integrity sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw== + version "1.32.2" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.2.tgz#66dc0250bc86c15d19ddee7135e93d0cf3d3257b" + integrity sha512-u1pUuzqwz3SAgvHSWp1k0mRhX82b2DdlVnP6UIetQPZtYbuJUDaPQhZE12jyjB7vYeOScfz9WPsZJB6Rpk7heA== dependencies: chokidar ">=2.0.0 <4.0.0" @@ -17394,7 +17526,16 @@ sdp@^2.12.0, sdp@^2.6.0: resolved "https://registry.yarnpkg.com/sdp/-/sdp-2.12.0.tgz#338a106af7560c86e4523f858349680350d53b22" integrity sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw== -secp256k1@3.8.0, secp256k1@^3.0.1, secp256k1@^3.7.1, secp256k1@^3.8.0: +secp256k1@4.0.2, secp256k1@^4.0.0, 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" + +secp256k1@^3.0.1, secp256k1@^3.7.1, secp256k1@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.0.tgz#28f59f4b01dbee9575f56a47034b7d2e3b3b352d" integrity sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw== @@ -17408,15 +17549,6 @@ secp256k1@3.8.0, secp256k1@^3.0.1, secp256k1@^3.7.1, secp256k1@^3.8.0: nan "^2.14.0" safe-buffer "^5.1.2" -secp256k1@4.0.2, secp256k1@^4.0.0, 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" - select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -17451,10 +17583,10 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -semver-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338" - integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw== +semver-regex@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.2.tgz#34b4c0d361eef262e07199dbef316d0f2ab11807" + integrity sha512-bXWyL6EAKOJa81XG1OZ/Yyuq+oT0b2YLlxx7c+mrdYPaPbnj6WgVULXhinMIeZGufuUBu/eVRqXEhiv4imfwxA== "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.7.1" @@ -17695,12 +17827,13 @@ shellwords@^0.1.1: integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== side-channel@^1.0.2, side-channel@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3" - integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== dependencies: - es-abstract "^1.18.0-next.0" - object-inspect "^1.8.0" + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" @@ -17777,15 +17910,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - slice-ansi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" @@ -18607,15 +18731,15 @@ symbol.prototype.description@^1.0.0: has-symbols "^1.0.1" object.getownpropertydescriptors "^2.1.0" -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== +table@^6.0.4: + version "6.0.7" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" + integrity sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" + ajv "^7.0.2" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" @@ -19108,9 +19232,9 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3: integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== tsutils@^3.17.1: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + version "3.19.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.19.1.tgz#d8566e0c51c82f32f9c25a4d367cd62409a547a9" + integrity sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw== dependencies: tslib "^1.8.1" @@ -19238,10 +19362,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389" - integrity sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ== +typescript@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" + integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== typical@^2.6.0, typical@^2.6.1: version "2.6.1" @@ -19407,9 +19531,9 @@ update-notifier@^4.1.1: xdg-basedir "^4.0.0" uri-js@^4.2.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" - integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" @@ -19505,9 +19629,9 @@ use@^3.1.0: integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== utf-8-validate@^5.0.2: - version "5.0.3" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.3.tgz#3b64e418ad2ff829809025fdfef595eab2f03a27" - integrity sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A== + version "5.0.4" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.4.tgz#72a1735983ddf7a05a43a9c6b67c5ce1c910f9b8" + integrity sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q== dependencies: node-gyp-build "^4.2.0" @@ -19558,6 +19682,18 @@ util@^0.11.0: dependencies: inherits "2.0.3" +util@^0.12.0: + version "0.12.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" + integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -19670,16 +19806,16 @@ w3c-xmlserializer@^2.0.0: dependencies: xml-name-validator "^3.0.0" -wait-on@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.2.0.tgz#6711e74422523279714a36d52cf49fb47c9d9597" - integrity sha512-U1D9PBgGw2XFc6iZqn45VBubw02VsLwnZWteQ1au4hUVHasTZuFSKRzlTB2dqgLhji16YVI8fgpEpwUdCr8B6g== +wait-on@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.2.1.tgz#05b66fcb4d7f5da01537f03e7cf96e8836422996" + integrity sha512-H2F986kNWMU9hKlI9l/ppO6tN8ZSJd35yBljMLa1/vjzWP++Qh6aXyt77/u7ySJFZQqBtQxnvm/xgG48AObXcw== dependencies: - axios "^0.19.2" - joi "^17.1.1" - lodash "^4.17.19" + axios "^0.21.1" + joi "^17.3.0" + lodash "^4.17.20" minimist "^1.2.5" - rxjs "^6.5.5" + rxjs "^6.6.3" walker@^1.0.7, walker@~1.0.5: version "1.0.7" @@ -19751,10 +19887,10 @@ web3-bzz@1.2.9: swarm-js "^0.1.40" underscore "1.9.1" -web3-bzz@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.3.0.tgz#83dfd77fa8a64bbb660462dffd0fee2a02ef1051" - integrity sha512-ibYAnKab+sgTo/UdfbrvYfWblXjjgSMgyy9/FHa6WXS14n/HVB+HfWqGz2EM3fok8Wy5XoKGMvdqvERQ/mzq1w== +web3-bzz@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.3.1.tgz#c7e13e5fbbbe4634b0d883e5440069fc58e58044" + integrity sha512-MN726zFpFpwhs3NMC35diJGkwTVUj+8LM/VWqooGX/MOjgYzNrJ7Wr8EzxoaTCy87edYNBprtxBkd0HzzLmung== dependencies: "@types/node" "^12.12.6" got "9.6.0" @@ -19779,14 +19915,14 @@ web3-core-helpers@1.2.9: web3-eth-iban "1.2.9" web3-utils "1.2.9" -web3-core-helpers@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.3.0.tgz#697cc3246a7eaaaac64ea506828d861c981c3f31" - integrity sha512-+MFb1kZCrRctf7UYE7NCG4rGhSXaQJ/KF07di9GVK1pxy1K0+rFi61ZobuV1ky9uQp+uhhSPts4Zp55kRDB5sw== +web3-core-helpers@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.3.1.tgz#ffd6f47c1b54a8523f00760a8d713f44d0f97e97" + integrity sha512-tMVU0ScyQUJd/HFWfZrvGf+QmPCodPyKQw1gQ+n9We/H3vPPbUxDjNeYnd4BbYy5O9ox+0XG6i3+JlwiSkgDkA== dependencies: underscore "1.9.1" - web3-eth-iban "1.3.0" - web3-utils "1.3.0" + web3-eth-iban "1.3.1" + web3-utils "1.3.1" web3-core-method@1.2.11: version "1.2.11" @@ -19812,17 +19948,17 @@ web3-core-method@1.2.9: web3-core-subscriptions "1.2.9" web3-utils "1.2.9" -web3-core-method@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.3.0.tgz#a71387af842aec7dbad5dbbd1130c14cc6c8beb3" - integrity sha512-h0yFDrYVzy5WkLxC/C3q+hiMnzxdWm9p1T1rslnuHgOp6nYfqzu/6mUIXrsS4h/OWiGJt+BZ0xVZmtC31HDWtg== +web3-core-method@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.3.1.tgz#c1d8bf1e2104a8d625c99caf94218ad2dc948c92" + integrity sha512-dA38tNVZWTxBFMlLFunLD5Az1AWRi5HqM+AtQrTIhxWCzg7rJSHuaYOZ6A5MHKGPWpdykLhzlna0SsNv5AVs8w== dependencies: "@ethersproject/transactions" "^5.0.0-beta.135" underscore "1.9.1" - web3-core-helpers "1.3.0" - web3-core-promievent "1.3.0" - web3-core-subscriptions "1.3.0" - web3-utils "1.3.0" + web3-core-helpers "1.3.1" + web3-core-promievent "1.3.1" + web3-core-subscriptions "1.3.1" + web3-utils "1.3.1" web3-core-promievent@1.2.11: version "1.2.11" @@ -19838,10 +19974,10 @@ web3-core-promievent@1.2.9: dependencies: eventemitter3 "3.1.2" -web3-core-promievent@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.3.0.tgz#e0442dd0a8989b6bdce09293976cee6d9237a484" - integrity sha512-blv69wrXw447TP3iPvYJpllkhW6B18nfuEbrfcr3n2Y0v1Jx8VJacNZFDFsFIcgXcgUIVCtOpimU7w9v4+rtaw== +web3-core-promievent@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.3.1.tgz#b4da4b34cd9681e22fcda25994d7629280a1e046" + integrity sha512-jGu7TkwUqIHlvWd72AlIRpsJqdHBQnHMeMktrows2148gg5PBPgpJ10cPFmCCzKT6lDOVh9B7pZMf9eckMDmiA== dependencies: eventemitter3 "4.0.4" @@ -19867,16 +20003,17 @@ web3-core-requestmanager@1.2.9: web3-providers-ipc "1.2.9" web3-providers-ws "1.2.9" -web3-core-requestmanager@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.3.0.tgz#c5b9a0304504c0e6cce6c90bc1a3bff82732aa1f" - integrity sha512-3yMbuGcomtzlmvTVqNRydxsx7oPlw3ioRL6ReF9PeNYDkUsZaUib+6Dp5eBt7UXh5X+SIn/xa1smhDHz5/HpAw== +web3-core-requestmanager@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.3.1.tgz#6dd2b5161ba778dfffe68994a4accff2decc54fe" + integrity sha512-9WTaN2SoyJX1amRyTzX2FtbVXsyWBI2Wef2Q3gPiWaEo/VRVm3e4Bq8MwxNTUMIJMO8RLGHjtdgsoDKPwfL73Q== dependencies: underscore "1.9.1" - web3-core-helpers "1.3.0" - web3-providers-http "1.3.0" - web3-providers-ipc "1.3.0" - web3-providers-ws "1.3.0" + util "^0.12.0" + web3-core-helpers "1.3.1" + web3-providers-http "1.3.1" + web3-providers-ipc "1.3.1" + web3-providers-ws "1.3.1" web3-core-subscriptions@1.2.11: version "1.2.11" @@ -19896,14 +20033,14 @@ web3-core-subscriptions@1.2.9: underscore "1.9.1" web3-core-helpers "1.2.9" -web3-core-subscriptions@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.3.0.tgz#c2622ccd2b84f4687475398ff966b579dba0847e" - integrity sha512-MUUQUAhJDb+Nz3S97ExVWveH4utoUnsbPWP+q1HJH437hEGb4vunIb9KvN3hFHLB+aHJfPeStM/4yYTz5PeuyQ== +web3-core-subscriptions@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.3.1.tgz#be1103259f91b7fc7f4c6a867aa34dea70a636f7" + integrity sha512-eX3N5diKmrxshc6ZBZ8EJxxAhCxdYPbYXuF2EfgdIyHmxwmYqIVvKepzO8388Bx8JD3D0Id/pKE0dC/FnDIHTQ== dependencies: eventemitter3 "4.0.4" underscore "1.9.1" - web3-core-helpers "1.3.0" + web3-core-helpers "1.3.1" web3-core@1.2.11: version "1.2.11" @@ -19931,18 +20068,18 @@ web3-core@1.2.9: web3-core-requestmanager "1.2.9" web3-utils "1.2.9" -web3-core@1.3.0, web3-core@^1.2.11, web3-core@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.3.0.tgz#b818903738461c1cca0163339e1d6d3fa51242cf" - integrity sha512-BwWvAaKJf4KFG9QsKRi3MNoNgzjI6szyUlgme1qNPxUdCkaS3Rdpa0VKYNHP7M/YTk82/59kNE66mH5vmoaXjA== +web3-core@1.3.1, web3-core@^1.2.11, web3-core@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.3.1.tgz#fb0fc5d952a7f3d580a7e6155d2f28be064e64cb" + integrity sha512-QlBwSyjl2pqYUBE7lH9PfLxa8j6AzzAtvLUqkgoaaFJYLP/+XavW1n6dhVCTq+U3L3eNc+bMp9GLjGDJNXMnGg== dependencies: "@types/bn.js" "^4.11.5" "@types/node" "^12.12.6" bignumber.js "^9.0.0" - web3-core-helpers "1.3.0" - web3-core-method "1.3.0" - web3-core-requestmanager "1.3.0" - web3-utils "1.3.0" + web3-core-helpers "1.3.1" + web3-core-method "1.3.1" + web3-core-requestmanager "1.3.1" + web3-utils "1.3.1" web3-eth-abi@1.2.11: version "1.2.11" @@ -19962,14 +20099,14 @@ web3-eth-abi@1.2.9: underscore "1.9.1" web3-utils "1.2.9" -web3-eth-abi@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.3.0.tgz#387b7ea9b38be69ad8856bc7b4e9a6a69bb4d22b" - integrity sha512-1OrZ9+KGrBeBRd3lO8upkpNua9+7cBsQAgor9wbA25UrcUYSyL8teV66JNRu9gFxaTbkpdrGqM7J/LXpraXWrg== +web3-eth-abi@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.3.1.tgz#d60fe5f15c7a3a426c553fdaa4199d07f1ad899c" + integrity sha512-ds4aTeKDUEqTXgncAtxvcfMpPiei9ey7+s2ZZ+OazK2CK5jWhFiJuuj9Q68kOT+hID7E1oSDVsNmJWFD/7lbMw== dependencies: - "@ethersproject/abi" "5.0.0-beta.153" + "@ethersproject/abi" "5.0.7" underscore "1.9.1" - web3-utils "1.3.0" + web3-utils "1.3.1" web3-eth-accounts@1.2.11: version "1.2.11" @@ -20005,10 +20142,10 @@ web3-eth-accounts@1.2.9: web3-core-method "1.2.9" web3-utils "1.2.9" -web3-eth-accounts@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.3.0.tgz#010acf389b2bee6d5e1aecb2fe78bfa5c8f26c7a" - integrity sha512-/Q7EVW4L2wWUbNRtOTwAIrYvJid/5UnKMw67x/JpvRMwYC+e+744P536Ja6SG4X3MnzFvd3E/jruV4qa6k+zIw== +web3-eth-accounts@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.3.1.tgz#63b247461f1ae0ae46f9a5d5aa896ea80237143e" + integrity sha512-wsV3/0Pbn5+pI8PiCD1CYw7I1dkQujcP//aJ+ZH8PoaHQoG6HnJ7nTp7foqa0r/X5lizImz/g5S8D76t3Z9tHA== dependencies: crypto-browserify "3.12.0" eth-lib "0.2.8" @@ -20017,10 +20154,10 @@ web3-eth-accounts@1.3.0: scrypt-js "^3.0.1" underscore "1.9.1" uuid "3.3.2" - web3-core "1.3.0" - web3-core-helpers "1.3.0" - web3-core-method "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-helpers "1.3.1" + web3-core-method "1.3.1" + web3-utils "1.3.1" web3-eth-contract@1.2.11: version "1.2.11" @@ -20052,20 +20189,20 @@ web3-eth-contract@1.2.9: web3-eth-abi "1.2.9" web3-utils "1.2.9" -web3-eth-contract@1.3.0, web3-eth-contract@^1.2.11, web3-eth-contract@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.3.0.tgz#c758340ac800788e29fa29edc8b0c0ac957b741c" - integrity sha512-3SCge4SRNCnzLxf0R+sXk6vyTOl05g80Z5+9/B5pERwtPpPWaQGw8w01vqYqsYBKC7zH+dxhMaUgVzU2Dgf7bQ== +web3-eth-contract@1.3.1, web3-eth-contract@^1.2.11, web3-eth-contract@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.3.1.tgz#05cb77bd2a671c5480897d20de487f3bae82e113" + integrity sha512-cHu9X1iGrK+Zbrj4wYKwHI1BtVGn/9O0JRsZqd9qcFGLwwAmaCJYy0sDn7PKCKDSL3qB+MDILoyI7FaDTWWTHg== dependencies: "@types/bn.js" "^4.11.5" underscore "1.9.1" - web3-core "1.3.0" - web3-core-helpers "1.3.0" - web3-core-method "1.3.0" - web3-core-promievent "1.3.0" - web3-core-subscriptions "1.3.0" - web3-eth-abi "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-helpers "1.3.1" + web3-core-method "1.3.1" + web3-core-promievent "1.3.1" + web3-core-subscriptions "1.3.1" + web3-eth-abi "1.3.1" + web3-utils "1.3.1" web3-eth-ens@1.2.11: version "1.2.11" @@ -20097,20 +20234,20 @@ web3-eth-ens@1.2.9: web3-eth-contract "1.2.9" web3-utils "1.2.9" -web3-eth-ens@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.3.0.tgz#0887ba38473c104cf5fb8a715828b3b354fa02a2" - integrity sha512-WnOru+EcuM5dteiVYJcHXo/I7Wq+ei8RrlS2nir49M0QpYvUPGbCGgTbifcjJQTWamgORtWdljSA1s2Asdb74w== +web3-eth-ens@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.3.1.tgz#ccfd621ddc1fecb44096bc8e60689499a9eb4421" + integrity sha512-MUQvYgUYQ5gAwbZyHwI7y+NTT6j98qG3MVhGCUf58inF5Gxmn9OlLJRw8Tofgf0K87Tk9Kqw1/2QxUE4PEZMMA== dependencies: content-hash "^2.5.2" eth-ens-namehash "2.0.8" underscore "1.9.1" - web3-core "1.3.0" - web3-core-helpers "1.3.0" - web3-core-promievent "1.3.0" - web3-eth-abi "1.3.0" - web3-eth-contract "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-helpers "1.3.1" + web3-core-promievent "1.3.1" + web3-eth-abi "1.3.1" + web3-eth-contract "1.3.1" + web3-utils "1.3.1" web3-eth-iban@1.2.11: version "1.2.11" @@ -20128,13 +20265,13 @@ web3-eth-iban@1.2.9: bn.js "4.11.8" web3-utils "1.2.9" -web3-eth-iban@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.3.0.tgz#15b782dfaf273ebc4e3f389f1367f4e88ddce4a5" - integrity sha512-v9mZWhR4fPF17/KhHLiWir4YHWLe09O3B/NTdhWqw3fdAMJNztzMHGzgHxA/4fU+rhrs/FhDzc4yt32zMEXBZw== +web3-eth-iban@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.3.1.tgz#4351e1a658efa5f3218357f0a38d6d8cad82481e" + integrity sha512-RCQLfR9Z+DNfpw7oUauYHg1HcVoEljzhwxKn3vi15gK0ssWnTwRGqUiIyVTeSb836G6oakOd5zh7XYqy7pn+nw== dependencies: bn.js "^4.11.9" - web3-utils "1.3.0" + web3-utils "1.3.1" web3-eth-personal@1.2.11: version "1.2.11" @@ -20160,17 +20297,17 @@ web3-eth-personal@1.2.9: web3-net "1.2.9" web3-utils "1.2.9" -web3-eth-personal@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.3.0.tgz#d376e03dc737d961ff1f8d1aca866efad8477135" - integrity sha512-2czUhElsJdLpuNfun9GeLiClo5O6Xw+bLSjl3f4bNG5X2V4wcIjX2ygep/nfstLLtkz8jSkgl/bV7esANJyeRA== +web3-eth-personal@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.3.1.tgz#cfe8af01588870d195dabf0a8d9e34956fb8856d" + integrity sha512-/vZEQpXJfBfYoy9KT911ItfoscEfF0Q2j8tsXzC2xmmasSZ6YvAUuPhflVmAo0IHQSX9rmxq0q1p3sbnE3x2pQ== dependencies: "@types/node" "^12.12.6" - web3-core "1.3.0" - web3-core-helpers "1.3.0" - web3-core-method "1.3.0" - web3-net "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-helpers "1.3.1" + web3-core-method "1.3.1" + web3-net "1.3.1" + web3-utils "1.3.1" web3-eth@1.2.11: version "1.2.11" @@ -20210,24 +20347,24 @@ web3-eth@1.2.9: web3-net "1.2.9" web3-utils "1.2.9" -web3-eth@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.3.0.tgz#898e5f5a8827f9bc6844e267a52eb388916a6771" - integrity sha512-/bzJcxXPM9EM18JM5kO2JjZ3nEqVo3HxqU93aWAEgJNqaP/Lltmufl2GpvIB2Hvj+FXAjAXquxUdQ2/xP7BzHQ== +web3-eth@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.3.1.tgz#60ac4b58e5fd17b8dbbb8378abd63b02e8326727" + integrity sha512-e4iL8ovj0zNxzbv4LTHEv9VS03FxKlAZD+95MolwAqtVoUnKC2H9X6dli0w6eyXP0aKw+mwY0g0CWQHzqZvtXw== dependencies: underscore "1.9.1" - web3-core "1.3.0" - web3-core-helpers "1.3.0" - web3-core-method "1.3.0" - web3-core-subscriptions "1.3.0" - web3-eth-abi "1.3.0" - web3-eth-accounts "1.3.0" - web3-eth-contract "1.3.0" - web3-eth-ens "1.3.0" - web3-eth-iban "1.3.0" - web3-eth-personal "1.3.0" - web3-net "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-helpers "1.3.1" + web3-core-method "1.3.1" + web3-core-subscriptions "1.3.1" + web3-eth-abi "1.3.1" + web3-eth-accounts "1.3.1" + web3-eth-contract "1.3.1" + web3-eth-ens "1.3.1" + web3-eth-iban "1.3.1" + web3-eth-personal "1.3.1" + web3-net "1.3.1" + web3-utils "1.3.1" web3-net@1.2.11: version "1.2.11" @@ -20247,26 +20384,26 @@ web3-net@1.2.9: web3-core-method "1.2.9" web3-utils "1.2.9" -web3-net@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.3.0.tgz#b69068cccffab58911c2f08ca4abfbefb0f948c6" - integrity sha512-Xz02KylOyrB2YZzCkysEDrY7RbKxb7LADzx3Zlovfvuby7HBwtXVexXKtoGqksa+ns1lvjQLLQGb+OeLi7Sr7w== +web3-net@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.3.1.tgz#79374b1df37429b0839b83b0abc4440ac6181568" + integrity sha512-vuMMWMk+NWHlrNfszGp3qRjH/64eFLiNIwUi0kO8JXQ896SP3Ma0su5sBfSPxNCig047E9GQimrL9wvYAJSO5A== dependencies: - web3-core "1.3.0" - web3-core-method "1.3.0" - web3-utils "1.3.0" + web3-core "1.3.1" + web3-core-method "1.3.1" + web3-utils "1.3.1" -web3-provider-engine@15.0.12, web3-provider-engine@^15.0.4: - version "15.0.12" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-15.0.12.tgz#24d7f2f6fb6de856824c7306291018c4fc543ac3" - integrity sha512-/OfhQalKPND1iB5ggvGuYF0+SIb2Qj5OFTrT2VrZWP79UhMTdP7T+L2FtblmRdCeOetoAzZHdBaIwLOZsmIX+w== +web3-provider-engine@15.0.4: + version "15.0.4" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-15.0.4.tgz#5c336bcad2274dff5218bc8db003fa4e9e464c24" + integrity sha512-Ob9oK0TUZfVC7NXkB7CQSWAiCdCD/Xnlh2zTnV8NdJR8LCrMAy2i6JedU70JHaxw59y7mM4GnsYOTTGkquFnNQ== dependencies: async "^2.5.0" backoff "^2.5.0" clone "^2.0.0" cross-fetch "^2.1.0" eth-block-tracker "^4.4.2" - eth-json-rpc-errors "^2.0.2" + eth-json-rpc-errors "^1.0.1" eth-json-rpc-filters "^4.1.1" eth-json-rpc-infura "^4.0.1" eth-json-rpc-middleware "^4.1.5" @@ -20284,17 +20421,45 @@ web3-provider-engine@15.0.12, web3-provider-engine@^15.0.4: xhr "^2.2.0" xtend "^4.0.1" -web3-provider-engine@15.0.4: - version "15.0.4" - resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-15.0.4.tgz#5c336bcad2274dff5218bc8db003fa4e9e464c24" - integrity sha512-Ob9oK0TUZfVC7NXkB7CQSWAiCdCD/Xnlh2zTnV8NdJR8LCrMAy2i6JedU70JHaxw59y7mM4GnsYOTTGkquFnNQ== +web3-provider-engine@16.0.1: + version "16.0.1" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-16.0.1.tgz#2600a39ede364cdc0a1fc773bf40a94f2177e605" + integrity sha512-/Eglt2aocXMBiDj7Se/lyZnNDaHBaoJlaUfbP5HkLJQC/HlGbR+3/W+dINirlJDhh7b54DzgykqY7ksaU5QgTg== dependencies: async "^2.5.0" backoff "^2.5.0" clone "^2.0.0" cross-fetch "^2.1.0" eth-block-tracker "^4.4.2" - eth-json-rpc-errors "^1.0.1" + eth-json-rpc-filters "^4.2.1" + eth-json-rpc-infura "^5.1.0" + eth-json-rpc-middleware "^6.0.0" + eth-rpc-errors "^3.0.0" + eth-sig-util "^1.4.2" + ethereumjs-block "^1.2.2" + ethereumjs-tx "^1.2.0" + ethereumjs-util "^5.1.5" + ethereumjs-vm "^2.3.4" + json-stable-stringify "^1.0.1" + promise-to-callback "^1.0.0" + readable-stream "^2.2.9" + request "^2.85.0" + semaphore "^1.0.3" + ws "^5.1.1" + xhr "^2.2.0" + xtend "^4.0.1" + +web3-provider-engine@^15.0.4: + version "15.0.12" + resolved "https://registry.yarnpkg.com/web3-provider-engine/-/web3-provider-engine-15.0.12.tgz#24d7f2f6fb6de856824c7306291018c4fc543ac3" + integrity sha512-/OfhQalKPND1iB5ggvGuYF0+SIb2Qj5OFTrT2VrZWP79UhMTdP7T+L2FtblmRdCeOetoAzZHdBaIwLOZsmIX+w== + dependencies: + async "^2.5.0" + backoff "^2.5.0" + clone "^2.0.0" + cross-fetch "^2.1.0" + eth-block-tracker "^4.4.2" + eth-json-rpc-errors "^2.0.2" eth-json-rpc-filters "^4.1.1" eth-json-rpc-infura "^4.0.1" eth-json-rpc-middleware "^4.1.5" @@ -20328,12 +20493,12 @@ web3-providers-http@1.2.9: web3-core-helpers "1.2.9" xhr2-cookies "1.1.0" -web3-providers-http@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.3.0.tgz#88227f64c88b32abed4359383c2663616e0dc531" - integrity sha512-cMKhUI6PqlY/EC+ZDacAxajySBu8AzW8jOjt1Pe/mbRQgS0rcZyvLePGTTuoyaA8C21F8UW+EE5jj7YsNgOuqA== +web3-providers-http@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.3.1.tgz#becbea61706b2fa52e15aca6fe519ee108a8fab9" + integrity sha512-DOujG6Ts7/hAMj0PW5p9/1vwxAIr+1CJ6ZWHshtfOq1v1KnMphVTGOrjcTTUvPT33/DA/so2pgGoPMrgaEIIvQ== dependencies: - web3-core-helpers "1.3.0" + web3-core-helpers "1.3.1" xhr2-cookies "1.1.0" web3-providers-ipc@1.2.11: @@ -20354,14 +20519,14 @@ web3-providers-ipc@1.2.9: underscore "1.9.1" web3-core-helpers "1.2.9" -web3-providers-ipc@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.3.0.tgz#d7c2b203733b46f7b4e7b15633d891648cf9a293" - integrity sha512-0CrLuRofR+1J38nEj4WsId/oolwQEM6Yl1sOt41S/6bNI7htdkwgVhSloFIMJMDFHtRw229QIJ6wIaKQz0X1Og== +web3-providers-ipc@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.3.1.tgz#3cb2572fc5286ab2f3117e0a2dce917816c3dedb" + integrity sha512-BNPscLbvwo+u/tYJrLvPnl/g/SQVSnqP/TjEsB033n4IXqTC4iZ9Of8EDmI0U6ds/9nwNqOBx3KsxbinL46UZA== dependencies: oboe "2.1.5" underscore "1.9.1" - web3-core-helpers "1.3.0" + web3-core-helpers "1.3.1" web3-providers-ws@1.2.11: version "1.2.11" @@ -20383,14 +20548,14 @@ web3-providers-ws@1.2.9: web3-core-helpers "1.2.9" websocket "^1.0.31" -web3-providers-ws@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.3.0.tgz#84adeff65acd4624d7f5bb43c5b2b22d8f0f63a4" - integrity sha512-Im5MthhJnJst8nSoq0TgbyOdaiFQFa5r6sHPOVllhgIgViDqzbnlAFW9sNzQ0Q8VXPNfPIQKi9cOrHlSRNPjRw== +web3-providers-ws@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.3.1.tgz#a70140811d138a1a5cf3f0c39d11887c8e341c83" + integrity sha512-DAbVbiizv0Hr/bLKjyyKMHc/66ccVkudan3eRsf+R/PXWCqfXb7q6Lwodj4llvC047pEuLKR521ZKr5wbfk1KQ== dependencies: eventemitter3 "4.0.4" underscore "1.9.1" - web3-core-helpers "1.3.0" + web3-core-helpers "1.3.1" websocket "^1.0.32" web3-shh@1.2.11: @@ -20413,15 +20578,15 @@ web3-shh@1.2.9: web3-core-subscriptions "1.2.9" web3-net "1.2.9" -web3-shh@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.3.0.tgz#62d15297da8fb5f733dd1b98f9ade300590f4d49" - integrity sha512-IZTojA4VCwVq+7eEIHuL1tJXtU+LJDhO8Y2QmuwetEWW1iBgWCGPHZasipWP+7kDpSm/5lo5GRxL72FF/Os/tA== +web3-shh@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.3.1.tgz#42294d684358c22aa48616cb9a3eb2e9c1e6362f" + integrity sha512-57FTQvOW1Zm3wqfZpIEqL4apEQIR5JAxjqA4RM4eL0jbdr+Zj5Y4J93xisaEVl6/jMtZNlsqYKTVswx8mHu1xw== dependencies: - web3-core "1.3.0" - web3-core-method "1.3.0" - web3-core-subscriptions "1.3.0" - web3-net "1.3.0" + web3-core "1.3.1" + web3-core-method "1.3.1" + web3-core-subscriptions "1.3.1" + web3-net "1.3.1" web3-utils@1.2.1: version "1.2.1" @@ -20464,10 +20629,10 @@ web3-utils@1.2.9: underscore "1.9.1" utf8 "3.0.0" -web3-utils@1.3.0, web3-utils@^1.2.11, web3-utils@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.3.0.tgz#5bac16e5e0ec9fe7bdcfadb621655e8aa3cf14e1" - integrity sha512-2mS5axFCbkhicmoDRuJeuo0TVGQDgC2sPi/5dblfVC+PMtX0efrb8Xlttv/eGkq7X4E83Pds34FH98TP2WOUZA== +web3-utils@1.3.1, web3-utils@^1.2.11, web3-utils@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.3.1.tgz#9aa880dd8c9463fe5c099107889f86a085370c2e" + integrity sha512-9gPwFm8SXtIJuzdrZ37PRlalu40fufXxo+H2PiCwaO6RpKGAvlUlWU0qQbyToFNXg7W2H8djEgoAVac8NLMCKQ== dependencies: bn.js "^4.11.9" eth-lib "0.2.8" @@ -20479,17 +20644,17 @@ web3-utils@1.3.0, web3-utils@^1.2.11, web3-utils@^1.3.0: utf8 "3.0.0" web3@*, web3@^1.0.0-beta.34: - version "1.3.0" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.3.0.tgz#8fe4cd6e2a21c91904f343ba75717ee4c76bb349" - integrity sha512-4q9dna0RecnrlgD/bD1C5S+81Untbd6Z/TBD7rb+D5Bvvc0Wxjr4OP70x+LlnwuRDjDtzBwJbNUblh2grlVArw== + version "1.3.1" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.3.1.tgz#f780138c92ae3c42ea45e1a3c6ae8844e0aa5054" + integrity sha512-lDJwOLSRWHYwhPy4h5TNgBRJ/lED7lWXyVOXHCHcEC8ai3coBNdgEXWBu/GGYbZMsS89EoUOJ14j3Ufi4dUkog== dependencies: - web3-bzz "1.3.0" - web3-core "1.3.0" - web3-eth "1.3.0" - web3-eth-personal "1.3.0" - web3-net "1.3.0" - web3-shh "1.3.0" - web3-utils "1.3.0" + web3-bzz "1.3.1" + web3-core "1.3.1" + web3-eth "1.3.1" + web3-eth-personal "1.3.1" + web3-net "1.3.1" + web3-shh "1.3.1" + web3-utils "1.3.1" web3@1.2.11: version "1.2.11" @@ -20702,12 +20867,7 @@ whatwg-fetch@2.0.4: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== -whatwg-fetch@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" - integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== - -whatwg-fetch@^3.5.0: +whatwg-fetch@^3.4.1, whatwg-fetch@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz#605a2cd0a7146e5db141e29d1c62ab84c0c4c868" integrity sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A== @@ -20736,6 +20896,19 @@ which-pm-runs@^1.0.0: resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + which@2.0.2, which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" From 8a774f2e66fec9cd8dbf0a23bfa17f56f12f2d93 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Wed, 13 Jan 2021 07:27:07 -0300 Subject: [PATCH 15/23] (Feature) - #1048 Tx will fail warning (#1675) * Makes getGasEstimationTxResponse exportable * Add check for failing txs on approveTxModal * Adds styles for reviewTx * Adds useTxSuccessCheck hook * Adds checkIfTxWillFail function * Uses checkIfTxWillFailAsync on reviewTx modal * Improves approveTx modal * Add check for failing transaction in contract interaction modal * Add check for reviewCollectible * Fix check on sendFunds reviewTx * Adds styling for contractInteraction modal * Fix gas calculation for native token transfers * Rename estimateDataGasCosts to parseRequiredTxGasResponse Adds getPreValidatedSignatures Refactor estimateTxGasCosts Refactor checkIfExecTxWillFail * Refactor checkIfExecTxWill usage * Refactor checkIfTxWillFailAsync in ReviewTx * Use getPreValidatedSignatures in createTransaction() * Refactor estimateTxGasCosts Rename estimateSafeTxGas to estimateExecTransactionGas * Refactor ReviewTx: extract useEffects to hooks * Remove unnecessary gas transfer amount * Refactor estimateTxGasCosts: extract checkIfTxIsExecution and estimateTxGas * Fix tx amount Remove console log * Moves useCheckIfTransactionWillFail to logic/hooks folder * Replaces useEffect usage with useCheckIfTransactionWillFail hook Also fix how some modals fetch the safeAddress * Improves modal's wording * Fix error parsing the cancel transaction error message from GETH nodes * Remove useCheckIfTransactionWillFail Adds useEstimateTransactionGas Renames estimateTxGas to estimateTransactionGas Removes estimateTxGasCosts Removes checkIfExecTxWillFail * Replace useCheckIfTransactionWillFail from modals with useEstimateTransactionGas * Replace estimateGasCosts from every review tx modal with useEstimateTransactionGas * Replace estimateGasCosts from every review tx modal with useEstimateTransactionGas * Extract isExecution calculation to useEstimateTransactionGas * Creates TransactionFailText * Uses TransactionFailText in the review modals * Fix wrong selector usage * Fix missing null check on cancel tx confirmations * Add guard for CLOSE_SNACKBAR action when tx was already dismissed * Improves useEstimateTransactionGas in review custom tx and contract interaction review * Fix review replace/remove/add owner modals styling * Refactor response of useEstimateTransactionGas * Remove safeAddress as param to the useEstimateTransactionGas * Improves how threshold is obtained in useEstimateTransactionGas.tsx * Rename gasCostHumanReadable to gasCostFormatted * Add operation to useEstimateTransactionGas * Refactor ConfirmTransactionModal to use useEstimateTransactionGas * Refactor proccessTransaction to use getPreValidatedSignatures method * Fix default export of ApproveTxModal * Rename estimateExecTransactionGas to estimateGasForTransactionCreation Remove estimateTransactionGas from gas.ts * Make estimateGasForTransactionCreation throw error instead of 0 gas * Adds estimateGasForTransactionExecution and estimateGasForTransactionApproval to gas.ts * Move estimateTransactionGas to useEstimateTransactionGas Refactors useEstimateTransactionGas to return isCreation and isOffChainSignature * Type and refactor generateSignaturesFromTxConfirmations Moves getPreValidatedSignatures to safeTxSigner.ts * Uses confirmations to estimateGasForTransactionExecution * Adds TransactionFeesText component Uses TransactionFeesText on ApproveTxModal * Pass more parameters to estimateGasForTransactionExecution * Removes unnecessary parameter in getNewTxNonce * Moves checkIfOffChainSignatureIsPossible to safeTxSigner.ts * Fix check for null confirmations * Uses checkIfOffChainSignatureIsPossible on createTransaction.ts * Move TransactionFailText inside TransactionFees component * Pass safeTxGas to useEstimateTransactionGas.tsx Improves how we use default params * Fix gas iteration on estimateGasForTransactionExecution * Fix estimateGasForTransactionExecution calculation * Fix generateSignaturesFromTxConfirmations calculation * Remove unnecessary Promise and await * Fix estimateGasForTransactionExecution for preApproving owner case * Improve logging * Uses operation in useEstimateTransactionGas Co-authored-by: Daniel Sanchez Co-authored-by: Fernando --- src/components/Modal/index.tsx | 2 +- src/components/TransactionFailText/index.tsx | 56 ++++ src/components/TransactionsFees/index.tsx | 43 ++++ src/logic/hooks/useEstimateTransactionGas.tsx | 241 ++++++++++++++++++ .../store/reducer/notifications.ts | 2 +- src/logic/safe/safeTxSigner.ts | 78 ++++-- .../store/actions/__tests__/utils.test.ts | 19 +- .../safe/store/actions/createTransaction.ts | 33 +-- .../safe/store/actions/processTransaction.ts | 38 +-- src/logic/safe/store/actions/utils.ts | 10 +- .../safe/transactions/__tests__/gas.test.ts | Bin 6395 -> 7372 bytes src/logic/safe/transactions/gas.ts | 198 +++++++------- src/logic/safe/transactions/send.ts | 5 +- .../components/Apps/components/AppFrame.tsx | 2 +- .../components/ConfirmTransactionModal.tsx | 40 +-- .../ContractInteraction/Review/index.tsx | 76 +++--- .../ReviewCustomTx/index.tsx | 54 ++-- .../screens/ContractInteraction/index.tsx | 6 +- .../screens/ReviewCollectible/index.tsx | 48 ++-- .../SendModal/screens/ReviewTx/index.tsx | 111 ++++---- .../ManageOwners/AddOwnerModal/index.tsx | 2 +- .../AddOwnerModal/screens/Review/index.tsx | 77 ++++-- .../AddOwnerModal/screens/Review/style.ts | 7 +- .../ManageOwners/RemoveOwnerModal/index.tsx | 15 +- .../RemoveOwnerModal/screens/Review/index.tsx | 97 ++++--- .../RemoveOwnerModal/screens/Review/style.ts | 7 +- .../ManageOwners/ReplaceOwnerModal/index.tsx | 45 ++-- .../screens/Review/index.tsx | 87 ++++--- .../ReplaceOwnerModal/screens/Review/style.ts | 7 +- .../Settings/ManageOwners/index.tsx | 4 +- .../ChangeThreshold/index.tsx | 73 ++++-- .../ChangeThreshold/style.ts | 3 +- .../Settings/ThresholdSettings/index.tsx | 8 +- .../ExpandedTx/ApproveTxModal/index.tsx | 73 ++---- .../ExpandedTx/OwnersColumn/index.tsx | 2 +- .../ExpandedTx/RejectTxModal/index.tsx | 54 ++-- .../TxsTable/ExpandedTx/index.tsx | 4 +- .../transactions/__tests__/utils.test.ts | 18 +- src/test/signatures.blockchain.ts | 10 +- 39 files changed, 1056 insertions(+), 599 deletions(-) create mode 100644 src/components/TransactionFailText/index.tsx create mode 100644 src/components/TransactionsFees/index.tsx create mode 100644 src/logic/hooks/useEstimateTransactionGas.tsx diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 40b6d1f7..69ff6ecc 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -17,7 +17,7 @@ const useStyles = makeStyles( position: 'absolute', top: '120px', width: '500px', - height: '540px', + height: '580px', borderRadius: sm, backgroundColor: '#ffffff', boxShadow: '0 0 5px 0 rgba(74, 85, 121, 0.5)', diff --git a/src/components/TransactionFailText/index.tsx b/src/components/TransactionFailText/index.tsx new file mode 100644 index 00000000..d61664cc --- /dev/null +++ b/src/components/TransactionFailText/index.tsx @@ -0,0 +1,56 @@ +import { createStyles, makeStyles } from '@material-ui/core' +import { sm } from 'src/theme/variables' +import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas' +import Row from 'src/components/layout/Row' +import Paragraph from 'src/components/layout/Paragraph' +import Img from 'src/components/layout/Img' +import InfoIcon from 'src/assets/icons/info_red.svg' +import React from 'react' +import { useSelector } from 'react-redux' +import { safeThresholdSelector } from 'src/logic/safe/store/selectors' + +const styles = createStyles({ + executionWarningRow: { + display: 'flex', + alignItems: 'center', + }, + warningIcon: { + marginRight: sm, + }, +}) + +const useStyles = makeStyles(styles) + +type TransactionFailTextProps = { + txEstimationExecutionStatus: EstimationStatus + isExecution: boolean +} + +export const TransactionFailText = ({ + txEstimationExecutionStatus, + isExecution, +}: TransactionFailTextProps): React.ReactElement | null => { + const classes = useStyles() + const threshold = useSelector(safeThresholdSelector) + + if (txEstimationExecutionStatus !== EstimationStatus.FAILURE) { + return null + } + + let errorMessage = 'To save gas costs, avoid creating the transaction.' + if (isExecution) { + errorMessage = + threshold && threshold > 1 + ? `To save gas costs, cancel this transaction` + : `To save gas costs, avoid executing the transaction.` + } + + return ( + + + Info Tooltip + This transaction will most likely fail. {errorMessage} + + + ) +} diff --git a/src/components/TransactionsFees/index.tsx b/src/components/TransactionsFees/index.tsx new file mode 100644 index 00000000..c5e54f19 --- /dev/null +++ b/src/components/TransactionsFees/index.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas' +import Paragraph from 'src/components/layout/Paragraph' +import { getNetworkInfo } from 'src/config' +import { TransactionFailText } from 'src/components/TransactionFailText' + +type TransactionFailTextProps = { + txEstimationExecutionStatus: EstimationStatus + gasCostFormatted: string + isExecution: boolean + isCreation: boolean + isOffChainSignature: boolean +} +const { nativeCoin } = getNetworkInfo() + +export const TransactionFees = ({ + gasCostFormatted, + isExecution, + isCreation, + isOffChainSignature, + txEstimationExecutionStatus, +}: TransactionFailTextProps): React.ReactElement | null => { + let transactionAction + if (isCreation) { + transactionAction = 'create' + } else if (isExecution) { + transactionAction = 'execute' + } else { + transactionAction = 'approve' + } + + return ( + <> + + You're about to {transactionAction} a transaction and will have to confirm it with your currently connected + wallet. + {!isOffChainSignature && + ` Make sure you have ${gasCostFormatted} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} + + + + ) +} diff --git a/src/logic/hooks/useEstimateTransactionGas.tsx b/src/logic/hooks/useEstimateTransactionGas.tsx new file mode 100644 index 00000000..0acb86d8 --- /dev/null +++ b/src/logic/hooks/useEstimateTransactionGas.tsx @@ -0,0 +1,241 @@ +import { useEffect, useState } from 'react' +import { + estimateGasForTransactionApproval, + estimateGasForTransactionCreation, + estimateGasForTransactionExecution, +} from 'src/logic/safe/transactions/gas' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { formatAmount } from 'src/logic/tokens/utils/formatAmount' +import { calculateGasPrice } from 'src/logic/wallets/ethTransactions' +import { getNetworkInfo } from 'src/config' +import { useSelector } from 'react-redux' +import { + safeCurrentVersionSelector, + safeParamAddressFromStateSelector, + safeThresholdSelector, +} from 'src/logic/safe/store/selectors' +import { CALL } from 'src/logic/safe/transactions' +import { providerSelector } from '../wallets/store/selectors' + +import { List } from 'immutable' +import { Confirmation } from 'src/logic/safe/store/models/types/confirmation' +import { checkIfOffChainSignatureIsPossible } from 'src/logic/safe/safeTxSigner' +import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' + +export enum EstimationStatus { + LOADING = 'LOADING', + FAILURE = 'FAILURE', + SUCCESS = 'SUCCESS', +} + +const checkIfTxIsExecution = (threshold: number, preApprovingOwner?: string, txConfirmations?: number): boolean => + txConfirmations === threshold || !!preApprovingOwner || threshold === 1 + +const checkIfTxIsApproveAndExecution = (threshold: number, txConfirmations: number): boolean => + txConfirmations + 1 === threshold + +const checkIfTxIsCreation = (txConfirmations: number): boolean => txConfirmations === 0 + +type TransactionEstimationProps = { + txData: string + safeAddress: string + txRecipient: string + txConfirmations?: List + txAmount?: string + operation?: number + gasPrice?: string + gasToken?: string + refundReceiver?: string // Address of receiver of gas payment (or 0 if tx.origin). + safeTxGas?: number + from?: string + isExecution: boolean + isCreation: boolean + isOffChainSignature?: boolean + approvalAndExecution?: boolean +} + +const estimateTransactionGas = async ({ + txData, + safeAddress, + txRecipient, + txConfirmations, + txAmount, + operation, + gasPrice, + gasToken, + refundReceiver, + safeTxGas, + from, + isExecution, + isCreation, + isOffChainSignature = false, + approvalAndExecution, +}: TransactionEstimationProps): Promise => { + if (isCreation) { + return estimateGasForTransactionCreation(safeAddress, txData, txRecipient, txAmount || '0', operation || CALL) + } + + if (!from) { + throw new Error('No from provided for approving or execute transaction') + } + + if (isExecution) { + return estimateGasForTransactionExecution({ + safeAddress, + txRecipient, + txConfirmations, + txAmount: txAmount || '0', + txData, + operation: operation || CALL, + from, + gasPrice: gasPrice || '0', + gasToken: gasToken || ZERO_ADDRESS, + refundReceiver: refundReceiver || ZERO_ADDRESS, + safeTxGas: safeTxGas || 0, + approvalAndExecution, + }) + } + + return estimateGasForTransactionApproval({ + safeAddress, + operation: operation || CALL, + txData, + txAmount: txAmount || '0', + txRecipient, + from, + isOffChainSignature, + }) +} + +type UseEstimateTransactionGasProps = { + txData: string + txRecipient: string + txConfirmations?: List + txAmount?: string + preApprovingOwner?: string + operation?: number + safeTxGas?: number +} + +type TransactionGasEstimationResult = { + txEstimationExecutionStatus: EstimationStatus + gasEstimation: number // Amount of gas needed for execute or approve the transaction + gasCost: string // Cost of gas in raw format (estimatedGas * gasPrice) + gasCostFormatted: string // Cost of gas in format '< | > 100' + gasPrice: string // Current price of gas unit + isExecution: boolean // Returns true if the user will execute the tx or false if it just signs it + isCreation: boolean // Returns true if the transaction is a creation transaction + isOffChainSignature: boolean // Returns true if offChainSignature is available +} + +export const useEstimateTransactionGas = ({ + txRecipient, + txData, + txConfirmations, + txAmount, + preApprovingOwner, + operation, + safeTxGas, +}: UseEstimateTransactionGasProps): TransactionGasEstimationResult => { + const [gasEstimation, setGasEstimation] = useState({ + txEstimationExecutionStatus: EstimationStatus.LOADING, + gasEstimation: 0, + gasCost: '0', + gasCostFormatted: '< 0.001', + gasPrice: '0', + isExecution: false, + isCreation: false, + isOffChainSignature: false, + }) + const { nativeCoin } = getNetworkInfo() + const safeAddress = useSelector(safeParamAddressFromStateSelector) + const threshold = useSelector(safeThresholdSelector) + const safeVersion = useSelector(safeCurrentVersionSelector) + const { account: from, smartContractWallet } = useSelector(providerSelector) + + useEffect(() => { + const estimateGas = async () => { + if (!txData.length) { + return + } + + const isExecution = checkIfTxIsExecution(Number(threshold), preApprovingOwner, txConfirmations?.size) + const isCreation = checkIfTxIsCreation(txConfirmations?.size || 0) + const approvalAndExecution = checkIfTxIsApproveAndExecution(Number(threshold), txConfirmations?.size || 0) + + try { + const isOffChainSignature = checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion) + + const gasEstimation = await estimateTransactionGas({ + safeAddress, + txRecipient, + txData, + txAmount, + txConfirmations, + isExecution, + isCreation, + isOffChainSignature, + operation, + from, + safeTxGas, + approvalAndExecution, + }) + const gasPrice = await calculateGasPrice() + const estimatedGasCosts = gasEstimation * parseInt(gasPrice, 10) + const gasCost = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const gasCostFormatted = formatAmount(gasCost) + + let txEstimationExecutionStatus = EstimationStatus.SUCCESS + + if (gasEstimation <= 0) { + txEstimationExecutionStatus = isOffChainSignature ? EstimationStatus.SUCCESS : EstimationStatus.FAILURE + } + + setGasEstimation({ + txEstimationExecutionStatus, + gasEstimation, + gasCost, + gasCostFormatted, + gasPrice, + isExecution, + isCreation, + isOffChainSignature, + }) + } catch (error) { + console.warn(error.message) + // We put a fixed the amount of gas to let the user try to execute the tx, but it's not accurate so it will probably fail + const gasEstimation = 10000 + const gasCost = fromTokenUnit(gasEstimation, nativeCoin.decimals) + const gasCostFormatted = formatAmount(gasCost) + setGasEstimation({ + txEstimationExecutionStatus: EstimationStatus.FAILURE, + gasEstimation, + gasCost, + gasCostFormatted, + gasPrice: '1', + isExecution, + isCreation, + isOffChainSignature: false, + }) + } + } + + estimateGas() + }, [ + txData, + safeAddress, + txRecipient, + txConfirmations, + txAmount, + preApprovingOwner, + nativeCoin.decimals, + threshold, + from, + operation, + safeVersion, + smartContractWallet, + safeTxGas, + ]) + + return gasEstimation +} diff --git a/src/logic/notifications/store/reducer/notifications.ts b/src/logic/notifications/store/reducer/notifications.ts index 802ab9bd..bb05f747 100644 --- a/src/logic/notifications/store/reducer/notifications.ts +++ b/src/logic/notifications/store/reducer/notifications.ts @@ -20,7 +20,7 @@ export default handleActions( const { dismissAll, key } = action.payload if (key) { - return state.update(key, (prev) => prev.set('dismissed', true)) + return state.update(key, (prev) => prev?.set('dismissed', true)) } if (dismissAll) { return state.withMutations((map) => { diff --git a/src/logic/safe/safeTxSigner.ts b/src/logic/safe/safeTxSigner.ts index 52de1a3b..4fce148d 100644 --- a/src/logic/safe/safeTxSigner.ts +++ b/src/logic/safe/safeTxSigner.ts @@ -1,31 +1,61 @@ -// https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures -// https://github.com/gnosis/safe-contracts/blob/master/test/gnosisSafeTeamEdition.js#L26 -export const generateSignaturesFromTxConfirmations = (confirmations, preApprovingOwner) => { - // The constant parts need to be sorted so that the recovered signers are sorted ascending - // (natural order) by address (not checksummed). - const confirmationsMap = confirmations.reduce((map, obj) => { - map[obj.owner.toLowerCase()] = obj // eslint-disable-line no-param-reassign - return map - }, {}) +import { List } from 'immutable' +import { Confirmation } from 'src/logic/safe/store/models/types/confirmation' +import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' +import semverSatisfies from 'semver/functions/satisfies' +import { SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES } from './transactions/offchainSigner' + +// Here we're checking that safe contract version is greater or equal 1.1.1, but +// theoretically EIP712 should also work for 1.0.0 contracts +// Also, offchain signatures are not working for ledger/trezor wallet because of a bug in their library: +// https://github.com/LedgerHQ/ledgerjs/issues/378 +// Couldn't find an issue for trezor but the error is almost the same +export const checkIfOffChainSignatureIsPossible = ( + isExecution: boolean, + isSmartContractWallet: boolean, + safeVersion?: string, +): boolean => + !isExecution && + !isSmartContractWallet && + !!safeVersion && + semverSatisfies(safeVersion, SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES) + +// https://docs.gnosis.io/safe/docs/contracts_signatures/#pre-validated-signatures +export const getPreValidatedSignatures = (from: string, initialString: string = EMPTY_DATA): string => { + return `${initialString}000000000000000000000000${from.replace( + EMPTY_DATA, + '', + )}000000000000000000000000000000000000000000000000000000000000000001` +} + +export const generateSignaturesFromTxConfirmations = ( + confirmations?: List, + preApprovingOwner?: string, +): string => { + let confirmationsMap = + confirmations?.map((value) => { + return { + signature: value.signature, + owner: value.owner.toLowerCase(), + } + }) || List([]) if (preApprovingOwner) { - confirmationsMap[preApprovingOwner.toLowerCase()] = { owner: preApprovingOwner } + confirmationsMap = confirmationsMap.push({ owner: preApprovingOwner, signature: null }) } + // The constant parts need to be sorted so that the recovered signers are sorted ascending + // (natural order) by address (not checksummed). + confirmationsMap = confirmationsMap.sort((ownerA, ownerB) => ownerA.owner.localeCompare(ownerB.owner)) + let sigs = '0x' - Object.keys(confirmationsMap) - .sort() - .forEach((addr) => { - const conf = confirmationsMap[addr] - if (conf.signature) { - sigs += conf.signature.slice(2) - } else { - // https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures - sigs += `000000000000000000000000${addr.replace( - '0x', - '', - )}000000000000000000000000000000000000000000000000000000000000000001` - } - }) + confirmationsMap.forEach(({ signature, owner }) => { + if (signature) { + sigs += signature.slice(2) + } else { + // https://docs.gnosis.io/safe/docs/contracts_signatures/#pre-validated-signatures + sigs += getPreValidatedSignatures(owner, '') + } + }) + return sigs } diff --git a/src/logic/safe/store/actions/__tests__/utils.test.ts b/src/logic/safe/store/actions/__tests__/utils.test.ts index db063f9a..b11ebcb3 100644 --- a/src/logic/safe/store/actions/__tests__/utils.test.ts +++ b/src/logic/safe/store/actions/__tests__/utils.test.ts @@ -3,22 +3,8 @@ import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' describe('Store actions utils > getNewTxNonce', () => { - it(`Should return passed predicted transaction nonce if it's a valid value`, async () => { - // Given - const txNonce = '45' - const lastTx = { nonce: 44 } as TxServiceModel - const safeInstance = {} - - // When - const nonce = await getNewTxNonce(txNonce, lastTx, safeInstance as GnosisSafe) - - // Then - expect(nonce).toBe('45') - }) - it(`Should return nonce of a last transaction + 1 if passed nonce is less than last transaction or invalid`, async () => { // Given - const txNonce = '' const lastTx = { nonce: 44 } as TxServiceModel const safeInstance = { methods: { @@ -29,7 +15,7 @@ describe('Store actions utils > getNewTxNonce', () => { } // When - const nonce = await getNewTxNonce(txNonce, lastTx, safeInstance as GnosisSafe) + const nonce = await getNewTxNonce(lastTx, safeInstance as GnosisSafe) // Then expect(nonce).toBe('45') @@ -37,7 +23,6 @@ describe('Store actions utils > getNewTxNonce', () => { it(`Should retrieve contract's instance nonce value as a fallback, if txNonce and lastTx are not valid`, async () => { // Given - const txNonce = '' const lastTx = null const safeInstance = { methods: { @@ -48,7 +33,7 @@ describe('Store actions utils > getNewTxNonce', () => { } // When - const nonce = await getNewTxNonce(txNonce, lastTx, safeInstance as GnosisSafe) + const nonce = await getNewTxNonce(lastTx, safeInstance as GnosisSafe) // Then expect(nonce).toBe('45') diff --git a/src/logic/safe/store/actions/createTransaction.ts b/src/logic/safe/store/actions/createTransaction.ts index 0106e56f..0e318e33 100644 --- a/src/logic/safe/store/actions/createTransaction.ts +++ b/src/logic/safe/store/actions/createTransaction.ts @@ -1,5 +1,4 @@ import { push } from 'connected-react-router' -import semverSatisfies from 'semver/functions/satisfies' import { ThunkAction } from 'redux-thunk' import { onboardUser } from 'src/components/ConnectButton' @@ -10,11 +9,10 @@ import { CALL, getApprovalTransaction, getExecutionTransaction, - SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES, saveTxToHistory, tryOffchainSigning, } from 'src/logic/safe/transactions' -import { estimateSafeTxGas } from 'src/logic/safe/transactions/gas' +import { estimateGasForTransactionCreation } from 'src/logic/safe/transactions/gas' import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion' import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' @@ -40,6 +38,7 @@ import { AnyAction } from 'redux' import { PayableTx } from 'src/types/contracts/types.d' import { AppReduxState } from 'src/store' import { Dispatch, DispatchReturn } from './types' +import { checkIfOffChainSignatureIsPossible, getPreValidatedSignatures } from 'src/logic/safe/safeTxSigner' export interface CreateTransactionArgs { navigateToTransactionsTab?: boolean @@ -87,18 +86,18 @@ const createTransaction = ( const { account: from, hardwareWallet, smartContractWallet } = providerSelector(state) const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const lastTx = await getLastTx(safeAddress) - const nonce = await getNewTxNonce(txNonce?.toString(), lastTx, safeInstance) + const nonce = txNonce ? txNonce.toString() : await getNewTxNonce(lastTx, safeInstance) const isExecution = await shouldExecuteTransaction(safeInstance, nonce, lastTx) const safeVersion = await getCurrentSafeVersion(safeInstance) - const safeTxGas = - safeTxGasArg || (await estimateSafeTxGas(safeInstance, safeAddress, txData, to, valueInWei, operation)) - - // https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures - const sigs = `0x000000000000000000000000${from.replace( - '0x', - '', - )}000000000000000000000000000000000000000000000000000000000000000001` + let safeTxGas + try { + safeTxGas = + safeTxGasArg || (await estimateGasForTransactionCreation(safeAddress, txData, to, valueInWei, operation)) + } catch (error) { + safeTxGas = safeTxGasArg || 0 + } + const sigs = getPreValidatedSignatures(from) const notificationsQueue = getNotificationsFromTxType(notifiedTransaction, origin) const beforeExecutionKey = dispatch(enqueueSnackbar(notificationsQueue.beforeExecution)) @@ -123,11 +122,7 @@ const createTransaction = ( const safeTxHash = generateSafeTxHash(safeAddress, txArgs) try { - // Here we're checking that safe contract version is greater or equal 1.1.1, but - // theoretically EIP712 should also work for 1.0.0 contracts - const canTryOffchainSigning = - !isExecution && !smartContractWallet && semverSatisfies(safeVersion, SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES) - if (canTryOffchainSigning) { + if (checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)) { const signature = await tryOffchainSigning(safeTxHash, { ...txArgs, safeAddress }, hardwareWallet) if (signature) { @@ -141,9 +136,7 @@ const createTransaction = ( } } - const tx = isExecution - ? await getExecutionTransaction(txArgs) - : await getApprovalTransaction(safeInstance, safeTxHash) + const tx = isExecution ? getExecutionTransaction(txArgs) : getApprovalTransaction(safeInstance, safeTxHash) const sendParams: PayableTx = { from, value: 0 } // if not set owner management tests will fail on ganache diff --git a/src/logic/safe/store/actions/processTransaction.ts b/src/logic/safe/store/actions/processTransaction.ts index eced5a75..8d31d343 100644 --- a/src/logic/safe/store/actions/processTransaction.ts +++ b/src/logic/safe/store/actions/processTransaction.ts @@ -1,12 +1,15 @@ import { AnyAction } from 'redux' import { ThunkAction } from 'redux-thunk' -import semverSatisfies from 'semver/functions/satisfies' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { getNotificationsFromTxType } from 'src/logic/notifications' -import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner' +import { + checkIfOffChainSignatureIsPossible, + generateSignaturesFromTxConfirmations, + getPreValidatedSignatures, +} from 'src/logic/safe/safeTxSigner' import { getApprovalTransaction, getExecutionTransaction, saveTxToHistory } from 'src/logic/safe/transactions' -import { SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES, tryOffchainSigning } from 'src/logic/safe/transactions/offchainSigner' +import { tryOffchainSigning } from 'src/logic/safe/transactions/offchainSigner' import { getCurrentSafeVersion } from 'src/logic/safe/utils/safeVersion' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import { providerSelector } from 'src/logic/wallets/store/selectors' @@ -33,7 +36,7 @@ interface ProcessTransactionArgs { type ProcessTransactionAction = ThunkAction, AppReduxState, DispatchReturn, AnyAction> -const processTransaction = ({ +export const processTransaction = ({ approveAndExecute, notifiedTransaction, safeAddress, @@ -49,17 +52,15 @@ const processTransaction = ({ const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const lastTx = await getLastTx(safeAddress) - const nonce = await getNewTxNonce(undefined, lastTx, safeInstance) + const nonce = await getNewTxNonce(lastTx, safeInstance) const isExecution = approveAndExecute || (await shouldExecuteTransaction(safeInstance, nonce, lastTx)) const safeVersion = await getCurrentSafeVersion(safeInstance) - let sigs = generateSignaturesFromTxConfirmations(tx.confirmations, approveAndExecute && userAddress) - // https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures + const preApprovingOwner = approveAndExecute ? userAddress : undefined + let sigs = generateSignaturesFromTxConfirmations(tx.confirmations, preApprovingOwner) + if (!sigs) { - sigs = `0x000000000000000000000000${from.replace( - '0x', - '', - )}000000000000000000000000000000000000000000000000000000000000000001` + sigs = getPreValidatedSignatures(from) } const notificationsQueue = getNotificationsFromTxType(notifiedTransaction, tx.origin) @@ -86,14 +87,7 @@ const processTransaction = ({ } try { - // Here we're checking that safe contract version is greater or equal 1.1.1, but - // theoretically EIP712 should also work for 1.0.0 contracts - // Also, offchain signatures are not working for ledger/trezor wallet because of a bug in their library: - // https://github.com/LedgerHQ/ledgerjs/issues/378 - // Couldn't find an issue for trezor but the error is almost the same - const canTryOffchainSigning = - !isExecution && !smartContractWallet && semverSatisfies(safeVersion, SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES) - if (canTryOffchainSigning) { + if (checkIfOffChainSignatureIsPossible(isExecution, smartContractWallet, safeVersion)) { const signature = await tryOffchainSigning(tx.safeTxHash, { ...txArgs, safeAddress }, hardwareWallet) if (signature) { @@ -109,9 +103,7 @@ const processTransaction = ({ } } - transaction = isExecution - ? await getExecutionTransaction(txArgs) - : await getApprovalTransaction(safeInstance, tx.safeTxHash) + transaction = isExecution ? getExecutionTransaction(txArgs) : getApprovalTransaction(safeInstance, tx.safeTxHash) const sendParams: any = { from, value: 0 } @@ -196,5 +188,3 @@ const processTransaction = ({ return txHash } - -export default processTransaction diff --git a/src/logic/safe/store/actions/utils.ts b/src/logic/safe/store/actions/utils.ts index 74b59b0d..828c6e92 100644 --- a/src/logic/safe/store/actions/utils.ts +++ b/src/logic/safe/store/actions/utils.ts @@ -16,15 +16,7 @@ export const getLastTx = async (safeAddress: string): Promise => { - if (txNonce) { - return txNonce - } - +export const getNewTxNonce = async (lastTx: TxServiceModel | null, safeInstance: GnosisSafe): Promise => { // use current's safe nonce as fallback return lastTx ? `${lastTx.nonce + 1}` : (await safeInstance.methods.nonce().call()).toString() } diff --git a/src/logic/safe/transactions/__tests__/gas.test.ts b/src/logic/safe/transactions/__tests__/gas.test.ts index 4c6982407a5c9bc130212ea01333fbc1e8e43ae7..828d1e64f6ff53355619733c309af0a4d4c98555 100644 GIT binary patch delta 86 zcmV-c0IC1`G0Zuz_!yJm0~C`W5*3q=6%8>UWp-t5AZcbGbZBKDa%FRHZ*FsCAY*TC sbYW?3b0BGMc42I3WFTW`VRB((bY*gLld%snv(6Pb0R!*9y`%dU0->%Uwg3PC delta 11 ScmX?O`P*>A4+-X4O)dZ;TLh&5 diff --git a/src/logic/safe/transactions/gas.ts b/src/logic/safe/transactions/gas.ts index 92982f12..fa220bac 100644 --- a/src/logic/safe/transactions/gas.ts +++ b/src/logic/safe/transactions/gas.ts @@ -1,19 +1,15 @@ -import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json' import { BigNumber } from 'bignumber.js' -import { AbiItem } from 'web3-utils' - -import { CALL } from '.' - import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' -import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' -import { EMPTY_DATA, calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions' -import { getAccountFrom, getWeb3 } from 'src/logic/wallets/getWeb3' -import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' +import { calculateGasOf, EMPTY_DATA } from 'src/logic/wallets/ethTransactions' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { sameString } from 'src/utils/strings' +import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' +import { generateSignaturesFromTxConfirmations } from 'src/logic/safe/safeTxSigner' +import { List } from 'immutable' +import { Confirmation } from 'src/logic/safe/store/models/types/confirmation' -const estimateDataGasCosts = (data: string): number => { +// Receives the response data of the safe method requiredTxGas() and parses it to get the gas amount +const parseRequiredTxGasResponse = (data: string): number => { const reducer = (accumulator, currentValue) => { if (currentValue === EMPTY_DATA) { return accumulator + 0 @@ -29,74 +25,15 @@ const estimateDataGasCosts = (data: string): number => { return data.match(/.{2}/g)?.reduce(reducer, 0) } -export const estimateTxGasCosts = async ( - safeAddress: string, - to: string, - data: string, - tx?: Transaction, - preApprovingOwner?: string, -): Promise => { - try { - const web3 = getWeb3() - const from = await getAccountFrom(web3) - - if (!from) { - return 0 - } - - const safeInstance = (new web3.eth.Contract(GnosisSafeSol.abi as AbiItem[], safeAddress) as unknown) as GnosisSafe - const nonce = await safeInstance.methods.nonce().call() - const threshold = await safeInstance.methods.getThreshold().call() - const isExecution = tx?.confirmations.size === Number(threshold) || !!preApprovingOwner || threshold === '1' - - let txData - if (isExecution) { - // https://docs.gnosis.io/safe/docs/docs5/#pre-validated-signatures - const signatures = tx?.confirmations - ? generateSignaturesFromTxConfirmations(tx.confirmations, preApprovingOwner) - : `0x000000000000000000000000${from.replace( - EMPTY_DATA, - '', - )}000000000000000000000000000000000000000000000000000000000000000001` - txData = await safeInstance.methods - .execTransaction( - to, - tx?.value || 0, - data, - CALL, - tx?.safeTxGas || 0, - 0, - 0, - ZERO_ADDRESS, - ZERO_ADDRESS, - signatures, - ) - .encodeABI() - } else { - const txHash = await safeInstance.methods - .getTransactionHash(to, tx?.value || 0, data, CALL, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce) - .call({ - from, - }) - txData = await safeInstance.methods.approveHash(txHash).encodeABI() - } - - const gas = await calculateGasOf(txData, from, safeAddress) - const gasPrice = await calculateGasPrice() - - return gas * parseInt(gasPrice, 10) - } catch (err) { - console.error('Error while estimating transaction execution gas costs:') - console.error(err) - - return 10000 - } -} - // Parses the result from the error message (GETH, OpenEthereum/Parity and Nethermind) and returns the data value export const getDataFromNodeErrorMessage = (errorMessage: string): string | undefined => { + // Replace illegal characters that often comes within the error string (like � for example) + // https://stackoverflow.com/questions/12754256/removing-invalid-characters-in-javascript + const normalizedErrorString = errorMessage.replace(/\uFFFD/g, '') + // Extracts JSON object from the error message - const [, ...error] = errorMessage.split('\n') + const [, ...error] = normalizedErrorString.split('\n') + try { const errorAsJSON = JSON.parse(error.join('')) @@ -130,7 +67,7 @@ export const getDataFromNodeErrorMessage = (errorMessage: string): string | unde } } -const getGasEstimationTxResponse = async (txConfig: { +export const getGasEstimationTxResponse = async (txConfig: { to: string from: string data: string @@ -190,8 +127,7 @@ const calculateMinimumGasForTransaction = async ( return 0 } -export const estimateSafeTxGas = async ( - safe: GnosisSafe | undefined, +export const estimateGasForTransactionCreation = async ( safeAddress: string, data: string, to: string, @@ -199,10 +135,7 @@ export const estimateSafeTxGas = async ( operation: number, ): Promise => { try { - let safeInstance = safe - if (!safeInstance) { - safeInstance = await getGnosisSafeInstanceAt(safeAddress) - } + const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const estimateData = safeInstance.methods.requiredTxGas(to, valueInWei, data, operation).encodeABI() const gasEstimationResponse = await getGasEstimationTxResponse({ @@ -214,7 +147,7 @@ export const estimateSafeTxGas = async ( const txGasEstimation = gasEstimationResponse + 10000 // 21000 - additional gas costs (e.g. base tx costs, transfer costs) - const dataGasEstimation = estimateDataGasCosts(estimateData) + 21000 + const dataGasEstimation = parseRequiredTxGasResponse(estimateData) + 21000 const additionalGasBatches = [0, 10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000, 5120000] return await calculateMinimumGasForTransaction( @@ -225,7 +158,98 @@ export const estimateSafeTxGas = async ( dataGasEstimation, ) } catch (error) { - console.error('Error calculating tx gas estimation', error) - return 0 + console.info('Error calculating tx gas estimation', error.message) + throw error } } + +type TransactionExecutionEstimationProps = { + txData: string + safeAddress: string + txRecipient: string + txConfirmations?: List + txAmount: string + operation: number + gasPrice: string + gasToken: string + refundReceiver: string // Address of receiver of gas payment (or 0 if tx.origin). + safeTxGas: number + from: string + approvalAndExecution?: boolean +} + +export const estimateGasForTransactionExecution = async ({ + safeAddress, + txRecipient, + txConfirmations, + txAmount, + txData, + operation, + gasPrice, + gasToken, + refundReceiver, + safeTxGas, + approvalAndExecution, +}: TransactionExecutionEstimationProps): Promise => { + const safeInstance = await getGnosisSafeInstanceAt(safeAddress) + try { + if (approvalAndExecution) { + console.info(`Estimating transaction success for execution & approval...`) + // @todo (agustin) once we solve the problem with the preApprovingOwner, we need to use the method bellow (execTransaction) with sigs = generateSignaturesFromTxConfirmations(txConfirmations,from) + const gasEstimation = await estimateGasForTransactionCreation( + safeAddress, + txData, + txRecipient, + txAmount, + operation, + ) + console.info(`Gas estimation successfully finished with gas amount: ${gasEstimation}`) + return gasEstimation + } + const sigs = generateSignaturesFromTxConfirmations(txConfirmations) + console.info(`Estimating transaction success for with gas amount: ${safeTxGas}...`) + await safeInstance.methods + .execTransaction(txRecipient, txAmount, txData, operation, safeTxGas, 0, gasPrice, gasToken, refundReceiver, sigs) + .call() + + console.info(`Gas estimation successfully finished with gas amount: ${safeTxGas}`) + return safeTxGas + } catch (error) { + throw new Error(`Gas estimation failed with gas amount: ${safeTxGas}`) + } +} + +type TransactionApprovalEstimationProps = { + txData: string + safeAddress: string + txRecipient: string + txAmount: string + operation: number + from: string + isOffChainSignature: boolean +} + +export const estimateGasForTransactionApproval = async ({ + safeAddress, + txRecipient, + txAmount, + txData, + operation, + from, + isOffChainSignature, +}: TransactionApprovalEstimationProps): Promise => { + if (isOffChainSignature) { + return 0 + } + + const safeInstance = await getGnosisSafeInstanceAt(safeAddress) + + const nonce = await safeInstance.methods.nonce().call() + const txHash = await safeInstance.methods + .getTransactionHash(txRecipient, txAmount, txData, operation, 0, 0, 0, ZERO_ADDRESS, ZERO_ADDRESS, nonce) + .call({ + from, + }) + const approveTransactionTxData = await safeInstance.methods.approveHash(txHash).encodeABI() + return calculateGasOf(approveTransactionTxData, from, safeAddress) +} diff --git a/src/logic/safe/transactions/send.ts b/src/logic/safe/transactions/send.ts index 67bbab2f..289c8fe3 100644 --- a/src/logic/safe/transactions/send.ts +++ b/src/logic/safe/transactions/send.ts @@ -30,10 +30,7 @@ export const getTransactionHash = async ({ return txHash } -export const getApprovalTransaction = async ( - safeInstance: GnosisSafe, - txHash: string, -): Promise> => { +export const getApprovalTransaction = (safeInstance: GnosisSafe, txHash: string): NonPayableTransactionObject => { try { return safeInstance.methods.approveHash(txHash) } catch (err) { diff --git a/src/routes/safe/components/Apps/components/AppFrame.tsx b/src/routes/safe/components/Apps/components/AppFrame.tsx index be761418..28c47ff0 100644 --- a/src/routes/safe/components/Apps/components/AppFrame.tsx +++ b/src/routes/safe/components/Apps/components/AppFrame.tsx @@ -32,7 +32,7 @@ import { LoadingContainer } from 'src/components/LoaderContainer/index' import { TIMEOUT } from 'src/utils/constants' import { web3ReadOnly } from 'src/logic/wallets/getWeb3' -import ConfirmTransactionModal from '../components/ConfirmTransactionModal' +import { ConfirmTransactionModal } from '../components/ConfirmTransactionModal' import { useIframeMessageHandler } from '../hooks/useIframeMessageHandler' import { useLegalConsent } from '../hooks/useLegalConsent' import LegalDisclaimer from './LegalDisclaimer' diff --git a/src/routes/safe/components/Apps/components/ConfirmTransactionModal.tsx b/src/routes/safe/components/Apps/components/ConfirmTransactionModal.tsx index 80eb88de..06b95a08 100644 --- a/src/routes/safe/components/Apps/components/ConfirmTransactionModal.tsx +++ b/src/routes/safe/components/Apps/components/ConfirmTransactionModal.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react' -import { Icon, Text, Title, GenericModal, ModalFooterConfirmation } from '@gnosis.pm/safe-react-components' +import { GenericModal, Icon, ModalFooterConfirmation, Text, Title } from '@gnosis.pm/safe-react-components' import { Transaction } from '@gnosis.pm/safe-apps-sdk-v1' import styled from 'styled-components' import { useDispatch } from 'react-redux' @@ -20,11 +20,11 @@ import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { MULTI_SEND_ADDRESS } from 'src/logic/contracts/safeContracts' import { DELEGATE_CALL, TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { encodeMultiSendCall } from 'src/logic/safe/transactions/multisend' -import { estimateSafeTxGas } from 'src/logic/safe/transactions/gas' import GasEstimationInfo from './GasEstimationInfo' import { getNetworkInfo } from 'src/config' import { TransactionParams } from './AppFrame' +import { EstimationStatus, useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' const isTxValid = (t: Transaction): boolean => { if (!['string', 'number'].includes(typeof t.value)) { @@ -82,7 +82,7 @@ type OwnProps = { const { nativeCoin } = getNetworkInfo() -const ConfirmTransactionModal = ({ +export const ConfirmTransactionModal = ({ isOpen, app, txs, @@ -95,32 +95,18 @@ const ConfirmTransactionModal = ({ onTxReject, }: OwnProps): React.ReactElement | null => { const [estimatedSafeTxGas, setEstimatedSafeTxGas] = useState(0) - const [estimatingGas, setEstimatingGas] = useState(false) + + const { gasEstimation, txEstimationExecutionStatus } = useEstimateTransactionGas({ + txData: encodeMultiSendCall(txs), + txRecipient: MULTI_SEND_ADDRESS, + operation: DELEGATE_CALL, + }) useEffect(() => { - const estimateGas = async () => { - try { - setEstimatingGas(true) - const safeTxGas = await estimateSafeTxGas( - undefined, - safeAddress, - encodeMultiSendCall(txs), - MULTI_SEND_ADDRESS, - '0', - DELEGATE_CALL, - ) - - setEstimatedSafeTxGas(safeTxGas) - } catch (err) { - console.error(err) - } finally { - setEstimatingGas(false) - } - } if (params?.safeTxGas) { - estimateGas() + setEstimatedSafeTxGas(gasEstimation) } - }, [params, safeAddress, txs]) + }, [params, gasEstimation]) const dispatch = useDispatch() if (!isOpen) { @@ -205,7 +191,7 @@ const ConfirmTransactionModal = ({
)} @@ -229,5 +215,3 @@ const ConfirmTransactionModal = ({ /> ) } - -export default ConfirmTransactionModal diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx index e67d8ae0..532bf33b 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles' import { useDispatch, useSelector } from 'react-redux' import { getNetworkInfo } from 'src/config' -import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' import AddressInfo from 'src/components/AddressInfo' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' @@ -14,15 +14,15 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { AbiItemExtended } from 'src/logic/contractInteraction/sources/ABIService' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' import { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style' import Header from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Header' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { generateFormFieldKey, getValueFromTxInputs } from '../utils' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' const useStyles = makeStyles(styles) @@ -45,41 +45,41 @@ const { nativeCoin } = getNetworkInfo() const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const classes = useStyles() const dispatch = useDispatch() - const { address: safeAddress } = useSelector(safeSelector) || {} - const [gasCosts, setGasCosts] = useState('< 0.001') + const safeAddress = useSelector(safeParamAddressFromStateSelector) + const [txParameters, setTxParameters] = useState<{ + txRecipient: string + txData: string + txAmount: string + }>({ txData: '', txAmount: '', txRecipient: '' }) + + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isOffChainSignature, + isCreation, + } = useEstimateTransactionGas({ + txRecipient: txParameters?.txRecipient, + txAmount: txParameters?.txAmount, + txData: txParameters?.txData, + }) + useEffect(() => { - let isCurrent = true - - const estimateGas = async (): Promise => { - const txData = tx.data ? tx.data.trim() : '' - - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - - if (isCurrent) { - setGasCosts(formattedGasCosts) - } - } - - estimateGas() - - return () => { - isCurrent = false - } - }, [safeAddress, tx.contractAddress, tx.data]) + setTxParameters({ + txRecipient: tx.contractAddress as string, + txAmount: tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0', + txData: tx.data ? tx.data.trim() : '', + }) + }, [tx.contractAddress, tx.value, tx.data, safeAddress]) const submitTx = async () => { - const txRecipient = tx.contractAddress - const txData = tx.data ? tx.data.trim() : '' - const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0' - if (safeAddress) { + if (safeAddress && txParameters) { dispatch( createTransaction({ safeAddress, - to: txRecipient as string, - valueInWei: txValue, - txData, + to: txParameters?.txRecipient, + valueInWei: txParameters?.txAmount, + txData: txParameters?.txData, notifiedTransaction: TX_NOTIFICATION_TYPES.STANDARD_TX, }), ) @@ -162,9 +162,13 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE - - {`You're about to create a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index 2512c69e..cda1aead 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -1,11 +1,11 @@ -import React, { useEffect, useState } from 'react' +import React from 'react' import { useDispatch, useSelector } from 'react-redux' import IconButton from '@material-ui/core/IconButton' import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import { getExplorerInfo, getNetworkInfo } from 'src/config' -import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' @@ -16,10 +16,8 @@ import Img from 'src/components/layout/Img' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' @@ -29,6 +27,8 @@ import ArrowDown from '../../assets/arrow-down.svg' import { styles } from './style' import { ExplorerButton } from '@gnosis.pm/safe-react-components' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' export type CustomTx = { contractAddress?: string @@ -49,29 +49,19 @@ const { nativeCoin } = getNetworkInfo() const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const classes = useStyles() const dispatch = useDispatch() - const { address: safeAddress } = useSelector(safeSelector) || {} - const [gasCosts, setGasCosts] = useState('< 0.001') - useEffect(() => { - let isCurrent = true + const safeAddress = useSelector(safeParamAddressFromStateSelector) - const estimateGas = async () => { - const txData = tx.data ? tx.data.trim() : '' - - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - - if (isCurrent) { - setGasCosts(formattedGasCosts) - } - } - - estimateGas() - - return () => { - isCurrent = false - } - }, [safeAddress, tx.data, tx.contractAddress]) + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isCreation, + isOffChainSignature, + } = useEstimateTransactionGas({ + txRecipient: tx.contractAddress as string, + txData: tx.data ? tx.data.trim() : '', + txAmount: tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0', + }) const submitTx = async (): Promise => { const txRecipient = tx.contractAddress @@ -161,9 +151,13 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { - - {`You're about to create a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx index d6428bef..c3ea4a7d 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/index.tsx @@ -7,7 +7,7 @@ import GnoForm from 'src/components/forms/GnoForm' import Block from 'src/components/layout/Block' import Hairline from 'src/components/layout/Hairline' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' -import { safeSelector } from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import Paragraph from 'src/components/layout/Paragraph' import Buttons from './Buttons' import ContractABI from './ContractABI' @@ -53,14 +53,14 @@ const ContractInteraction: React.FC = ({ isABI, }) => { const classes = useStyles() - const { address: safeAddress = '' } = useSelector(safeSelector) || {} + const safeAddress = useSelector(safeParamAddressFromStateSelector) let setCallResults React.useMemo(() => { if (contractAddress) { initialValues.contractAddress = contractAddress } - }, [contractAddress, initialValues.contractAddress]) + }, [contractAddress, initialValues]) const saveForm = async (values: CreatedTx): Promise => { await handleSubmit(values, false) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index c1d5cd18..63d4c942 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -3,9 +3,7 @@ import { useDispatch, useSelector } from 'react-redux' import IconButton from '@material-ui/core/IconButton' import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' - -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import { getExplorerInfo, getNetworkInfo } from 'src/config' +import { getExplorerInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' @@ -17,10 +15,8 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { nftTokensSelector } from 'src/logic/collectibles/store/selectors' import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -31,8 +27,8 @@ import ArrowDown from '../assets/arrow-down.svg' import { styles } from './style' import { ExplorerButton } from '@gnosis.pm/safe-react-components' - -const { nativeCoin } = getNetworkInfo() +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' const useStyles = makeStyles(styles) @@ -53,34 +49,38 @@ const ReviewCollectible = ({ onClose, onPrev, tx }: Props): React.ReactElement = const classes = useStyles() const shortener = textShortener() const dispatch = useDispatch() - const { address: safeAddress } = useSelector(safeSelector) || {} + const safeAddress = useSelector(safeParamAddressFromStateSelector) const nftTokens = useSelector(nftTokensSelector) - const [gasCosts, setGasCosts] = useState('< 0.001') const txToken = nftTokens.find( ({ assetAddress, tokenId }) => assetAddress === tx.assetAddress && tokenId === tx.nftTokenId, ) const [data, setData] = useState('') + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isOffChainSignature, + isCreation, + } = useEstimateTransactionGas({ + txData: data, + txRecipient: tx.recipientAddress, + }) + useEffect(() => { let isCurrent = true - const estimateGas = async () => { + const calculateERC721TransferData = async () => { try { const txData = await generateERC721TransferTxData(tx, safeAddress) - const estimatedGasCosts = await estimateTxGasCosts(safeAddress ?? '', tx.recipientAddress, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - if (isCurrent) { - setGasCosts(formattedGasCosts) setData(txData) } } catch (error) { - console.error('Error while calculating estimated gas:', error) + console.error('Error calculating ERC721 transfer data:', error.message) } } - - estimateGas() + calculateERC721TransferData() return () => { isCurrent = false @@ -164,9 +164,13 @@ const ReviewCollectible = ({ onClose, onPrev, tx }: Props): React.ReactElement = )} - - {`You're about to create a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx index 17b0bcd7..8dbb6b3c 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -3,7 +3,7 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { toTokenUnit, fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' import { getExplorerInfo, getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' @@ -17,11 +17,9 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getSpendingLimitContract } from 'src/logic/contracts/safeContracts' import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' @@ -35,7 +33,10 @@ import ArrowDown from '../assets/arrow-down.svg' import { styles } from './style' import { ExplorerButton } from '@gnosis.pm/safe-react-components' - +import { TokenProps } from 'src/logic/tokens/store/model/token' +import { RecordOf } from 'immutable' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' const useStyles = makeStyles(styles) const { nativeCoin } = getNetworkInfo() @@ -55,59 +56,74 @@ type ReviewTxProps = { tx: ReviewTxProp } -const ReviewTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactElement => { - const classes = useStyles() - const dispatch = useDispatch() - const { address: safeAddress } = useSelector(safeSelector) || {} - const tokens = useSelector(extendedSafeTokensSelector) - const [gasCosts, setGasCosts] = useState('< 0.001') +const useTxAmount = (tx: ReviewTxProp, isSendingNativeToken: boolean, txToken?: RecordOf): string => { + const [txAmount, setTxAmount] = useState('0') + + // txAmount should be 0 if we send tokens + // the real value is encoded in txData and will be used by the contract + // if txAmount > 0 it would send ETH from the Safe (and the data will be empty) + useEffect(() => { + const txAmount = isSendingNativeToken ? toTokenUnit(tx.amount, nativeCoin.decimals) : '0' + setTxAmount(txAmount) + }, [tx.amount, txToken, isSendingNativeToken]) + + return txAmount +} + +const useTxData = ( + isSendingNativeToken: boolean, + txAmount: string, + recipientAddress: string, + txToken?: RecordOf, +): string => { const [data, setData] = useState('') - const txToken = useMemo(() => tokens.find((token) => sameAddress(token.address, tx.token)), [tokens, tx.token]) - const isSendingETH = sameAddress(txToken?.address, nativeCoin.address) - const txRecipient = isSendingETH ? tx.recipientAddress : txToken?.address - useEffect(() => { - let isCurrent = true - - const estimateGas = async () => { + const updateTxDataAsync = async () => { if (!txToken) { return } let txData = EMPTY_DATA - - if (!isSendingETH) { + if (!isSendingNativeToken) { const StandardToken = await getHumanFriendlyToken() const tokenInstance = await StandardToken.at(txToken.address as string) - const txAmount = toTokenUnit(tx.amount, txToken.decimals) - - txData = tokenInstance.contract.methods.transfer(tx.recipientAddress, txAmount).encodeABI() - } - - const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, txRecipient as string, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - - if (isCurrent) { - setGasCosts(formattedGasCosts) - setData(txData) + txData = tokenInstance.contract.methods.transfer(recipientAddress, txAmount).encodeABI() } + setData(txData) } - estimateGas() + updateTxDataAsync() + }, [isSendingNativeToken, recipientAddress, txAmount, txToken]) - return () => { - isCurrent = false - } - }, [isSendingETH, safeAddress, tx.amount, tx.recipientAddress, txRecipient, txToken]) + return data +} + +const ReviewTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactElement => { + const classes = useStyles() + const dispatch = useDispatch() + const safeAddress = useSelector(safeParamAddressFromStateSelector) + const tokens = useSelector(extendedSafeTokensSelector) + const txToken = useMemo(() => tokens.find((token) => sameAddress(token.address, tx.token)), [tokens, tx.token]) + const isSendingNativeToken = sameAddress(txToken?.address, nativeCoin.address) + const txRecipient = isSendingNativeToken ? tx.recipientAddress : txToken?.address || '' + + const txAmount = useTxAmount(tx, isSendingNativeToken, txToken) + const data = useTxData(isSendingNativeToken, txAmount, tx.recipientAddress, txToken) + + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isCreation, + isOffChainSignature, + } = useEstimateTransactionGas({ + txData: data, + txRecipient, + }) const submitTx = async () => { const isSpendingLimit = sameString(tx.txType, 'spendingLimit') - // txAmount should be 0 if we send tokens - // the real value is encoded in txData and will be used by the contract - // if txAmount > 0 it would send ETH from the Safe - const txAmount = isSendingETH ? toTokenUnit(tx.amount, nativeCoin.decimals) : '0' if (!safeAddress) { console.error('There was an error trying to submit the transaction, the safeAddress was not found') @@ -115,11 +131,12 @@ const ReviewTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactElement => } if (isSpendingLimit && txToken && tx.tokenSpendingLimit) { + const spendingLimitTokenAddress = isSendingNativeToken ? ZERO_ADDRESS : txToken.address const spendingLimit = getSpendingLimitContract() spendingLimit.methods .executeAllowanceTransfer( safeAddress, - sameAddress(txToken.address, nativeCoin.address) ? ZERO_ADDRESS : txToken.address, + spendingLimitTokenAddress, tx.recipientAddress, toTokenUnit(tx.amount, txToken.decimals), ZERO_ADDRESS, @@ -207,9 +224,13 @@ const ReviewTx = ({ onClose, onPrev, tx }: ReviewTxProps): React.ReactElement => - - {`You're about to create a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx index a4e73801..23f1f973 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/index.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { OwnerForm } from './screens/OwnerForm' -import ReviewAddOwner from './screens/Review' +import { ReviewAddOwner } from './screens/Review' import ThresholdForm from './screens/ThresholdForm' import Modal from 'src/components/Modal' diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index 2b74e8b0..9329feeb 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -1,11 +1,10 @@ import IconButton from '@material-ui/core/IconButton' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import { getExplorerInfo, getNetworkInfo } from 'src/config' +import { getExplorerInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' @@ -16,37 +15,61 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { styles } from './style' import { ExplorerButton } from '@gnosis.pm/safe-react-components' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' export const ADD_OWNER_SUBMIT_BTN_TEST_ID = 'add-owner-submit-btn' -const { nativeCoin } = getNetworkInfo() +const useStyles = makeStyles(styles) -const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => { - const [gasCosts, setGasCosts] = useState('< 0.001') - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string +type ReviewAddOwnerProps = { + onClickBack: () => void + onClose: () => void + onSubmit: () => void + values: { + ownerAddress: string + threshold: string + ownerName: string + } +} + +export const ReviewAddOwner = ({ onClickBack, onClose, onSubmit, values }: ReviewAddOwnerProps): React.ReactElement => { + const classes = useStyles() + const [data, setData] = useState('') + const safeAddress = useSelector(safeParamAddressFromStateSelector) const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) + + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isOffChainSignature, + isCreation, + } = useEstimateTransactionGas({ + txData: data, + txRecipient: safeAddress, + }) + useEffect(() => { let isCurrent = true - const estimateGas = async () => { - const safeInstance = await getGnosisSafeInstanceAt(safeAddress) - const txData = safeInstance.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) + const calculateAddOwnerData = async () => { + try { + const safeInstance = await getGnosisSafeInstanceAt(safeAddress) + const txData = safeInstance.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI() - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - if (isCurrent) { - setGasCosts(formattedGasCosts) + if (isCurrent) { + setData(txData) + } + } catch (error) { + console.error('Error calculating ERC721 transfer data:', error.message) } } - - estimateGas() + calculateAddOwnerData() return () => { isCurrent = false @@ -68,7 +91,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => - + @@ -157,11 +180,13 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => - - You're about to create a transaction and will have to confirm it with your currently connected wallet. -
- {`Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} -
+
@@ -183,5 +208,3 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => ) } - -export default withStyles(styles as any)(ReviewAddOwner) diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/style.ts b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/style.ts index 537bd9d9..6b8f83c3 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/style.ts +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/style.ts @@ -1,6 +1,7 @@ import { background, border, lg, secondaryText, sm } from 'src/theme/variables' +import { createStyles } from '@material-ui/core' -export const styles = () => ({ +export const styles = createStyles({ root: { height: '372px', }, @@ -76,7 +77,9 @@ export const styles = () => ({ }, }, gasCostsContainer: { - padding: `0 ${lg}`, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', textAlign: 'center', width: '100%', }, diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx index 9147afb7..3fe84603 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import CheckOwner from './screens/CheckOwner' -import ReviewRemoveOwner from './screens/Review' +import { ReviewRemoveOwnerModal } from './screens/Review' import ThresholdForm from './screens/ThresholdForm' import Modal from 'src/components/Modal' @@ -69,7 +69,12 @@ type RemoveOwnerProps = { ownerName: string } -const RemoveOwner = ({ isOpen, onClose, ownerAddress, ownerName }: RemoveOwnerProps): React.ReactElement => { +export const RemoveOwnerModal = ({ + isOpen, + onClose, + ownerAddress, + ownerName, +}: RemoveOwnerProps): React.ReactElement => { const classes = useStyles() const [activeScreen, setActiveScreen] = useState('checkOwner') const [values, setValues] = useState({}) @@ -124,18 +129,16 @@ const RemoveOwner = ({ isOpen, onClose, ownerAddress, ownerName }: RemoveOwnerPr )} {activeScreen === 'reviewRemoveOwner' && ( - )} ) } - -export default RemoveOwner diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx index 7829a950..191e7c89 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/index.tsx @@ -1,11 +1,10 @@ import IconButton from '@material-ui/core/IconButton' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import { getExplorerInfo, getNetworkInfo } from 'src/config' +import { getExplorerInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' @@ -16,50 +15,84 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts' import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { styles } from './style' import { ExplorerButton } from '@gnosis.pm/safe-react-components' import { getOwnersWithNameFromAddressBook } from 'src/logic/addressBook/utils' import { List } from 'immutable' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' export const REMOVE_OWNER_REVIEW_BTN_TEST_ID = 'remove-owner-review-btn' -const { nativeCoin } = getNetworkInfo() +const useStyles = makeStyles(styles) -const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { - const [gasCosts, setGasCosts] = useState('< 0.001') - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string +type ReviewRemoveOwnerProps = { + onClickBack: () => void + onClose: () => void + onSubmit: () => void + ownerAddress: string + ownerName: string + threshold?: number +} + +export const ReviewRemoveOwnerModal = ({ + onClickBack, + onClose, + onSubmit, + ownerAddress, + ownerName, + threshold, +}: ReviewRemoveOwnerProps): React.ReactElement => { + const classes = useStyles() + const [data, setData] = useState('') + const safeAddress = useSelector(safeParamAddressFromStateSelector) const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) const addressBook = useSelector(addressBookSelector) const ownersWithAddressBookName = owners ? getOwnersWithNameFromAddressBook(addressBook, owners) : List([]) + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isCreation, + isOffChainSignature, + } = useEstimateTransactionGas({ + txData: data, + txRecipient: safeAddress, + }) + useEffect(() => { let isCurrent = true - const estimateGas = async () => { - const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) - const safeOwners = await gnosisSafe.methods.getOwners().call() - const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) - const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] - const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, values.threshold).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - - if (isCurrent) { - setGasCosts(formattedGasCosts) - } + if (!threshold) { + console.error("Threshold value was not define, tx can't be executed") + return } - estimateGas() + const calculateRemoveOwnerData = async () => { + try { + const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) + const safeOwners = await gnosisSafe.methods.getOwners().call() + const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) + const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] + const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, threshold).encodeABI() + + if (isCurrent) { + setData(txData) + } + } catch (error) { + console.error('Error calculating ERC721 transfer data:', error.message) + } + } + calculateRemoveOwnerData() + return () => { isCurrent = false } - }, [ownerAddress, safeAddress, values.threshold]) + }, [safeAddress, ownerAddress, threshold]) return ( <> @@ -95,7 +128,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre Any transaction requires the confirmation of: - {`${values.threshold} out of ${owners ? owners.size - 1 : 0} owner(s)`} + {`${threshold} out of ${owners ? owners.size - 1 : 0} owner(s)`}
@@ -165,11 +198,13 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre - - You're about to create a transaction and will have to confirm it with your currently connected wallet. -
- {`Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} -
+
@@ -191,5 +226,3 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre ) } - -export default withStyles(styles as any)(ReviewRemoveOwner) diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/style.ts b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/style.ts index 90b7a749..090072fa 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/style.ts +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review/style.ts @@ -1,6 +1,7 @@ import { background, border, lg, secondaryText, sm } from 'src/theme/variables' +import { createStyles } from '@material-ui/core' -export const styles = () => ({ +export const styles = createStyles({ root: { height: '372px', }, @@ -76,7 +77,9 @@ export const styles = () => ({ }, }, gasCostsContainer: { - padding: `0 ${lg}`, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', textAlign: 'center', width: '100%', }, diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.tsx index 1968fcc4..10266f78 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/index.tsx @@ -3,7 +3,6 @@ import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import OwnerForm from './screens/OwnerForm' -import ReviewReplaceOwner from './screens/Review' import Modal from 'src/components/Modal' import { addOrUpdateAddressBookEntry } from 'src/logic/addressBook/store/actions/addOrUpdateAddressBookEntry' @@ -16,6 +15,7 @@ import { checksumAddress } from 'src/utils/checksumAddress' import { makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook' import { sameAddress } from 'src/logic/wallets/ethAddresses' import { Dispatch } from 'src/logic/safe/store/actions/types.d' +import { ReviewReplaceOwnerModal } from './screens/Review' const styles = createStyles({ biggerModalWindow: { @@ -28,9 +28,8 @@ const styles = createStyles({ const useStyles = makeStyles(styles) type OwnerValues = { - ownerAddress: string - ownerName: string - threshold: string + newOwnerAddress: string + newOwnerName: string } export const sendReplaceOwner = async ( @@ -44,7 +43,7 @@ export const sendReplaceOwner = async ( const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((ownerAddress) => sameAddress(ownerAddress, ownerAddressToRemove)) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] - const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddressToRemove, values.ownerAddress).encodeABI() + const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddressToRemove, values.newOwnerAddress).encodeABI() const txHash = await dispatch( createTransaction({ @@ -61,8 +60,8 @@ export const sendReplaceOwner = async ( replaceSafeOwner({ safeAddress, oldOwnerAddress: ownerAddressToRemove, - ownerAddress: values.ownerAddress, - ownerName: values.ownerName, + ownerAddress: values.newOwnerAddress, + ownerName: values.newOwnerName, }), ) } @@ -75,10 +74,18 @@ type ReplaceOwnerProps = { ownerName: string } -const ReplaceOwner = ({ isOpen, onClose, ownerAddress, ownerName }: ReplaceOwnerProps): React.ReactElement => { +export const ReplaceOwnerModal = ({ + isOpen, + onClose, + ownerAddress, + ownerName, +}: ReplaceOwnerProps): React.ReactElement => { const classes = useStyles() const [activeScreen, setActiveScreen] = useState('checkOwner') - const [values, setValues] = useState({}) + const [values, setValues] = useState({ + newOwnerAddress: '', + newOwnerName: '', + }) const dispatch = useDispatch() const safeAddress = useSelector(safeParamAddressFromStateSelector) const threshold = useSelector(safeThresholdSelector) @@ -86,7 +93,10 @@ const ReplaceOwner = ({ isOpen, onClose, ownerAddress, ownerName }: ReplaceOwner useEffect( () => () => { setActiveScreen('checkOwner') - setValues({}) + setValues({ + newOwnerAddress: '', + newOwnerName: '', + }) }, [isOpen], ) @@ -96,9 +106,10 @@ const ReplaceOwner = ({ isOpen, onClose, ownerAddress, ownerName }: ReplaceOwner const ownerSubmitted = (newValues) => { const { ownerAddress, ownerName } = newValues const checksumAddr = checksumAddress(ownerAddress) - values.ownerName = ownerName - values.ownerAddress = checksumAddr - setValues(values) + setValues({ + newOwnerAddress: checksumAddr, + newOwnerName: ownerName, + }) setActiveScreen('reviewReplaceOwner') } @@ -108,7 +119,9 @@ const ReplaceOwner = ({ isOpen, onClose, ownerAddress, ownerName }: ReplaceOwner await sendReplaceOwner(values, safeAddress, ownerAddress, dispatch, threshold) dispatch( - addOrUpdateAddressBookEntry(makeAddressBookEntry({ address: values.ownerAddress, name: values.ownerName })), + addOrUpdateAddressBookEntry( + makeAddressBookEntry({ address: values.newOwnerAddress, name: values.newOwnerName }), + ), ) } catch (error) { console.error('Error while removing an owner', error) @@ -128,7 +141,7 @@ const ReplaceOwner = ({ isOpen, onClose, ownerAddress, ownerName }: ReplaceOwner )} {activeScreen === 'reviewReplaceOwner' && ( - ) } - -export default ReplaceOwner diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 231b8d7e..a56a069f 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -1,5 +1,5 @@ import IconButton from '@material-ui/core/IconButton' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' @@ -7,8 +7,7 @@ import { useSelector } from 'react-redux' import { List } from 'immutable' import { ExplorerButton } from '@gnosis.pm/safe-react-components' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import { getExplorerInfo, getNetworkInfo } from 'src/config' +import { getExplorerInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' @@ -24,47 +23,75 @@ import { safeParamAddressFromStateSelector, safeThresholdSelector, } from 'src/logic/safe/store/selectors' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getOwnersWithNameFromAddressBook } from 'src/logic/addressBook/utils' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { styles } from './style' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' +import { TransactionFees } from 'src/components/TransactionsFees' export const REPLACE_OWNER_SUBMIT_BTN_TEST_ID = 'replace-owner-submit-btn' -const { nativeCoin } = getNetworkInfo() +const useStyles = makeStyles(styles) -const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { - const [gasCosts, setGasCosts] = useState('< 0.001') - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string +type ReplaceOwnerProps = { + onClose: () => void + onClickBack: () => void + onSubmit: () => void + ownerAddress: string + ownerName: string + values: { + newOwnerAddress: string + newOwnerName: string + } +} + +export const ReviewReplaceOwnerModal = ({ + onClickBack, + onClose, + onSubmit, + ownerAddress, + ownerName, + values, +}: ReplaceOwnerProps): React.ReactElement => { + const classes = useStyles() + const [data, setData] = useState('') + const safeAddress = useSelector(safeParamAddressFromStateSelector) const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) const threshold = useSelector(safeThresholdSelector) const addressBook = useSelector(addressBookSelector) const ownersWithAddressBookName = owners ? getOwnersWithNameFromAddressBook(addressBook, owners) : List([]) + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isCreation, + isOffChainSignature, + } = useEstimateTransactionGas({ + txData: data, + txRecipient: safeAddress, + }) + useEffect(() => { let isCurrent = true - const estimateGas = async () => { + const calculateReplaceOwnerData = async () => { const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] - const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddress, values.ownerAddress).encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) + const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddress, values.newOwnerAddress).encodeABI() if (isCurrent) { - setGasCosts(formattedGasCosts) + setData(txData) } } - estimateGas() + calculateReplaceOwnerData() return () => { isCurrent = false } - }, [ownerAddress, safeAddress, values.ownerAddress]) + }, [ownerAddress, safeAddress, values.newOwnerAddress]) return ( <> @@ -78,7 +105,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre - + @@ -172,19 +199,19 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre - + - {values.ownerName} + {values.newOwnerName} - {values.ownerAddress} + {values.newOwnerAddress} - - + + @@ -195,11 +222,13 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre - - You're about to create a transaction and will have to confirm it with your currently connected wallet. -
- {`Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} -
+
@@ -221,5 +250,3 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre ) } - -export default withStyles(styles as any)(ReviewRemoveOwner) diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/style.ts b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/style.ts index 07df003a..5bbbe831 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/style.ts +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/style.ts @@ -1,6 +1,7 @@ import { background, border, lg, secondaryText, sm } from 'src/theme/variables' +import { createStyles } from '@material-ui/core' -export const styles = () => ({ +export const styles = createStyles({ root: { height: '372px', }, @@ -81,7 +82,9 @@ export const styles = () => ({ }, }, gasCostsContainer: { - padding: `0 ${lg}`, + display: 'flex', + flexDirection: 'column', + alignItems: 'center', textAlign: 'center', width: '100%', }, diff --git a/src/routes/safe/components/Settings/ManageOwners/index.tsx b/src/routes/safe/components/Settings/ManageOwners/index.tsx index df255ca5..f4cb8f19 100644 --- a/src/routes/safe/components/Settings/ManageOwners/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/index.tsx @@ -11,8 +11,8 @@ import RemoveOwnerIcon from '../assets/icons/bin.svg' import AddOwnerModal from './AddOwnerModal' import { EditOwnerModal } from './EditOwnerModal' import OwnerAddressTableCell from './OwnerAddressTableCell' -import RemoveOwnerModal from './RemoveOwnerModal' -import ReplaceOwnerModal from './ReplaceOwnerModal' +import { RemoveOwnerModal } from './RemoveOwnerModal' +import { ReplaceOwnerModal } from './ReplaceOwnerModal' import RenameOwnerIcon from './assets/icons/rename-owner.svg' import ReplaceOwnerIcon from './assets/icons/replace-owner.svg' import { OWNERS_TABLE_ADDRESS_ID, OWNERS_TABLE_NAME_ID, generateColumns, getOwnerData } from './dataFetcher' diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx index 58fb82e3..d28cbb5d 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx @@ -1,10 +1,8 @@ import IconButton from '@material-ui/core/IconButton' import MenuItem from '@material-ui/core/MenuItem' -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import { getNetworkInfo } from 'src/config' import { styles } from './style' import Field from 'src/components/forms/Field' @@ -18,35 +16,60 @@ import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gas' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' +import { SafeOwner } from 'src/logic/safe/store/models/safe' +import { List } from 'immutable' +import { useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' + +import { TransactionFees } from 'src/components/TransactionsFees' const THRESHOLD_FIELD_NAME = 'threshold' -const { nativeCoin } = getNetworkInfo() +const useStyles = makeStyles(styles) -const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddress, threshold }) => { - const [gasCosts, setGasCosts] = useState('< 0.001') +type ChangeThresholdModalProps = { + onChangeThreshold: (newThreshold: number) => void + onClose: () => void + owners?: List + safeAddress: string + threshold?: number +} + +export const ChangeThresholdModal = ({ + onChangeThreshold, + onClose, + owners, + safeAddress, + threshold = 1, +}: ChangeThresholdModalProps): React.ReactElement => { + const classes = useStyles() + const [data, setData] = useState('') + + const { + gasCostFormatted, + txEstimationExecutionStatus, + isCreation, + isExecution, + isOffChainSignature, + } = useEstimateTransactionGas({ + txData: data, + txRecipient: safeAddress, + }) useEffect(() => { let isCurrent = true - const estimateGasCosts = async () => { + const calculateChangeThresholdData = async () => { const safeInstance = await getGnosisSafeInstanceAt(safeAddress) - const txData = safeInstance.methods.changeThreshold('1').encodeABI() - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCostsAsEth) + const txData = safeInstance.methods.changeThreshold(threshold).encodeABI() if (isCurrent) { - setGasCosts(formattedGasCosts) + setData(txData) } } - estimateGasCosts() - + calculateChangeThresholdData() return () => { isCurrent = false } - }, [safeAddress]) + }, [safeAddress, threshold]) const handleSubmit = (values) => { const newThreshold = values[THRESHOLD_FIELD_NAME] @@ -81,7 +104,7 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr render={(props) => ( <> - {[...Array(Number(owners.size))].map((x, index) => ( + {[...Array(Number(owners?.size))].map((x, index) => ( {index + 1} @@ -99,14 +122,18 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr - {`out of ${owners.size} owner(s)`} + {`out of ${owners?.size} owner(s)`} - - {`You're about to create a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${nativeCoin.name} in this wallet to fund this confirmation.`} - +
@@ -124,5 +151,3 @@ const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddr ) } - -export default withStyles(styles as any)(ChangeThreshold) diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/style.ts b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/style.ts index e0f9c000..e3f31c05 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/style.ts +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/style.ts @@ -1,6 +1,7 @@ import { lg, md, secondaryText, sm } from 'src/theme/variables' +import { createStyles } from '@material-ui/core' -export const styles = () => ({ +export const styles = createStyles({ heading: { padding: `${sm} ${lg}`, justifyContent: 'space-between', diff --git a/src/routes/safe/components/Settings/ThresholdSettings/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/index.tsx index ccc3f4e5..753f758c 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/index.tsx @@ -2,7 +2,7 @@ import { makeStyles } from '@material-ui/core/styles' import React, { useState, useEffect } from 'react' import { useDispatch, useSelector } from 'react-redux' -import ChangeThreshold from './ChangeThreshold' +import { ChangeThresholdModal } from './ChangeThreshold' import { styles } from './style' import Modal from 'src/components/Modal' @@ -30,7 +30,7 @@ const ThresholdSettings = (): React.ReactElement => { const [isModalOpen, setModalOpen] = useState(false) const dispatch = useDispatch() const threshold = useSelector(safeThresholdSelector) - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string + const safeAddress = useSelector(safeParamAddressFromStateSelector) const owners = useSelector(safeOwnersSelector) const granted = useSelector(grantedSelector) @@ -38,7 +38,7 @@ const ThresholdSettings = (): React.ReactElement => { setModalOpen((prevOpen) => !prevOpen) } - const onChangeThreshold = async (newThreshold) => { + const onChangeThreshold = async (newThreshold: number) => { const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.changeThreshold(newThreshold).encodeABI() @@ -87,7 +87,7 @@ const ThresholdSettings = (): React.ReactElement => { open={isModalOpen} title="Change Required Confirmations" > - { - let isCurrent = true - - const estimateGas = async () => { - const estimatedGasCosts = await estimateTxGasCosts( - safeAddress, - tx.recipient, - tx.data as string, - tx, - approveAndExecute ? userAddress : undefined, - ) - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - if (isCurrent) { - setGasCosts(formattedGasCosts) - } - } - - estimateGas() - - return () => { - isCurrent = false - } - }, [approveAndExecute, safeAddress, tx, userAddress]) + const { + gasCostFormatted, + txEstimationExecutionStatus, + isExecution, + isOffChainSignature, + isCreation, + } = useEstimateTransactionGas({ + txRecipient: tx.recipient, + txData: tx.data || '', + txConfirmations: tx.confirmations, + txAmount: tx.value, + preApprovingOwner: approveAndExecute ? userAddress : undefined, + safeTxGas: tx.safeTxGas, + operation: tx.operation, + }) const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute) @@ -159,15 +146,13 @@ const ApproveTxModal = ({ )} - - - {`You're about to ${ - approveAndExecute ? 'execute' : 'approve' - } a transaction and will have to confirm it with your currently connected wallet. Make sure you have ${gasCosts} (fee price) ${ - nativeCoin.name - } in this wallet to fund this confirmation.`} - - +