diff --git a/.eslintrc.js b/.eslintrc.js index a4bfe751..8c535ecb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,10 +1,10 @@ module.exports = { parser: '@typescript-eslint/parser', extends: [ - 'plugin:react/recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier/@typescript-eslint', - 'plugin:prettier/recommended', + 'plugin:react/recommended', // React recommended rules plugin + 'plugin:@typescript-eslint/recommended', // Plugin to use typescript with eslint + 'prettier', // Add prettier rules to eslint + 'plugin:prettier/recommended', // Plugin to use prettier rules with eslint ], plugins: ['react-hooks'], parserOptions: { diff --git a/.github/workflows/deploy-ewc.yml b/.github/workflows/deploy-ewc.yml index 6fa71020..2081c697 100644 --- a/.github/workflows/deploy-ewc.yml +++ b/.github/workflows/deploy-ewc.yml @@ -11,7 +11,7 @@ on: env: REPO_NAME_ALPHANUMERIC: safereact - REACT_APP_NETWORK: 'ewc' + REACT_APP_NETWORK: 'energy_web_chain' STAGING_BUCKET_NAME: ${{ secrets.STAGING_EWC_BUCKET_NAME }} REACT_APP_SENTRY_DSN: ${{ secrets.SENTRY_DSN_EWC }} REACT_APP_GOOGLE_ANALYTICS: ${{ secrets.REACT_APP_GOOGLE_ANALYTICS_ID_EWC }} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4608ec9d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,116 +0,0 @@ -# if: (branch = development) OR (branch = master) OR (type = pull_request) OR (tag IS present) -if: (branch = master) OR (tag IS present) -dist: focal -language: node_js -node_js: - - '12' -os: - - linux -matrix: - # include: - # - env: - # - REACT_APP_NETWORK='mainnet' - # - STAGING_BUCKET_NAME=${STAGING_MAINNET_BUCKET_NAME} - # - REACT_APP_SENTRY_DSN=${SENTRY_DSN_MAINNET} - # - SENTRY_PROJECT=${SENTRY_PROJECT_MAINNET} - # - REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET} - # - REACT_APP_GNOSIS_APPS_URL=${REACT_APP_GNOSIS_APPS_URL_PROD} - # if: (branch = master AND NOT type = pull_request) OR tag IS present - # - env: - # - REACT_APP_NETWORK='rinkeby' - # - REACT_APP_SENTRY_DSN=${SENTRY_DSN_RINKEBY} - # - SENTRY_PROJECT=${SENTRY_PROJECT_RINKEBY} - # - REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY} - # - REACT_APP_GNOSIS_APPS_URL=${REACT_APP_GNOSIS_APPS_URL_STAGING} - # if: (branch = development AND NOT type = pull_request) OR (branch = master) OR tag IS present - # - env: - # - REACT_APP_NETWORK='xdai' - # - STAGING_BUCKET_NAME=${STAGING_XDAI_BUCKET_NAME} - # - REACT_APP_SENTRY_DSN=${SENTRY_DSN_XDAI} - # - SENTRY_PROJECT=${SENTRY_PROJECT_XDAI} - # - REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_XDAI} - # if: (branch = master) OR tag IS present - # - env: - # - REACT_APP_NETWORK='volta' - # - STAGING_BUCKET_NAME=${STAGING_VOLTA_BUCKET_NAME} - # - REACT_APP_SENTRY_DSN=${SENTRY_DSN_VOLTA} - # - SENTRY_PROJECT=${SENTRY_PROJECT_VOLTA} - # - REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_VOLTA} - # if: (branch = master) OR tag IS present - # - env: - # - REACT_APP_NETWORK='energy_web_chain' - # - STAGING_BUCKET_NAME=${STAGING_EWC_BUCKET_NAME} - # - REACT_APP_SENTRY_DSN=${SENTRY_DSN_EWC} - # - SENTRY_PROJECT=${SENTRY_PROJECT_EWC} - # - REACT_APP_GOOGLE_ANALYTICS=${REACT_APP_GOOGLE_ANALYTICS_ID_EWC} - # if: (branch = master AND NOT type = pull_request) OR tag IS present -cache: - npm: false - yarn: true -before_script: - - if [[ -n "$TRAVIS_TAG" ]]; then export REACT_APP_ENV='production'; fi; - - if [ $TRAVIS_PULL_REQUEST != "false" ]; then export PUBLIC_URL="/${REACT_APP_NETWORK}/app"; fi; -before_install: - # Needed to deploy pull request and releases - # - sudo apt-get update - # - sudo apt-get -y install python3-pip python3-dev libusb-1.0-0-dev libudev-dev - # - pip install awscli --upgrade --user -script: - - yarn prettier:check - # - yarn test:coverage - # - yarn build - # - if [[ $TRAVIS_BRANCH == "master" && $TRAVIS_PULL_REQUEST == "false" ]] || [ -n "$TRAVIS_TAG" ]; then - # echo "Upload sentry source maps"; - # yarn sentry-upload-sourcemaps; - # else - # echo "Skip source map upload"; - # fi; -after_success: - # Pull Request - Deploy it to a review environment - # Travis doesn't do deploy step with pull requests builds - # - ./config/travis/deploy_pull_request.sh - # Releases (tagged commits) - Deploy it to a release environment - # - ./config/travis/deploy_release.sh - # - yarn coveralls - -deploy: - # Development environment only on rinkeby - # - provider: s3 - # bucket: $DEV_BUCKET_NAME - # access_key_id: $AWS_ACCESS_KEY_ID - # secret_access_key: $AWS_SECRET_ACCESS_KEY - # skip_cleanup: true - # local_dir: build - # upload_dir: app - # region: $AWS_DEFAULT_REGION - # on: - # branch: development - # condition: $REACT_APP_NETWORK = rinkeby - - # Staging environment - # - provider: s3 - # bucket: $STAGING_BUCKET_NAME - # access_key_id: $AWS_ACCESS_KEY_ID - # secret_access_key: $AWS_SECRET_ACCESS_KEY - # skip_cleanup: true - # local_dir: build - # upload_dir: current/app - # region: $AWS_DEFAULT_REGION - # on: - # branch: master - - # Prepare production deployment - # - provider: s3 - # bucket: $STAGING_BUCKET_NAME - # secret_access_key: $AWS_SECRET_ACCESS_KEY - # access_key_id: $AWS_ACCESS_KEY_ID - # skip_cleanup: true - # local_dir: build - # upload_dir: releases/$TRAVIS_TAG - # region: $AWS_DEFAULT_REGION - # on: - # tags: true - # - provider: script - # script: ./config/travis/prepare_production_deployment.sh - # on: - # tags: true diff --git a/config/travis/deploy_pull_request.sh b/config/travis/deploy_pull_request.sh deleted file mode 100755 index e6f5e884..00000000 --- a/config/travis/deploy_pull_request.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -function deploy_pull_request { - REVIEW_ENVIRONMENT_DOMAIN='review.gnosisdev.com' - - # Pull request name with "pr" prefix - PULL_REQUEST_NAME="pr$TRAVIS_PULL_REQUEST" - - # Feature name without all path. Example gnosis/pm-trading-ui -> pm-trading-ui - REPO_NAME=$(basename $TRAVIS_REPO_SLUG) - # Only alphanumeric characters. Example pm-trading-ui -> pmtradingui - REPO_NAME_ALPHANUMERIC=$(echo $REPO_NAME | sed 's/[^a-zA-Z0-9]//g') - - # TRAVIS_PULL_REQUEST contains pull request number - REVIEW_FEATURE_FOLDER="$REPO_NAME_ALPHANUMERIC/$PULL_REQUEST_NAME" - - # Deploy safe-team project - aws s3 sync build s3://${REVIEW_BUCKET_NAME}/${REVIEW_FEATURE_FOLDER}/${REACT_APP_NETWORK}/app --delete -} - -function publish_pull_request_urls_in_github { - REVIEW_FEATURE_URL="https://$PULL_REQUEST_NAME--$REPO_NAME_ALPHANUMERIC.$REVIEW_ENVIRONMENT_DOMAIN/$REACT_APP_NETWORK/app" - - # Using the Issues api instead of the PR api - # Done so because every PR is an issue, and the issues api allows to post general comments, - # while the PR api requires that comments are made to specific files and specific commits - GITHUB_PR_COMMENTS=https://api.github.com/repos/${TRAVIS_REPO_SLUG}/issues/${TRAVIS_PULL_REQUEST}/comments - curl -H "Authorization: token ${GITHUB_API_TOKEN}" --request POST ${GITHUB_PR_COMMENTS} --data '{"body":"Travis automatic deployment:\r\n '${REVIEW_FEATURE_URL}' \r\n"}' -} - -# Only: -# - Pull requests -# - Security env variables are available. PR from forks don't have them. -if [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ -n "$AWS_ACCESS_KEY_ID" ] -then - deploy_pull_request - publish_pull_request_urls_in_github -fi diff --git a/package.json b/package.json index cde7198c..825b8173 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "safe-react", - "version": "3.1.2", + "version": "3.2.0", "description": "Allowing crypto users manage funds in a safer way", "website": "https://github.com/gnosis/safe-react#readme", "bugs": { @@ -161,21 +161,21 @@ "@gnosis.pm/safe-apps-sdk": "1.0.3", "@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#fb1a523", + "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#f610327", "@gnosis.pm/util-contracts": "2.0.6", - "@ledgerhq/hw-transport-node-hid-singleton": "5.41.0", + "@ledgerhq/hw-transport-node-hid-singleton": "5.45.0", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.11.0", "@material-ui/lab": "4.0.0-alpha.57", "@openzeppelin/contracts": "3.1.0", - "@sentry/react": "^5.30.0", - "@sentry/tracing": "^5.30.0", + "@sentry/react": "^6.2.1", + "@sentry/tracing": "^6.2.1", "@truffle/contract": "^4.3.0", "@unstoppabledomains/resolution": "^1.17.0", "async-sema": "^3.1.0", "axios": "0.21.1", "bignumber.js": "9.0.1", - "bnc-onboard": "1.19.2", + "bnc-onboard": "~1.20.0", "classnames": "^2.2.6", "concurrently": "^5.3.0", "connected-react-router": "6.8.0", @@ -186,13 +186,13 @@ "electron-is-dev": "^1.2.0", "electron-log": "^4.3.0", "electron-settings": "^4.0.2", - "electron-updater": "4.3.5", + "electron-updater": "4.3.8", "eth-sig-util": "^2.5.3", "ethereum-blockies-base64": "^1.0.2", "ethereumjs-abi": "0.6.8", "exponential-backoff": "^3.1.0", "express": "^4.17.1", - "final-form": "^4.20.1", + "final-form": "^4.20.2", "final-form-calculate": "^1.3.2", "history": "4.10.1", "immortal-db": "^1.1.0", @@ -207,7 +207,7 @@ "notistack": "https://github.com/gnosis/notistack.git#v0.9.4", "object-hash": "^2.1.1", "qrcode.react": "1.0.1", - "query-string": "6.13.8", + "query-string": "6.14.1", "react": "16.13.1", "react-device-detect": "^1.15.0", "react-dom": "16.13.1", @@ -233,8 +233,8 @@ "web3-utils": "^1.2.11" }, "devDependencies": { - "@rescripts/cli": "^0.0.15", - "@sentry/cli": "^1.62.0", + "@rescripts/cli": "^0.0.16", + "@sentry/cli": "^1.63.1", "@storybook/addon-actions": "^5.3.19", "@storybook/addon-links": "^5.3.19", "@storybook/addons": "^5.3.19", @@ -242,41 +242,41 @@ "@storybook/react": "^5.3.19", "@testing-library/jest-dom": "^5.11.6", "@testing-library/react": "^11.2.2", - "@typechain/web3-v1": "^2.0.0", + "@typechain/web3-v1": "^2.2.0", "@types/history": "4.6.2", "@types/jest": "^26.0.16", "@types/lodash.get": "^4.4.6", "@types/lodash.memoize": "^4.1.6", - "@types/node": "^14.14.10", - "@types/react": "^16.9.55", + "@types/node": "^14.14.30", + "@types/react": "^16.14.5", "@types/react-dom": "^16.9.9", "@types/react-redux": "^7.1.11", "@types/react-router-dom": "^5.1.6", "@types/redux-actions": "^2.6.1", "@types/styled-components": "^5.1.4", - "@typescript-eslint/eslint-plugin": "^4.14.0", - "@typescript-eslint/parser": "^4.14.0", + "@typescript-eslint/eslint-plugin": "^4.17.0", + "@typescript-eslint/parser": "^4.17.0", "cross-env": "^7.0.3", "dotenv": "^8.2.0", "dotenv-expand": "^5.1.0", "electron": "^9.4.0", - "electron-builder": "22.9.1", + "electron-builder": "22.10.5", "electron-notarize": "1.0.0", "eslint": "^7.17.0", - "eslint-config-prettier": "^7.2.0", + "eslint-config-prettier": "^8.1.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", - "husky": "^4.3.0", + "husky": "~4.3.8", "lint-staged": "^10.5.2", - "patch-package": "^6.2.2", + "patch-package": "^6.4.6", "postinstall-postinstall": "^2.1.0", "prettier": "^2.2.0", "sass": "^1.32.0", "typechain": "^4.0.0", - "typescript": "4.1.3", + "typescript": "4.2.3", "wait-on": "5.2.1" } } diff --git a/src/components/App/ReceiveModal.tsx b/src/components/App/ReceiveModal.tsx index 0574c485..98edb0f4 100644 --- a/src/components/App/ReceiveModal.tsx +++ b/src/components/App/ReceiveModal.tsx @@ -94,7 +94,7 @@ const ReceiveModal = ({ onClose, safeAddress, safeName }: Props): ReactElement = <> - Receive funds + Receive assets @@ -106,7 +106,7 @@ const ReceiveModal = ({ onClose, safeAddress, safeName }: Props): ReactElement = This is the address of your Safe. Deposit funds by scanning the QR code or copying the address below. Only send{' '} - {networkInfo.nativeCoin.name} and ERC-20 tokens to this address! + {networkInfo.nativeCoin.name} and assets to this address (e.g. ETH, ERC20, ERC721)! diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index 5f7a5bc0..149f7d84 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -171,7 +171,7 @@ const SafeHeader = ({ - New Transaction + New transaction diff --git a/src/components/CookiesBanner/index.tsx b/src/components/CookiesBanner/index.tsx index 06fc2bc9..9219aab6 100644 --- a/src/components/CookiesBanner/index.tsx +++ b/src/components/CookiesBanner/index.tsx @@ -129,6 +129,10 @@ const CookiesBanner = (): ReactElement => { } setLocalAnalytics(acceptedAnalytics) setLocalNecessary(acceptedNecessary) + + if (acceptedAnalytics && !isDesktop) { + loadGoogleAnalytics() + } } } fetchCookiesFromStorage() @@ -162,10 +166,6 @@ const CookiesBanner = (): ReactElement => { dispatch.current(openCookieBanner({ cookieBannerOpen: false })) } - if (showAnalytics && !isDesktop) { - loadGoogleAnalytics() - } - if (showIntercom) { loadIntercom() } diff --git a/src/components/Stepper/index.tsx b/src/components/Stepper/index.tsx index 07ee8497..824a1c77 100644 --- a/src/components/Stepper/index.tsx +++ b/src/components/Stepper/index.tsx @@ -11,6 +11,7 @@ import Controls from './Controls' import GnoForm from 'src/components/forms/GnoForm' import Hairline from 'src/components/layout/Hairline' import { history } from 'src/store' +import { LoadFormValues } from 'src/routes/load/container/Load' const transitionProps = { timeout: { @@ -20,7 +21,7 @@ const transitionProps = { } export interface StepperPageFormProps { - values: Record + values: LoadFormValues errors: Record form: FormApi } diff --git a/src/config/networks/energy_web_chain.ts b/src/config/networks/energy_web_chain.ts index 8a340c81..1f908757 100644 --- a/src/config/networks/energy_web_chain.ts +++ b/src/config/networks/energy_web_chain.ts @@ -55,7 +55,6 @@ const mainnet: NetworkConfig = { WALLETS.PORTIS, WALLETS.TORUS, WALLETS.TRUST, - WALLETS.WALLET_CONNECT, WALLETS.WALLET_LINK, WALLETS.AUTHEREUM, WALLETS.LATTICE, diff --git a/src/logic/collectibles/store/selectors/index.ts b/src/logic/collectibles/store/selectors/index.ts index d6737a6a..1c5e6412 100644 --- a/src/logic/collectibles/store/selectors/index.ts +++ b/src/logic/collectibles/store/selectors/index.ts @@ -16,10 +16,6 @@ export const nftAssetsListSelector = createSelector(nftAssets, (assets): NFTAsse return assets ? Object.values(assets) : [] }) -export const nftAssetsListAddressesSelector = createSelector(nftAssetsListSelector, (assets): string[] => { - return Array.from(new Set(assets.map((nftAsset) => nftAsset.address))) -}) - export const availableNftAssetsAddresses = createSelector(nftTokensSelector, (userNftTokens): string[] => { return Array.from(new Set(userNftTokens.map((nftToken) => nftToken.assetAddress))) }) diff --git a/src/logic/collectibles/utils/index.ts b/src/logic/collectibles/utils/index.ts index 5eae89c2..830c17aa 100644 --- a/src/logic/collectibles/utils/index.ts +++ b/src/logic/collectibles/utils/index.ts @@ -1,13 +1,8 @@ import { getNetworkId, getNetworkInfo } from 'src/config' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' -import { nftAssetsListAddressesSelector } from 'src/logic/collectibles/store/selectors' -import { BuildTx, ServiceTx } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' -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, @@ -29,24 +24,6 @@ const ENS_CONTRACT_ADDRESS = { // 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 {BuildTx['tx']} tx - * @returns boolean - */ -export const isSendERC721Transaction = (tx: BuildTx['tx']): 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 as ServiceTx).to) || hasERC721Transfer -} - /** * Returns the symbol of the provided ERC721 contract * @param {string} contractAddress diff --git a/src/logic/contracts/safeContracts.ts b/src/logic/contracts/safeContracts.ts index 384fcc8e..17345da0 100644 --- a/src/logic/contracts/safeContracts.ts +++ b/src/logic/contracts/safeContracts.ts @@ -5,7 +5,7 @@ import Web3 from 'web3' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' -import { calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions' +import { calculateGasOf, EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import { getWeb3, getNetworkIdFrom } from 'src/logic/wallets/getWeb3' import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' import { GnosisSafeProxyFactory } from 'src/types/contracts/GnosisSafeProxyFactory.d' @@ -99,7 +99,7 @@ export const getSafeDeploymentTransaction = ( safeAccounts, numConfirmations, ZERO_ADDRESS, - '0x', + EMPTY_DATA, DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, @@ -120,7 +120,7 @@ export const estimateGasForDeployingSafe = async ( safeAccounts, numConfirmations, ZERO_ADDRESS, - '0x', + EMPTY_DATA, DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, @@ -130,14 +130,11 @@ export const estimateGasForDeployingSafe = async ( const proxyFactoryData = proxyFactoryMaster.methods .createProxyWithNonce(safeMaster.options.address, gnosisSafeData, safeCreationSalt) .encodeABI() - const gas = await calculateGasOf({ + return calculateGasOf({ data: proxyFactoryData, from: userAccount, to: proxyFactoryMaster.options.address, }) - const gasPrice = await calculateGasPrice() - - return gas * parseInt(gasPrice, 10) } export const getGnosisSafeInstanceAt = (safeAddress: string): GnosisSafe => { diff --git a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts index e127acee..adc85654 100644 --- a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts +++ b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts @@ -1,6 +1,6 @@ import axios from 'axios' -import { getSafeServiceBaseUrl } from 'src/config' +import { getSafeClientGatewayBaseUrl } from 'src/config' import { fetchTokenCurrenciesBalances, BalanceEndpoint, @@ -46,7 +46,7 @@ describe('fetchTokenCurrenciesBalances', () => { }, ] - const apiUrl = getSafeServiceBaseUrl(safeAddress) + const apiUrl = getSafeClientGatewayBaseUrl(safeAddress) // @ts-ignore axios.get.mockImplementationOnce(() => Promise.resolve({ data: expectedResult })) @@ -57,6 +57,6 @@ describe('fetchTokenCurrenciesBalances', () => { // then expect(result).toStrictEqual(expectedResult) expect(axios.get).toHaveBeenCalled() - expect(axios.get).toBeCalledWith(`${apiUrl}/balances/usd/?exclude_spam=${excludeSpamTokens}`) + expect(axios.get).toBeCalledWith(`${apiUrl}/balances/usd/?trusted=false&exclude_spam=${excludeSpamTokens}`) }) }) diff --git a/src/logic/currencyValues/api/fetchCurrenciesRates.ts b/src/logic/currencyValues/api/fetchCurrenciesRates.ts index d61924f6..20d1d6b2 100644 --- a/src/logic/currencyValues/api/fetchCurrenciesRates.ts +++ b/src/logic/currencyValues/api/fetchCurrenciesRates.ts @@ -4,7 +4,7 @@ import BigNumber from 'bignumber.js' import { EXCHANGE_RATE_URL } from 'src/utils/constants' import { fetchTokenCurrenciesBalances } from './fetchTokenCurrenciesBalances' import { sameString } from 'src/utils/strings' -import { AVAILABLE_CURRENCIES } from '../store/model/currencyValues' +import { AVAILABLE_CURRENCIES } from 'src/logic/currencyValues/store/model/currencyValues' const fetchCurrenciesRates = async ( baseCurrency: string, @@ -15,8 +15,8 @@ const fetchCurrenciesRates = async ( if (sameString(targetCurrencyValue, AVAILABLE_CURRENCIES.NETWORK)) { try { const tokenCurrenciesBalances = await fetchTokenCurrenciesBalances(safeAddress) - if (tokenCurrenciesBalances?.length) { - rate = new BigNumber(1).div(tokenCurrenciesBalances[0].fiatConversion).toNumber() + if (tokenCurrenciesBalances.items.length) { + rate = new BigNumber(1).div(tokenCurrenciesBalances.items[0].fiatConversion).toNumber() } } catch (error) { console.error(`Fetching ${AVAILABLE_CURRENCIES.NETWORK} data from the relayer errored`, error) diff --git a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts index d9855f85..fd21f689 100644 --- a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts +++ b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts @@ -1,22 +1,29 @@ import axios from 'axios' -import { getSafeServiceBaseUrl } from 'src/config' +import { getSafeClientGatewayBaseUrl } from 'src/config' import { TokenProps } from 'src/logic/tokens/store/model/token' +import { checksumAddress } from 'src/utils/checksumAddress' -export type BalanceEndpoint = { - tokenAddress: string - token?: TokenProps +export type TokenBalance = { + tokenInfo: TokenProps balance: string fiatBalance: string fiatConversion: string - fiatCode: string +} + +export type BalanceEndpoint = { + fiatTotal: string + items: TokenBalance[] } export const fetchTokenCurrenciesBalances = ( safeAddress: string, excludeSpamTokens = true, -): Promise => { - const url = `${getSafeServiceBaseUrl(safeAddress)}/balances/usd/?exclude_spam=${excludeSpamTokens}` + trustedTokens = false, +): Promise => { + const url = `${getSafeClientGatewayBaseUrl( + checksumAddress(safeAddress), + )}/balances/usd/?trusted=${trustedTokens}&exclude_spam=${excludeSpamTokens}` return axios.get(url).then(({ data }) => data) } diff --git a/src/logic/hooks/useEstimateSafeCreationGas.tsx b/src/logic/hooks/useEstimateSafeCreationGas.tsx new file mode 100644 index 00000000..40a712d0 --- /dev/null +++ b/src/logic/hooks/useEstimateSafeCreationGas.tsx @@ -0,0 +1,59 @@ +import { useEffect, useState } from 'react' +import { useSelector } from 'react-redux' +import { userAccountSelector } from '../wallets/store/selectors' +import { estimateGasForDeployingSafe } from 'src/logic/contracts/safeContracts' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { formatAmount } from 'src/logic/tokens/utils/formatAmount' +import { getNetworkInfo } from 'src/config' +import { calculateGasPrice } from 'src/logic/wallets/ethTransactions' + +type EstimateSafeCreationGasProps = { + addresses: string[] + numOwners: number + safeCreationSalt: number +} + +type SafeCreationEstimationResult = { + gasEstimation: number // Amount of gas needed for execute or approve the transaction + gasCostFormatted: string // Cost of gas in format '< | > 100' + gasLimit: number // Minimum gas requited to execute the Tx +} + +const { nativeCoin } = getNetworkInfo() + +export const useEstimateSafeCreationGas = ({ + addresses, + numOwners, + safeCreationSalt, +}: EstimateSafeCreationGasProps): SafeCreationEstimationResult => { + const [gasEstimation, setGasEstimation] = useState({ + gasEstimation: 0, + gasCostFormatted: '< 0.001', + gasLimit: 0, + }) + const userAccount = useSelector(userAccountSelector) + + useEffect(() => { + const estimateGas = async () => { + if (!addresses.length || !numOwners || !userAccount) { + return + } + + const gasEstimation = await estimateGasForDeployingSafe(addresses, numOwners, userAccount, safeCreationSalt) + const gasPrice = await calculateGasPrice() + const estimatedGasCosts = gasEstimation * parseInt(gasPrice, 10) + const gasCost = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const gasCostFormatted = formatAmount(gasCost) + + setGasEstimation({ + gasEstimation, + gasCostFormatted, + gasLimit: gasEstimation, + }) + } + + estimateGas() + }, [numOwners, userAccount, safeCreationSalt, addresses]) + + return gasEstimation +} diff --git a/src/logic/hooks/useEstimateTransactionGas.tsx b/src/logic/hooks/useEstimateTransactionGas.tsx index 63e336d2..8cd5e268 100644 --- a/src/logic/hooks/useEstimateTransactionGas.tsx +++ b/src/logic/hooks/useEstimateTransactionGas.tsx @@ -237,12 +237,13 @@ export const useEstimateTransactionGas = ({ approvalAndExecution, }) + const totalGasEstimation = (gasEstimation + fixedGasCosts) * 2 const gasPrice = manualGasPrice ? web3.utils.toWei(manualGasPrice, 'gwei') : await calculateGasPrice() const gasPriceFormatted = web3.utils.fromWei(gasPrice, 'gwei') - const estimatedGasCosts = (gasEstimation + fixedGasCosts) * parseInt(gasPrice, 10) + const estimatedGasCosts = totalGasEstimation * parseInt(gasPrice, 10) const gasCost = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const gasCostFormatted = formatAmount(gasCost) - const gasLimit = ((gasEstimation + fixedGasCosts) * 2).toString() + const gasLimit = totalGasEstimation.toString() let txEstimationExecutionStatus = EstimationStatus.SUCCESS diff --git a/src/logic/safe/hooks/useLoadSafe.tsx b/src/logic/safe/hooks/useLoadSafe.tsx index d847d2a9..116bf24c 100644 --- a/src/logic/safe/hooks/useLoadSafe.tsx +++ b/src/logic/safe/hooks/useLoadSafe.tsx @@ -7,7 +7,6 @@ import fetchSafeTokens from 'src/logic/tokens/store/actions/fetchSafeTokens' import fetchLatestMasterContractVersion from 'src/logic/safe/store/actions/fetchLatestMasterContractVersion' import fetchSafe from 'src/logic/safe/store/actions/fetchSafe' import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions' -import fetchSafeCreationTx from 'src/logic/safe/store/actions/fetchSafeCreationTx' import { Dispatch } from 'src/logic/safe/store/actions/types.d' export const useLoadSafe = (safeAddress?: string): boolean => { @@ -21,7 +20,6 @@ export const useLoadSafe = (safeAddress?: string): boolean => { await dispatch(fetchSafe(safeAddress)) setIsSafeLoaded(true) await dispatch(fetchSafeTokens(safeAddress)) - dispatch(fetchSafeCreationTx(safeAddress)) dispatch(fetchTransactions(safeAddress)) dispatch(addViewedSafe(safeAddress)) } diff --git a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts index 027f6cd8..36b84fff 100644 --- a/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts +++ b/src/logic/safe/store/actions/__tests__/transactionHelpers.test.ts @@ -1,275 +1,15 @@ import { getMockedSafeInstance, getMockedTxServiceModel } from 'src/test/utils/safeHelper' -import { makeTransaction } from 'src/logic/safe/store/models/transaction' -import { TransactionStatus, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import makeSafe from 'src/logic/safe/store/models/safe' -import { List, Map, Record } from 'immutable' -import { makeToken, TokenProps } from 'src/logic/tokens/store/model/token' -import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { - buildTx, - calculateTransactionStatus, - calculateTransactionType, generateSafeTxHash, getRefundParams, - isCancelTransaction, - isCustomTransaction, - isInnerTransaction, - isModifySettingsTransaction, isMultiSendTransaction, - isOutgoingTransaction, - isPendingTransaction, isUpgradeTransaction, } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' import { getERC20DecimalsAndSymbol } from 'src/logic/tokens/utils/tokenHelpers' -import { DELEGATE_CALL } from 'src/logic/safe/transactions' const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' -describe('isInnerTransaction', () => { - it('It should return true if the transaction recipient is our given safeAddress and the txValue is 0', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) - it('It should return false if the transaction recipient is our given safeAddress and the txValue is >0', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '100' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction recipient is not our given safeAddress', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return true if the transaction recipient is the given safeAddress and the txValue is 0', () => { - // given - const transaction = makeTransaction({ recipient: safeAddress, value: '0' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) - it('It should return false if the transaction recipient is the given safeAddress and the txValue is >0', () => { - // given - const transaction = makeTransaction({ recipient: safeAddress, value: '100' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction recipient is not the given safeAddress', () => { - // given - const transaction = makeTransaction({ recipient: safeAddress2, value: '100' }) - - // when - const result = isInnerTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) -}) - -describe.skip('isCancelTransaction', () => { - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - const mockedETHAccount = '0xd76e0B566e218a80F4c96458FE09a322EBAa9aF2' - it('It should return false if given a inner transaction with empty data', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) - it('It should return false if given a inner transaction without empty data', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: 'test' }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction recipient is not the safeAddress', () => { - // given - const transaction = getMockedTxServiceModel({ to: mockedETHAccount, value: '0', data: null }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction value is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '100', data: null }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction data is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: mockedETHAccount }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction operation is not call', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, operation: DELEGATE_CALL }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction baseGas is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, baseGas: 10 }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction gasPrice is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, gasPrice: '10' }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction gasToken is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null, gasToken: mockedETHAccount }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the refundReceiver is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ - to: safeAddress, - value: '0', - data: null, - refundReceiver: mockedETHAccount, - }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return true for a transaction with everything empty except for to parameter equals to the safeAddress,', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress }) - - // when - const result = isCancelTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) -}) - -describe('isPendingTransaction', () => { - it('It should return true if the transaction is on pending status', () => { - // given - const transaction = makeTransaction({ status: TransactionStatus.PENDING }) - const cancelTx = makeTransaction({ data: null }) - - // when - const result = isPendingTransaction(transaction, cancelTx) - - // then - expect(result).toBe(true) - }) - it('It should return true If the transaction is not pending status but the cancellation transaction is', () => { - // given - const transaction = makeTransaction({ status: TransactionStatus.AWAITING_CONFIRMATIONS }) - const cancelTx = makeTransaction({ status: TransactionStatus.PENDING }) - - // when - const result = isPendingTransaction(transaction, cancelTx) - - // then - expect(result).toBe(true) - }) - it('It should return true If the transaction and a cancellation transaction are not pending', () => { - // given - const transaction = makeTransaction({ status: TransactionStatus.CANCELLED }) - const cancelTx = makeTransaction({ status: TransactionStatus.AWAITING_CONFIRMATIONS }) - - // when - const result = isPendingTransaction(transaction, cancelTx) - - // then - expect(result).toBe(false) - }) -}) - -describe('isModifySettingsTransaction', () => { - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - it('It should return true if given an inner transaction without empty data', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: 'test' }) - - // when - const result = isModifySettingsTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) - it('It should return false if given an inner transaction with empty data', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null }) - - // when - const result = isModifySettingsTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) -}) - describe('isMultiSendTransaction', () => { it('It should return true if given a transaction without value, the data has multisend data', () => { // given @@ -337,160 +77,6 @@ describe('isUpgradeTransaction', () => { }) }) -describe('isOutgoingTransaction', () => { - it('It should return true if the transaction recipient is not a safe address and data is not empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0', data: 'test' }) - - // when - const result = isOutgoingTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - }) - it('It should return true if the transaction has an address equal to the safe address', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: 'test' }) - - // when - const result = isOutgoingTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) - it('It should return false if the transaction recipient is not a safe address and data is empty', () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress, value: '0', data: null }) - - // when - const result = isOutgoingTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - }) -}) - -jest.mock('src/logic/collectibles/utils') -jest.mock('src/logic/tokens/utils/tokenHelpers') -describe('isCustomTransaction', () => { - afterAll(() => { - jest.unmock('src/logic/collectibles/utils') - jest.unmock('src/logic/tokens/utils/tokenHelpers') - }) - it('It should return true if Is outgoing transaction, is not an erc20 transaction, not an upgrade transaction and not and erc721 transaction', async () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0', data: 'test' }) - const knownTokens = Map & Readonly>() - const token = makeToken({ - address: '0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', - name: 'OmiseGo', - symbol: 'OMG', - decimals: 18, - logoUri: - 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', - }) - knownTokens.set('0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', token) - - const collectiblesHelpers = require('src/logic/collectibles/utils') - const txHelpers = require('src/logic/tokens/utils/tokenHelpers') - - txHelpers.isSendERC20Transaction.mockImplementationOnce(() => false) - collectiblesHelpers.isSendERC721Transaction.mockImplementationOnce(() => false) - - // when - const result = await isCustomTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - expect(txHelpers.isSendERC20Transaction).toHaveBeenCalled() - expect(collectiblesHelpers.isSendERC721Transaction).toHaveBeenCalled() - }) - it('It should return true if is outgoing transaction, is not SendERC20Transaction, is not isUpgradeTransaction and not isSendERC721Transaction', async () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0', data: 'test' }) - const knownTokens = Map & Readonly>() - const token = makeToken({ - address: '0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', - name: 'OmiseGo', - symbol: 'OMG', - decimals: 18, - logoUri: - 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', - }) - knownTokens.set('0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', token) - - const collectiblesHelpers = require('src/logic/collectibles/utils') - const txHelpers = require('src/logic/tokens/utils/tokenHelpers') - - txHelpers.isSendERC20Transaction.mockImplementationOnce(() => false) - collectiblesHelpers.isSendERC721Transaction.mockImplementationOnce(() => false) - - // when - const result = await isCustomTransaction(transaction, safeAddress) - - // then - expect(result).toBe(true) - expect(txHelpers.isSendERC20Transaction).toHaveBeenCalled() - expect(collectiblesHelpers.isSendERC721Transaction).toHaveBeenCalled() - }) - it('It should return false if is outgoing transaction, not SendERC20Transaction, isUpgradeTransaction and not isSendERC721Transaction', async () => { - // given - const upgradeTxData = `0x8d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f200dfa693da0d16f5e7e78fdcbede8fc6ebea44f1cf000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000247de7edef000000000000000000000000d5d82b6addc9027b22dca772aa68d5d74cdbdf4400dfa693da0d16f5e7e78fdcbede8fc6ebea44f1cf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f08a032300000000000000000000000034cfac646f301356faa8b21e94227e3583fe3f5f0000000000000000000000000000` - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0', data: upgradeTxData }) - const knownTokens = Map & Readonly>() - const token = makeToken({ - address: '0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', - name: 'OmiseGo', - symbol: 'OMG', - decimals: 18, - logoUri: - 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', - }) - knownTokens.set('0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', token) - - const collectiblesHelpers = require('src/logic/collectibles/utils') - const txHelpers = require('src/logic/tokens/utils/tokenHelpers') - - txHelpers.isSendERC20Transaction.mockImplementationOnce(() => true) - collectiblesHelpers.isSendERC721Transaction.mockImplementationOnce(() => false) - - // when - const result = await isCustomTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - expect(txHelpers.isSendERC20Transaction).toHaveBeenCalled() - }) - it('It should return false if is outgoing transaction, is not SendERC20Transaction, not isUpgradeTransaction and isSendERC721Transaction', async () => { - // given - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0', data: 'test' }) - const knownTokens = Map & Readonly>() - const token = makeToken({ - address: '0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', - name: 'OmiseGo', - symbol: 'OMG', - decimals: 18, - logoUri: - 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', - }) - knownTokens.set('0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', token) - - const collectiblesHelpers = require('src/logic/collectibles/utils') - const txHelpers = require('src/logic/tokens/utils/tokenHelpers') - - txHelpers.isSendERC20Transaction.mockImplementationOnce(() => false) - collectiblesHelpers.isSendERC721Transaction.mockImplementationOnce(() => true) - - // when - const result = await isCustomTransaction(transaction, safeAddress) - - // then - expect(result).toBe(false) - expect(txHelpers.isSendERC20Transaction).toHaveBeenCalled() - expect(collectiblesHelpers.isSendERC721Transaction).toHaveBeenCalled() - }) -}) - describe('getRefundParams', () => { it('It should return null if given a transaction with the gasPrice == 0', async () => { // given @@ -588,374 +174,6 @@ describe('getRefundParams', () => { }) }) -describe('getDecodedParams', () => { - it('', () => { - // given - // when - // then - }) -}) - -describe('isTransactionCancelled', () => { - it('', () => { - // given - // when - // then - }) -}) - -describe('calculateTransactionStatus', () => { - it('It should return SUCCESS if the tx is executed and successful', () => { - // given - const transaction = makeTransaction({ isExecuted: true, isSuccessful: true }) - const safe = makeSafe() - const currentUser = safeAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.SUCCESS) - }) - it('It should return CANCELLED if the tx is cancelled and successful', () => { - // given - const transaction = makeTransaction({ cancelled: true }) - const safe = makeSafe() - const currentUser = safeAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.CANCELLED) - }) - it('It should return AWAITING_EXECUTION if the tx has an amount of confirmations equal to the safe threshold', () => { - // given - const makeUser = Record({ - owner: '', - type: '', - hash: '', - signature: '', - }) - const transaction = makeTransaction({ cancelled: true, confirmations: List([makeUser(), makeUser(), makeUser()]) }) - const safe = makeSafe({ threshold: 3 }) - const currentUser = safeAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.CANCELLED) - }) - it('It should return SUCCESS if the tx is the creation transaction', () => { - // given - const transaction = makeTransaction({ creationTx: true, confirmations: List() }) - const safe = makeSafe({ threshold: 3 }) - const currentUser = safeAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.SUCCESS) - }) - it('It should return PENDING if the tx is pending', () => { - // given - const transaction = makeTransaction({ confirmations: List(), isPending: true }) - const safe = makeSafe({ threshold: 3 }) - const currentUser = safeAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.PENDING) - }) - it('It should return AWAITING_CONFIRMATIONS if the tx has confirmations bellow the threshold, the user is owner and signed', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const makeUser = Record({ - owner: '', - type: '', - hash: '', - signature: '', - }) - const transaction = makeTransaction({ confirmations: List([makeUser({ owner: userAddress })]) }) - const safe = makeSafe({ - threshold: 3, - owners: List([ - { name: '', address: userAddress }, - { name: '', address: userAddress2 }, - ]), - }) - const currentUser = userAddress - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.AWAITING_CONFIRMATIONS) - }) - it('It should return AWAITING_YOUR_CONFIRMATION if the tx has confirmations bellow the threshold, the user is owner and not signed', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const makeUser = Record({ - owner: '', - type: '', - hash: '', - signature: '', - }) - - const transaction = makeTransaction({ confirmations: List([makeUser({ owner: userAddress })]) }) - const safe = makeSafe({ - threshold: 3, - owners: List([ - { name: '', address: userAddress }, - { name: '', address: userAddress2 }, - ]), - }) - const currentUser = userAddress2 - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.AWAITING_YOUR_CONFIRMATION) - }) - it('It should return AWAITING_CONFIRMATIONS if the tx has confirmations bellow the threshold, the user is not owner', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const makeUser = Record({ - owner: '', - type: '', - hash: '', - signature: '', - }) - - const transaction = makeTransaction({ confirmations: List([makeUser({ owner: userAddress })]) }) - const safe = makeSafe({ threshold: 3, owners: List([{ name: '', address: userAddress }]) }) - const currentUser = userAddress2 - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.AWAITING_CONFIRMATIONS) - }) - it('It should return FAILED if the tx is not successful', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const makeUser = Record({ - owner: '', - type: '', - hash: '', - signature: '', - }) - - const transaction = makeTransaction({ - confirmations: List([makeUser({ owner: userAddress })]), - isSuccessful: false, - }) - const safe = makeSafe({ threshold: 3, owners: List([{ name: '', address: userAddress }]) }) - const currentUser = userAddress2 - - // when - const result = calculateTransactionStatus(transaction, safe, currentUser) - - // then - expect(result).toBe(TransactionStatus.FAILED) - }) -}) - -describe('calculateTransactionType', () => { - it('It should return TOKEN If the tx is a token transfer transaction', () => { - // given - const transaction = makeTransaction({ isTokenTransfer: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.TOKEN) - }) - it('It should return COLLECTIBLE If the tx is a collectible transfer transaction', () => { - // given - const transaction = makeTransaction({ isCollectibleTransfer: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.COLLECTIBLE) - }) - it('It should return SETTINGS If the tx is a modifySettings transaction', () => { - // given - const transaction = makeTransaction({ modifySettingsTx: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.SETTINGS) - }) - - it('It should return CANCELLATION If the tx is a cancellation transaction', () => { - // given - const transaction = makeTransaction({ isCancellationTx: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.CANCELLATION) - }) - - it('It should return CUSTOM If the tx is a custom transaction', () => { - // given - const transaction = makeTransaction({ customTx: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.CUSTOM) - }) - it('It should return CUSTOM If the tx is a creation transaction', () => { - // given - const transaction = makeTransaction({ creationTx: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.CREATION) - }) - it('It should return UPGRADE If the tx is an upgrade transaction', () => { - // given - const transaction = makeTransaction({ upgradeTx: true }) - - // when - const result = calculateTransactionType(transaction) - - // then - expect(result).toBe(TransactionTypes.UPGRADE) - }) -}) - -describe('buildTx', () => { - it('Returns a valid transaction', async () => { - // given - const cancelTx1 = { - baseGas: 0, - blockNumber: 0, - confirmations: [], - confirmationsRequired: 2, - data: null, - dataDecoded: undefined, - ethGasPrice: '0', - executionDate: null, - executor: '', - fee: '', - gasPrice: '', - gasToken: '', - gasUsed: 0, - isExecuted: false, - isSuccessful: true, - modified: '', - nonce: 0, - operation: 0, - origin: null, - refundReceiver: '', - safe: '', - safeTxGas: 0, - safeTxHash: '', - signatures: '', - submissionDate: null, - to: '', - transactionHash: null, - value: '', - } - const transaction = getMockedTxServiceModel({ to: safeAddress2, value: '0' }) - const userAddress = 'address1' - const cancellationTxs = List([cancelTx1]) - const token = makeToken({ - address: '0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', - name: 'OmiseGo', - symbol: 'OMG', - decimals: 18, - logoUri: - 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', - }) - const knownTokens = Map & Readonly>() - knownTokens.set('0x00Df91984582e6e96288307E9c2f20b38C8FeCE9', token) - const outgoingTxs = [cancelTx1] - const safeInstance = makeSafe({ name: 'LOADED SAFE', address: safeAddress }) - const expectedTx = makeTransaction({ - baseGas: 0, - blockNumber: 0, - cancelled: false, - confirmations: List([]), - creationTx: false, - customTx: false, - data: EMPTY_DATA, - dataDecoded: null, - decimals: 18, - decodedParams: null, - executionDate: '', - executionTxHash: '', - executor: '', - gasPrice: '', - gasToken: ZERO_ADDRESS, - isCancellationTx: false, - isCollectibleTransfer: false, - isExecuted: false, - isSuccessful: false, - isTokenTransfer: false, - modifySettingsTx: false, - multiSendTx: false, - nonce: 0, - operation: 0, - origin: '', - recipient: safeAddress2, - refundParams: null, - refundReceiver: ZERO_ADDRESS, - safeTxGas: 0, - safeTxHash: '', - setupData: '', - status: TransactionStatus.FAILED, - submissionDate: '', - symbol: 'ETH', - upgradeTx: false, - value: '0', - fee: '', - }) - - // when - const txResult = await buildTx({ - cancellationTxs, - currentUser: userAddress, - outgoingTxs, - safe: safeInstance, - tx: transaction, - }) - - // then - expect(txResult).toStrictEqual(expectedTx) - }) -}) - -describe('updateStoredTransactionsStatus', () => { - it('', () => { - // given - // when - // then - }) -}) - describe('generateSafeTxHash', () => { it('It should return a safe transaction hash', () => { // given diff --git a/src/logic/safe/store/actions/__tests__/utils.test.ts b/src/logic/safe/store/actions/__tests__/utils.test.ts index 549b93eb..82579f99 100644 --- a/src/logic/safe/store/actions/__tests__/utils.test.ts +++ b/src/logic/safe/store/actions/__tests__/utils.test.ts @@ -1,99 +1,158 @@ -import { getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils' -import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' -import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' -import { getMockedSafeInstance } from 'src/test/utils/safeHelper' -import { NonPayableTransactionObject } from 'src/types/contracts/types' +import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils' +import { getMockedSafeInstance, getMockedTxServiceModel } from 'src/test/utils/safeHelper' +import axios from 'axios' +import { buildTxServiceUrl } from 'src/logic/safe/transactions' -describe('Store actions utils > getNewTxNonce', () => { - it(`Should return nonce of a last transaction + 1 if passed nonce is less than last transaction or invalid`, async () => { - // Given - const lastTx = { nonce: 44 } as TxServiceModel - const safeInstance = { - methods: { - nonce: () => ({ - call: () => Promise.resolve('45'), - }), - }, - } +describe('shouldExecuteTransaction', () => { + it('It should return false if given a safe with a threshold > 1', async () => { + // given + const nonce = '0' + const threshold = '2' + const safeInstance = getMockedSafeInstance({ threshold }) + const lastTx = getMockedTxServiceModel({}) - // When - const nonce = await getNewTxNonce(lastTx, safeInstance as GnosisSafe) + // when + const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) - // Then - expect(nonce).toBe('45') + // then + expect(result).toBe(false) }) + it('It should return true if given a safe with a threshold === 1 and the previous transaction is already executed', async () => { + // given + const nonce = '1' + const threshold = '1' + const safeInstance = getMockedSafeInstance({ threshold, nonce }) + const lastTx = getMockedTxServiceModel({}) - it(`Should retrieve contract's instance nonce value as a fallback, if txNonce and lastTx are not valid`, async () => { - // Given + // when + const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) + + // then + expect(result).toBe(true) + }) + it('It should return true if given a safe with a threshold === 1 and the previous transaction is already executed', async () => { + // given + const nonce = '10' + const threshold = '1' + const safeInstance = getMockedSafeInstance({ threshold, nonce }) + const lastTx = getMockedTxServiceModel({ isExecuted: true }) + + // when + const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) + + // then + expect(result).toBe(true) + }) + it('It should return false if given a safe with a threshold === 1 and the previous transaction is not yet executed', async () => { + // given + const nonce = '10' + const threshold = '1' + const safeInstance = getMockedSafeInstance({ threshold }) + const lastTx = getMockedTxServiceModel({ isExecuted: false }) + + // when + const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) + + // then + expect(result).toBe(false) + }) +}) + +describe('getNewTxNonce', () => { + it('It should return 2 if given the last transaction with nonce 1', async () => { + // given + const safeInstance = getMockedSafeInstance({}) + const lastTx = getMockedTxServiceModel({ nonce: 1 }) + const expectedResult = '2' + + // when + const result = await getNewTxNonce(lastTx, safeInstance) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return 0 if given a safe with nonce 0 and no transactions should use safe contract instance for retrieving nonce', async () => { + // given + const safeNonce = '0' + const safeInstance = getMockedSafeInstance({ nonce: safeNonce }) + const expectedResult = '0' + const mockFnCall = jest.fn().mockImplementation(() => safeNonce) + const mockFnNonce = jest.fn().mockImplementation(() => ({ call: mockFnCall })) + + safeInstance.methods.nonce = mockFnNonce + + // when + const result = await getNewTxNonce(null, safeInstance) + + // then + expect(result).toBe(expectedResult) + expect(mockFnNonce).toHaveBeenCalled() + expect(mockFnCall).toHaveBeenCalled() + mockFnNonce.mockRestore() + mockFnCall.mockRestore() + }) + it('Given a Safe and the last transaction, should return nonce of the last transaction + 1', async () => { + // given + const safeInstance = getMockedSafeInstance({}) + const expectedResult = '11' + const lastTx = getMockedTxServiceModel({ nonce: 10 }) + + // when + const result = await getNewTxNonce(lastTx, safeInstance) + + // then + expect(result).toBe(expectedResult) + }) +}) + +jest.mock('axios') +jest.mock('console') +describe('getLastTx', () => { + afterAll(() => { + jest.unmock('axios') + jest.unmock('console') + }) + const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' + it('It should return the last transaction for a given a safe address', async () => { + // given + const lastTx = getMockedTxServiceModel({ nonce: 1 }) + const url = buildTxServiceUrl(safeAddress) + + // when + // @ts-ignore + axios.get.mockImplementationOnce(() => { + return { + data: { + results: [lastTx], + }, + } + }) + + const result = await getLastTx(safeAddress) + + // then + expect(result).toStrictEqual(lastTx) + expect(axios.get).toHaveBeenCalled() + expect(axios.get).toBeCalledWith(url, { params: { limit: 1 } }) + }) + it('If should return null If catches an error getting last transaction', async () => { + // given const lastTx = null - const safeInstance = { - methods: { - nonce: () => ({ - call: () => Promise.resolve('45'), - }), - }, - } + const url = buildTxServiceUrl(safeAddress) - // When - const nonce = await getNewTxNonce(lastTx, safeInstance as GnosisSafe) + // when + // @ts-ignore + axios.get.mockImplementationOnce(() => { + throw new Error() + }) + console.error = jest.fn() + const result = await getLastTx(safeAddress) + const spyConsole = jest.spyOn(console, 'error').mockImplementation() - // Then - expect(nonce).toBe('45') - }) -}) - -describe('Store actions utils > shouldExecuteTransaction', () => { - it(`should return false if there's a previous tx pending to be executed`, async () => { - // Given - const safeInstance = getMockedSafeInstance({}) - safeInstance.methods.getThreshold = () => - ({ - call: () => Promise.resolve('1'), - } as NonPayableTransactionObject) - - const nonce = '1' - const lastTx = { isExecuted: false } as TxServiceModel - - // When - const isExecution = await shouldExecuteTransaction(safeInstance as GnosisSafe, nonce, lastTx) - - // Then - expect(isExecution).toBeFalsy() - }) - - it(`should return false if threshold is greater than 1`, async () => { - // Given - const safeInstance = getMockedSafeInstance({}) - safeInstance.methods.getThreshold = () => - ({ - call: () => Promise.resolve('2'), - } as NonPayableTransactionObject) - - const nonce = '1' - const lastTx = { isExecuted: true } as TxServiceModel - - // When - const isExecution = await shouldExecuteTransaction(safeInstance as GnosisSafe, nonce, lastTx) - - // Then - expect(isExecution).toBeFalsy() - }) - - it(`should return true is threshold is 1 and previous tx is executed`, async () => { - // Given - const safeInstance = getMockedSafeInstance({ nonce: '1' }) - safeInstance.methods.getThreshold = () => - ({ - call: () => Promise.resolve('1'), - } as NonPayableTransactionObject) - - const nonce = '1' - const lastTx = { isExecuted: true } as TxServiceModel - - // When - const isExecution = await shouldExecuteTransaction(safeInstance as GnosisSafe, nonce, lastTx) - - // Then - expect(isExecution).toBeTruthy() + // then + expect(result).toStrictEqual(lastTx) + expect(axios.get).toHaveBeenCalled() + expect(axios.get).toBeCalledWith(url, { params: { limit: 1 } }) + expect(spyConsole).toHaveBeenCalled() }) }) diff --git a/src/logic/safe/store/actions/addIncomingTransactions.ts b/src/logic/safe/store/actions/addIncomingTransactions.ts deleted file mode 100644 index 012d6455..00000000 --- a/src/logic/safe/store/actions/addIncomingTransactions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const ADD_INCOMING_TRANSACTIONS = 'ADD_INCOMING_TRANSACTIONS' - -export const addIncomingTransactions = createAction(ADD_INCOMING_TRANSACTIONS) diff --git a/src/logic/safe/store/actions/addModuleTransactions.ts b/src/logic/safe/store/actions/addModuleTransactions.ts deleted file mode 100644 index 6c26cb59..00000000 --- a/src/logic/safe/store/actions/addModuleTransactions.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createAction } from 'redux-actions' -import { ModuleTxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions' - -export const ADD_MODULE_TRANSACTIONS = 'ADD_MODULE_TRANSACTIONS' - -export type AddModuleTransactionsAction = { - payload: { - safeAddress: string - modules: ModuleTxServiceModel[] - } -} - -export const addModuleTransactions = createAction(ADD_MODULE_TRANSACTIONS) diff --git a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts b/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts deleted file mode 100644 index bbb4c25b..00000000 --- a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts +++ /dev/null @@ -1,86 +0,0 @@ -import axios, { AxiosResponse } from 'axios' - -import { getSafeServiceBaseUrl } from 'src/config' -import { checksumAddress } from 'src/utils/checksumAddress' -import { Transaction } from 'src/logic/safe/store/models/types/transactions.d' - -export type ServiceUriParams = { - safeAddress: string - limit: number - offset: number - orderBy?: string // todo: maybe this should be key of MultiSigTransaction | keyof EthereumTransaction - queued?: boolean - trusted?: boolean -} - -type TransactionDTO = { - count: number - next?: string - previous?: string - results: Transaction[] -} - -const getAllTransactionsUri = (safeAddress: string): string => { - const address = checksumAddress(safeAddress) - return `${getSafeServiceBaseUrl(address)}/all-transactions/` -} - -const fetchAllTransactions = async ( - urlParams: ServiceUriParams, - eTag?: string, -): Promise<{ responseEtag?: string; results: Transaction[]; count?: number }> => { - const { safeAddress, limit, offset, orderBy, queued, trusted } = urlParams - try { - const url = getAllTransactionsUri(safeAddress) - - const config = { - params: { - limit, - offset, - orderBy, - queued, - trusted, - }, - headers: eTag ? { 'If-None-Match': eTag } : undefined, - } - - const response: AxiosResponse = await axios.get(url, config) - - if (response.data.count > 0) { - const { etag } = response.headers - - if (eTag !== etag) { - return { - responseEtag: etag, - results: response.data.results, - count: response.data.count, - } - } - } - } catch (err) { - if (!(err && err.response && err.response.status === 304)) { - console.error(`Requests for outgoing transactions for ${safeAddress || 'unknown'} failed with 404`, err) - } else { - // NOTE: this is the expected implementation, currently the backend is not returning 304. - // So I check if the returned etag is the same instead (see above) - } - } - return { responseEtag: eTag, results: [] } -} - -const etagsByPage = {} -export const loadAllTransactions = async ( - uriParams: ServiceUriParams, -): Promise<{ - transactions: Transaction[] - totalTransactionsAmount?: number -}> => { - const previousEtag = etagsByPage && etagsByPage[uriParams.offset] - const { responseEtag, results, count } = await fetchAllTransactions(uriParams, previousEtag) - etagsByPage[uriParams.offset] = responseEtag - - return { - transactions: results, - totalTransactionsAmount: count, - } -} diff --git a/src/logic/safe/store/actions/allTransactions/pagination.ts b/src/logic/safe/store/actions/allTransactions/pagination.ts deleted file mode 100644 index a1b2b237..00000000 --- a/src/logic/safe/store/actions/allTransactions/pagination.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createAction } from 'redux-actions' -import { Transaction } from '../../models/types/transactions.d' - -export const LOAD_MORE_TRANSACTIONS = 'LOAD_MORE_TRANSACTIONS' - -export type LoadMoreTransactionsAction = { - payload: { - safeAddress: string - transactions: Transaction[] - totalTransactionsAmount: number - } -} - -export const loadMore = createAction(LOAD_MORE_TRANSACTIONS) diff --git a/src/logic/safe/store/actions/fetchSafeCreationTx.ts b/src/logic/safe/store/actions/fetchSafeCreationTx.ts deleted file mode 100644 index 6504d226..00000000 --- a/src/logic/safe/store/actions/fetchSafeCreationTx.ts +++ /dev/null @@ -1,55 +0,0 @@ -import axios from 'axios' -import { List } from 'immutable' - -import { buildSafeCreationTxUrl } from 'src/logic/safe/utils/buildSafeCreationTxUrl' -import { addOrUpdateTransactions } from './transactions/addOrUpdateTransactions' -import { makeTransaction } from 'src/logic/safe/store/models/transaction' -import { TransactionTypes, TransactionStatus } from 'src/logic/safe/store/models/types/transaction' -import { web3ReadOnly } from 'src/logic/wallets/getWeb3' - -const getCreationTx = async (safeAddress) => { - const url = buildSafeCreationTxUrl(safeAddress) - const response = await axios.get(url) - return { - ...response.data, - creationTx: true, - nonce: null, - } -} - -const fetchSafeCreationTx = (safeAddress) => async (dispatch) => { - if (!safeAddress) return - const creationTxFetched = await getCreationTx(safeAddress) - - const { - created, - creationTx, - creator, - factoryAddress, - masterCopy, - setupData, - transactionHash, - type, - } = creationTxFetched - const txType = type || TransactionTypes.CREATION - const safeTxHash = web3ReadOnly.utils.toHex('this is the creation transaction') - - const creationTxAsRecord = makeTransaction({ - created, - creator, - factoryAddress, - masterCopy, - nonce: -1, - setupData, - creationTx, - executionTxHash: transactionHash, - type: txType, - safeTxHash, - status: TransactionStatus.SUCCESS, - submissionDate: created, - }) - - dispatch(addOrUpdateTransactions({ safeAddress, transactions: List([creationTxAsRecord]) })) -} - -export default fetchSafeCreationTx diff --git a/src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions.ts b/src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions.ts deleted file mode 100644 index cf156eed..00000000 --- a/src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS = 'ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS' - -export const addOrUpdateCancellationTransactions = createAction(ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS) diff --git a/src/logic/safe/store/actions/transactions/addOrUpdateTransactions.ts b/src/logic/safe/store/actions/transactions/addOrUpdateTransactions.ts deleted file mode 100644 index 8d6cb275..00000000 --- a/src/logic/safe/store/actions/transactions/addOrUpdateTransactions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const ADD_OR_UPDATE_TRANSACTIONS = 'ADD_OR_UPDATE_TRANSACTIONS' - -export const addOrUpdateTransactions = createAction(ADD_OR_UPDATE_TRANSACTIONS) diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions.ts deleted file mode 100644 index a1cf32df..00000000 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions.ts +++ /dev/null @@ -1,69 +0,0 @@ -import axios from 'axios' - -import { buildTxServiceUrl } from 'src/logic/safe/transactions' -import { buildIncomingTxServiceUrl } from 'src/logic/safe/transactions/incomingTxHistory' -import { buildModuleTxServiceUrl } from 'src/logic/safe/transactions/moduleTxHistory' -import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' -import { IncomingTxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions' -import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import { ModuleTxServiceModel } from './loadModuleTransactions' - -const getServiceUrl = (txType: string, safeAddress: string): string => { - return { - [TransactionTypes.INCOMING]: buildIncomingTxServiceUrl, - [TransactionTypes.OUTGOING]: buildTxServiceUrl, - [TransactionTypes.MODULE]: buildModuleTxServiceUrl, - }[txType](safeAddress) -} - -// TODO: Remove this magic -/* eslint-disable */ -async function fetchTransactions( - txType: TransactionTypes.MODULE, - safeAddress: string, - eTag: string | null, -): Promise<{ eTag: string | null; results: ModuleTxServiceModel[] }> -async function fetchTransactions( - txType: TransactionTypes.INCOMING, - safeAddress: string, - eTag: string | null, -): Promise<{ eTag: string | null; results: IncomingTxServiceModel[] }> -async function fetchTransactions( - txType: TransactionTypes.OUTGOING, - safeAddress: string, - eTag: string | null, -): Promise<{ eTag: string | null; results: TxServiceModel[] }> -async function fetchTransactions( - txType: TransactionTypes.MODULE | TransactionTypes.INCOMING | TransactionTypes.OUTGOING, - safeAddress: string, - eTag: string | null, -): Promise<{ eTag: string | null; results: ModuleTxServiceModel[] | TxServiceModel[] | IncomingTxServiceModel[] }> { - /* eslint-enable */ - try { - const url = getServiceUrl(txType, safeAddress) - const response = await axios.get(url, eTag ? { headers: { 'If-None-Match': eTag } } : undefined) - - if (response.data.count > 0) { - const { etag } = response.headers - - if (eTag !== etag) { - return { - eTag: etag, - results: response.data.results, - } - } - } - } catch (err) { - if (!(err && err.response && err.response.status === 304)) { - console.error(`Requests for outgoing transactions for ${safeAddress || 'unknown'} failed with 404`, err) - } else { - // NOTE: this is the expected implementation, currently the backend is not returning 304. - // So I check if the returned etag is the same instead (see above) - } - } - - // defaults to an empty array to avoid type errors - return { eTag, results: [] } -} - -export default fetchTransactions diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadGatewayTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadGatewayTransactions.ts index 15c002c5..1530da4b 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadGatewayTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadGatewayTransactions.ts @@ -42,15 +42,25 @@ export const loadPagedHistoryTransactions = async ( export const loadHistoryTransactions = async (safeAddress: string): Promise => { const historyTransactionsUrl = getHistoryTransactionsUrl(safeAddress) - const { - data: { results, ...pointers }, - } = await axios.get>(historyTransactionsUrl) + try { + const { + data: { results, ...pointers }, + } = await axios.get>(historyTransactionsUrl) - if (!historyPointers[safeAddress]) { - historyPointers[safeAddress] = pointers + if (!historyPointers[safeAddress]) { + historyPointers[safeAddress] = pointers + } + + return results + } catch (error) { + // When the safe is just created there is a delay until the gateway recognize the + // safe address, when that happens it returns 404. + if (error.response.status === 404) { + return [] + } + + throw Error(`There was an error trying to fetch history txs from safeAddress ${safeAddress}`) } - - return results } /************/ @@ -90,14 +100,23 @@ export const loadPagedQueuedTransactions = async ( export const loadQueuedTransactions = async (safeAddress: string): Promise => { const queuedTransactionsUrl = getQueuedTransactionsUrl(safeAddress) + try { + const { + data: { results, ...pointers }, + } = await axios.get>(queuedTransactionsUrl) - const { - data: { results, ...pointers }, - } = await axios.get>(queuedTransactionsUrl) + if (!queuedPointers[safeAddress] || queuedPointers[safeAddress].next === null) { + queuedPointers[safeAddress] = pointers + } - if (!queuedPointers[safeAddress] || queuedPointers[safeAddress].next === null) { - queuedPointers[safeAddress] = pointers + return results + } catch (error) { + // When the safe is just created there is a delay until the gateway recognize the + // safe address, when that happens it returns 404. + if (error.response.status === 404) { + return [] + } + + throw Error(`There was an error trying to fetch queued txs from safeAddress ${safeAddress}`) } - - return results } diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts deleted file mode 100644 index 2a8d8bab..00000000 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts +++ /dev/null @@ -1,103 +0,0 @@ -import bn from 'bignumber.js' -import { List, Map } from 'immutable' -import { Transaction, TransactionReceipt } from 'web3-core' -import { AbiItem } from 'web3-utils' - -import { getNetworkInfo } from 'src/config' -import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' -import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi' -import { web3ReadOnly } from 'src/logic/wallets/getWeb3' -import { makeIncomingTransaction } from 'src/logic/safe/store/models/incomingTransaction' -import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions' -import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import { isENSContract } from 'src/logic/collectibles/utils' - -export type IncomingTxServiceModel = { - blockNumber: number - transactionHash: string - to: string - value: number - tokenAddress: string - from: string -} - -const buildIncomingTransactionFrom = ([tx, symbol, decimals, fee]: [ - IncomingTxServiceModel, - string, - number, - string, -]) => { - // this is a particular treatment for the DCD token, as it seems to lack of symbol and decimal methods - if (tx.tokenAddress && tx.tokenAddress.toLowerCase() === '0xe0b7927c4af23765cb51314a0e0521a9645f0e2a') { - symbol = 'DCD' - decimals = 9 - } - - const { transactionHash, ...incomingTx } = tx - - return makeIncomingTransaction({ - ...incomingTx, - symbol, - decimals, - fee, - executionTxHash: transactionHash, - safeTxHash: transactionHash, - }) -} - -const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { - const batch = new web3ReadOnly.BatchRequest() - const { nativeCoin } = getNetworkInfo() - - const whenTxsValues = txs.map((tx) => { - const methods = [ - 'symbol', - 'decimals', - { method: 'getTransaction', args: [tx.transactionHash], type: 'eth' }, - { method: 'getTransactionReceipt', args: [tx.transactionHash], type: 'eth' }, - ] - - return generateBatchRequests< - [ - IncomingTxServiceModel, - string | undefined, - string | undefined, - Transaction | undefined, - TransactionReceipt | undefined, - ] - >({ - abi: ALTERNATIVE_TOKEN_ABI as AbiItem[], - address: tx.tokenAddress, - batch, - context: tx, - methods, - }) - }) - - batch.execute() - - return Promise.all(whenTxsValues).then((txsValues) => - txsValues.map(([tx, symbolFetched, decimals, ethTx, ethTxReceipt]) => { - let symbol = symbolFetched - if (!symbolFetched) { - symbol = isENSContract(tx.tokenAddress) ? 'ENS' : nativeCoin.symbol - } - return [ - tx, - symbol, - decimals ? decimals : nativeCoin.decimals, - new bn(ethTx?.gasPrice ?? 0).times(ethTxReceipt?.gasUsed ?? 0), - ] - }), - ) -} - -let previousETag: string | null = null -export const loadIncomingTransactions = async (safeAddress: string): Promise>> => { - const { eTag, results } = await fetchTransactions(TransactionTypes.INCOMING, safeAddress, previousETag) - previousETag = eTag - - const incomingTxsWithData = await batchIncomingTxsTokenDataRequest(results) - const incomingTxsRecord = incomingTxsWithData.map(buildIncomingTransactionFrom) - return Map({ [safeAddress]: List(incomingTxsRecord) }) -} diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions.ts deleted file mode 100644 index 7dd1b7b7..00000000 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions.ts +++ /dev/null @@ -1,35 +0,0 @@ -import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions' -import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import { DataDecoded, Operation } from 'src/logic/safe/store/models/types/transactions.d' - -export type ModuleTxServiceModel = { - created: string - executionDate: string - blockNumber: number - transactionHash: string - safe: string - module: string - to: string - value: string - data: string - operation: Operation - dataDecoded: DataDecoded -} - -type ETag = string | null - -let previousETag: ETag = null -export const loadModuleTransactions = async (safeAddress: string): Promise => { - if (!safeAddress) { - return [] - } - - const { eTag, results }: { eTag: ETag; results: ModuleTxServiceModel[] } = await fetchTransactions( - TransactionTypes.MODULE, - safeAddress, - previousETag, - ) - previousETag = eTag - - return results -} diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts index 299d6205..0dc51f08 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions.ts @@ -1,14 +1,6 @@ -import { fromJS, List, Map } from 'immutable' +import { List } from 'immutable' -import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' -import { CancellationTransactions } from 'src/logic/safe/store/reducer/cancellationTransactions' -import { web3ReadOnly } from 'src/logic/wallets/getWeb3' -import { PROVIDER_REDUCER_ID } from 'src/logic/wallets/store/reducer/provider' -import { buildTx, isCancelTransaction } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' -import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe' -import { store } from 'src/store' -import fetchTransactions from 'src/logic/safe/store/actions/transactions/fetchTransactions/fetchTransactions' -import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' +import { Transaction } from 'src/logic/safe/store/models/types/transaction' import { SafeRecord } from 'src/logic/safe/store/models/safe' import { DataDecoded } from 'src/logic/safe/store/models/types/transactions.d' @@ -52,13 +44,8 @@ export type TxServiceModel = { value: string } -export type SafeTransactionsType = { - cancel: any - outgoing: any -} - export type OutgoingTxs = { - cancellationTxs: Record | CancellationTransactions + cancellationTxs: Record outgoingTxs: TxServiceModel[] | List } @@ -66,161 +53,3 @@ export type BatchProcessTxsProps = OutgoingTxs & { currentUser?: string safe: SafeRecord } - -/** - * Differentiates outgoing transactions from its cancel ones and returns a split map - * @param {string} safeAddress - safe's Ethereum Address - * @param {TxServiceModel[]} outgoingTxs - collection of transactions (usually, returned by the /transactions service) - * @returns {any|{cancellationTxs: {}, outgoingTxs: []}} - */ -const extractCancelAndOutgoingTxs = (safeAddress: string, outgoingTxs: TxServiceModel[]): OutgoingTxs => { - return outgoingTxs.reduce( - (acc: { cancellationTxs: Record; outgoingTxs: TxServiceModel[] }, transaction) => { - if ( - isCancelTransaction(transaction, safeAddress) && - outgoingTxs.find((tx) => tx.nonce === transaction.nonce && !isCancelTransaction(tx, safeAddress)) - ) { - if (!isNaN(Number(transaction.nonce))) { - acc.cancellationTxs[transaction.nonce] = transaction - } - } else { - acc.outgoingTxs = [...acc.outgoingTxs, transaction] - } - return acc - }, - { - cancellationTxs: {}, - outgoingTxs: [], - }, - ) -} - -type BatchRequestReturnValues = [TxServiceModel | Transaction, string | undefined] - -/** - * Requests Contract's code for all the Contracts the Safe has interacted with - * @param transactions - * @returns {Promise<[Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>, Promise<*[]>]>} - */ -const batchRequestContractCode = ( - transactions: (TxServiceModel | Transaction)[], -): Promise => { - if (!transactions || !Array.isArray(transactions)) { - throw new Error('`transactions` must be provided in order to lookup information') - } - - const batch = new web3ReadOnly.BatchRequest() - - // this will no longer be used when txs-list-v2 feature is finished - // that's why I'm doing this to move forward - const whenTxsValues = (transactions as any[]).map((tx) => { - return generateBatchRequests({ - abi: [], - address: tx.to, - batch, - context: tx, - methods: [{ method: 'getCode', type: 'eth', args: [tx.to] }], - }) - }) - - batch.execute() - - return Promise.all(whenTxsValues) -} - -/** - * Receives a list of outgoing and its cancellation transactions and builds the tx object that will be store - * @param cancellationTxs - * @param currentUser - * @param knownTokens - * @param outgoingTxs - * @param safe - * @returns {Promise<{cancel: {}, outgoing: []}>} - */ -const batchProcessOutgoingTransactions = async ({ - cancellationTxs, - currentUser, - outgoingTxs, - safe, -}: BatchProcessTxsProps): Promise<{ - cancel: Record - outgoing: Transaction[] -}> => { - // cancellation transactions - const cancelTxsValues = List(Object.values(cancellationTxs)) - const cancellationTxsWithData = cancelTxsValues.size ? await batchRequestContractCode(cancelTxsValues.toArray()) : [] - - const cancel = {} - for (const [tx] of cancellationTxsWithData) { - cancel[`${tx.nonce}`] = await buildTx({ - cancellationTxs, - currentUser, - outgoingTxs, - safe, - tx, - }) - } - - // outgoing transactions - const outgoingTxsList: List = - (outgoingTxs as TxServiceModel[]).length !== undefined - ? List(outgoingTxs as TxServiceModel[]) - : (outgoingTxs as List) - const outgoingTxsWithData = outgoingTxsList.size ? await batchRequestContractCode(outgoingTxsList.toArray()) : [] - - const outgoing: Transaction[] = [] - for (const [tx] of outgoingTxsWithData) { - outgoing.push( - await buildTx({ - cancellationTxs, - currentUser, - outgoingTxs, - safe, - tx, - }), - ) - } - - return { cancel, outgoing } -} - -let previousETag: string | null = null -export const loadOutgoingTransactions = async (safeAddress: string): Promise => { - const defaultResponse = { - cancel: Map(), - outgoing: List(), - } - const state = store.getState() - - if (!safeAddress) { - return defaultResponse - } - - const currentUser: string = state[PROVIDER_REDUCER_ID].get('account') - const safe: SafeRecord = state[SAFE_REDUCER_ID].getIn(['safes', safeAddress]) - - if (!safe) { - return defaultResponse - } - - const { eTag, results }: { eTag: string | null; results: TxServiceModel[] } = await fetchTransactions( - TransactionTypes.OUTGOING, - safeAddress, - previousETag, - ) - previousETag = eTag - const { cancellationTxs, outgoingTxs } = extractCancelAndOutgoingTxs(safeAddress, results) - - // this should be only used for the initial load or when paginating - const { cancel, outgoing } = await batchProcessOutgoingTransactions({ - cancellationTxs, - currentUser, - outgoingTxs, - safe, - }) - - return { - cancel: fromJS(cancel), - outgoing: fromJS(outgoing), - } -} diff --git a/src/logic/safe/store/actions/transactions/pendingTransactions.ts b/src/logic/safe/store/actions/transactions/pendingTransactions.ts deleted file mode 100644 index edb383fb..00000000 --- a/src/logic/safe/store/actions/transactions/pendingTransactions.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { List, Map } from 'immutable' -import { batch } from 'react-redux' -import { TransactionReceipt } from 'web3-core' - -import { addOrUpdateCancellationTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions' -import { addOrUpdateTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions' -import { removeCancellationTransaction } from 'src/logic/safe/store/actions/transactions/removeCancellationTransaction' -import { removeTransaction } from 'src/logic/safe/store/actions/transactions/removeTransaction' -import { Dispatch } from 'src/logic/safe/store/actions/types.d' -import { makeConfirmation } from 'src/logic/safe/store/models/confirmation' -import { Transaction, TransactionStatus } from 'src/logic/safe/store/models/types/transaction' -import { safeTransactionsSelector } from 'src/logic/safe/store/selectors' -import { sameAddress } from 'src/logic/wallets/ethAddresses' -import { web3ReadOnly } from 'src/logic/wallets/getWeb3' -import { AppReduxState } from 'src/store' - -type SetPendingTransactionParams = { - transaction: Transaction - from: string -} - -const setTxStatusAsPending = ({ transaction, from }: SetPendingTransactionParams): Transaction => - transaction.withMutations((transaction) => { - transaction - // setting user as the one who has triggered the tx - // this allows to display the owner's "pending" status - .updateIn(['ownersWithPendingActions', transaction.isCancellationTx ? 'reject' : 'confirm'], (previous) => - previous.push(from), - ) - // global transaction status - .set('status', TransactionStatus.PENDING) - }) - -type SetOptimisticTransactionParams = { - transaction: Transaction - from: string - isExecution: boolean - receipt: TransactionReceipt -} - -const updateTxBasedOnReceipt = ({ - transaction, - from, - isExecution, - receipt, -}: SetOptimisticTransactionParams): Transaction => { - const txToStore = isExecution - ? transaction.withMutations((tx) => { - tx.set('executionTxHash', receipt.transactionHash) - .set('blockNumber', receipt.blockNumber) - .set('executionDate', tx.submissionDate) - .set('fee', web3ReadOnly.utils.toWei(`${receipt.gasUsed}`, 'gwei')) - .set('executor', from) - .set('isExecuted', true) - .set('isSuccessful', receipt.status) - .set('status', receipt.status ? TransactionStatus.SUCCESS : TransactionStatus.FAILED) - }) - : transaction.set('status', TransactionStatus.AWAITING_CONFIRMATIONS) - - return txToStore.withMutations((tx) => { - const senderHasAlreadyConfirmed = tx.confirmations.findIndex(({ owner }) => sameAddress(owner, from)) !== -1 - - if (!senderHasAlreadyConfirmed) { - // updates confirmations status - tx.update('confirmations', (confirmations) => confirmations.push(makeConfirmation({ owner: from }))) - } - - tx.updateIn(['ownersWithPendingActions', 'reject'], (prev) => prev.clear()).updateIn( - ['ownersWithPendingActions', 'confirm'], - (prev) => prev.clear(), - ) - }) -} - -type StoreTxParams = { - transaction: Transaction - safeAddress: string - dispatch: Dispatch - state: AppReduxState -} - -export const storeTx = async ({ transaction, safeAddress, dispatch, state }: StoreTxParams): Promise => { - if (transaction.isCancellationTx) { - // `transaction` is the Cancellation tx - // So we need to decide the `status` for the main transaction this `transaction` is cancelling - let status: TransactionStatus = TransactionStatus.AWAITING_YOUR_CONFIRMATION - // `cancelled`, will become true if its corresponding Cancellation tx was successfully executed - let cancelled = false - - switch (transaction.status) { - case TransactionStatus.SUCCESS: - status = TransactionStatus.CANCELLED - cancelled = true - break - case TransactionStatus.PENDING: - status = TransactionStatus.PENDING - break - default: - break - } - - const safeTransactions = safeTransactionsSelector(state) - - const transactions = safeTransactions.withMutations((txs) => { - const txIndex = txs.findIndex(({ nonce }) => Number(nonce) === Number(transaction.nonce)) - txs.update(txIndex, (tx) => tx.set('status', status).set('cancelled', cancelled)) - }) - - batch(() => { - dispatch( - addOrUpdateCancellationTransactions({ - safeAddress, - transactions: Map({ [`${transaction.nonce}`]: transaction }), - }), - ) - dispatch(addOrUpdateTransactions({ safeAddress, transactions })) - }) - } else { - dispatch(addOrUpdateTransactions({ safeAddress, transactions: List([transaction]) })) - } -} - -type StoreSignedTxParams = StoreTxParams & { - from: string - isExecution: boolean -} - -export const storeSignedTx = ({ transaction, from, isExecution, ...rest }: StoreSignedTxParams): Promise => - storeTx({ - transaction: isExecution ? setTxStatusAsPending({ transaction, from }) : transaction, - ...rest, - }) - -type StoreExecParams = StoreTxParams & { - from: string - isExecution: boolean - safeAddress: string - receipt: TransactionReceipt -} - -export const storeExecutedTx = ({ safeAddress, dispatch, state, ...rest }: StoreExecParams): Promise => - storeTx({ - transaction: updateTxBasedOnReceipt({ ...rest }), - safeAddress, - dispatch, - state, - }) - -export const removeTxFromStore = ( - transaction: Transaction, - safeAddress: string, - dispatch: Dispatch, - state: AppReduxState, -): void => { - if (transaction.isCancellationTx) { - const safeTransactions = safeTransactionsSelector(state) - const transactions = safeTransactions.withMutations((txs) => { - const txIndex = txs.findIndex(({ nonce }) => Number(nonce) === Number(transaction.nonce)) - txs[txIndex].set('status', TransactionStatus.AWAITING_YOUR_CONFIRMATION) - }) - - batch(() => { - dispatch(addOrUpdateTransactions({ safeAddress, transactions })) - dispatch(removeCancellationTransaction({ safeAddress, transaction })) - }) - } else { - dispatch(removeTransaction({ safeAddress, transaction })) - } -} diff --git a/src/logic/safe/store/actions/transactions/removeCancellationTransaction.ts b/src/logic/safe/store/actions/transactions/removeCancellationTransaction.ts deleted file mode 100644 index 985f313a..00000000 --- a/src/logic/safe/store/actions/transactions/removeCancellationTransaction.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const REMOVE_CANCELLATION_TRANSACTION = 'REMOVE_CANCELLATION_TRANSACTION' - -export const removeCancellationTransaction = createAction(REMOVE_CANCELLATION_TRANSACTION) diff --git a/src/logic/safe/store/actions/transactions/removeTransaction.ts b/src/logic/safe/store/actions/transactions/removeTransaction.ts deleted file mode 100644 index 3a84f3d4..00000000 --- a/src/logic/safe/store/actions/transactions/removeTransaction.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createAction } from 'redux-actions' - -export const REMOVE_TRANSACTION = 'REMOVE_TRANSACTION' - -export const removeTransaction = createAction(REMOVE_TRANSACTION) diff --git a/src/logic/safe/store/actions/transactions/utils/addMockSafeCreationTx.ts b/src/logic/safe/store/actions/transactions/utils/addMockSafeCreationTx.ts deleted file mode 100644 index 8543f5cb..00000000 --- a/src/logic/safe/store/actions/transactions/utils/addMockSafeCreationTx.ts +++ /dev/null @@ -1,27 +0,0 @@ -const addMockSafeCreationTx = (safeAddress: string) => [ - { - blockNumber: null, - baseGas: 0, - confirmations: [], - data: null, - executionDate: null, - gasPrice: 0, - gasToken: '0x0000000000000000000000000000000000000000', - isExecuted: true, - nonce: null, - operation: 0, - refundReceiver: '0x0000000000000000000000000000000000000000', - safe: safeAddress, - safeTxGas: 0, - safeTxHash: '', - signatures: null, - submissionDate: null, - executor: '', - to: '', - transactionHash: null, - value: 0, - creationTx: true, - }, -] - -export default addMockSafeCreationTx diff --git a/src/logic/safe/store/actions/transactions/utils/newTransactionsHelpers.ts b/src/logic/safe/store/actions/transactions/utils/newTransactionsHelpers.ts deleted file mode 100644 index 9a93ed00..00000000 --- a/src/logic/safe/store/actions/transactions/utils/newTransactionsHelpers.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Transaction, TxType } from 'src/logic/safe/store/models/types/transactions.d' - -export const isMultiSigTx = (tx: Transaction): boolean => { - return TxType[tx.txType] === TxType.MULTISIG_TRANSACTION -} -export const isModuleTx = (tx: Transaction): boolean => { - return TxType[tx.txType] === TxType.MODULE_TRANSACTION -} -export const isEthereumTx = (tx: Transaction): boolean => { - return TxType[tx.txType] === TxType.ETHEREUM_TRANSACTION -} diff --git a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts index e14a0f3b..62238891 100644 --- a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts +++ b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts @@ -1,105 +1,17 @@ -import { List } from 'immutable' import { getNetworkInfo } from 'src/config' -import { getERC20DecimalsAndSymbol, isSendERC20Transaction } from 'src/logic/tokens/utils/tokenHelpers' -import { getERC721Symbol, isSendERC721Transaction } from 'src/logic/collectibles/utils' -import { isEmptyAddress, sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' +import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { makeConfirmation } from 'src/logic/safe/store/models/confirmation' -import { Confirmation } from 'src/logic/safe/store/models/types/confirmation' -import { makeTransaction } from 'src/logic/safe/store/models/transaction' -import { - Transaction, - TransactionStatus, - TransactionStatusValues, - TransactionTypes, - TransactionTypeValues, - TxArgs, - RefundParams, - isStoredTransaction, -} from 'src/logic/safe/store/models/types/transaction' -import { AppReduxState, store } from 'src/store' -import { - safeSelector, - safeTransactionsSelector, - safeCancellationTransactionsSelector, -} from 'src/logic/safe/store/selectors' -import { addOrUpdateTransactions } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions' +import { Transaction, TxArgs, RefundParams } from 'src/logic/safe/store/models/types/transaction' import { BatchProcessTxsProps, TxServiceModel, } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' import { TypedDataUtils } from 'eth-sig-util' -import { ProviderRecord } from 'src/logic/wallets/store/model/provider' -import { SafeRecord } from 'src/logic/safe/store/models/safe' -import { DecodedParams } from 'src/routes/safe/store/models/types/transactions.d' -import { CALL } from 'src/logic/safe/transactions' export const isEmptyData = (data?: string | null): boolean => { return !data || data === EMPTY_DATA } -export const isInnerTransaction = (tx: BuildTx['tx'] | Transaction, safeAddress: string): boolean => { - let isSameAddress = false - - if ((tx as TxServiceModel).to !== undefined) { - isSameAddress = sameAddress((tx as TxServiceModel).to, safeAddress) - } else if ((tx as Transaction).recipient !== undefined) { - isSameAddress = sameAddress((tx as Transaction).recipient, safeAddress) - } - - return isSameAddress && Number(tx.value) === 0 -} - -export const isCancelTransaction = (tx: BuildTx['tx'], safeAddress: string): boolean => { - if (isStoredTransaction(tx)) { - if (!sameAddress(tx.recipient, safeAddress)) { - return false - } - } else { - if (!sameAddress(tx.to, safeAddress)) { - return false - } - } - - if (Number(tx.value)) { - return false - } - - if (tx.data && !isEmptyData(tx.data)) { - return false - } - - if (tx.operation !== CALL) { - return false - } - - if (tx.baseGas) { - return false - } - - if (Number(tx.gasPrice)) { - return false - } - - if (tx.gasToken && !isEmptyAddress(tx.gasToken)) { - return false - } - - if (tx.refundReceiver && !isEmptyAddress(tx.refundReceiver)) { - return false - } - - return true -} - -export const isPendingTransaction = (tx: Transaction, cancelTx: Transaction): boolean => { - return (!!cancelTx && cancelTx.status === 'pending') || tx.status === 'pending' -} - -export const isModifySettingsTransaction = (tx: BuildTx['tx'], safeAddress: string): boolean => { - return isInnerTransaction(tx, safeAddress) && !isEmptyData(tx.data) -} - export const isMultiSendTransaction = (tx: BuildTx['tx']): boolean => { return !isEmptyData(tx.data) && tx.data?.substring(0, 10) === '0x8d80ff0a' && Number(tx.value) === 0 } @@ -113,19 +25,6 @@ export const isUpgradeTransaction = (tx: BuildTx['tx']): boolean => { ) } -export const isOutgoingTransaction = (tx: BuildTx['tx'], safeAddress?: string): boolean => { - return !sameAddress((tx as ServiceTx).to, safeAddress) && !isEmptyData(tx.data) -} - -export const isCustomTransaction = async (tx: BuildTx['tx'], safeAddress?: string): Promise => { - const isOutgoing = isOutgoingTransaction(tx, safeAddress) - const isErc20 = await isSendERC20Transaction(tx) - const isUpgrade = isUpgradeTransaction(tx) - const isErc721 = isSendERC721Transaction(tx) - - return isOutgoing && !isErc20 && !isUpgrade && !isErc721 -} - export const getRefundParams = async ( tx: BuildTx['tx'], tokenInfo: (string) => Promise<{ decimals: number; symbol: string } | null>, @@ -162,224 +61,14 @@ export const getRefundParams = async ( return refundParams } -export const getDecodedParams = (tx: BuildTx['tx']): DecodedParams | null => { - if (tx.dataDecoded) { - return { - [tx.dataDecoded.method]: tx.dataDecoded.parameters.reduce( - (acc, param) => ({ - ...acc, - [param.name]: param.value, - }), - {}, - ), - } - } - return null -} - -export const getConfirmations = (tx: BuildTx['tx']): List => { - return List( - (tx.confirmations as ServiceTx['confirmations'])?.map((conf) => - makeConfirmation({ - owner: conf.owner, - hash: conf.transactionHash, - signature: conf.signature, - }), - ) ?? [], - ) -} - -export const isTransactionCancelled = ( - tx: BuildTx['tx'], - outgoingTxs: BuildTx['outgoingTxs'], - cancellationTxs: BuildTx['cancellationTxs'], -): boolean => { - return ( - // not executed - !tx.isExecuted && - // there's an executed cancel tx, with same nonce - ((tx.nonce && !!cancellationTxs[tx.nonce] && cancellationTxs[tx.nonce].isExecuted) || - // there's an executed tx, with same nonce - outgoingTxs.some((outgoingTx) => tx.nonce === outgoingTx.nonce && outgoingTx.isExecuted)) - ) -} - -export const calculateTransactionStatus = ( - tx: Transaction, - { owners, threshold, nonce }: SafeRecord, - currentUser?: string | null, -): TransactionStatusValues => { - let txStatus - - 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.isPending) { - txStatus = TransactionStatus.PENDING - } else { - const userConfirmed = tx.confirmations.filter((conf) => conf.owner === currentUser).size === 1 - const userIsSafeOwner = owners.filter((owner) => owner.address === currentUser).size === 1 - txStatus = - !userConfirmed && userIsSafeOwner - ? TransactionStatus.AWAITING_YOUR_CONFIRMATION - : TransactionStatus.AWAITING_CONFIRMATIONS - } - - if (tx.isSuccessful === false) { - txStatus = TransactionStatus.FAILED - } - - return txStatus -} - -export const calculateTransactionType = (tx: Transaction): TransactionTypeValues => { - let txType = TransactionTypes.OUTGOING - - if (tx.isTokenTransfer) { - txType = TransactionTypes.TOKEN - } else if (tx.isCollectibleTransfer) { - txType = TransactionTypes.COLLECTIBLE - } else if (tx.modifySettingsTx) { - txType = TransactionTypes.SETTINGS - } else if (tx.isCancellationTx) { - txType = TransactionTypes.CANCELLATION - } else if (tx.customTx) { - txType = TransactionTypes.CUSTOM - } else if (tx.creationTx) { - txType = TransactionTypes.CREATION - } else if (tx.upgradeTx) { - txType = TransactionTypes.UPGRADE - } - - return txType -} - export type ServiceTx = TxServiceModel | TxToMock export type BuildTx = BatchProcessTxsProps & { tx: ServiceTx | Transaction } -export const buildTx = async ({ - cancellationTxs, - currentUser, - outgoingTxs, - safe, - tx, -}: BuildTx): Promise => { - const safeAddress = safe.address - const { nativeCoin } = getNetworkInfo() - const isModifySettingsTx = isModifySettingsTransaction(tx, safeAddress) - const isTxCancelled = isTransactionCancelled(tx, outgoingTxs, cancellationTxs) - const isSendERC721Tx = isSendERC721Transaction(tx) - const isSendERC20Tx = await isSendERC20Transaction(tx) - const isMultiSendTx = isMultiSendTransaction(tx) - const isUpgradeTx = isUpgradeTransaction(tx) - const isCustomTx = await isCustomTransaction(tx, safeAddress) - const isCancellationTx = isCancelTransaction(tx, safeAddress) - const refundParams = await getRefundParams(tx, getERC20DecimalsAndSymbol) - const decodedParams = getDecodedParams(tx) - const confirmations = getConfirmations(tx) - - let tokenDecimals = nativeCoin.decimals - let tokenSymbol = nativeCoin.symbol - try { - if (isSendERC20Tx) { - const { decimals, symbol } = await getERC20DecimalsAndSymbol((tx as ServiceTx).to) - tokenDecimals = decimals - tokenSymbol = symbol - } else if (isSendERC721Tx) { - tokenSymbol = await getERC721Symbol((tx as ServiceTx).to) - } - } catch (err) { - console.log(`Failed to retrieve token data from ${(tx as ServiceTx).to}`) - } - - const txToStore = makeTransaction({ - baseGas: tx.baseGas, - blockNumber: (tx as ServiceTx).blockNumber, - cancelled: isTxCancelled, - confirmations, - customTx: isCustomTx, - data: tx.data ? tx.data : EMPTY_DATA, - dataDecoded: tx.dataDecoded, - decimals: tokenDecimals, - decodedParams, - executionDate: (tx as ServiceTx).executionDate, - executionTxHash: (tx as ServiceTx).transactionHash, - executor: (tx as ServiceTx).executor, - fee: (tx as ServiceTx).fee, - gasPrice: tx.gasPrice, - gasToken: tx.gasToken || ZERO_ADDRESS, - isCancellationTx, - isCollectibleTransfer: isSendERC721Tx, - isExecuted: tx.isExecuted, - isSuccessful: (tx as ServiceTx).isSuccessful, - isTokenTransfer: isSendERC20Tx, - modifySettingsTx: isModifySettingsTx, - multiSendTx: isMultiSendTx, - nonce: tx.nonce, - operation: tx.operation, - origin: (tx as ServiceTx).origin, - recipient: (tx as ServiceTx).to, - refundParams, - refundReceiver: tx.refundReceiver || ZERO_ADDRESS, - safeTxGas: tx.safeTxGas, - safeTxHash: tx.safeTxHash, - submissionDate: tx.submissionDate, - symbol: tokenSymbol, - upgradeTx: isUpgradeTx, - value: tx.value?.toString(), - }) - - return txToStore - .set('status', calculateTransactionStatus(txToStore, safe, currentUser)) - .set('type', calculateTransactionType(txToStore)) -} - export type TxToMock = TxArgs & Partial -export const mockTransaction = (tx: TxToMock, safeAddress: string, state: AppReduxState): Promise => { - const safe = safeSelector(state) - const cancellationTxs = safeCancellationTransactionsSelector(state) - const outgoingTxs = safeTransactionsSelector(state) - - if (!safe) { - throw new Error('Failed to recover Safe from the store') - } - - return buildTx({ - cancellationTxs, - currentUser: undefined, - outgoingTxs, - safe, - tx, - }) -} - -export const updateStoredTransactionsStatus = (dispatch: (any) => void, walletRecord: ProviderRecord): void => { - const state = store.getState() - const safe = safeSelector(state) - - if (safe) { - const safeAddress = safe.address - const transactions = safeTransactionsSelector(state) - dispatch( - addOrUpdateTransactions({ - safeAddress, - transactions: transactions.withMutations((list) => - list.map((tx) => tx.set('status', calculateTransactionStatus(tx, safe, walletRecord.account))), - ), - }), - ) - } -} - export function generateSafeTxHash(safeAddress: string, txArgs: TxArgs): string { const messageTypes = { EIP712Domain: [{ type: 'address', name: 'verifyingContract' }], diff --git a/src/logic/safe/store/middleware/notificationsMiddleware.ts b/src/logic/safe/store/middleware/notificationsMiddleware.ts index 3f7972a3..f516a141 100644 --- a/src/logic/safe/store/middleware/notificationsMiddleware.ts +++ b/src/logic/safe/store/middleware/notificationsMiddleware.ts @@ -3,34 +3,19 @@ import { push } from 'connected-react-router' import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications' import closeSnackbarAction from 'src/logic/notifications/store/actions/closeSnackbar' import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { - getAwaitingTransactions, - getAwaitingGatewayTransactions, -} from 'src/logic/safe/transactions/awaitingTransactions' +import { getAwaitingGatewayTransactions } from 'src/logic/safe/transactions/awaitingTransactions' import { getSafeVersionInfo } from 'src/logic/safe/utils/safeVersion' import { isUserAnOwner } from 'src/logic/wallets/ethAddresses' import { userAccountSelector } from 'src/logic/wallets/store/selectors' import { grantedSelector } from 'src/routes/safe/container/selector' -import { ADD_INCOMING_TRANSACTIONS } from 'src/logic/safe/store/actions/addIncomingTransactions' -import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions' import { ADD_QUEUED_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/gatewayTransactions' -import updateSafe from 'src/logic/safe/store/actions/updateSafe' -import { - safeParamAddressFromStateSelector, - safesMapSelector, - safeCancellationTransactionsSelector, -} from 'src/logic/safe/store/selectors' +import { safeParamAddressFromStateSelector, safesMapSelector } from 'src/logic/safe/store/selectors' import { isTransactionSummary } from 'src/logic/safe/store/models/types/gateway.d' import { loadFromStorage, saveToStorage } from 'src/utils/storage' import { ADD_OR_UPDATE_SAFE } from '../actions/addOrUpdateSafe' -const watchedActions = [ - ADD_OR_UPDATE_TRANSACTIONS, - ADD_INCOMING_TRANSACTIONS, - ADD_OR_UPDATE_SAFE, - ADD_QUEUED_TRANSACTIONS, -] +const watchedActions = [ADD_OR_UPDATE_SAFE, ADD_QUEUED_TRANSACTIONS] const LAST_TIME_USED_LOGGED_IN_ID = 'LAST_TIME_USED_LOGGED_IN_ID' @@ -85,32 +70,6 @@ const notificationsMiddleware = (store) => (next) => async (action) => { const state = store.getState() switch (action.type) { - case ADD_OR_UPDATE_TRANSACTIONS: { - const { safeAddress, transactions } = action.payload - const userAddress: string = userAccountSelector(state) - const cancellationTransactions = safeCancellationTransactionsSelector(state) - const awaitingTransactions = getAwaitingTransactions(transactions, cancellationTransactions, userAddress) - const awaitingTxsSubmissionDateList = awaitingTransactions.map((tx) => tx.submissionDate) - - const safes = safesMapSelector(state) - const currentSafe = safes.get(safeAddress) - - if (!currentSafe || !isUserAnOwner(currentSafe, userAddress) || awaitingTransactions.size === 0) { - break - } - - const notificationKey = `${safeAddress}-awaiting` - - await sendAwaitingTransactionNotification( - dispatch, - safeAddress, - awaitingTxsSubmissionDateList, - notificationKey, - onNotificationClicked(dispatch, notificationKey, safeAddress), - ) - - break - } case ADD_QUEUED_TRANSACTIONS: { const { safeAddress, values } = action.payload const transactions = values.filter((tx) => isTransactionSummary(tx)).map((item) => item.transaction) @@ -138,23 +97,6 @@ const notificationsMiddleware = (store) => (next) => async (action) => { break } - case ADD_INCOMING_TRANSACTIONS: { - action.payload.forEach((incomingTransactions, safeAddress) => { - const { latestIncomingTxBlock } = state.safes.get('safes').get(safeAddress, {}) - - const newIncomingTransactions = incomingTransactions.filter((tx) => tx.blockNumber > latestIncomingTxBlock) - - dispatch( - updateSafe({ - address: safeAddress, - latestIncomingTxBlock: newIncomingTransactions.size - ? newIncomingTransactions.first().blockNumber - : latestIncomingTxBlock, - }), - ) - }) - break - } case ADD_OR_UPDATE_SAFE: { const state = store.getState() const { safe } = action.payload diff --git a/src/logic/safe/store/models/incomingTransaction.ts b/src/logic/safe/store/models/incomingTransaction.ts deleted file mode 100644 index 22e00f62..00000000 --- a/src/logic/safe/store/models/incomingTransaction.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Record } from 'immutable' - -export const INCOMING_TX_TYPES = { - INCOMING: 'INCOMING', - ERC721_TRANSFER: 'ERC721_TRANSFER', - ERC20_TRANSFER: 'ERC20_TRANSFER', - ETHER_TRANSFER: 'ETHER_TRANSFER', -} - -export const makeIncomingTransaction = Record({ - blockNumber: 0, - executionTxHash: '', - safeTxHash: '', - to: '', - value: 0, - tokenAddress: '', - from: '', - symbol: '', - decimals: 18, - fee: '', - executionDate: '', - type: 'INCOMING', - status: 'success', - nonce: null, - confirmations: null, - recipient: null, - data: null, - operation: null, - safeTxGas: null, - baseGas: null, - gasPrice: null, - gasToken: null, - refundReceiver: null, - isExecuted: null, - submissionDate: null, - executor: null, - cancelled: null, - modifySettingsTx: null, - cancellationTx: null, - customTx: null, - creationTx: null, - isTokenTransfer: null, - decodedParams: null, - refundParams: null, -}) diff --git a/src/logic/safe/store/models/transaction.ts b/src/logic/safe/store/models/transaction.ts deleted file mode 100644 index a0d3e21c..00000000 --- a/src/logic/safe/store/models/transaction.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { List, Map, Record } from 'immutable' - -import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' -import { - PendingActionType, - TransactionProps, - TransactionStatus, - TransactionTypes, -} from 'src/logic/safe/store/models/types/transaction' - -export const makeTransaction = Record({ - baseGas: 0, - blockNumber: 0, - cancelled: false, - confirmations: List([]), - created: '', - creator: '', - creationTx: false, - customTx: false, - data: null, - dataDecoded: null, - decimals: 18, - decodedParams: {}, - executionDate: '', - executionTxHash: undefined, - executor: '', - factoryAddress: '', - fee: null, - gasPrice: '0', - gasToken: ZERO_ADDRESS, - isCancellationTx: false, - isCollectibleTransfer: false, - isExecuted: false, - isPending: false, - isSuccessful: true, - isTokenTransfer: false, - masterCopy: '', - modifySettingsTx: false, - multiSendTx: false, - nonce: 0, - operation: 0, - origin: null, - ownersWithPendingActions: Map({ [PendingActionType.CONFIRM]: List([]), [PendingActionType.REJECT]: List([]) }), - recipient: '', - refundParams: null, - refundReceiver: ZERO_ADDRESS, - safeTxGas: 0, - safeTxHash: '', - setupData: '', - status: TransactionStatus.PENDING, - submissionDate: '', - symbol: '', - transactionHash: '', - type: TransactionTypes.OUTGOING, - upgradeTx: false, - value: '0', -}) diff --git a/src/logic/safe/store/models/types/transaction.ts b/src/logic/safe/store/models/types/transaction.ts index c69b6cf1..005e113c 100644 --- a/src/logic/safe/store/models/types/transaction.ts +++ b/src/logic/safe/store/models/types/transaction.ts @@ -1,15 +1,10 @@ import { List, Map, RecordOf } from 'immutable' -import { ModuleTxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions' -import { Token } from 'src/logic/tokens/store/model/token' import { Confirmation } from './confirmation' import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' -import { DataDecoded, Transfer } from './transactions' -import { DecodedParams } from 'src/routes/safe/store/models/types/transactions.d' -import { BuildTx } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' +import { DataDecoded, DecodedParams, Transfer } from './transactions.d' export enum TransactionTypes { - INCOMING = 'incoming', OUTGOING = 'outgoing', SETTINGS = 'settings', CUSTOM = 'custom', @@ -92,10 +87,6 @@ export type TransactionProps = { export type Transaction = RecordOf & Readonly -export const isStoredTransaction = (tx: BuildTx['tx']): tx is Transaction => { - return typeof (tx as Transaction).recipient !== 'undefined' -} - export type TxArgs = { baseGas: number data: string @@ -111,17 +102,3 @@ export type TxArgs = { to: string valueInWei: string } - -type SafeModuleCompatibilityTypes = { - nonce?: string // not required for this tx: added for compatibility - fee?: number // not required for this tx: added for compatibility - executionTxHash?: string // not required for this tx: added for compatibility - safeTxHash: string // table uses this key as a unique row identifier, added for compatibility -} - -export type SafeModuleTransaction = ModuleTxServiceModel & - SafeModuleCompatibilityTypes & { - status: TransactionStatus - type: TransactionTypes - tokenInfo?: Token - } diff --git a/src/logic/safe/store/models/types/transactions.d.ts b/src/logic/safe/store/models/types/transactions.d.ts index 4d753d61..335ca7a1 100644 --- a/src/logic/safe/store/models/types/transactions.d.ts +++ b/src/logic/safe/store/models/types/transactions.d.ts @@ -116,73 +116,6 @@ export interface Transfer { from: string } -export enum TxType { - MULTISIG_TRANSACTION = 'MULTISIG_TRANSACTION', - ETHEREUM_TRANSACTION = 'ETHEREUM_TRANSACTION', - MODULE_TRANSACTION = 'MODULE_TRANSACTION', -} - -export interface MultiSigTransaction { - safe: string - to: string - value: string - data: string | null - operation: number - gasToken: string - safeTxGas: number - baseGas: number - gasPrice: string - refundReceiver: string - nonce: number - executionDate: string | null - submissionDate: string - modified: string - blockNumber: number | null - transactionHash: string | null - safeTxHash: string - executor: string | null - isExecuted: boolean - isSuccessful: boolean | null - ethGasPrice: string | null - gasUsed: number | null - fee: string | null - origin: string | null - dataDecoded: DataDecoded | null - confirmationsRequired: number | null - confirmations: Confirmation[] - signatures: string | null - transfers: Transfer[] - txType: TxType.MULTISIG_TRANSACTION -} - -export interface ModuleTransaction { - created: string - executionDate: string - blockNumber: number - transactionHash: string - safe: string - module: string - to: string - value: string - data: string - operation: Operation - transfers: Transfer[] - txType: TxType.MODULE_TRANSACTION -} - -export interface EthereumTransaction { - executionDate: string - to: string - data: string | null - txHash: string - blockNumber: number - transfers: Transfer[] - txType: TxType.ETHEREUM_TRANSACTION - from: string -} - -export type Transaction = MultiSigTransaction | ModuleTransaction | EthereumTransaction - // SAFE METHODS TO ITS ID // https://github.com/gnosis/safe-contracts/blob/development/test/safeMethodNaming.js // https://github.com/gnosis/safe-contracts/blob/development/contracts/GnosisSafe.sol diff --git a/src/logic/safe/store/reducer/allTransactions.ts b/src/logic/safe/store/reducer/allTransactions.ts deleted file mode 100644 index dcfcb3e5..00000000 --- a/src/logic/safe/store/reducer/allTransactions.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { handleActions } from 'redux-actions' - -import { Transaction } from 'src/logic/safe/store/models/types/transactions.d' -import { - LOAD_MORE_TRANSACTIONS, - LoadMoreTransactionsAction, -} from 'src/logic/safe/store/actions/allTransactions/pagination' - -export const TRANSACTIONS = 'allTransactions' - -export interface TransactionsState { - [safeAddress: string]: { - totalTransactionsCount: number - transactions: Transaction[] - } -} - -export default handleActions( - { - // todo: because we are thinking in remove immutableJS, I will implement this without it so it can be easier removed in future - [LOAD_MORE_TRANSACTIONS]: (state: TransactionsState, action: LoadMoreTransactionsAction) => { - const { safeAddress, transactions, totalTransactionsAmount } = action.payload - const oldState = state[safeAddress] - - return { - ...state, - [safeAddress]: { - ...oldState, - transactions: [...(oldState?.transactions || []), ...transactions], - totalTransactionsCount: - totalTransactionsAmount > 0 ? totalTransactionsAmount : state[safeAddress].totalTransactionsCount, - }, - } - }, - }, - {}, -) diff --git a/src/logic/safe/store/reducer/cancellationTransactions.ts b/src/logic/safe/store/reducer/cancellationTransactions.ts deleted file mode 100644 index 52258daa..00000000 --- a/src/logic/safe/store/reducer/cancellationTransactions.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Map } from 'immutable' -import { Action, handleActions } from 'redux-actions' - -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateCancellationTransactions' -import { REMOVE_CANCELLATION_TRANSACTION } from 'src/logic/safe/store/actions/transactions/removeCancellationTransaction' -import { AppReduxState } from 'src/store' - -export const CANCELLATION_TRANSACTIONS_REDUCER_ID = 'cancellationTransactions' - -export type CancellationTransactions = Map -export type CancellationTxState = Map - -type CancellationTransactionsPayload = { safeAddress: string; transactions: CancellationTransactions } -type CancellationTransactionPayload = { safeAddress: string; transaction: Transaction } - -export default handleActions< - AppReduxState['cancellationTransactions'], - CancellationTransactionsPayload | CancellationTransactionPayload ->( - { - [ADD_OR_UPDATE_CANCELLATION_TRANSACTIONS]: (state, action: Action) => { - const { safeAddress, transactions } = action.payload - - if (!safeAddress || !transactions || !transactions.size) { - return state - } - - return state.withMutations((map) => { - const stateTransactionsMap = map.get(safeAddress) - - if (stateTransactionsMap) { - transactions.forEach((updateTx) => { - const keyPath = [safeAddress, `${updateTx.nonce}`] - - if (updateTx.confirmations.size) { - // if there are confirmations then we replace what's stored with the new tx - // as we assume that this is the newest tx returned by the server - map.setIn(keyPath, updateTx) - } else { - // if there are no confirmations, we assume this is a mocked tx - // as txs without confirmation are not being returned by the server (?has_confirmations=true) - map.mergeDeepIn(keyPath, updateTx) - } - }) - } else { - map.set(safeAddress, transactions) - } - }) - }, - [REMOVE_CANCELLATION_TRANSACTION]: (state, action: Action) => { - const { safeAddress, transaction } = action.payload - - if (!safeAddress || !transaction) { - return state - } - - return state.withMutations((map) => { - const stateTransactionsMap = map.get(safeAddress) - - if (stateTransactionsMap) { - map.deleteIn([safeAddress, `${transaction.nonce}`]) - } - }) - }, - }, - Map(), -) diff --git a/src/logic/safe/store/reducer/incomingTransactions.ts b/src/logic/safe/store/reducer/incomingTransactions.ts deleted file mode 100644 index a5273385..00000000 --- a/src/logic/safe/store/reducer/incomingTransactions.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Map } from 'immutable' -import { handleActions } from 'redux-actions' - -import { ADD_INCOMING_TRANSACTIONS } from 'src/logic/safe/store/actions/addIncomingTransactions' -import { AppReduxState } from 'src/store' - -export const INCOMING_TRANSACTIONS_REDUCER_ID = 'incomingTransactions' - -export default handleActions( - { - [ADD_INCOMING_TRANSACTIONS]: (state, action) => action.payload, - }, - Map(), -) diff --git a/src/logic/safe/store/reducer/moduleTransactions.ts b/src/logic/safe/store/reducer/moduleTransactions.ts deleted file mode 100644 index 27b310b2..00000000 --- a/src/logic/safe/store/reducer/moduleTransactions.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { handleActions } from 'redux-actions' - -import { - ADD_MODULE_TRANSACTIONS, - AddModuleTransactionsAction, -} from 'src/logic/safe/store/actions/addModuleTransactions' -import { ModuleTxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadModuleTransactions' - -export const MODULE_TRANSACTIONS_REDUCER_ID = 'moduleTransactions' - -export interface ModuleTransactionsState { - [safeAddress: string]: ModuleTxServiceModel[] -} - -export default handleActions( - { - [ADD_MODULE_TRANSACTIONS]: (state: ModuleTransactionsState, action: AddModuleTransactionsAction) => { - const { modules, safeAddress } = action.payload - const oldModuleTxs = state[safeAddress] ?? [] - const oldModuleTxsHashes = oldModuleTxs.map(({ transactionHash }) => transactionHash) - // As backend is returning the whole list of txs on every request, - // to avoid duplicates, filtering happens in this level. - const newModuleTxs = modules.filter((moduleTx) => !oldModuleTxsHashes.includes(moduleTx.transactionHash)) - - return { - ...state, - [safeAddress]: [...oldModuleTxs, ...newModuleTxs], - } - }, - }, - {}, -) diff --git a/src/logic/safe/store/reducer/transactions.ts b/src/logic/safe/store/reducer/transactions.ts deleted file mode 100644 index fe19bb18..00000000 --- a/src/logic/safe/store/reducer/transactions.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { List, Map } from 'immutable' -import { Action, handleActions } from 'redux-actions' - -import { ADD_OR_UPDATE_TRANSACTIONS } from 'src/logic/safe/store/actions/transactions/addOrUpdateTransactions' -import { REMOVE_TRANSACTION } from 'src/logic/safe/store/actions/transactions/removeTransaction' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { AppReduxState } from 'src/store' - -export const TRANSACTIONS_REDUCER_ID = 'transactions' - -type TransactionBasePayload = { safeAddress: string } -type TransactionsPayload = TransactionBasePayload & { transactions: List } -type TransactionPayload = TransactionBasePayload & { transaction: Transaction } - -type Payload = TransactionsPayload | TransactionPayload - -export default handleActions( - { - [ADD_OR_UPDATE_TRANSACTIONS]: (state, action: Action) => { - const { safeAddress, transactions } = action.payload - - if (!safeAddress || !transactions || !transactions.size) { - return state - } - - return state.withMutations((map) => { - const stateTransactionsList = map.get(safeAddress) - - if (stateTransactionsList) { - const txsToStore = stateTransactionsList.withMutations((txsList) => { - transactions.forEach((updateTx) => { - const storedTxIndex = txsList.findIndex((txIterator) => txIterator.safeTxHash === updateTx.safeTxHash) - - if (storedTxIndex !== -1) { - // Update - if (updateTx.confirmations.size) { - // if there are confirmations then we replace what's stored with the new tx - // as we assume that this is the newest tx returned by the server - txsList.update(storedTxIndex, () => updateTx) - } else { - // if there are no confirmations, we assume this is a mocked tx - // as txs without confirmation are not being returned by the server (?has_confirmations=true) - txsList.update(storedTxIndex, (storedTx) => storedTx.mergeDeep(updateTx)) - } - } else { - // Add new - txsList.unshift(updateTx) - } - }) - }) - map.set(safeAddress, txsToStore) - } else { - map.set(safeAddress, transactions) - } - }) - }, - [REMOVE_TRANSACTION]: (state, action: Action) => { - const { safeAddress, transaction } = action.payload - - if (!safeAddress || !transaction) { - return state - } - - return state.withMutations((map) => { - const stateTransactionsList = map.get(safeAddress) - - if (stateTransactionsList) { - const storedTxIndex = stateTransactionsList.findIndex((storedTx) => storedTx.equals(transaction)) - - if (storedTxIndex !== -1) { - map.deleteIn([safeAddress, storedTxIndex]) - } - } - }) - }, - }, - Map(), -) diff --git a/src/logic/safe/store/reducer/types/safe.d.ts b/src/logic/safe/store/reducer/types/safe.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/logic/safe/store/selectors/allTransactions.ts b/src/logic/safe/store/selectors/allTransactions.ts deleted file mode 100644 index e8729e61..00000000 --- a/src/logic/safe/store/selectors/allTransactions.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { TransactionsState, TRANSACTIONS } from '../reducer/allTransactions' -import { createSelector } from 'reselect' -import { safeParamAddressFromStateSelector } from './index' -import { AppReduxState } from 'src/store' - -export const getTransactionsStateSelector = (state: AppReduxState): TransactionsState => state[TRANSACTIONS] - -export const allTransactionsSelector = createSelector(getTransactionsStateSelector, (transactionsState) => { - return transactionsState -}) - -export const safeAllTransactionsSelector = createSelector( - safeParamAddressFromStateSelector, - allTransactionsSelector, - (safeAddress, transactions) => (safeAddress ? transactions[safeAddress]?.transactions : []), -) - -export const safeTotalTransactionsAmountSelector = createSelector( - safeParamAddressFromStateSelector, - allTransactionsSelector, - (safeAddress, transactions) => (safeAddress ? transactions[safeAddress]?.totalTransactionsCount : 0), -) diff --git a/src/logic/safe/store/selectors/index.ts b/src/logic/safe/store/selectors/index.ts index 95c2ec12..7675d0a9 100644 --- a/src/logic/safe/store/selectors/index.ts +++ b/src/logic/safe/store/selectors/index.ts @@ -1,15 +1,9 @@ -import { List, Map, Set } from 'immutable' +import { List, Set } from 'immutable' import { matchPath, RouteComponentProps } from 'react-router-dom' import { createSelector } from 'reselect' import { SAFELIST_ADDRESS, SAFE_PARAM_ADDRESS } from 'src/routes/routes' -import { - CANCELLATION_TRANSACTIONS_REDUCER_ID, - CancellationTransactions, -} from 'src/logic/safe/store/reducer/cancellationTransactions' -import { INCOMING_TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/incomingTransactions' import { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe' -import { TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/transactions' import { AppReduxState } from 'src/store' import { checksumAddress } from 'src/utils/checksumAddress' @@ -30,12 +24,6 @@ export const latestMasterContractVersionSelector = createSelector(safesStateSele safeState.get('latestMasterContractVersion'), ) -const transactionsSelector = (state: AppReduxState) => state[TRANSACTIONS_REDUCER_ID] - -const cancellationTransactionsSelector = (state: AppReduxState) => state[CANCELLATION_TRANSACTIONS_REDUCER_ID] - -const incomingTransactionsSelector = (state: AppReduxState) => state[INCOMING_TRANSACTIONS_REDUCER_ID] - export const safeParamAddressFromStateSelector = (state: AppReduxState): string => { const match = matchPath<{ safeAddress: string }>(state.router.location.pathname, { path: `${SAFELIST_ADDRESS}/:safeAddress`, @@ -56,22 +44,6 @@ export const safeParamAddressSelector = ( return urlAdd ? checksumAddress(urlAdd) : '' } -export const safeTransactionsSelector = createSelector( - transactionsSelector, - safeParamAddressFromStateSelector, - (transactions, address) => { - if (!transactions) { - return List([]) - } - - if (!address) { - return List([]) - } - - return transactions.get(address, List([])) - }, -) - export const addressBookQueryParamsSelector = (state: AppReduxState): string | undefined => { const { location } = state.router @@ -81,38 +53,6 @@ export const addressBookQueryParamsSelector = (state: AppReduxState): string | u } } -export const safeCancellationTransactionsSelector = createSelector( - cancellationTransactionsSelector, - safeParamAddressFromStateSelector, - (cancellationTransactions, address): CancellationTransactions => { - if (!cancellationTransactions) { - return Map() - } - - if (!address) { - return Map() - } - - return cancellationTransactions.get(address, Map()) - }, -) - -export const safeIncomingTransactionsSelector = createSelector( - incomingTransactionsSelector, - safeParamAddressFromStateSelector, - (incomingTransactions, address) => { - if (!incomingTransactions) { - return List([]) - } - - if (!address) { - return List([]) - } - - return incomingTransactions.get(address, List()) - }, -) - export const safeSelector = createSelector( safesMapSelector, safeParamAddressFromStateSelector, diff --git a/src/logic/safe/store/selectors/transactions.ts b/src/logic/safe/store/selectors/transactions.ts deleted file mode 100644 index 7fc6e3eb..00000000 --- a/src/logic/safe/store/selectors/transactions.ts +++ /dev/null @@ -1,18 +0,0 @@ -// import { List } from 'immutable' -// import { createSelector } from 'reselect' -// -// import { safeIncomingTransactionsSelector, safeTransactionsSelector } from 'src/logic/safe/store/selectors' -// import { Transaction, SafeModuleTransaction } from 'src/logic/safe/store/models/types/transaction' -// import { safeModuleTransactionsSelector } from 'src/routes/safe/container/selector' - -// export const extendedTransactionsSelector = createSelector( -// safeTransactionsSelector, -// safeIncomingTransactionsSelector, -// safeModuleTransactionsSelector, -// (transactions, incomingTransactions, moduleTransactions): List => -// List().withMutations((list) => { -// list.concat(transactions).concat(incomingTransactions).concat(moduleTransactions) -// }), -// ) - -export {} diff --git a/src/logic/safe/transactions/awaitingTransactions.ts b/src/logic/safe/transactions/awaitingTransactions.ts index 7b1345de..a6ff1212 100644 --- a/src/logic/safe/transactions/awaitingTransactions.ts +++ b/src/logic/safe/transactions/awaitingTransactions.ts @@ -1,30 +1,6 @@ -import { List } from 'immutable' - -import { isPendingTransaction } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' import { isStatusAwaitingConfirmation } from 'src/logic/safe/store/models/types/gateway.d' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' import { Transaction as GatewayTransaction } from 'src/logic/safe/store/models/types/gateway' -import { addressInList } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' -import { CancellationTransactions } from 'src/logic/safe/store/reducer/cancellationTransactions' - -export const getAwaitingTransactions = ( - allTransactions: List, - cancellationTxs: CancellationTransactions, - userAccount: string, -): List => { - return allTransactions.filter((tx) => { - const cancelTx = !!tx.nonce && !isNaN(Number(tx.nonce)) ? cancellationTxs.get(`${tx.nonce}`) : null - - // The transaction is not executed and is not cancelled, nor pending, so it's still waiting confirmations - if (!tx.executionTxHash && !tx.cancelled && cancelTx && !isPendingTransaction(tx, cancelTx)) { - // Then we check if the waiting confirmations are not from the current user, otherwise, filters this transaction - const transactionWaitingUser = tx.confirmations.filter(({ owner }) => owner !== userAccount) - return transactionWaitingUser.size > 0 - } - - return false - }) -} +import { addressInList } from 'src/routes/safe/components/Transactions/TxList/utils' export const getAwaitingGatewayTransactions = ( allTransactions: GatewayTransaction[], diff --git a/src/logic/safe/transactions/gas.ts b/src/logic/safe/transactions/gas.ts index 1d6949b9..9c79dd1d 100644 --- a/src/logic/safe/transactions/gas.ts +++ b/src/logic/safe/transactions/gas.ts @@ -296,10 +296,12 @@ export const estimateGasForTransactionExecution = async ({ }: TransactionExecutionEstimationProps): Promise => { const safeInstance = await getGnosisSafeInstanceAt(safeAddress) try { - if (approvalAndExecution) { - console.info(`Estimating transaction success for execution & approval...`) + let gasEstimation + // If safeTxGas === 0 we still have to estimate the gas limit to execute the transaction so we need to get an estimation + if (approvalAndExecution || safeTxGas === 0) { + console.info(`Estimating transaction necessary gas...`) // @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( + gasEstimation = await estimateGasForTransactionCreation( safeAddress, txData, txRecipient, @@ -307,17 +309,21 @@ export const estimateGasForTransactionExecution = async ({ operation, safeTxGas, ) - console.info(`Gas estimation successfully finished with gas amount: ${gasEstimation}`) - return gasEstimation + + if (approvalAndExecution) { + // If it's approve and execute we don't have all the signatures to do a complete simulation, we return the gas estimation + console.info(`Gas estimation successfully finished with gas amount: ${gasEstimation}`) + return gasEstimation + } } + // If we have all signatures we can do a call to ensure the transaction will be successful or fail const sigs = generateSignaturesFromTxConfirmations(txConfirmations) - console.info(`Estimating transaction success for with gas amount: ${safeTxGas}...`) + console.info(`Check transaction success 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 + return safeTxGas || gasEstimation } catch (error) { throw new Error(`Gas estimation failed with gas amount: ${safeTxGas}`) } diff --git a/src/logic/safe/transactions/incomingTxHistory.ts b/src/logic/safe/transactions/incomingTxHistory.ts deleted file mode 100644 index f4cbf582..00000000 --- a/src/logic/safe/transactions/incomingTxHistory.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { getSafeServiceBaseUrl } from 'src/config' -import { checksumAddress } from 'src/utils/checksumAddress' - -export const buildIncomingTxServiceUrl = (safeAddress: string): string => { - const address = checksumAddress(safeAddress) - return `${getSafeServiceBaseUrl(address)}/incoming-transfers/` -} diff --git a/src/logic/safe/transactions/moduleTxHistory.ts b/src/logic/safe/transactions/moduleTxHistory.ts deleted file mode 100644 index 656b4381..00000000 --- a/src/logic/safe/transactions/moduleTxHistory.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { getSafeServiceBaseUrl } from 'src/config' -import { checksumAddress } from 'src/utils/checksumAddress' - -export const buildModuleTxServiceUrl = (safeAddress: string): string => { - const address = checksumAddress(safeAddress) - const url = getSafeServiceBaseUrl(address) - - return `${url}/module-transactions/` -} diff --git a/src/logic/safe/transactions/offchainSigner/index.ts b/src/logic/safe/transactions/offchainSigner/index.ts index 08e04803..4a1e3b6b 100644 --- a/src/logic/safe/transactions/offchainSigner/index.ts +++ b/src/logic/safe/transactions/offchainSigner/index.ts @@ -17,7 +17,7 @@ const SIGNERS = { const getSignersByWallet = (isHW) => isHW ? [SIGNERS.ETH_SIGN] : [SIGNERS.EIP712_V3, SIGNERS.EIP712_V4, SIGNERS.EIP712, SIGNERS.ETH_SIGN] -export const SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES = '>=1.1.1' +export const SAFE_VERSION_FOR_OFFCHAIN_SIGNATURES = '>=1.0.0' export const tryOffchainSigning = async (safeTxHash: string, txArgs, isHW: boolean): Promise => { let signature diff --git a/src/logic/safe/utils/buildSafeCreationTxUrl.ts b/src/logic/safe/utils/buildSafeCreationTxUrl.ts deleted file mode 100644 index 624bc608..00000000 --- a/src/logic/safe/utils/buildSafeCreationTxUrl.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { getSafeServiceBaseUrl } from 'src/config' -import { checksumAddress } from 'src/utils/checksumAddress' - -export const buildSafeCreationTxUrl = (safeAddress: string): string => { - const address = checksumAddress(safeAddress) - return `${getSafeServiceBaseUrl(address)}/creation/` -} diff --git a/src/logic/safe/utils/safeVersion.ts b/src/logic/safe/utils/safeVersion.ts index 1c085225..116d2068 100644 --- a/src/logic/safe/utils/safeVersion.ts +++ b/src/logic/safe/utils/safeVersion.ts @@ -14,7 +14,7 @@ type FeatureConfigByVersion = { } const FEATURES_BY_VERSION: FeatureConfigByVersion[] = [ - { name: FEATURES.ERC721, validVersion: '>=1.1.1' }, + { name: FEATURES.ERC721 }, { name: FEATURES.ERC1155, validVersion: '>=1.1.1' }, { name: FEATURES.SAFE_APPS }, { name: FEATURES.CONTRACT_INTERACTION }, diff --git a/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts b/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts index 6321f706..c547c8e7 100644 --- a/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts +++ b/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts @@ -1,6 +1,7 @@ import axios, { AxiosResponse } from 'axios' import { getTokensServiceBaseUrl } from 'src/config' +import { TokenType } from 'src/logic/safe/store/models/types/gateway' export type TokenResult = { address: string @@ -8,7 +9,7 @@ export type TokenResult = { logoUri: string name: string symbol: string - type: string + type: TokenType } export const fetchErc20AndErc721AssetsList = (): Promise> => { diff --git a/src/logic/tokens/api/fetchSafeCollectibles.ts b/src/logic/tokens/api/fetchSafeCollectibles.ts index f847a2c0..4f0a5bfd 100644 --- a/src/logic/tokens/api/fetchSafeCollectibles.ts +++ b/src/logic/tokens/api/fetchSafeCollectibles.ts @@ -1,6 +1,6 @@ import axios, { AxiosResponse } from 'axios' -import { getSafeServiceBaseUrl } from 'src/config' +import { getSafeClientGatewayBaseUrl } from 'src/config' import { checksumAddress } from 'src/utils/checksumAddress' export type CollectibleResult = { @@ -17,8 +17,6 @@ export type CollectibleResult = { } export const fetchSafeCollectibles = async (safeAddress: string): Promise> => { - const address = checksumAddress(safeAddress) - const url = `${getSafeServiceBaseUrl(address)}/collectibles/` - + const url = `${getSafeClientGatewayBaseUrl(checksumAddress(safeAddress))}/collectibles/` return axios.get>(url) } diff --git a/src/logic/tokens/store/actions/fetchSafeTokens.ts b/src/logic/tokens/store/actions/fetchSafeTokens.ts index 6957080d..fb585e94 100644 --- a/src/logic/tokens/store/actions/fetchSafeTokens.ts +++ b/src/logic/tokens/store/actions/fetchSafeTokens.ts @@ -2,12 +2,13 @@ import { backOff } from 'exponential-backoff' import { List, Map } from 'immutable' import { Dispatch } from 'redux' +import { fetchTokenCurrenciesBalances, TokenBalance } from 'src/logic/currencyValues/api/fetchTokenCurrenciesBalances' + import { - fetchTokenCurrenciesBalances, - BalanceEndpoint, -} from 'src/logic/currencyValues/api/fetchTokenCurrenciesBalances' -import { setCurrencyBalances } from 'src/logic/currencyValues/store/actions/setCurrencyBalances' -import { CurrencyRateValueRecord, makeBalanceCurrency } from 'src/logic/currencyValues/store/model/currencyValues' + AVAILABLE_CURRENCIES, + CurrencyRateValueRecord, + makeBalanceCurrency, +} from 'src/logic/currencyValues/store/model/currencyValues' import addTokens from 'src/logic/tokens/store/actions/saveTokens' import { makeToken, Token } from 'src/logic/tokens/store/model/token' import { TokenState } from 'src/logic/tokens/store/reducer/tokens' @@ -16,6 +17,10 @@ import { AppReduxState } from 'src/store' import { humanReadableValue } from 'src/logic/tokens/utils/humanReadableValue' import { safeActiveTokensSelector, safeBlacklistedTokensSelector, safeSelector } from 'src/logic/safe/store/selectors' import { tokensSelector } from 'src/logic/tokens/store/selectors' +import { currentCurrencySelector } from 'src/logic/currencyValues/store/selectors' +import { sameAddress, ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' +import { setCurrencyBalances } from 'src/logic/currencyValues/store/actions/setCurrencyBalances' +import { getNetworkInfo } from 'src/config' interface ExtractedData { balances: Map @@ -24,17 +29,20 @@ interface ExtractedData { tokens: List } -const extractDataFromResult = (currentTokens: TokenState) => ( +const { nativeCoin } = getNetworkInfo() + +const extractDataFromResult = (currentTokens: TokenState, fiatCode: string) => ( acc: ExtractedData, - { balance, fiatBalance, fiatCode, token, tokenAddress }: BalanceEndpoint, + { balance, fiatBalance, tokenInfo }: TokenBalance, ): ExtractedData => { - if (tokenAddress === null) { + const { address: tokenAddress, decimals } = tokenInfo + if (sameAddress(tokenAddress, ZERO_ADDRESS) || sameAddress(tokenAddress, nativeCoin.address)) { acc.ethBalance = humanReadableValue(balance, 18) } else { - acc.balances = acc.balances.merge({ [tokenAddress]: humanReadableValue(balance, Number(token?.decimals)) }) + acc.balances = acc.balances.merge({ [tokenAddress]: humanReadableValue(balance, Number(decimals)) }) if (currentTokens && !currentTokens.get(tokenAddress)) { - acc.tokens = acc.tokens.push(makeToken({ address: tokenAddress, ...token })) + acc.tokens = acc.tokens.push(makeToken({ ...tokenInfo })) } } @@ -58,6 +66,7 @@ const fetchSafeTokens = (safeAddress: string) => async ( const state = getState() const safe = safeSelector(state) const currentTokens = tokensSelector(state) + const currencySelected = currentCurrencySelector(state) if (!safe) { return @@ -67,8 +76,8 @@ const fetchSafeTokens = (safeAddress: string) => async ( const alreadyActiveTokens = safeActiveTokensSelector(state) const blacklistedTokens = safeBlacklistedTokensSelector(state) - const { balances, currencyList, ethBalance, tokens } = tokenCurrenciesBalances.reduce( - extractDataFromResult(currentTokens), + const { balances, currencyList, ethBalance, tokens } = tokenCurrenciesBalances.items.reduce( + extractDataFromResult(currentTokens, currencySelected || AVAILABLE_CURRENCIES.USD), { balances: Map(), currencyList: List(), diff --git a/src/logic/tokens/store/model/token.ts b/src/logic/tokens/store/model/token.ts index 1657359c..e0c612bb 100644 --- a/src/logic/tokens/store/model/token.ts +++ b/src/logic/tokens/store/model/token.ts @@ -1,4 +1,5 @@ import { Record, RecordOf } from 'immutable' +import { TokenType } from 'src/logic/safe/store/models/types/gateway' export type TokenProps = { address: string @@ -7,6 +8,7 @@ export type TokenProps = { decimals: number | string logoUri: string balance: number | string + type?: TokenType } export const makeToken = Record({ diff --git a/src/logic/tokens/utils/tokenHelpers.ts b/src/logic/tokens/utils/tokenHelpers.ts index 7fbdcd0a..9dc7d305 100644 --- a/src/logic/tokens/utils/tokenHelpers.ts +++ b/src/logic/tokens/utils/tokenHelpers.ts @@ -4,11 +4,10 @@ import { AbiItem } from 'web3-utils' import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { getTokenInfos } from 'src/logic/tokens/store/actions/fetchTokens' -import { isSendERC721Transaction } from 'src/logic/collectibles/utils' import { makeToken, Token } from 'src/logic/tokens/store/model/token' import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi' import { web3ReadOnly as web3 } from 'src/logic/wallets/getWeb3' -import { BuildTx, isEmptyData, ServiceTx } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' +import { BuildTx, isEmptyData } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' import { CALL } from 'src/logic/safe/transactions' import { sameAddress } from 'src/logic/wallets/ethAddresses' @@ -69,21 +68,6 @@ export const getERC20DecimalsAndSymbol = async ( return tokenInfo } -export const isSendERC20Transaction = async (tx: BuildTx['tx']): Promise => { - let isSendTokenTx = !isSendERC721Transaction(tx) && isTokenTransfer(tx) - - if (isSendTokenTx) { - const { decimals, symbol } = await getERC20DecimalsAndSymbol((tx as ServiceTx).to) - - // some contracts may implement the same methods as in ERC20 standard - // we may falsely treat them as tokens, so in case we get any errors when getting token info - // we fallback to displaying custom transaction - isSendTokenTx = decimals !== null && symbol !== null - } - - return isSendTokenTx -} - export type GetTokenByAddress = { tokenAddress: string tokens: List diff --git a/src/logic/wallets/store/actions/fetchProvider.ts b/src/logic/wallets/store/actions/fetchProvider.ts index e6e40153..f75794b1 100644 --- a/src/logic/wallets/store/actions/fetchProvider.ts +++ b/src/logic/wallets/store/actions/fetchProvider.ts @@ -8,12 +8,10 @@ import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' import { getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3' import { makeProvider } from 'src/logic/wallets/store/model/provider' -import { updateStoredTransactionsStatus } from 'src/logic/safe/store/actions/transactions/utils/transactionHelpers' export const processProviderResponse = (dispatch, provider) => { const walletRecord = makeProvider(provider) dispatch(addProvider(walletRecord)) - updateStoredTransactionsStatus(dispatch, walletRecord) } const handleProviderNotification = (provider, dispatch) => { diff --git a/src/routes/load/components/ReviewInformation/index.tsx b/src/routes/load/components/ReviewInformation/index.tsx index edf41823..ae729f36 100644 --- a/src/routes/load/components/ReviewInformation/index.tsx +++ b/src/routes/load/components/ReviewInformation/index.tsx @@ -17,8 +17,9 @@ import { getAccountsFrom } from 'src/routes/open/utils/safeDataExtractor' import { useStyles } from './styles' import { getExplorerInfo } from 'src/config' import { ExplorerButton } from '@gnosis.pm/safe-react-components' +import { LoadFormValues } from 'src/routes/load/container/Load' -const checkIfUserAddressIsAnOwner = (values: Record, userAddress: string): boolean => { +const checkIfUserAddressIsAnOwner = (values: LoadFormValues, userAddress: string): boolean => { let isOwner = false for (let i = 0; i < getNumOwnersFrom(values); i += 1) { @@ -33,7 +34,7 @@ const checkIfUserAddressIsAnOwner = (values: Record, userAddress interface Props { userAddress: string - values: Record + values: LoadFormValues } const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => { @@ -138,7 +139,7 @@ const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => } const Review = ({ userAddress }: { userAddress: string }) => - function ReviewPage(controls: React.ReactNode, { values }: { values: Record }): React.ReactElement { + function ReviewPage(controls: React.ReactNode, { values }: { values: LoadFormValues }): React.ReactElement { return ( <> diff --git a/src/routes/load/container/Load.tsx b/src/routes/load/container/Load.tsx index 6e4b5305..1557ba3a 100644 --- a/src/routes/load/container/Load.tsx +++ b/src/routes/load/container/Load.tsx @@ -35,12 +35,24 @@ export const loadSafe = async ( await addSafe(safeProps) } -export interface LoadFormValues { +interface ReviewSafeCreationValues { + confirmations: string + name: string + owner0Address: string + owner0Name: string + safeCreationSalt: number +} + +interface LoadForm { name: string address: string threshold: string + owner0Address: string + owner0Name: string } +export type LoadFormValues = ReviewSafeCreationValues | LoadForm + const Load = (): React.ReactElement => { const dispatch = useDispatch() const provider = useSelector(providerNameSelector) diff --git a/src/routes/open/components/Layout.tsx b/src/routes/open/components/Layout.tsx index 9620c05b..e7e1689d 100644 --- a/src/routes/open/components/Layout.tsx +++ b/src/routes/open/components/Layout.tsx @@ -20,7 +20,7 @@ import { 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' +import { providerNameSelector, userAccountSelector } from 'src/logic/wallets/store/selectors' import { useSelector } from 'react-redux' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { getNameFromAddressBook } from 'src/logic/addressBook/utils' @@ -94,7 +94,6 @@ export const Layout = (props: LayoutProps): React.ReactElement => { const { onCallSafeContractSubmit, safeProps } = props const provider = useSelector(providerNameSelector) - const network = useSelector(networkSelector) const userAccount = useSelector(userAccountSelector) useEffect(() => { @@ -107,33 +106,31 @@ export const Layout = (props: LayoutProps): React.ReactElement => { const initialValues = useInitialValuesFrom(userAccount, safeProps) + if (!provider) { + return + } + return ( - <> - {provider ? ( - - - - - - - Create New Safe - - - - - - - - - ) : ( - - )} - + + + + + + + Create New Safe + + + + + + + + ) } diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index 4f08ff61..8e899bee 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -1,7 +1,6 @@ import TableContainer from '@material-ui/core/TableContainer' import classNames from 'classnames' -import React, { useEffect, useState } from 'react' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import React, { ReactElement, useEffect, useMemo } from 'react' import { getExplorerInfo, getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import Identicon from 'src/components/Identicon' @@ -11,45 +10,41 @@ import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import OpenPaper from 'src/components/Stepper/OpenPaper' -import { estimateGasForDeployingSafe } from 'src/logic/contracts/safeContracts' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getAccountsFrom, getNamesFrom, getSafeCreationSaltFrom } from 'src/routes/open/utils/safeDataExtractor' +import { + CreateSafeValues, + getAccountsFrom, + getNamesFrom, + getSafeCreationSaltFrom, +} from 'src/routes/open/utils/safeDataExtractor' import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' import { useStyles } from './styles' import { ExplorerButton } from '@gnosis.pm/safe-react-components' +import { useEstimateSafeCreationGas } from 'src/logic/hooks/useEstimateSafeCreationGas' +import { FormApi } from 'final-form' +import { StepperPageFormProps } from 'src/components/Stepper' +import { LoadFormValues } from 'src/routes/load/container/Load' type ReviewComponentProps = { - userAccount: string - values: any + values: LoadFormValues + form: FormApi } const { nativeCoin } = getNetworkInfo() -const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { +const ReviewComponent = ({ values, form }: ReviewComponentProps): ReactElement => { const classes = useStyles() - const [gasCosts, setGasCosts] = useState('< 0.001') const names = getNamesFrom(values) - const addresses = getAccountsFrom(values) + const addresses = useMemo(() => getAccountsFrom(values), [values]) + const numOwners = getNumOwnersFrom(values) - const safeCreationSalt = getSafeCreationSaltFrom(values) + const safeCreationSalt = getSafeCreationSaltFrom(values as CreateSafeValues) + const { gasCostFormatted, gasLimit } = useEstimateSafeCreationGas({ addresses, numOwners, safeCreationSalt }) useEffect(() => { - const estimateGas = async () => { - if (!addresses.length || !numOwners || !userAccount) { - return - } - const estimatedGasCosts = ( - await estimateGasForDeployingSafe(addresses, numOwners, userAccount, safeCreationSalt) - ).toString() - const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) - const formattedGasCosts = formatAmount(gasCosts) - setGasCosts(formattedGasCosts) - } - - estimateGas() - }, [addresses, numOwners, safeCreationSalt, userAccount]) + form.mutators.setValue('gasLimit', gasLimit) + }, [gasLimit, form.mutators]) return ( <> @@ -135,8 +130,8 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { You're about to create a new Safe and will have to confirm a transaction with your currently connected - wallet. The creation will cost approximately {gasCosts} {nativeCoin.name}. The exact amount will be determined - by your wallet. + wallet. The creation will cost approximately {gasCostFormatted} {nativeCoin.name}. The exact amount will be + determined by your wallet. @@ -144,7 +139,7 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { } export const Review = () => - function ReviewPage(controls, props): React.ReactElement { + function ReviewPage(controls: React.ReactNode, props: StepperPageFormProps): React.ReactElement { return ( <> diff --git a/src/routes/open/components/fields.ts b/src/routes/open/components/fields.ts index 4df7b36e..87d0f0b7 100644 --- a/src/routes/open/components/fields.ts +++ b/src/routes/open/components/fields.ts @@ -4,13 +4,17 @@ export const FIELD_OWNERS = 'owners' export const FIELD_SAFE_NAME = 'safeName' export const FIELD_CREATION_PROXY_SALT = 'safeCreationSalt' -export const getOwnerNameBy = (index) => `owner${index}Name` -export const getOwnerAddressBy = (index) => `owner${index}Address` +export const getOwnerNameBy = (index: number): string => `owner${index}Name` +export const getOwnerAddressBy = (index: number): string => `owner${index}Address` export const getNumOwnersFrom = (values) => { const accounts = Object.keys(values) .sort() - .filter((key) => /^owner\d+Address$/.test(key) && !!values[key]) + .filter((key) => { + const res = /^owner\d+Address$/.test(key) + + return res && !!values[key] + }) return accounts.length } diff --git a/src/routes/open/container/Open.tsx b/src/routes/open/container/Open.tsx index 9744f4f3..51136910 100644 --- a/src/routes/open/container/Open.tsx +++ b/src/routes/open/container/Open.tsx @@ -6,11 +6,12 @@ import { useLocation } from 'react-router-dom' import { PromiEvent, TransactionReceipt } from 'web3-core' import { SafeDeployment } from 'src/routes/opening' -import { InitialValuesForm, Layout } from 'src/routes/open/components/Layout' +import { Layout } from 'src/routes/open/components/Layout' import Page from 'src/components/layout/Page' import { getSafeDeploymentTransaction } from 'src/logic/contracts/safeContracts' import { checkReceiptStatus } from 'src/logic/wallets/ethTransactions' import { + CreateSafeValues, getAccountsFrom, getNamesFrom, getOwnersFrom, @@ -29,6 +30,8 @@ import { useAnalytics } from 'src/utils/googleAnalytics' const SAFE_PENDING_CREATION_STORAGE_KEY = 'SAFE_PENDING_CREATION_STORAGE_KEY' +type LoadedSafeType = CreateSafeValues & { txHash: string } + interface SafeCreationQueryParams { ownerAddresses: string | string[] | null ownerNames: string | string[] | null @@ -85,7 +88,7 @@ export const getSafeProps = async ( return safeProps } -export const createSafe = (values: InitialValuesForm, userAccount: string): PromiEvent => { +export const createSafe = (values: CreateSafeValues, userAccount: string): PromiEvent => { const confirmations = getThresholdFrom(values) const name = getSafeNameFrom(values) const ownersNames = getNamesFrom(values) @@ -93,7 +96,10 @@ export const createSafe = (values: InitialValuesForm, userAccount: string): Prom const safeCreationSalt = getSafeCreationSaltFrom(values) const deploymentTx = getSafeDeploymentTransaction(ownerAddresses, confirmations, safeCreationSalt) - const promiEvent = deploymentTx.send({ from: userAccount }) + const promiEvent = deploymentTx.send({ + from: userAccount, + gas: values?.gasLimit, + }) promiEvent .once('transactionHash', (txHash) => { @@ -155,28 +161,28 @@ const Open = (): React.ReactElement => { load() }, []) - const createSafeProxy = async (formValues?: InitialValuesForm) => { + const createSafeProxy = async (formValues?: CreateSafeValues) => { let values = formValues // save form values, used when the user rejects the TX and wants to retry - if (formValues) { - const copy = { ...formValues } + if (values) { + const copy = { ...values } saveToStorage(SAFE_PENDING_CREATION_STORAGE_KEY, copy) } else { - values = await loadFromStorage(SAFE_PENDING_CREATION_STORAGE_KEY) + values = (await loadFromStorage(SAFE_PENDING_CREATION_STORAGE_KEY)) as CreateSafeValues } - const promiEvent = createSafe(values as InitialValuesForm, userAccount) + const promiEvent = createSafe(values, userAccount) setCreationTxPromise(promiEvent) setShowProgress(true) } const onSafeCreated = async (safeAddress): Promise => { - const pendingCreation = await loadFromStorage<{ txHash: string }>(SAFE_PENDING_CREATION_STORAGE_KEY) + const pendingCreation = await loadFromStorage(SAFE_PENDING_CREATION_STORAGE_KEY) - const name = getSafeNameFrom(pendingCreation) - const ownersNames = getNamesFrom(pendingCreation) - const ownerAddresses = getAccountsFrom(pendingCreation) + const name = pendingCreation ? getSafeNameFrom(pendingCreation) : '' + const ownersNames = getNamesFrom(pendingCreation as CreateSafeValues) + const ownerAddresses = pendingCreation ? getAccountsFrom(pendingCreation) : [] const safeProps = await getSafeProps(safeAddress, name, ownersNames, ownerAddresses) await dispatch(addOrUpdateSafe(safeProps)) diff --git a/src/routes/open/utils/safeDataExtractor.spec.ts b/src/routes/open/utils/safeDataExtractor.spec.ts index ff1946b3..a4add102 100644 --- a/src/routes/open/utils/safeDataExtractor.spec.ts +++ b/src/routes/open/utils/safeDataExtractor.spec.ts @@ -8,6 +8,9 @@ describe('Test JS', () => { owner1Address: 'bar', owner2Address: 'baz', owners: 3, + confirmations: '0', + name: '', + safeCreationSalt: 0, } expect(getAccountsFrom(safe)).toEqual(['foo', 'bar', 'baz']) @@ -15,9 +18,15 @@ describe('Test JS', () => { it('return the names of owners', () => { const safe = { owner0Name: 'foo', + owner0Address: '0x', owner1Name: 'bar', + owner1Address: '0x', owner2Name: 'baz', + owner2Address: '0x', owners: 3, + confirmations: '0', + name: '', + safeCreationSalt: 0, } expect(getNamesFrom(safe)).toEqual(['foo', 'bar', 'baz']) @@ -31,12 +40,15 @@ describe('Test JS', () => { owner2Name: 'bazName', owner2Address: 'bazAddress', owners: 1, + confirmations: '0', + name: '', + safeCreationSalt: 0, } - expect(getNamesFrom(safe)).toEqual(['fooName']) - expect(getAccountsFrom(safe)).toEqual(['fooAddress']) + expect(getNamesFrom(safe)).toEqual(['fooName', 'barName', 'bazName']) + expect(getAccountsFrom(safe)).toEqual(['fooAddress', 'barAddress', 'bazAddress']) }) - it('return name and address ordered alphabetically', () => { + it('return name and address keys ordered alphabetically', () => { const safe = { owner1Name: 'barName', owner1Address: 'barAddress', @@ -45,14 +57,19 @@ describe('Test JS', () => { owner2Address: 'bazAddress', owner0Address: 'fooAddress', owners: 1, + confirmations: '0', + name: '', + safeCreationSalt: 0, } - expect(getNamesFrom(safe)).toEqual(['fooName']) - expect(getAccountsFrom(safe)).toEqual(['fooAddress']) + expect(getNamesFrom(safe)).toEqual(['fooName', 'barName', 'bazName']) + expect(getAccountsFrom(safe)).toEqual(['fooAddress', 'barAddress', 'bazAddress']) }) it('return the number of required confirmations', () => { const safe = { confirmations: '1', + name: '', + safeCreationSalt: 0, } expect(getThresholdFrom(safe)).toEqual(1) diff --git a/src/routes/open/utils/safeDataExtractor.ts b/src/routes/open/utils/safeDataExtractor.ts index fd380228..e44452c8 100644 --- a/src/routes/open/utils/safeDataExtractor.ts +++ b/src/routes/open/utils/safeDataExtractor.ts @@ -2,31 +2,45 @@ import { List } from 'immutable' import { makeOwner } from 'src/logic/safe/store/models/owner' import { SafeOwner } from 'src/logic/safe/store/models/safe' +import { LoadFormValues } from 'src/routes/load/container/Load' +import { getNumOwnersFrom } from 'src/routes/open/components/fields' -export const getAccountsFrom = (values) => { +export type CreateSafeValues = { + confirmations: string + name: string + owner0Address?: string + owner0Name?: string + safeCreationSalt: number + gasLimit?: number + owners?: number | string +} + +export const getAccountsFrom = (values: CreateSafeValues | LoadFormValues): string[] => { const accounts = Object.keys(values) .sort() .filter((key) => /^owner\d+Address$/.test(key)) - return accounts.map((account) => values[account]).slice(0, values.owners) + const numOwners = getNumOwnersFrom(values) + return accounts.map((account) => values[account]).slice(0, numOwners) } -export const getNamesFrom = (values) => { +export const getNamesFrom = (values: CreateSafeValues | LoadFormValues): string[] => { const accounts = Object.keys(values) .sort() .filter((key) => /^owner\d+Name$/.test(key)) - return accounts.map((account) => values[account]).slice(0, values.owners) + const numOwners = getNumOwnersFrom(values) + return accounts.map((account) => values[account]).slice(0, numOwners) } -export const getOwnersFrom = (names, addresses): List => { +export const getOwnersFrom = (names: string[], addresses: string[]): List => { const owners = names.map((name, index) => makeOwner({ name, address: addresses[index] })) return List(owners) } -export const getThresholdFrom = (values) => Number(values.confirmations) +export const getThresholdFrom = (values: CreateSafeValues): number => Number(values.confirmations) -export const getSafeNameFrom = (values) => values.name +export const getSafeNameFrom = (values: CreateSafeValues): string => values.name -export const getSafeCreationSaltFrom = (values) => values.safeCreationSalt +export const getSafeCreationSaltFrom = (values: CreateSafeValues): number => values.safeCreationSalt diff --git a/src/routes/safe/components/Apps/__tests__/utils.test.ts b/src/routes/safe/components/Apps/__tests__/utils.test.ts new file mode 100644 index 00000000..b2e43f87 --- /dev/null +++ b/src/routes/safe/components/Apps/__tests__/utils.test.ts @@ -0,0 +1,48 @@ +import { isAppManifestValid } from '../utils' +import { SafeApp, SAFE_APP_FETCH_STATUS } from '../types.d' + +describe('SafeApp manifest', () => { + it('It should return true given a manifest with mandatory values supplied', async () => { + const manifest = { + name: 'test', + description: 'a test', + error: false, + } + + const result = isAppManifestValid(manifest as SafeApp) + expect(result).toBe(true) + }) + + it('It should return false given a manifest without name', async () => { + const manifest = { + name: '', + description: 'a test', + error: false, + } + + const result = isAppManifestValid(manifest as SafeApp) + expect(result).toBe(false) + }) + + it('It should return false given a manifest without description', async () => { + const manifest = { + name: 'test', + description: '', + error: false, + } + + const result = isAppManifestValid(manifest as SafeApp) + expect(result).toBe(false) + }) + + it('It should return false given a manifest with error', async () => { + const manifest = { + name: 'test', + description: 'a test', + error: true, + } + + const result = isAppManifestValid(manifest as SafeApp) + expect(result).toBe(false) + }) +}) diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index f4ce90b7..3fa9d1f3 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -79,7 +79,7 @@ export const staticAppsList: Array = [ { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmQs6CUbMUyKe3Sa3tU3HcnWWzsuCk8oJEk8CZKhRcJfEh`, disabled: false, - networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY], + networks: [ETHEREUM_NETWORK.MAINNET], }, // Pooltogether { @@ -119,7 +119,7 @@ export const staticAppsList: Array = [ }, // TX-Builder { - url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmYES1Se6i6679z3PfQ62bydgVVEoSRUabvjB35DfUGPGA`, + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmZBgEvjqi9Jg8xATr9uUgNUVmnfYiECNxZv9Taux7mzgV`, disabled: false, networks: [ ETHEREUM_NETWORK.MAINNET, @@ -165,8 +165,6 @@ export const isAppManifestValid = (appInfo: SafeApp): boolean => appInfo.name !== 'unknown' && // `description` exists !!appInfo.description && - // `url` exists - !!appInfo.url && // no `error` (or `error` undefined) !appInfo.error @@ -201,7 +199,7 @@ export const getAppInfoFromUrl = memoize( const appInfo = await axios.get(`${noTrailingSlashUrl}/manifest.json`, { timeout: 5_000 }) // verify imported app fulfil safe requirements - if (!appInfo?.data || isAppManifestValid(appInfo.data)) { + if (!appInfo?.data || !isAppManifestValid(appInfo.data)) { throw Error('The app does not fulfil the structure required.') } @@ -210,9 +208,16 @@ export const getAppInfoFromUrl = memoize( const jsonDataLength = 20 const remainingSpace = originFieldSize - res.url.length - jsonDataLength + const appInfoData = { + name: appInfo.data.name, + iconPath: appInfo.data.iconPath, + description: appInfo.data.description, + providedBy: appInfo.data.providedBy, + } + res = { ...res, - ...appInfo.data, + ...appInfoData, id: JSON.stringify({ url: res.url, name: appInfo.data.name.substring(0, remainingSpace) }), error: false, loadingStatus: SAFE_APP_FETCH_STATUS.SUCCESS, diff --git a/src/routes/safe/components/Balances/Coins/index.tsx b/src/routes/safe/components/Balances/Coins/index.tsx index 603960af..7b72922f 100644 --- a/src/routes/safe/components/Balances/Coins/index.tsx +++ b/src/routes/safe/components/Balances/Coins/index.tsx @@ -53,7 +53,7 @@ const CurrencyTooltip = (props: CurrencyTooltipProps): React.ReactElement | null const value = valueWithCurrency.replace(/[^\d.-]/g, '') if (!Number(value) && Number(balance)) { return ( - + Info Tooltip @@ -91,7 +91,7 @@ const Coins = (props: Props): React.ReactElement => { data={filteredData} defaultFixed defaultOrderBy={BALANCE_TABLE_ASSET_ID} - defaultRowsPerPage={10} + defaultRowsPerPage={100} label="Balances" size={filteredData.size} > diff --git a/src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/index.tsx index 6bf71077..1f584b24 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/index.tsx @@ -13,7 +13,7 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { safeFeaturesEnabledSelector } from 'src/logic/safe/store/selectors' import { useStyles } from 'src/routes/safe/components/Balances/SendModal/screens/ChooseTxType/style' -import ContractInteractionIcon from 'src/routes/safe/components/Transactions/TxsTable/TxType/assets/custom.svg' +import ContractInteractionIcon from 'src/routes/safe/components/Transactions/TxList/assets/custom.svg' import Collectible from '../assets/collectibles.svg' import Token from '../assets/token.svg' @@ -116,7 +116,7 @@ const ChooseTxType = ({ onClose, recipientAddress, setActiveScreen }: ChooseTxTy className={classNames(classes.leftIcon, classes.iconSmall)} src={ContractInteractionIcon} /> - Contract Interaction + Contract interaction )} diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx index 9022b85d..6fecb6f4 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons/index.tsx @@ -30,7 +30,7 @@ const Buttons = ({ onClose }: ButtonProps) => { return ( - {(txParameters, toggleEditMode) => ( <> -
+
@@ -223,7 +223,7 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE - - - - - ) - }} - - - ) -} - -const AddCustomAssetComponent = withStyles(styles as any)(AddCustomAsset) - -export default AddCustomAssetComponent diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/style.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/style.ts deleted file mode 100644 index 6c8f0b35..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/style.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { lg, md } from 'src/theme/variables' - -export const styles = () => ({ - title: { - padding: `${lg} 0 20px`, - fontSize: md, - }, - formContainer: { - padding: '0 20px', - minHeight: '369px', - }, - addressInput: { - marginBottom: '15px', - display: 'flex', - flexGrow: 1, - backgroundColor: 'red', - }, - tokenImageHeading: { - margin: '0 0 15px', - }, - checkbox: { - padding: '0 7px 0 0', - width: '18px', - height: '18px', - }, - checkboxLabel: { - letterSpacing: '-0.5px', - }, - buttonRow: { - height: '84px', - justifyContent: 'center', - }, -}) diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/utils.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/utils.ts deleted file mode 100644 index 58bde5fe..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens' - -export const getSymbolAndDecimalsFromContract = async (tokenAddress) => { - const tokenContract = await getHumanFriendlyToken() - const token = await tokenContract.at(tokenAddress) - let values - - try { - const [symbol, decimals] = await Promise.all([token.symbol(), token.decimals()]) - values = [symbol, decimals.toString()] - } catch { - values = [] - } - - return values -} diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/validators.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/validators.ts deleted file mode 100644 index 95dcbcb4..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomAsset/validators.ts +++ /dev/null @@ -1,21 +0,0 @@ -import memoize from 'lodash.memoize' -import { isERC721Contract } from 'src/logic/collectibles/utils' -import { sameAddress } from 'src/logic/wallets/ethAddresses' - -// eslint-disable-next-line -export const addressIsAssetContract = memoize(async (tokenAddress) => { - const isAsset = await isERC721Contract(tokenAddress) - if (!isAsset) { - return 'Not a asset address' - } -}) - -// eslint-disable-next-line -export const doesntExistInAssetsList = (assetsList) => - memoize((tokenAddress) => { - const tokenIndex = assetsList.findIndex(({ address }) => sameAddress(address, tokenAddress)) - - if (tokenIndex !== -1) { - return 'Token already exists in your token list' - } - }) diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.tsx b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.tsx deleted file mode 100644 index c5053040..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/index.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import { makeStyles } from '@material-ui/core/styles' -import React, { useState } from 'react' -import { FormSpy } from 'react-final-form' - -import { styles } from './style' -import { getSymbolAndDecimalsFromContract } from './utils' -import { addressIsTokenContract, doesntExistInTokenList } from './validators' - -import Field from 'src/components/forms/Field' -import GnoForm from 'src/components/forms/GnoForm' -import TextField from 'src/components/forms/TextField' -import AddressInput from 'src/components/forms/AddressInput' -import { composeValidators, minMaxLength, required } from 'src/components/forms/validator' -import Block from 'src/components/layout/Block' -import Button from 'src/components/layout/Button' -import Col from 'src/components/layout/Col' -import Hairline from 'src/components/layout/Hairline' -import Img from 'src/components/layout/Img' -import Paragraph from 'src/components/layout/Paragraph' -import Row from 'src/components/layout/Row' - -import TokenPlaceholder from 'src/routes/safe/components/Balances/assets/token_placeholder.svg' -import { checksumAddress } from 'src/utils/checksumAddress' -import { Checkbox } from '@gnosis.pm/safe-react-components' -import { useDispatch } from 'react-redux' -import { addToken } from 'src/logic/tokens/store/actions/addToken' -import updateActiveTokens from 'src/logic/safe/store/actions/updateActiveTokens' -import activateTokenForAllSafes from 'src/logic/safe/store/actions/activateTokenForAllSafes' -import { Token } from 'src/logic/tokens/store/model/token' -import { List, Set } from 'immutable' - -export const ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID = 'add-custom-token-address-input' -export const ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID = 'add-custom-token-symbols-input' -export const ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID = 'add-custom-token-decimals-input' -export const ADD_CUSTOM_TOKEN_FORM = 'add-custom-token-form' - -const INITIAL_FORM_STATE = { - address: '', - decimals: '', - symbol: '', - logoUri: '', -} - -const useStyles = makeStyles(styles) - -type Props = { - activeTokens: List - onClose: () => void - parentList: string - safeAddress: string - setActiveScreen: (screen: string) => void - tokens: List -} - -const AddCustomToken = (props: Props): React.ReactElement => { - const { activeTokens, onClose, parentList, safeAddress, setActiveScreen, tokens } = props - const [formValues, setFormValues] = useState(INITIAL_FORM_STATE) - const classes = useStyles() - const dispatch = useDispatch() - - const handleSubmit = (values) => { - const address = checksumAddress(values.address) - const token = { - address, - decimals: values.decimals, - symbol: values.symbol, - name: values.symbol, - } - - dispatch(addToken(token)) - if (values.showForAllSafes) { - dispatch(activateTokenForAllSafes(token.address)) - } else { - const activeTokensAddresses = Set(activeTokens.map(({ address }) => address)) - dispatch(updateActiveTokens(safeAddress, activeTokensAddresses.add(token.address))) - } - - onClose() - } - - const populateFormValuesFromAddress = async (tokenAddress) => { - const tokenData = await getSymbolAndDecimalsFromContract(tokenAddress) - - if (tokenData.length) { - const [symbol, decimals] = tokenData - - setFormValues({ - address: tokenAddress, - symbol, - decimals, - name: symbol, - } as any) - } - } - - const formSpyOnChangeHandler = async (state) => { - const { dirty, errors, submitSucceeded, validating, values } = state - // for some reason this is called after submitting, we don't need to update the values - // after submit - if (submitSucceeded) { - return - } - - if (dirty && !validating && errors.address) { - setFormValues(INITIAL_FORM_STATE) - } - - if (!errors.address && !validating && dirty) { - await populateFormValuesFromAddress(values.address) - } - } - - const formMutators = { - setTokenAddress: (args, state, utils) => { - utils.changeValue(state, 'address', () => args[0]) - }, - } - - const goBack = () => { - setActiveScreen(parentList) - } - - return ( - <> - - {(...args) => { - const mutators = args[3] - - return ( - <> - - - Add custom token - - - - - - - - - - - - - Token Image - Token image - - - - - - - - - - ) - }} - - - ) -} - -export default AddCustomToken diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/style.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/style.ts deleted file mode 100644 index 793edae9..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/style.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { lg, md } from 'src/theme/variables' -import { createStyles } from '@material-ui/core' - -export const styles = createStyles({ - title: { - padding: `${lg} 0 20px`, - fontSize: md, - }, - formContainer: { - padding: '0 20px', - minHeight: '369px', - }, - addressInput: { - marginBottom: '15px', - display: 'flex', - flexGrow: 1, - backgroundColor: 'red', - }, - tokenImageHeading: { - margin: '0 0 15px', - }, - checkbox: { - padding: '0 7px 0 0', - width: '18px', - height: '18px', - }, - checkboxLabel: { - letterSpacing: '-0.5px', - }, - buttonRow: { - height: '84px', - justifyContent: 'center', - }, -}) diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/utils.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/utils.ts deleted file mode 100644 index 58bde5fe..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens' - -export const getSymbolAndDecimalsFromContract = async (tokenAddress) => { - const tokenContract = await getHumanFriendlyToken() - const token = await tokenContract.at(tokenAddress) - let values - - try { - const [symbol, decimals] = await Promise.all([token.symbol(), token.decimals()]) - values = [symbol, decimals.toString()] - } catch { - values = [] - } - - return values -} diff --git a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/validators.ts b/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/validators.ts deleted file mode 100644 index 636a1454..00000000 --- a/src/routes/safe/components/Balances/Tokens/screens/AddCustomToken/validators.ts +++ /dev/null @@ -1,31 +0,0 @@ -import memoize from 'lodash.memoize' - -import { isAddressAToken } from 'src/logic/tokens/utils/tokenHelpers' -import { sameAddress } from 'src/logic/wallets/ethAddresses' - -export const addressIsTokenContract = memoize(async (tokenAddress) => { - // SECOND APPROACH: - // They both seem to work the same - // const tokenContract = await getStandardTokenContract() - // try { - // await tokenContract.at(tokenAddress) - // } catch { - // return 'Not a token address' - // } - - const isToken = await isAddressAToken(tokenAddress) - - if (!isToken) { - return 'Not a token address' - } -}) - -// eslint-disable-next-line -export const doesntExistInTokenList = (tokenList) => - memoize((tokenAddress: string) => { - const tokenIndex = tokenList.findIndex(({ address }) => sameAddress(address, tokenAddress)) - - if (tokenIndex !== -1) { - return 'Token already exists in your token list' - } - }) diff --git a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/index.tsx b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/index.tsx index 6f4f4e93..5671a662 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/index.tsx +++ b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/index.tsx @@ -10,10 +10,7 @@ import Paragraph from 'src/components/layout/Paragraph' import { useStyles } from './style' -import Spacer from 'src/components/Spacer' import Block from 'src/components/layout/Block' -import Button from 'src/components/layout/Button' -import Divider from 'src/components/layout/Divider' import Hairline from 'src/components/layout/Hairline' import Row from 'src/components/layout/Row' import { nftAssetsListSelector } from 'src/logic/collectibles/store/selectors' @@ -26,12 +23,6 @@ import { safeParamAddressFromStateSelector, } from 'src/logic/safe/store/selectors' -export const ADD_CUSTOM_ASSET_BUTTON_TEST_ID = 'add-custom-asset-btn' - -type Props = { - setActiveScreen: (newScreen: string) => void -} - const filterBy = (filter, nfts) => nfts.filter( (asset) => @@ -41,7 +32,7 @@ const filterBy = (filter, nfts) => asset.symbol.toLowerCase().includes(filter.toLowerCase()), ) -const AssetsList = (props: Props): React.ReactElement => { +export const AssetsList = (): React.ReactElement => { const classes = useStyles() const searchClasses = { input: classes.searchInput, @@ -99,7 +90,7 @@ const AssetsList = (props: Props): React.ReactElement => { const nftAssetsFilteredList = filterBy(filterValue, nftAssetsList) const itemData = createItemData(nftAssetsFilteredList) - const switchToAddCustomAssetScreen = () => props.setActiveScreen('addCustomAsset') + return ( <> @@ -113,21 +104,6 @@ const AssetsList = (props: Props): React.ReactElement => { searchIcon={
} value={filterValue} /> - - - - @@ -154,5 +130,3 @@ const AssetsList = (props: Props): React.ReactElement => { ) } - -export default AssetsList diff --git a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/style.ts b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/style.ts index 52b060b2..65c0ed1b 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/style.ts +++ b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/style.ts @@ -57,7 +57,6 @@ export const useStyles = makeStyles( alignItems: 'center', }, searchContainer: { - width: '180px', marginLeft: xs, marginRight: xs, }, @@ -69,6 +68,7 @@ export const useStyles = makeStyles( '& > button': { display: 'none', }, + flex: 1, }, searchIcon: { '&:hover': { diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.tsx b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.tsx index 7cd838cb..aa7e12cc 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.tsx +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/index.tsx @@ -9,11 +9,7 @@ import { FixedSizeList } from 'react-window' import TokenRow from './TokenRow' import { useStyles } from './style' - -import Spacer from 'src/components/Spacer' import Block from 'src/components/layout/Block' -import Button from 'src/components/layout/Button' -import Divider from 'src/components/layout/Divider' import Hairline from 'src/components/layout/Hairline' import Row from 'src/components/layout/Row' import { Token } from 'src/logic/tokens/store/model/token' @@ -32,7 +28,6 @@ const filterBy = (filter: string, tokens: List): List => ) type Props = { - setActiveScreen: (newScreen: string) => void tokens: List activeTokens: List blacklistedTokens: Set @@ -47,7 +42,7 @@ export type ItemData = { export const TokenList = (props: Props): React.ReactElement => { const classes = useStyles() - const { setActiveScreen, tokens, activeTokens, blacklistedTokens, safeAddress } = props + const { tokens, activeTokens, blacklistedTokens, safeAddress } = props const [activeTokensAddresses, setActiveTokensAddresses] = useState(Set(activeTokens.map(({ address }) => address))) const [blacklistedTokensAddresses, setBlacklistedTokensAddresses] = useState>(blacklistedTokens) const [filter, setFilter] = useState('') @@ -93,8 +88,6 @@ export const TokenList = (props: Props): React.ReactElement => { onSwitch, }) - const switchToAddCustomTokenScreen = () => setActiveScreen('addCustomToken') - const getItemKey = (index: number, { tokens }): string => { return tokens.get(index).address } @@ -115,20 +108,6 @@ export const TokenList = (props: Props): React.ReactElement => { searchIcon={
} value={filter} /> - - - - diff --git a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.ts b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.ts index 18631a78..dbf3500b 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.ts +++ b/src/routes/safe/components/Balances/Tokens/screens/TokenList/style.ts @@ -65,7 +65,6 @@ export const useStyles = makeStyles( alignItems: 'center', }, searchContainer: { - width: '180px', marginLeft: xs, marginRight: xs, }, @@ -77,6 +76,7 @@ export const useStyles = makeStyles( '& > button': { display: 'none', }, + flex: 1, }, searchIcon: { '&:hover': { diff --git a/src/routes/safe/components/Balances/dataFetcher.ts b/src/routes/safe/components/Balances/dataFetcher.ts index e950560e..7d48d54a 100644 --- a/src/routes/safe/components/Balances/dataFetcher.ts +++ b/src/routes/safe/components/Balances/dataFetcher.ts @@ -6,6 +6,7 @@ import { formatAmountInUsFormat } from 'src/logic/tokens/utils/formatAmount' import { TableColumn } from 'src/components/Table/types.d' import { BalanceCurrencyList } from 'src/logic/currencyValues/store/model/currencyValues' import { Token } from 'src/logic/tokens/store/model/token' +import { sameAddress } from 'src/logic/wallets/ethAddresses' export const BALANCE_TABLE_ASSET_ID = 'asset' export const BALANCE_TABLE_BALANCE_ID = 'balance' @@ -13,23 +14,17 @@ export const BALANCE_TABLE_VALUE_ID = 'value' const { nativeCoin } = getNetworkInfo() -const getTokenValue = (token: Token, currencyValues?: BalanceCurrencyList, currencyRate?: number): string => { - const currencyValue = currencyValues?.find(({ tokenAddress }) => { - if (token.address === nativeCoin.address && !tokenAddress) { - return true - } +const getTokenValue = (token: Token, currencyValues: BalanceCurrencyList, currencyRate: number): string => { + const currencyValue = currencyValues.find( + ({ tokenAddress }) => sameAddress(token.address, tokenAddress) || sameAddress(token.address, nativeCoin.address), + ) - return token.address === tokenAddress - }) - - if (!currencyValue || !currencyRate) { + if (!currencyValue) { return '' } const { balanceInBaseCurrency } = currencyValue - const balance = new BigNumber(balanceInBaseCurrency).times(currencyRate).toString() - - return balance + return new BigNumber(balanceInBaseCurrency).times(currencyRate).toString() } const getTokenPriceInCurrency = (balance: string, currencySelected?: string): string => { @@ -57,7 +52,8 @@ export const getBalanceData = ( ): List => { const { nativeCoin } = getNetworkInfo() return activeTokens.map((token) => { - const balance = getTokenValue(token, currencyValues, currencyRate) + const balance = currencyRate && currencyValues ? getTokenValue(token, currencyValues, currencyRate) : '0' + return { [BALANCE_TABLE_ASSET_ID]: { name: token.name, diff --git a/src/routes/safe/components/Balances/index.tsx b/src/routes/safe/components/Balances/index.tsx index 49bd4d8b..be80a8ba 100644 --- a/src/routes/safe/components/Balances/index.tsx +++ b/src/routes/safe/components/Balances/index.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' import ReceiveModal from 'src/components/App/ReceiveModal' -import Tokens from './Tokens' +import { Tokens } from './Tokens' import { styles } from './style' import Modal from 'src/components/Modal' @@ -56,7 +56,7 @@ const Balances = (): React.ReactElement => { const featuresEnabled = useSelector(safeFeaturesEnabledSelector) const safeName = useSelector(safeNameSelector) ?? '' - useFetchTokens(address as string) + useFetchTokens(address) useEffect(() => { const erc721Enabled = Boolean(featuresEnabled?.includes(FEATURES.ERC721)) diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx index a86ab0b4..436e233a 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/index.tsx @@ -80,7 +80,7 @@ export const RemoveOwnerModal = ({ }: RemoveOwnerProps): React.ReactElement => { const classes = useStyles() const [activeScreen, setActiveScreen] = useState('checkOwner') - const [values, setValues] = useState({}) + const [values, setValues] = useState({ ownerAddress, ownerName, threshold: '' }) const dispatch = useDispatch() const safeAddress = useSelector(safeParamAddressFromStateSelector) const threshold = useSelector(safeThresholdSelector) || 1 @@ -88,7 +88,6 @@ export const RemoveOwnerModal = ({ useEffect( () => () => { setActiveScreen('checkOwner') - setValues({}) }, [isOpen], ) @@ -106,8 +105,8 @@ export const RemoveOwnerModal = ({ } const thresholdSubmitted = (newValues) => { - values.threshold = newValues.threshold - setValues(values) + const cpValues = { ...values, threshold: newValues.threshold } + setValues(cpValues) setActiveScreen('reviewRemoveOwner') } @@ -138,7 +137,7 @@ export const RemoveOwnerModal = ({ onSubmit={onRemoveOwner} ownerAddress={ownerAddress} ownerName={ownerName} - threshold={threshold} + threshold={Number(values.threshold)} /> )} 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 5a088416..c69aba52 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 @@ -27,6 +27,7 @@ import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionPara import { styles } from './style' import { TransactionFees } from 'src/components/TransactionsFees' import { EditableTxParameters } from 'src/routes/safe/components/Transactions/helpers/EditableTxParameters' +import { sameAddress } from 'src/logic/wallets/ethAddresses' export const REMOVE_OWNER_REVIEW_BTN_TEST_ID = 'remove-owner-review-btn' @@ -87,7 +88,7 @@ export const ReviewRemoveOwnerModal = ({ try { const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() - const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) + const index = safeOwners.findIndex((owner) => sameAddress(owner, ownerAddress)) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, threshold).encodeABI() @@ -141,6 +142,7 @@ export const ReviewRemoveOwnerModal = ({ + {/* Details */} @@ -166,6 +168,7 @@ export const ReviewRemoveOwnerModal = ({ + {/* Owners */} diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/ThresholdForm/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/ThresholdForm/index.tsx index f58a75c0..a7d66ca3 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/ThresholdForm/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/ThresholdForm/index.tsx @@ -2,7 +2,7 @@ import IconButton from '@material-ui/core/IconButton' import MenuItem from '@material-ui/core/MenuItem' import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' -import React from 'react' +import React, { ReactElement } from 'react' import { useSelector } from 'react-redux' import { styles } from './style' @@ -18,12 +18,19 @@ import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { safeOwnersSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' +import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' export const REMOVE_OWNER_THRESHOLD_NEXT_BTN_TEST_ID = 'remove-owner-threshold-next-btn' const useStyles = makeStyles(styles) -const ThresholdForm = ({ onClickBack, onClose, onSubmit }) => { +type Props = { + onClickBack: () => void + onClose: () => void + onSubmit: (txParameters: TxParameters) => void +} + +const ThresholdForm = ({ onClickBack, onClose, onSubmit }: Props): ReactElement => { const classes = useStyles() const owners = useSelector(safeOwnersSelector) const threshold = useSelector(safeThresholdSelector) as number diff --git a/src/routes/safe/components/Settings/SafeDetails/index.tsx b/src/routes/safe/components/Settings/SafeDetails/index.tsx index cb74ce86..3beb72e5 100644 --- a/src/routes/safe/components/Settings/SafeDetails/index.tsx +++ b/src/routes/safe/components/Settings/SafeDetails/index.tsx @@ -22,7 +22,9 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { UpdateSafeModal } from 'src/routes/safe/components/Settings/UpdateSafeModal' import { grantedSelector } from 'src/routes/safe/container/selector' import updateSafe from 'src/logic/safe/store/actions/updateSafe' -import Link from 'src/components/layout/Link' +import { Icon, Link, Text } from '@gnosis.pm/safe-react-components' +import styled from 'styled-components' + import { latestMasterContractVersionSelector, safeCurrentVersionSelector, @@ -40,6 +42,15 @@ export const SAFE_NAME_UPDATE_SAFE_BTN_TEST_ID = 'update-safe-name-btn' const useStyles = makeStyles(styles) +const StyledLink = styled(Link)` + margin: 12px 0 0 0; +` +const StyledIcon = styled(Icon)` + position: relative; + top: 3px; + left: 6px; +` + const SafeDetails = (): React.ReactElement => { const classes = useStyles() const isUserOwner = useSelector(grantedSelector) @@ -111,12 +122,13 @@ const SafeDetails = (): React.ReactElement => { Safe Version - - + + {getSafeVersion()} {getSafeVersionUpdate()} - - + + + {safeNeedsUpdate && isUserOwner ? ( @@ -137,9 +149,9 @@ const SafeDetails = (): React.ReactElement => { Modify Safe name - - You can change the name of this Safe. This name is only stored locally and never shared with Gnosis or any - third parties. + + You can change the name of this Safe. This name is only stored locally
+ and never shared with Gnosis or any third parties.
( -
- - Data (hex encoded): - - -
-) diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/ActionModal.tsx b/src/routes/safe/components/Transactions/TxList/ActionModal.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/ActionModal.tsx rename to src/routes/safe/components/Transactions/TxList/ActionModal.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/AddressInfo.tsx b/src/routes/safe/components/Transactions/TxList/AddressInfo.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/AddressInfo.tsx rename to src/routes/safe/components/Transactions/TxList/AddressInfo.tsx diff --git a/src/routes/safe/components/Transactions/TxList/HexEncodedData.tsx b/src/routes/safe/components/Transactions/TxList/HexEncodedData.tsx new file mode 100644 index 00000000..81955e08 --- /dev/null +++ b/src/routes/safe/components/Transactions/TxList/HexEncodedData.tsx @@ -0,0 +1,68 @@ +import { Text } from '@gnosis.pm/safe-react-components' +import { createStyles, makeStyles } from '@material-ui/core/styles' +import React, { ReactElement, useState } from 'react' + +import Paragraph from 'src/components/layout/Paragraph' +import LinkWithRef from 'src/components/layout/Link' +import { shortVersionOf } from 'src/logic/wallets/ethAddresses' + +export const styles = createStyles({ + txDataParagraph: { + whiteSpace: 'normal', + }, + linkTxData: { + textDecoration: 'underline', + cursor: 'pointer', + }, +}) + +const useStyles = makeStyles(styles) + +export const HexEncodedData = ({ hexData }: { hexData: string }): ReactElement => { + const classes = useStyles() + const [showTxData, setShowTxData] = useState(false) + const showExpandBtn = hexData.length > 20 + + return ( +
+ + Data (hex encoded): + + + {showExpandBtn ? ( + <> + {showTxData ? ( + <> + {hexData}{' '} + setShowTxData(false)} + rel="noopener noreferrer" + target="_blank" + > + Show Less + + + ) : ( + <> + {shortVersionOf(hexData, 20)}{' '} + setShowTxData(true)} + rel="noopener noreferrer" + target="_blank" + > + Show More + + + )} + + ) : ( + hexData + )} + +
+ ) +} diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/HistoryTransactions.tsx b/src/routes/safe/components/Transactions/TxList/HistoryTransactions.tsx similarity index 58% rename from src/routes/safe/components/Transactions/GatewayTransactions/HistoryTransactions.tsx rename to src/routes/safe/components/Transactions/TxList/HistoryTransactions.tsx index 00be4d7b..75f42967 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/HistoryTransactions.tsx +++ b/src/routes/safe/components/Transactions/TxList/HistoryTransactions.tsx @@ -1,15 +1,17 @@ -import { Loader } from '@gnosis.pm/safe-react-components' +import { Loader, Title } from '@gnosis.pm/safe-react-components' import React, { ReactElement } from 'react' import { usePagedHistoryTransactions } from './hooks/usePagedHistoryTransactions' -import { Centered } from './styled' +import { Centered, NoTransactions } from './styled' import { HistoryTxList } from './HistoryTxList' import { TxsInfiniteScroll } from './TxsInfiniteScroll' +import Img from 'src/components/layout/Img' +import NoTransactionsImage from './assets/no-transactions.svg' export const HistoryTransactions = (): ReactElement => { const { count, hasMore, next, transactions, isLoading } = usePagedHistoryTransactions() - if (count === 0) { + if (count === 0 && isLoading) { return ( @@ -17,6 +19,15 @@ export const HistoryTransactions = (): ReactElement => { ) } + if (count === 0) { + return ( + + No Transactions yet + History transactions will appear here + + ) + } + return ( diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/HistoryTxList.tsx b/src/routes/safe/components/Transactions/TxList/HistoryTxList.tsx similarity index 96% rename from src/routes/safe/components/Transactions/GatewayTransactions/HistoryTxList.tsx rename to src/routes/safe/components/Transactions/TxList/HistoryTxList.tsx index b57f7347..edba291f 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/HistoryTxList.tsx +++ b/src/routes/safe/components/Transactions/TxList/HistoryTxList.tsx @@ -1,7 +1,7 @@ import React, { ReactElement, useContext } from 'react' import { TransactionDetails } from 'src/logic/safe/store/models/types/gateway.d' -import { TxsInfiniteScrollContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxsInfiniteScroll' +import { TxsInfiniteScrollContext } from 'src/routes/safe/components/Transactions/TxList/TxsInfiniteScroll' import { formatWithSchema } from 'src/utils/date' import { sameString } from 'src/utils/strings' import { StyledTransactions, StyledTransactionsGroup, SubTitle } from './styled' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/InfoDetails.tsx b/src/routes/safe/components/Transactions/TxList/InfoDetails.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/InfoDetails.tsx rename to src/routes/safe/components/Transactions/TxList/InfoDetails.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/MethodDetails.tsx b/src/routes/safe/components/Transactions/TxList/MethodDetails.tsx similarity index 93% rename from src/routes/safe/components/Transactions/GatewayTransactions/MethodDetails.tsx rename to src/routes/safe/components/Transactions/TxList/MethodDetails.tsx index d849aa8a..d4b38121 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/MethodDetails.tsx +++ b/src/routes/safe/components/Transactions/TxList/MethodDetails.tsx @@ -4,7 +4,7 @@ import styled from 'styled-components' import { DataDecoded } from 'src/logic/safe/store/models/types/gateway.d' import { isArrayParameter } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils' -import Value from 'src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value' +import Value from 'src/routes/safe/components/Transactions/TxList/MethodValue' const TxDetailsMethodParam = styled.div<{ isArrayParameter: boolean }>` padding-left: 24px; diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx b/src/routes/safe/components/Transactions/TxList/MethodValue.tsx similarity index 100% rename from src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx rename to src/routes/safe/components/Transactions/TxList/MethodValue.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/MultiSendDetails.tsx b/src/routes/safe/components/Transactions/TxList/MultiSendDetails.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/MultiSendDetails.tsx rename to src/routes/safe/components/Transactions/TxList/MultiSendDetails.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/OwnerRow.tsx b/src/routes/safe/components/Transactions/TxList/OwnerRow.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/OwnerRow.tsx rename to src/routes/safe/components/Transactions/TxList/OwnerRow.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/QueueTransactions.tsx b/src/routes/safe/components/Transactions/TxList/QueueTransactions.tsx similarity index 85% rename from src/routes/safe/components/Transactions/GatewayTransactions/QueueTransactions.tsx rename to src/routes/safe/components/Transactions/TxList/QueueTransactions.tsx index f5e55f62..5339a6dc 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/QueueTransactions.tsx +++ b/src/routes/safe/components/Transactions/TxList/QueueTransactions.tsx @@ -1,29 +1,20 @@ import { Loader, Title } from '@gnosis.pm/safe-react-components' import React, { ReactElement } from 'react' -import style from 'styled-components' import Img from 'src/components/layout/Img' import { ActionModal } from './ActionModal' import NoTransactionsImage from './assets/no-transactions.svg' import { usePagedQueuedTransactions } from './hooks/usePagedQueuedTransactions' import { QueueTxList } from './QueueTxList' -import { Centered } from './styled' +import { Centered, NoTransactions } from './styled' import { TxActionProvider } from './TxActionProvider' import { TxsInfiniteScroll } from './TxsInfiniteScroll' import { TxLocationContext } from './TxLocationProvider' -const NoTransactions = style.div` - display: flex; - flex-direction: column; - margin-top: 60px; -` - export const QueueTransactions = (): ReactElement => { const { count, isLoading, hasMore, next, transactions } = usePagedQueuedTransactions() - // `loading` is, actually `!transactions` - // added the `transaction` verification to prevent `Object is possibly 'undefined'` error - if (isLoading || !transactions) { + if (count === 0 && isLoading) { return ( @@ -31,11 +22,13 @@ export const QueueTransactions = (): ReactElement => { ) } - if (count === 0) { + // `loading` is, actually `!transactions` + // added the `transaction` verification to prevent `Object is possibly 'undefined'` error + if (count === 0 || !transactions) { return ( No Transactions yet - Transactions will appear here + Queue transactions will appear here ) } diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/QueueTxList.tsx b/src/routes/safe/components/Transactions/TxList/QueueTxList.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/QueueTxList.tsx rename to src/routes/safe/components/Transactions/TxList/QueueTxList.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/SpendingLimitDetails.tsx b/src/routes/safe/components/Transactions/TxList/SpendingLimitDetails.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/SpendingLimitDetails.tsx rename to src/routes/safe/components/Transactions/TxList/SpendingLimitDetails.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TokenTransferAmount.tsx b/src/routes/safe/components/Transactions/TxList/TokenTransferAmount.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TokenTransferAmount.tsx rename to src/routes/safe/components/Transactions/TxList/TokenTransferAmount.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxActionProvider.tsx b/src/routes/safe/components/Transactions/TxList/TxActionProvider.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxActionProvider.tsx rename to src/routes/safe/components/Transactions/TxList/TxActionProvider.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxCollapsed.tsx b/src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxCollapsed.tsx rename to src/routes/safe/components/Transactions/TxList/TxCollapsed.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxCollapsedActions.tsx b/src/routes/safe/components/Transactions/TxList/TxCollapsedActions.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxCollapsedActions.tsx rename to src/routes/safe/components/Transactions/TxList/TxCollapsedActions.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxData.tsx b/src/routes/safe/components/Transactions/TxList/TxData.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxData.tsx rename to src/routes/safe/components/Transactions/TxList/TxData.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxDetails.tsx b/src/routes/safe/components/Transactions/TxList/TxDetails.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxDetails.tsx rename to src/routes/safe/components/Transactions/TxList/TxDetails.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxExpandedActions.tsx b/src/routes/safe/components/Transactions/TxList/TxExpandedActions.tsx similarity index 95% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxExpandedActions.tsx rename to src/routes/safe/components/Transactions/TxList/TxExpandedActions.tsx index 37175329..71e0c28c 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/TxExpandedActions.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxExpandedActions.tsx @@ -2,7 +2,7 @@ import { Button } from '@gnosis.pm/safe-react-components' import React, { ReactElement } from 'react' import { Transaction } from 'src/logic/safe/store/models/types/gateway.d' -import { useActionButtonsHandlers } from 'src/routes/safe/components/Transactions/GatewayTransactions/hooks/useActionButtonsHandlers' +import { useActionButtonsHandlers } from 'src/routes/safe/components/Transactions/TxList/hooks/useActionButtonsHandlers' type TxExpandedActionsProps = { transaction: Transaction diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxHistoryCollapsed.tsx b/src/routes/safe/components/Transactions/TxList/TxHistoryCollapsed.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxHistoryCollapsed.tsx rename to src/routes/safe/components/Transactions/TxList/TxHistoryCollapsed.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxHistoryRow.tsx b/src/routes/safe/components/Transactions/TxList/TxHistoryRow.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxHistoryRow.tsx rename to src/routes/safe/components/Transactions/TxList/TxHistoryRow.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxHoverProvider.tsx b/src/routes/safe/components/Transactions/TxList/TxHoverProvider.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxHoverProvider.tsx rename to src/routes/safe/components/Transactions/TxList/TxHoverProvider.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxInfo.tsx b/src/routes/safe/components/Transactions/TxList/TxInfo.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxInfo.tsx rename to src/routes/safe/components/Transactions/TxList/TxInfo.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxInfoCreation.tsx b/src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxInfoCreation.tsx rename to src/routes/safe/components/Transactions/TxList/TxInfoCreation.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxInfoDetails.tsx b/src/routes/safe/components/Transactions/TxList/TxInfoDetails.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxInfoDetails.tsx rename to src/routes/safe/components/Transactions/TxList/TxInfoDetails.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxInfoSettings.tsx b/src/routes/safe/components/Transactions/TxList/TxInfoSettings.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxInfoSettings.tsx rename to src/routes/safe/components/Transactions/TxList/TxInfoSettings.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxInfoTransfer.tsx b/src/routes/safe/components/Transactions/TxList/TxInfoTransfer.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxInfoTransfer.tsx rename to src/routes/safe/components/Transactions/TxList/TxInfoTransfer.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxLocationProvider.tsx b/src/routes/safe/components/Transactions/TxList/TxLocationProvider.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxLocationProvider.tsx rename to src/routes/safe/components/Transactions/TxList/TxLocationProvider.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxOwners.tsx b/src/routes/safe/components/Transactions/TxList/TxOwners.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxOwners.tsx rename to src/routes/safe/components/Transactions/TxList/TxOwners.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxQueueCollapsed.tsx b/src/routes/safe/components/Transactions/TxList/TxQueueCollapsed.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxQueueCollapsed.tsx rename to src/routes/safe/components/Transactions/TxList/TxQueueCollapsed.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxQueueRow.tsx b/src/routes/safe/components/Transactions/TxList/TxQueueRow.tsx similarity index 95% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxQueueRow.tsx rename to src/routes/safe/components/Transactions/TxList/TxQueueRow.tsx index 5405ddaf..f72f8eb6 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/TxQueueRow.tsx +++ b/src/routes/safe/components/Transactions/TxList/TxQueueRow.tsx @@ -2,7 +2,7 @@ import { AccordionDetails } from '@gnosis.pm/safe-react-components' import React, { ReactElement, useContext, useEffect, useState } from 'react' import { Transaction } from 'src/logic/safe/store/models/types/gateway.d' -import { useTransactionActions } from 'src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionActions' +import { useTransactionActions } from 'src/routes/safe/components/Transactions/TxList/hooks/useTransactionActions' import { NoPaddingAccordion, StyledAccordionSummary } from './styled' import { TxDetails } from './TxDetails' import { TxHoverContext } from './TxHoverProvider' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxSummary.tsx b/src/routes/safe/components/Transactions/TxList/TxSummary.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxSummary.tsx rename to src/routes/safe/components/Transactions/TxList/TxSummary.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/TxsInfiniteScroll.tsx b/src/routes/safe/components/Transactions/TxList/TxsInfiniteScroll.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/TxsInfiniteScroll.tsx rename to src/routes/safe/components/Transactions/TxList/TxsInfiniteScroll.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/check-circle-green.svg b/src/routes/safe/components/Transactions/TxList/assets/check-circle-green.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/check-circle-green.svg rename to src/routes/safe/components/Transactions/TxList/assets/check-circle-green.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/custom.svg b/src/routes/safe/components/Transactions/TxList/assets/custom.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/custom.svg rename to src/routes/safe/components/Transactions/TxList/assets/custom.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/incoming.svg b/src/routes/safe/components/Transactions/TxList/assets/incoming.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/incoming.svg rename to src/routes/safe/components/Transactions/TxList/assets/incoming.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/no-transactions.svg b/src/routes/safe/components/Transactions/TxList/assets/no-transactions.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/no-transactions.svg rename to src/routes/safe/components/Transactions/TxList/assets/no-transactions.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/outgoing.svg b/src/routes/safe/components/Transactions/TxList/assets/outgoing.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/outgoing.svg rename to src/routes/safe/components/Transactions/TxList/assets/outgoing.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/plus-circle-green.svg b/src/routes/safe/components/Transactions/TxList/assets/plus-circle-green.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/plus-circle-green.svg rename to src/routes/safe/components/Transactions/TxList/assets/plus-circle-green.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/settings.svg b/src/routes/safe/components/Transactions/TxList/assets/settings.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/settings.svg rename to src/routes/safe/components/Transactions/TxList/assets/settings.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/transactions-list-active.svg b/src/routes/safe/components/Transactions/TxList/assets/transactions-list-active.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/transactions-list-active.svg rename to src/routes/safe/components/Transactions/TxList/assets/transactions-list-active.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/assets/transactions-list-inactive.svg b/src/routes/safe/components/Transactions/TxList/assets/transactions-list-inactive.svg similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/assets/transactions-list-inactive.svg rename to src/routes/safe/components/Transactions/TxList/assets/transactions-list-inactive.svg diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useActionButtonsHandlers.ts b/src/routes/safe/components/Transactions/TxList/hooks/useActionButtonsHandlers.ts similarity index 94% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useActionButtonsHandlers.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useActionButtonsHandlers.ts index 3921d215..2226c29e 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useActionButtonsHandlers.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useActionButtonsHandlers.ts @@ -3,11 +3,11 @@ import { useSelector } from 'react-redux' import { Transaction } from 'src/logic/safe/store/models/types/gateway.d' import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { addressInList } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' +import { addressInList } from 'src/routes/safe/components/Transactions/TxList/utils' import { useTransactionActions } from './useTransactionActions' -import { TransactionActionStateContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxActionProvider' -import { TxHoverContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxHoverProvider' -import { TxLocationContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxLocationProvider' +import { TransactionActionStateContext } from 'src/routes/safe/components/Transactions/TxList/TxActionProvider' +import { TxHoverContext } from 'src/routes/safe/components/Transactions/TxList/TxHoverProvider' +import { TxLocationContext } from 'src/routes/safe/components/Transactions/TxList/TxLocationProvider' type ActionButtonsHandlers = { canCancel: boolean diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useAssetInfo.ts b/src/routes/safe/components/Transactions/TxList/hooks/useAssetInfo.ts similarity index 93% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useAssetInfo.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useAssetInfo.ts index dc6b3467..55ac92c8 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useAssetInfo.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useAssetInfo.ts @@ -9,8 +9,7 @@ import { SettingsChange, TransactionInfo, } from 'src/logic/safe/store/models/types/gateway.d' -import { getTxAmount } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' -import { NOT_AVAILABLE } from 'src/routes/safe/components/Transactions/TxsTable/columns' +import { getTxAmount, NOT_AVAILABLE } from 'src/routes/safe/components/Transactions/TxList/utils' export type TokenTransferAsset = { type: 'Transfer' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useHistoryTransactions.ts b/src/routes/safe/components/Transactions/TxList/hooks/useHistoryTransactions.ts similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useHistoryTransactions.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useHistoryTransactions.ts diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/usePagedHistoryTransactions.ts b/src/routes/safe/components/Transactions/TxList/hooks/usePagedHistoryTransactions.ts similarity index 96% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/usePagedHistoryTransactions.ts rename to src/routes/safe/components/Transactions/TxList/hooks/usePagedHistoryTransactions.ts index 9f685957..44ef7310 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/usePagedHistoryTransactions.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/usePagedHistoryTransactions.ts @@ -5,7 +5,7 @@ import { loadPagedHistoryTransactions } from 'src/logic/safe/store/actions/trans import { addHistoryTransactions } from 'src/logic/safe/store/actions/transactions/gatewayTransactions' import { TransactionDetails } from 'src/logic/safe/store/models/types/gateway.d' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { useHistoryTransactions } from 'src/routes/safe/components/Transactions/GatewayTransactions/hooks/useHistoryTransactions' +import { useHistoryTransactions } from 'src/routes/safe/components/Transactions/TxList/hooks/useHistoryTransactions' type PagedTransactions = { count: number diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/usePagedQueuedTransactions.ts b/src/routes/safe/components/Transactions/TxList/hooks/usePagedQueuedTransactions.ts similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/usePagedQueuedTransactions.ts rename to src/routes/safe/components/Transactions/TxList/hooks/usePagedQueuedTransactions.ts diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useQueueTransactions.ts b/src/routes/safe/components/Transactions/TxList/hooks/useQueueTransactions.ts similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useQueueTransactions.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useQueueTransactions.ts diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionActions.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionActions.ts similarity index 97% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionActions.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useTransactionActions.ts index 1f3042fb..5e3b7566 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionActions.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionActions.ts @@ -6,8 +6,8 @@ import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selector import { getQueuedTransactionsByNonce } from 'src/logic/safe/store/selectors/gatewayTransactions' import { sameAddress } from 'src/logic/wallets/ethAddresses' import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { TxLocationContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxLocationProvider' -import { isCancelTransaction } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' +import { TxLocationContext } from 'src/routes/safe/components/Transactions/TxList/TxLocationProvider' +import { isCancelTransaction } from 'src/routes/safe/components/Transactions/TxList/utils' import { grantedSelector } from 'src/routes/safe/container/selector' import { AppReduxState } from 'src/store' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionDetails.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionDetails.ts similarity index 96% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionDetails.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useTransactionDetails.ts index 060d4f2a..8c569093 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionDetails.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionDetails.ts @@ -3,7 +3,7 @@ import { useDispatch, useSelector } from 'react-redux' import { ExpandedTxDetails } from 'src/logic/safe/store/models/types/gateway.d' import { fetchTransactionDetails } from 'src/logic/safe/store/actions/fetchTransactionDetails' -import { TxLocationContext } from 'src/routes/safe/components/Transactions/GatewayTransactions/TxLocationProvider' +import { TxLocationContext } from 'src/routes/safe/components/Transactions/TxList/TxLocationProvider' import { getTransactionDetails } from 'src/logic/safe/store/selectors/gatewayTransactions' import { AppReduxState } from 'src/store' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionStatus.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionStatus.ts similarity index 98% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionStatus.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useTransactionStatus.ts index 299bb0b2..e64637b7 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionStatus.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionStatus.ts @@ -10,7 +10,7 @@ import { Transaction, } from 'src/logic/safe/store/models/types/gateway.d' import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { addressInList } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' +import { addressInList } from 'src/routes/safe/components/Transactions/TxList/utils' export type TransactionStatusProps = { color: ThemeColors diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionType.ts b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts similarity index 88% rename from src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionType.ts rename to src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts index 61e54268..ca04efbc 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionType.ts +++ b/src/routes/safe/components/Transactions/TxList/hooks/useTransactionType.ts @@ -3,11 +3,11 @@ import { useSelector } from 'react-redux' import { Transaction } from 'src/logic/safe/store/models/types/gateway.d' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import CustomTxIcon from 'src/routes/safe/components/Transactions/GatewayTransactions/assets/custom.svg' -import IncomingTxIcon from 'src/routes/safe/components/Transactions/GatewayTransactions/assets/incoming.svg' -import OutgoingTxIcon from 'src/routes/safe/components/Transactions/GatewayTransactions/assets/outgoing.svg' -import SettingsTxIcon from 'src/routes/safe/components/Transactions/GatewayTransactions/assets/settings.svg' -import { isCancelTransaction } from 'src/routes/safe/components/Transactions/GatewayTransactions/utils' +import CustomTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/custom.svg' +import IncomingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/incoming.svg' +import OutgoingTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/outgoing.svg' +import SettingsTxIcon from 'src/routes/safe/components/Transactions/TxList/assets/settings.svg' +import { isCancelTransaction } from 'src/routes/safe/components/Transactions/TxList/utils' export type TxTypeProps = { icon: string @@ -15,7 +15,7 @@ export type TxTypeProps = { } export const useTransactionType = (tx: Transaction): TxTypeProps => { - const [type, setType] = useState({ icon: CustomTxIcon, text: 'Custom transaction' }) + const [type, setType] = useState({ icon: CustomTxIcon, text: 'Contract interaction' }) const safeAddress = useSelector(safeParamAddressFromStateSelector) useEffect(() => { @@ -62,7 +62,7 @@ export const useTransactionType = (tx: Transaction): TxTypeProps => { break } - setType({ icon: CustomTxIcon, text: 'Custom transaction' }) + setType({ icon: CustomTxIcon, text: 'Contract interaction' }) break } } diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/index.tsx b/src/routes/safe/components/Transactions/TxList/index.tsx similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/index.tsx rename to src/routes/safe/components/Transactions/TxList/index.tsx diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/modals/ApproveTxModal.tsx b/src/routes/safe/components/Transactions/TxList/modals/ApproveTxModal.tsx similarity index 99% rename from src/routes/safe/components/Transactions/GatewayTransactions/modals/ApproveTxModal.tsx rename to src/routes/safe/components/Transactions/TxList/modals/ApproveTxModal.tsx index d6b1694a..eca47c1d 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/modals/ApproveTxModal.tsx +++ b/src/routes/safe/components/Transactions/TxList/modals/ApproveTxModal.tsx @@ -26,7 +26,7 @@ import { TxParametersDetail } from 'src/routes/safe/components/Transactions/help import { EditableTxParameters } from 'src/routes/safe/components/Transactions/helpers/EditableTxParameters' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { isThresholdReached } from 'src/routes/safe/components/Transactions/GatewayTransactions/hooks/useTransactionActions' +import { isThresholdReached } from 'src/routes/safe/components/Transactions/TxList/hooks/useTransactionActions' import { Overwrite } from 'src/types/helpers' import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' import { makeConfirmation } from 'src/logic/safe/store/models/confirmation' diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/modals/RejectTxModal.tsx b/src/routes/safe/components/Transactions/TxList/modals/RejectTxModal.tsx similarity index 98% rename from src/routes/safe/components/Transactions/GatewayTransactions/modals/RejectTxModal.tsx rename to src/routes/safe/components/Transactions/TxList/modals/RejectTxModal.tsx index 97637461..3426ba5a 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/modals/RejectTxModal.tsx +++ b/src/routes/safe/components/Transactions/TxList/modals/RejectTxModal.tsx @@ -46,7 +46,6 @@ export const RejectTxModal = ({ isOpen, onClose, gwTransaction }: Props): React. isOffChainSignature, isCreation, gasLimit, - gasEstimation, gasPriceFormatted, } = useEstimateTransactionGas({ txData: EMPTY_DATA, @@ -85,7 +84,7 @@ export const RejectTxModal = ({ isOpen, onClose, gwTransaction }: Props): React. diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/modals/style.ts b/src/routes/safe/components/Transactions/TxList/modals/style.ts similarity index 100% rename from src/routes/safe/components/Transactions/GatewayTransactions/modals/style.ts rename to src/routes/safe/components/Transactions/TxList/modals/style.ts diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/styled.tsx b/src/routes/safe/components/Transactions/TxList/styled.tsx similarity index 98% rename from src/routes/safe/components/Transactions/GatewayTransactions/styled.tsx rename to src/routes/safe/components/Transactions/TxList/styled.tsx index 10afad0f..de8d7f19 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/styled.tsx +++ b/src/routes/safe/components/Transactions/TxList/styled.tsx @@ -503,3 +503,8 @@ export const AlignItemsWithMargin = styled.div` margin-right: 6px; } ` +export const NoTransactions = styled.div` + display: flex; + flex-direction: column; + margin-top: 60px; +` diff --git a/src/routes/safe/components/Transactions/GatewayTransactions/utils.ts b/src/routes/safe/components/Transactions/TxList/utils.ts similarity index 85% rename from src/routes/safe/components/Transactions/GatewayTransactions/utils.ts rename to src/routes/safe/components/Transactions/TxList/utils.ts index 7bd9a5d9..d461e8cc 100644 --- a/src/routes/safe/components/Transactions/GatewayTransactions/utils.ts +++ b/src/routes/safe/components/Transactions/TxList/utils.ts @@ -9,21 +9,11 @@ import { TransactionInfo, Transfer, } from 'src/logic/safe/store/models/types/gateway.d' -import { SafeModuleTransaction } from 'src/logic/safe/store/models/types/transaction' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { sameAddress } from 'src/logic/wallets/ethAddresses' import { sameString } from 'src/utils/strings' -export const TX_TABLE_ID = 'id' -export const TX_TABLE_TYPE_ID = 'type' -export const TX_TABLE_DATE_ID = 'date' -export const TX_TABLE_AMOUNT_ID = 'amount' -export const TX_TABLE_STATUS_ID = 'status' -export const TX_TABLE_RAW_TX_ID = 'tx' -export const TX_TABLE_RAW_CANCEL_TX_ID = 'cancelTx' -export const TX_TABLE_EXPAND_ICON = 'expand' - export const NOT_AVAILABLE = 'n/a' interface AmountData { @@ -100,17 +90,6 @@ export const getTxTokenData = (txInfo: Transfer): txTokenData => { } } -export interface TableData { - amount: string - cancelTx?: Transaction - date: string - dateOrder?: number - id: string - status: string - tx: Transaction | SafeModuleTransaction - type: any -} - // TODO: isCancel // how can we be sure that it's a cancel tx without asking for tx-details? // can the client-gateway service provide info about the tx, Like: `isCancelTransaction: boolean`? diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx deleted file mode 100644 index 9b9431b5..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx +++ /dev/null @@ -1,242 +0,0 @@ -import Checkbox from '@material-ui/core/Checkbox' -import FormControlLabel from '@material-ui/core/FormControlLabel' -import IconButton from '@material-ui/core/IconButton' -import { makeStyles } from '@material-ui/core/styles' -import Close from '@material-ui/icons/Close' -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' - -import { styles } from './style' - -import Modal from 'src/components/Modal' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import Button from 'src/components/layout/Button' -import Hairline from 'src/components/layout/Hairline' -import Paragraph from 'src/components/layout/Paragraph' -import Row from 'src/components/layout/Row' -import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { processTransaction } from 'src/logic/safe/store/actions/processTransaction' - -import { safeParamAddressFromStateSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { EstimationStatus, useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' -import { TransactionFees } from 'src/components/TransactionsFees' -import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' -import { TxParametersDetail } from 'src/routes/safe/components/Transactions/helpers/TxParametersDetail' -import { EditableTxParameters } from 'src/routes/safe/components/Transactions/helpers/EditableTxParameters' - -const useStyles = makeStyles(styles) - -export const APPROVE_TX_MODAL_SUBMIT_BTN_TEST_ID = 'approve-tx-modal-submit-btn' -export const REJECT_TX_MODAL_SUBMIT_BTN_TEST_ID = 'reject-tx-modal-submit-btn' - -const getModalTitleAndDescription = (thresholdReached, isCancelTx) => { - const modalInfo = { - title: 'Execute Transaction Rejection', - description: 'This action will execute this transaction.', - } - - if (isCancelTx) { - return modalInfo - } - - if (thresholdReached) { - modalInfo.title = 'Execute Transaction' - modalInfo.description = - 'This action will execute this transaction. A separate Transaction will be performed to submit the execution.' - } else { - modalInfo.title = 'Approve Transaction' - modalInfo.description = - 'This action will approve this transaction. A separate Transaction will be performed to submit the approval.' - } - - return modalInfo -} - -type Props = { - onClose: () => void - canExecute: boolean - isCancelTx?: boolean - isOpen: boolean - thresholdReached: boolean - tx: Transaction - txParameters: TxParameters -} - -export const ApproveTxModal = ({ - onClose, - canExecute, - isCancelTx = false, - isOpen, - thresholdReached, - tx, -}: Props): React.ReactElement => { - const dispatch = useDispatch() - const userAddress = useSelector(userAccountSelector) - const classes = useStyles() - const threshold = useSelector(safeThresholdSelector) || 1 - const safeAddress = useSelector(safeParamAddressFromStateSelector) - const [approveAndExecute, setApproveAndExecute] = useState(canExecute) - const { description, title } = getModalTitleAndDescription(thresholdReached, isCancelTx) - const oneConfirmationLeft = !thresholdReached && tx.confirmations.size + 1 === threshold - const isTheTxReadyToBeExecuted = oneConfirmationLeft ? true : thresholdReached - const [manualGasPrice, setManualGasPrice] = useState() - - const { - gasLimit, - gasPriceFormatted, - 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, - manualGasPrice, - }) - - const handleExecuteCheckbox = () => setApproveAndExecute((prevApproveAndExecute) => !prevApproveAndExecute) - - const approveTx = (txParameters: TxParameters) => { - dispatch( - processTransaction({ - safeAddress, - tx: tx as any, - userAddress, - notifiedTransaction: TX_NOTIFICATION_TYPES.CONFIRMATION_TX, - approveAndExecute: canExecute && approveAndExecute && isTheTxReadyToBeExecuted, - ethParameters: txParameters, - thresholdReached, - }), - ) - onClose() - } - - const getParametersStatus = () => { - if (canExecute || approveAndExecute) { - return 'SAFE_DISABLED' - } - - return 'DISABLED' - } - - const closeEditModalCallback = (txParameters: TxParameters) => { - const oldGasPrice = Number(gasPriceFormatted) - const newGasPrice = Number(txParameters.ethGasPrice) - - if (newGasPrice && oldGasPrice !== newGasPrice) { - setManualGasPrice(txParameters.ethGasPrice) - } - } - - return ( - - - {(txParameters, toggleEditMode) => { - return ( - <> - {/* Header */} - - - {title} - - - - - - - - - {/* Tx info */} - - - {description} - - Transaction nonce: -
- {tx.nonce} -
- - {oneConfirmationLeft && canExecute && ( - <> - - Approving this transaction executes it right away. - {!isCancelTx && - ' If you want approve but execute the transaction manually later, click on the checkbox below.'} - - - {!isCancelTx && ( - - } - label="Execute transaction" - data-testid="execute-checkbox" - /> - )} - - )} - - {/* Tx Parameters */} - {approveAndExecute && ( - - )} -
-
- {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( - - - - )} - {/* Footer */} - - - - - - ) - }} -
-
- ) -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/style.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/style.ts deleted file mode 100644 index 19a99e1e..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/style.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createStyles } from '@material-ui/core' -import { background, border, lg, md, sm } from 'src/theme/variables' - -export const styles = createStyles({ - heading: { - padding: `${sm} ${lg}`, - justifyContent: 'space-between', - boxSizing: 'border-box', - height: '74px', - }, - headingText: { - fontSize: lg, - }, - closeIcon: { - height: '35px', - width: '35px', - }, - container: { - padding: `${md} ${lg}`, - }, - buttonRow: { - height: '84px', - justifyContent: 'center', - position: 'relative', - bottom: 0, - width: '100%', - borderTop: `1px solid ${border}`, - }, - nonceNumber: { - marginTop: sm, - fontSize: md, - }, - gasCostsContainer: { - backgroundColor: background, - padding: `0 ${lg}`, - }, -}) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx deleted file mode 100644 index bae4e469..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { makeStyles } from '@material-ui/core/styles' -import React from 'react' -import { EthHashInfo } from '@gnosis.pm/safe-react-components' - -import { Transaction } from 'src/logic/safe/store/models/types/transaction' - -import { formatDate } from 'src/routes/safe/components/Transactions/TxsTable/columns' -import Bold from 'src/components/layout/Bold' -import Paragraph from 'src/components/layout/Paragraph' -import Block from 'src/components/layout/Block' -import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import { getExplorerInfo } from 'src/config' - -const useStyles = makeStyles({ - address: { - height: '20px', - }, - txData: { - alignItems: 'center', - display: 'flex', - lineHeight: '1.6', - }, - txHash: { - paddingRight: '3px', - }, -}) - -type Props = { - tx?: Transaction -} - -export const CreationTx = ({ tx }: Props): React.ReactElement | null => { - const classes = useStyles() - const isCreationTx = tx?.type === TransactionTypes.CREATION - - if (!tx || !isCreationTx) { - return null - } - const explorerUrl = getExplorerInfo(tx.creator) - const scanBlockFactoryAddressUrl = getExplorerInfo(tx.factoryAddress) - const scanBlockMasterCopyUrl = getExplorerInfo(tx.masterCopy) - - return isCreationTx ? ( - <> - - Created: - {formatDate(tx.created)} - - - Creator: - {tx.creator ? : 'n/a'} - - - Factory: - {tx.factoryAddress ? ( - - ) : ( - 'n/a' - )} - - - Mastercopy: - {tx.masterCopy ? ( - - ) : ( - 'n/a' - )} - - - ) : null -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTx/index.tsx deleted file mode 100644 index 7d9e1ccd..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTx/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react' -import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransaction' -import { formatDate } from 'src/routes/safe/components/Transactions/TxsTable/columns' -import Bold from 'src/components/layout/Bold' -import Paragraph from 'src/components/layout/Paragraph' - -export const IncomingTx = ({ tx }) => { - if (!tx) { - return null - } - - const isIncomingTx = !!INCOMING_TX_TYPES[tx.type] - - return isIncomingTx ? ( - - Created: - {formatDate(tx.executionDate)} - - ) : null -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx deleted file mode 100644 index 3243d867..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { makeStyles } from '@material-ui/core/styles' -import React from 'react' -import { useSelector } from 'react-redux' - -import { EtherscanLink } from 'src/components/EtherscanLink' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' -import { getIncomingTxAmount } from 'src/routes/safe/components/Transactions/TxsTable/columns' -import { lg, md } from 'src/theme/variables' - -export const TRANSACTIONS_DESC_INCOMING_TEST_ID = 'tx-description-incoming' - -const useStyles = makeStyles({ - txDataContainer: { - paddingTop: lg, - paddingLeft: md, - paddingBottom: md, - borderRight: '2px solid rgb(232, 231, 230)', - }, -}) - -const TransferDescription = ({ from, txFromName, value = '' }) => ( - - Received {value} from: -
- {txFromName ? ( - - ) : ( - - )} -
-) - -const IncomingTxDescription = ({ tx }) => { - const classes = useStyles() - const txFromName = useSelector((state) => getNameFromAddressBookSelector(state, tx.from)) - return ( - - - - ) -} - -export default IncomingTxDescription diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OutgoingTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OutgoingTx/index.tsx deleted file mode 100644 index 674fb8f7..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OutgoingTx/index.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react' - -import { formatDate } from 'src/routes/safe/components/Transactions/TxsTable/columns' -import Bold from 'src/components/layout/Bold' -import Paragraph from 'src/components/layout/Paragraph' -import { TransactionTypes } from 'src/logic/safe/store/models/types/transaction' - -export const OutgoingTx = ({ tx }) => { - if (!tx) { - return null - } - - const isOutgoingTx = [ - TransactionTypes.OUTGOING, - TransactionTypes.UPGRADE, - TransactionTypes.CUSTOM, - TransactionTypes.SETTINGS, - TransactionTypes.COLLECTIBLE, - TransactionTypes.TOKEN, - ].includes(tx.type) - - return isOutgoingTx ? ( - <> - - Created: - {formatDate(tx.submissionDate)} - - {tx.executionDate && ( - - Executed: - {formatDate(tx.executionDate)} - - )} - {tx.refundParams && ( - - Refund: - max. {tx.refundParams.fee} {tx.refundParams.symbol} - - )} - {tx.operation === 1 && ( - - Delegate Call - - )} - {tx.operation === 2 && ( - - Contract Creation - - )} - - ) : null -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx deleted file mode 100644 index 06bbaec6..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx +++ /dev/null @@ -1,194 +0,0 @@ -import { makeStyles } from '@material-ui/core/styles' -import cn from 'classnames' -import React from 'react' -import { useSelector } from 'react-redux' -import { EthHashInfo } from '@gnosis.pm/safe-react-components' - -import CancelSmallFilledCircle from './assets/cancel-small-filled.svg' -import ConfirmSmallFilledCircle from './assets/confirm-small-filled.svg' -import ConfirmSmallGreenCircle from './assets/confirm-small-green.svg' -import ConfirmSmallGreyCircle from './assets/confirm-small-grey.svg' -import ConfirmSmallRedCircle from './assets/confirm-small-red.svg' -import PendingSmallYellowCircle from './assets/confirm-small-yellow.svg' -import { styles } from './style' - -import Block from 'src/components/layout/Block' -import Button from 'src/components/layout/Button' -import Img from 'src/components/layout/Img' -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import { OwnersWithoutConfirmations } from './index' -import { getExplorerInfo } from 'src/config' - -export const CONFIRM_TX_BTN_TEST_ID = 'confirm-btn' -export const EXECUTE_TX_BTN_TEST_ID = 'execute-btn' -export const REJECT_TX_BTN_TEST_ID = 'reject-btn' -export const EXECUTE_REJECT_TX_BTN_TEST_ID = 'execute-reject-btn' - -type OwnerComponentProps = { - executor: string - isCancelTx?: boolean - onTxConfirm?: () => void - onTxExecute?: () => void - onTxReject?: () => void - ownersUnconfirmed: OwnersWithoutConfirmations - ownersWhoConfirmed: string[] - showConfirmBtn?: boolean - showExecuteBtn?: boolean - showExecuteRejectBtn?: boolean - showRejectBtn?: boolean - thresholdReached: boolean - userAddress: string - confirmed?: boolean - owner: string - pendingAcceptAction?: boolean - pendingRejectAction?: boolean -} - -const useStyles = makeStyles(styles) - -const OwnerComponent = (props: OwnerComponentProps): React.ReactElement => { - const { - owner, - pendingAcceptAction, - pendingRejectAction, - isCancelTx, - thresholdReached, - executor, - showConfirmBtn, - onTxConfirm, - onTxExecute, - showExecuteBtn, - showRejectBtn, - userAddress, - onTxReject, - showExecuteRejectBtn, - confirmed, - } = props - const nameInAdbk = useSelector((state) => getNameFromAddressBookSelector(state, owner)) - const classes = useStyles() - const [imgCircle, setImgCircle] = React.useState(ConfirmSmallGreyCircle) - - React.useMemo(() => { - if (pendingAcceptAction || pendingRejectAction) { - setImgCircle(PendingSmallYellowCircle) - return - } - if (confirmed) { - setImgCircle(isCancelTx ? CancelSmallFilledCircle : ConfirmSmallFilledCircle) - return - } - if (thresholdReached || executor) { - setImgCircle(isCancelTx ? ConfirmSmallRedCircle : ConfirmSmallGreenCircle) - return - } - setImgCircle(ConfirmSmallGreyCircle) - }, [confirmed, thresholdReached, executor, isCancelTx, pendingAcceptAction, pendingRejectAction]) - - const getTimelineLine = () => { - if (pendingAcceptAction || pendingRejectAction) { - return classes.verticalPendingAction - } - if (isCancelTx) { - return classes.verticalLineCancel - } - return classes.verticalLineDone - } - - const confirmButton = () => { - if (pendingRejectAction) { - return null - } - if (pendingAcceptAction) { - return Pending - } - return ( - <> - {showConfirmBtn && ( - - )} - {showExecuteBtn && ( - - )} - - ) - } - - const rejectButton = () => { - if (pendingRejectAction) { - return Pending - } - if (pendingAcceptAction) { - return null - } - return ( - <> - {showRejectBtn && ( - - )} - {showExecuteRejectBtn && ( - - )} - - ) - } - const explorerUrl = getExplorerInfo(owner) - return ( - -
-
- -
- - - {owner === userAddress && {isCancelTx ? rejectButton() : confirmButton()}} - {owner === executor && Executor} - - ) -} - -export default OwnerComponent diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnersList.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnersList.tsx deleted file mode 100644 index 0d0b4058..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnersList.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react' - -import OwnerComponent from './OwnerComponent' -import { OwnersWithoutConfirmations } from './index' - -type OwnersListProps = { - executor: string - isCancelTx?: boolean - onTxConfirm?: () => void - onTxExecute?: () => void - onTxReject?: () => void - ownersUnconfirmed: OwnersWithoutConfirmations - ownersWhoConfirmed: string[] - showConfirmBtn?: boolean - showExecuteBtn?: boolean - showExecuteRejectBtn?: boolean - showRejectBtn?: boolean - thresholdReached: boolean - userAddress: string -} - -const OwnersList = (props: OwnersListProps): React.ReactElement => { - const { ownersUnconfirmed, ownersWhoConfirmed } = props - return ( - <> - {ownersWhoConfirmed.map((owner) => ( - - ))} - {ownersUnconfirmed.map(({ hasPendingAcceptActions, hasPendingRejectActions, owner }) => ( - - ))} - - ) -} - -export default OwnersList diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/cancel-small-filled.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/cancel-small-filled.svg deleted file mode 100644 index 8c2b45dd..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/cancel-small-filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-green.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-green.svg deleted file mode 100644 index ed4fbbb7..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-green.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-red.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-red.svg deleted file mode 100644 index 191eb63a..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/check-large-filled-red.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-green.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-green.svg deleted file mode 100644 index 353553ca..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-green.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-grey.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-grey.svg deleted file mode 100644 index 1abe86e5..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-grey.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-red.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-red.svg deleted file mode 100644 index e5ddd508..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-large-red.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-filled.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-filled.svg deleted file mode 100644 index 7f170aec..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-filled.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-green.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-green.svg deleted file mode 100644 index c4bb04c8..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-green.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-grey.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-grey.svg deleted file mode 100644 index 45a7fd9a..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-grey.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-red.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-red.svg deleted file mode 100644 index 4e9f8350..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-red.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-yellow.svg b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-yellow.svg deleted file mode 100644 index fbd9928b..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/assets/confirm-small-yellow.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx deleted file mode 100644 index c23827af..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/index.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import cn from 'classnames' -import React from 'react' -import { useSelector } from 'react-redux' - -import OwnersList from './OwnersList' -import CheckLargeFilledGreenCircle from './assets/check-large-filled-green.svg' -import CheckLargeFilledRedCircle from './assets/check-large-filled-red.svg' -import ConfirmLargeGreenCircle from './assets/confirm-large-green.svg' -import ConfirmLargeGreyCircle from './assets/confirm-large-grey.svg' -import ConfirmLargeRedCircle from './assets/confirm-large-red.svg' - -import Block from 'src/components/layout/Block' -import Col from 'src/components/layout/Col' -import Img from 'src/components/layout/Img' -import Paragraph from 'src/components/layout/Paragraph/index' -import { userAccountSelector } from 'src/logic/wallets/store/selectors' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { List } from 'immutable' -import { makeStyles } from '@material-ui/core/styles' -import { styles } from './style' -import { makeTransaction } from 'src/logic/safe/store/models/transaction' -import { safeOwnersSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' -import { TransactionStatus } from 'src/logic/safe/store/models/types/transaction' -import { SafeOwner } from 'src/logic/safe/store/models/safe' - -export type OwnersWithoutConfirmations = { - hasPendingAcceptActions: boolean - hasPendingRejectActions: boolean - owner: string -}[] - -function getOwnersConfirmations(tx: Transaction, userAddress: string): [string[], boolean] { - const ownersWhoConfirmed: string[] = [] - let currentUserAlreadyConfirmed = false - - tx.confirmations?.forEach((conf) => { - if (conf.owner === userAddress) { - currentUserAlreadyConfirmed = true - } - - ownersWhoConfirmed.push(conf.owner) - }) - return [ownersWhoConfirmed, currentUserAlreadyConfirmed] -} - -function getPendingOwnersConfirmations( - owners: List<{ name: string; address: string }>, - tx: Transaction, - userAddress: string, -): [OwnersWithoutConfirmations, boolean] { - const ownersWithNoConfirmations: string[] = [] - let currentUserNotConfirmed = true - - owners.forEach((owner) => { - const confirmationsEntry = tx.confirmations.find((conf) => conf.owner === owner.address) - if (!confirmationsEntry) { - ownersWithNoConfirmations.push(owner.address) - } - if (confirmationsEntry && confirmationsEntry.owner === userAddress) { - currentUserNotConfirmed = false - } - }) - - const confirmationPendingActions = tx.ownersWithPendingActions.get('confirm') - const confirmationRejectActions = tx.ownersWithPendingActions.get('reject') - - const ownersWithNoConfirmationsSorted = ownersWithNoConfirmations - .map((owner) => ({ - hasPendingAcceptActions: !!confirmationPendingActions?.includes(owner), - hasPendingRejectActions: !!confirmationRejectActions?.includes(owner), - owner, - })) - // Reorders the list of unconfirmed owners, owners with pendingActions should be first - .sort((ownerA, ownerB) => { - // If the first owner has pending actions, A should be before B - if (ownerA.hasPendingRejectActions || ownerA.hasPendingAcceptActions) { - return -1 - } - // The first owner has not pending actions but the second yes, B should be before A - if (ownerB.hasPendingRejectActions || ownerB.hasPendingAcceptActions) { - return 1 - } - // Otherwise do not change order - return 0 - }) - - return [ownersWithNoConfirmationsSorted, currentUserNotConfirmed] -} - -const useStyles = makeStyles(styles) - -type ownersColumnProps = { - tx: Transaction - cancelTx?: Transaction - thresholdReached: boolean - cancelThresholdReached: boolean - onTxConfirm: () => void - onTxExecute: () => void - onTxReject: () => void - canExecute: boolean - canExecuteCancel: boolean -} - -const OwnersColumn = ({ - tx, - cancelTx = makeTransaction({ isCancellationTx: true, status: TransactionStatus.AWAITING_YOUR_CONFIRMATION }), - thresholdReached, - cancelThresholdReached, - onTxConfirm, - onTxExecute, - onTxReject, - canExecute, - canExecuteCancel, -}: ownersColumnProps): React.ReactElement => { - const classes = useStyles() - let showOlderTxAnnotation - if (tx.isExecuted || cancelTx.isExecuted) { - showOlderTxAnnotation = false - } else { - showOlderTxAnnotation = (thresholdReached && !canExecute) || (cancelThresholdReached && !canExecuteCancel) - } - const owners = useSelector(safeOwnersSelector) as List - const threshold = useSelector(safeThresholdSelector) - const userAddress = useSelector(userAccountSelector) - const [ownersWhoConfirmed, currentUserAlreadyConfirmed] = getOwnersConfirmations(tx, userAddress) - const [ownersUnconfirmed, userIsUnconfirmedOwner] = getPendingOwnersConfirmations(owners, tx, userAddress) - const [ownersWhoConfirmedCancel, currentUserAlreadyConfirmedCancel] = getOwnersConfirmations(cancelTx, userAddress) - const [ownersUnconfirmedCancel, userIsUnconfirmedCancelOwner] = getPendingOwnersConfirmations( - owners, - cancelTx, - userAddress, - ) - - let displayButtonRow = true - if (tx.executionTxHash) { - // One of owners already executed the tx - displayButtonRow = false - } else if (tx.status === 'cancelled') { - // tx is cancelled (replaced) by another one - displayButtonRow = false - } else if (currentUserAlreadyConfirmedCancel) { - displayButtonRow = false - } - - // TODO: simplify this whole logic around tx status, it's getting hard to maintain and follow - const showConfirmBtn = - !tx.isExecuted && - tx.status !== 'pending' && - cancelTx.status !== 'pending' && - !tx.cancelled && - userIsUnconfirmedOwner && - !currentUserAlreadyConfirmed && - !thresholdReached - - const showExecuteBtn = - canExecute && !tx.isExecuted && thresholdReached && tx.status !== 'pending' && cancelTx.status !== 'pending' - - const showRejectBtn = - !cancelTx.isExecuted && - !tx.isExecuted && - tx.status !== 'pending' && - cancelTx.status !== 'pending' && - userIsUnconfirmedCancelOwner && - !currentUserAlreadyConfirmedCancel && - !cancelThresholdReached && - displayButtonRow - - const showExecuteRejectBtn = - !cancelTx.isExecuted && - !tx.isExecuted && - canExecuteCancel && - cancelThresholdReached && - tx.status !== 'pending' && - cancelTx.status !== 'pending' - - const txThreshold = cancelTx.isExecuted ? tx.confirmations.size : threshold - const cancelThreshold = tx.isExecuted ? cancelTx.confirmations.size : threshold - - return ( - - -
- -
- {tx.isExecuted - ? `Confirmed [${tx.confirmations.size}/${tx.confirmations.size}]` - : `Confirmed [${tx.confirmations.size}/${txThreshold}]`} -
- - {/* Cancel TX thread - START */} - -
-
- -
- {cancelTx.isExecuted - ? `Rejected [${cancelTx.confirmations.size}/${cancelTx.confirmations.size}]` - : `Rejected [${cancelTx.confirmations.size}/${cancelThreshold}]`} - - - {/* Cancel TX thread - END */} - -
-
- {!tx.isExecuted && !cancelTx.isExecuted && Confirm / Execute tx} - {tx.isExecuted && TX Executed icon} - {cancelTx.isExecuted && TX Executed icon} -
- Executed - - - {showOlderTxAnnotation && ( - - There are older transactions that need to be executed first - - )} - - ) -} - -export default OwnersColumn diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/style.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/style.ts deleted file mode 100644 index 36e8fdf2..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/style.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { boldFont, border, error, primary, secondary, secondaryText, sm, warning } from 'src/theme/variables' -import { createStyles } from '@material-ui/core/styles' - -export const styles = createStyles({ - ownersList: { - height: '192px', - overflowY: 'scroll', - padding: 0, - width: '100%', - }, - rightCol: { - borderLeft: `2px solid ${border}`, - boxSizing: 'border-box', - }, - verticalLine: { - backgroundColor: secondaryText, - height: '55px', - left: '27px', - position: 'absolute', - top: '-27px', - width: '2px', - zIndex: 12, - }, - verticalLinePending: { - backgroundColor: secondaryText, - }, - verticalLineDone: { - backgroundColor: secondary, - }, - verticalLineCancel: { - backgroundColor: error, - }, - verticalPendingAction: { - backgroundColor: warning, - }, - icon: { - marginRight: sm, - }, - owner: { - borderBottom: `1px solid ${border}`, - }, - container: { - alignItems: 'center', - display: 'flex', - padding: '13px 15px 13px 18px', - position: 'relative', - }, - ownerListTitle: { - alignItems: 'center', - display: 'flex', - fontSize: '11px', - fontWeight: boldFont, - letterSpacing: '1px', - lineHeight: 1.3, - padding: '15px 15px 15px 18px', - position: 'relative', - textTransform: 'uppercase', - }, - olderTxAnnotation: { - textAlign: 'center', - }, - ownerListTitleDone: { - color: secondary, - }, - ownerListTitleCancelDone: { - color: error, - }, - name: { - height: '15px', - overflow: 'hidden', - textOverflow: 'ellipsis', - }, - address: { - height: '20px', - }, - spacer: { - flex: 'auto', - }, - circleState: { - display: 'flex', - justifyContent: 'center', - marginRight: '18px', - width: '20px', - zIndex: 13, - - '& > img': { - display: 'block', - }, - }, - button: { - alignSelf: 'center', - flexGrow: 0, - fontSize: '16px', - justifyContent: 'center', - paddingLeft: '14px', - paddingRight: '14px', - }, - lastButton: { - marginLeft: '10px', - }, - executor: { - alignSelf: 'center', - background: border, - borderRadius: '3px', - color: primary, - fontSize: '11px', - height: '24px', - lineHeight: '24px', - padding: '0 12px', - }, -}) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx deleted file mode 100644 index 8198ee61..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import IconButton from '@material-ui/core/IconButton' -import { makeStyles } from '@material-ui/core/styles' -import Close from '@material-ui/icons/Close' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' - -import { styles } from './style' - -import Modal from 'src/components/Modal' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import Button from 'src/components/layout/Button' -import Hairline from 'src/components/layout/Hairline' -import Paragraph from 'src/components/layout/Paragraph' -import Row from 'src/components/layout/Row' -import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { createTransaction } from 'src/logic/safe/store/actions/createTransaction' - -import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { EstimationStatus, useEstimateTransactionGas } from 'src/logic/hooks/useEstimateTransactionGas' -import { TransactionFees } from 'src/components/TransactionsFees' -import { TxParametersDetail } from 'src/routes/safe/components/Transactions/helpers/TxParametersDetail' -import { EditableTxParameters } from 'src/routes/safe/components/Transactions/helpers/EditableTxParameters' -import { TxParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' -import { ParametersStatus } from 'src/routes/safe/components/Transactions/helpers/utils' - -const useStyles = makeStyles(styles) - -type Props = { - isOpen: boolean - onClose: () => void - tx: Transaction -} - -export const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { - const dispatch = useDispatch() - const safeAddress = useSelector(safeParamAddressFromStateSelector) - const classes = useStyles() - - const { - gasCostFormatted, - txEstimationExecutionStatus, - isExecution, - isOffChainSignature, - isCreation, - gasLimit, - gasEstimation, - gasPriceFormatted, - } = useEstimateTransactionGas({ - txData: EMPTY_DATA, - txRecipient: safeAddress, - }) - - const sendReplacementTransaction = (txParameters: TxParameters) => { - dispatch( - createTransaction({ - safeAddress, - to: safeAddress, - valueInWei: '0', - txNonce: tx.nonce, - origin: tx.origin, - safeTxGas: txParameters.safeTxGas ? Number(txParameters.safeTxGas) : undefined, - ethParameters: txParameters, - notifiedTransaction: TX_NOTIFICATION_TYPES.CANCELLATION_TX, - }), - ) - onClose() - } - - const getParametersStatus = (): ParametersStatus => { - return 'CANCEL_TRANSACTION' - } - - return ( - - - {(txParameters, toggleEditMode) => { - return ( - <> - - - Reject transaction - - - - - - - - - - This action will cancel this transaction. A separate transaction will be performed to submit the - rejection. - - - Transaction nonce: -
- {tx.nonce} -
-
- {/* Tx Parameters */} - -
- {txEstimationExecutionStatus === EstimationStatus.LOADING ? null : ( - - - - )} - - - - - - ) - }} -
-
- ) -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/style.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/style.ts deleted file mode 100644 index 19a99e1e..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/style.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createStyles } from '@material-ui/core' -import { background, border, lg, md, sm } from 'src/theme/variables' - -export const styles = createStyles({ - heading: { - padding: `${sm} ${lg}`, - justifyContent: 'space-between', - boxSizing: 'border-box', - height: '74px', - }, - headingText: { - fontSize: lg, - }, - closeIcon: { - height: '35px', - width: '35px', - }, - container: { - padding: `${md} ${lg}`, - }, - buttonRow: { - height: '84px', - justifyContent: 'center', - position: 'relative', - bottom: 0, - width: '100%', - borderTop: `1px solid ${border}`, - }, - nonceNumber: { - marginTop: sm, - fontSize: md, - }, - gasCostsContainer: { - backgroundColor: background, - padding: `0 ${lg}`, - }, -}) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx deleted file mode 100644 index ed2a11d9..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx +++ /dev/null @@ -1,335 +0,0 @@ -import { IconText, Text, EthHashInfo } from '@gnosis.pm/safe-react-components' -import { makeStyles } from '@material-ui/core/styles' -import React from 'react' - -import styled from 'styled-components' - -import { styles } from './styles' -import Value from './Value' - -import Col from 'src/components/layout/Col' -import { RESET_TIME_OPTIONS } from 'src/routes/safe/components/Settings/SpendingLimit/FormFields/ResetTime' -import useTokenInfo from 'src/logic/safe/hooks/useTokenInfo' -import { AddressInfo, ResetTimeInfo, TokenInfo } from 'src/routes/safe/components/Settings/SpendingLimit/InfoDisplay' -import Block from 'src/components/layout/Block' -import { - extractMultiSendDataDecoded, - MultiSendDetails, -} from 'src/routes/safe/store/actions/transactions/utils/multiSendDecodedDetails' -import Bold from 'src/components/layout/Bold' -import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' -import Collapse from 'src/components/Collapse' -import { useSelector } from 'react-redux' -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import Paragraph from 'src/components/layout/Paragraph' -import LinkWithRef from 'src/components/layout/Link' -import { shortVersionOf } from 'src/logic/wallets/ethAddresses' -import { Transaction, SafeModuleTransaction } from 'src/logic/safe/store/models/types/transaction' -import { DataDecoded } from 'src/logic/safe/store/models/types/transactions.d' -import DividerLine from 'src/components/DividerLine' -import { isArrayParameter } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils' - -import { getExplorerInfo, getNetworkInfo } from 'src/config' -import { decodeMethods, isDeleteAllowanceMethod, isSetAllowanceMethod } from 'src/logic/contracts/methodIds' - -export const TRANSACTIONS_DESC_CUSTOM_VALUE_TEST_ID = 'tx-description-custom-value' -export const TRANSACTIONS_DESC_CUSTOM_DATA_TEST_ID = 'tx-description-custom-data' -export const TRANSACTION_DESC_ACTION_TEST_ID = 'tx-description-action-data' - -const useStyles = makeStyles(styles) - -const TxDetailsMethodName = styled(Text)` - text-indent: 4px; -` -const TxDetailsMethodParam = styled.div<{ isArrayParameter: boolean }>` - padding-left: 8px; - display: ${({ isArrayParameter }) => (isArrayParameter ? 'block' : 'flex')}; - align-items: center; - - p:first-of-type { - margin-right: ${({ isArrayParameter }) => (isArrayParameter ? '0' : '4px')}; - } -` -const TxDetailsContent = styled.div` - padding: 8px 8px 8px 16px; - overflow-wrap: break-word; -` - -const TxInfo = styled.div` - padding: 8px 8px 8px 16px; -` - -const StyledMethodName = styled(Text)` - white-space: nowrap; -` - -const { nativeCoin } = getNetworkInfo() - -const TxInfoDetails = ({ data }: { data: DataDecoded }): React.ReactElement => ( - - - {data.method} - - - {data.parameters.map((param, index) => ( - - - {param.name}({param.type}): - - - - ))} - -) - -const SpendingLimitDetailsContainer = styled.div` - padding-left: 24px; -` - -const spendingLimitTxType = (data: string | null): { isSetSpendingLimit: boolean; isDeleteSpendingLimit: boolean } => ({ - isSetSpendingLimit: !!data && isSetAllowanceMethod(data), - isDeleteSpendingLimit: !!data && isDeleteAllowanceMethod(data), -}) - -interface NewSpendingLimitDetailsProps { - data: DataDecoded -} - -const ModifySpendingLimitDetails = ({ data }: NewSpendingLimitDetailsProps): React.ReactElement => { - const [beneficiary, tokenAddress, amount, resetTimeMin] = React.useMemo( - () => data.parameters.map(({ value }) => value), - [data.parameters], - ) - - const resetTimeLabel = React.useMemo( - () => RESET_TIME_OPTIONS.find(({ value }) => +value === +resetTimeMin / 24 / 60)?.label ?? '', - [resetTimeMin], - ) - - const tokenInfo = useTokenInfo(tokenAddress) - - return ( - <> - - Modify Spending Limit: - - - - - - - {tokenInfo && ( - - )} - - - - - - - ) -} - -const DeleteSpendingLimitDetails = ({ data }: NewSpendingLimitDetailsProps): React.ReactElement => { - const [beneficiary, tokenAddress] = React.useMemo(() => data.parameters.map(({ value }) => value), [data.parameters]) - const tokenInfo = useTokenInfo(tokenAddress) - - return ( - <> - - Delete Spending Limit: - - - - - - {tokenInfo && } - - - ) -} - -const MultiSendCustomDataAction = ({ tx, order }: { tx: MultiSendDetails; order: number }): React.ReactElement => { - const classes = useStyles() - const methodName = tx.dataDecoded?.method ? ` (${tx.dataDecoded.method})` : '' - const data = tx.dataDecoded ?? decodeMethods(tx.data) - const explorerUrl = getExplorerInfo(tx.to) - const { isSetSpendingLimit, isDeleteSpendingLimit } = spendingLimitTxType(tx.data) - - return ( - } - > - {isSetSpendingLimit || isDeleteSpendingLimit ? ( - - {isSetSpendingLimit && } - {isDeleteSpendingLimit && } - - ) : ( - - - - Send {fromTokenUnit(tx.value, nativeCoin.decimals)} {nativeCoin.name} to: - - - - - {!!data ? : tx.data && } - - )} - - ) -} - -const MultiSendCustomData = ({ txDetails }: { txDetails: MultiSendDetails[] }): React.ReactElement => { - const classes = useStyles() - - return ( - - {txDetails.map((tx, index) => ( - - ))} - - ) -} - -export const TxData = ({ data }: { data: string }): React.ReactElement => { - const classes = useStyles() - const [showTxData, setShowTxData] = React.useState(false) - const showExpandBtn = data.length > 20 - - return ( - - {showExpandBtn ? ( - <> - {showTxData ? ( - <> - {data}{' '} - setShowTxData(false)} - rel="noopener noreferrer" - target="_blank" - > - Show Less - - - ) : ( - <> - {shortVersionOf(data, 20)}{' '} - setShowTxData(true)} - rel="noopener noreferrer" - target="_blank" - > - Show More - - - )} - - ) : ( - data - )} - - ) -} - -const TxActionData = ({ dataDecoded }: { dataDecoded: DataDecoded }): React.ReactElement => { - const classes = useStyles() - - return ( - <> - - - - Action - - - - - - ) -} - -interface HexEncodedDataProps { - data: string -} - -const HexEncodedData = ({ data }: HexEncodedDataProps): React.ReactElement => { - const classes = useStyles() - - return ( - - Data (hex encoded): - - - ) -} - -interface GenericCustomDataProps { - amount?: string - data?: string | null - recipient?: string - storedTx: Transaction | SafeModuleTransaction -} - -const GenericCustomData = ({ - amount = '0', - data = null, - recipient, - storedTx, -}: GenericCustomDataProps): React.ReactElement => { - const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, recipient)) - const explorerUrl = recipient ? getExplorerInfo(recipient) : '' - const txData = storedTx?.dataDecoded ?? decodeMethods(data) - const { isSetSpendingLimit, isDeleteSpendingLimit } = spendingLimitTxType(data) - - return isSetSpendingLimit || isDeleteSpendingLimit ? ( - <> - {isSetSpendingLimit && } - {isDeleteSpendingLimit && } - - ) : ( - - {recipient && ( - - Send {amount} to: - - - - )} - - {!!txData ? : data && } - - ) -} - -interface CustomDescriptionProps { - amount?: string - data?: string | null - recipient?: string - storedTx: Transaction -} - -const CustomDescription = ({ amount, data, recipient, storedTx }: CustomDescriptionProps): React.ReactElement => { - const txDetails = (storedTx.multiSendTx && extractMultiSendDataDecoded(storedTx).txDetails) ?? undefined - - return txDetails ? ( - - ) : ( - - ) -} - -export default CustomDescription diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx deleted file mode 100644 index 9c2b70a2..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import React, { ReactElement } from 'react' -import { useSelector } from 'react-redux' -import { EtherscanLink } from 'src/components/EtherscanLink' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import Paragraph from 'src/components/layout/Paragraph' - -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' -import { SAFE_METHODS_NAMES, SafeMethods } from 'src/routes/safe/store/models/types/transactions.d' - -export const TRANSACTIONS_DESC_ADD_OWNER_TEST_ID = 'tx-description-add-owner' -export const TRANSACTIONS_DESC_REMOVE_OWNER_TEST_ID = 'tx-description-remove-owner' -export const TRANSACTIONS_DESC_CHANGE_THRESHOLD_TEST_ID = 'tx-description-change-threshold' -export const TRANSACTIONS_DESC_ADD_MODULE_TEST_ID = 'tx-description-add-module' -export const TRANSACTIONS_DESC_REMOVE_MODULE_TEST_ID = 'tx-description-remove-module' -export const TRANSACTIONS_DESC_NO_DATA = 'tx-description-no-data' - -interface RemovedOwnerProps { - removedOwner: string -} - -const RemovedOwner = ({ removedOwner }: RemovedOwnerProps): ReactElement => { - const ownerChangedName = useSelector((state) => getNameFromAddressBookSelector(state, removedOwner)) - - return ( - - Remove owner: - {ownerChangedName ? ( - - ) : ( - - )} - - ) -} - -interface AddedOwnerProps { - addedOwner: string -} - -const AddedOwner = ({ addedOwner }: AddedOwnerProps): ReactElement => { - const ownerChangedName = useSelector((state) => getNameFromAddressBookSelector(state, addedOwner)) - - return ( - - Add owner: - {ownerChangedName ? ( - - ) : ( - - )} - - ) -} - -interface NewThresholdProps { - newThreshold: string -} - -const NewThreshold = ({ newThreshold }: NewThresholdProps): ReactElement => ( - - Change required confirmations: - - {newThreshold} - - -) - -interface AddModuleProps { - module: string -} - -const AddModule = ({ module }: AddModuleProps): ReactElement => ( - - Add module: - - -) - -interface RemoveModuleProps { - module: string -} - -const RemoveModule = ({ module }: RemoveModuleProps): ReactElement => ( - - Remove module: - - -) - -interface SettingsDescriptionProps { - action?: SafeMethods - addedOwner?: string - newThreshold?: string - removedOwner?: string - module?: string -} - -const SettingsDescription = ({ - action, - addedOwner, - newThreshold, - removedOwner, - module, -}: SettingsDescriptionProps): ReactElement => { - if (action === SAFE_METHODS_NAMES.REMOVE_OWNER && removedOwner && newThreshold) { - return ( - <> - - - - ) - } - - if (action === SAFE_METHODS_NAMES.CHANGE_THRESHOLD && newThreshold) { - return - } - - if (action === SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD && addedOwner && newThreshold) { - return ( - <> - - - - ) - } - - if (action === SAFE_METHODS_NAMES.SWAP_OWNER && removedOwner && addedOwner) { - return ( - <> - - - - ) - } - - if (action === SAFE_METHODS_NAMES.ENABLE_MODULE && module) { - return - } - - if (action === SAFE_METHODS_NAMES.DISABLE_MODULE && module) { - return - } - - return ( - - No data available for current transaction - - ) -} - -export default SettingsDescription diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx deleted file mode 100644 index 58a7c2a6..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { ReactElement } from 'react' -import { useSelector } from 'react-redux' -import { EtherscanLink } from 'src/components/EtherscanLink' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' - -import { TRANSACTIONS_DESC_SEND_TEST_ID } from './index' -import SendModal from 'src/routes/safe/components/Balances/SendModal' - -interface TransferDescriptionProps { - amountWithSymbol: string - recipient?: string - tokenAddress?: string - rawAmount?: string - isTokenTransfer: boolean -} - -const TransferDescription = ({ - amountWithSymbol = '', - recipient, - tokenAddress, - rawAmount, - isTokenTransfer, -}: TransferDescriptionProps): ReactElement | null => { - const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, recipient)) - const [sendModalOpen, setSendModalOpen] = React.useState(false) - const sendModalOpenHandler = () => { - setSendModalOpen(true) - } - - return recipient ? ( - <> - - Send {amountWithSymbol} to: - {recipientName ? ( - - ) : ( - - )} - - setSendModalOpen(false)} - recipientAddress={recipient} - selectedToken={tokenAddress} - tokenAmount={rawAmount} - /> - - ) : null -} - -export default TransferDescription diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.tsx deleted file mode 100644 index 789aa29d..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/index.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { makeStyles } from '@material-ui/core/styles' -import React from 'react' - -import { styles } from './styles' -import { getTxData } from './utils' -import SettingsDescription from './SettingsDescription' -import CustomDescription from './CustomDescription' -import TransferDescription from './TransferDescription' - -import { getRawTxAmount, getTxAmount } from 'src/routes/safe/components/Transactions/TxsTable/columns' -import Block from 'src/components/layout/Block' -import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' - -export const TRANSACTIONS_DESC_SEND_TEST_ID = 'tx-description-send' - -const useStyles = makeStyles(styles) - -const SettingsDescriptionTx = ({ tx }: { tx: Transaction }): React.ReactElement => { - const { action, addedOwner, module, newThreshold, removedOwner } = getTxData(tx) - return -} - -const CustomDescriptionTx = ({ tx }: { tx: Transaction }): React.ReactElement => { - const amount = getTxAmount(tx, false) - const { data, recipient } = getTxData(tx) - return -} - -const UpgradeDescriptionTx = ({ tx }: { tx: Transaction }): React.ReactElement => { - const { data } = getTxData(tx) - return
{data}
-} - -const TransferDescriptionTx = ({ tx }: { tx: Transaction }): React.ReactElement => { - const amountWithSymbol = getTxAmount(tx, false) - const rawAmount = getRawTxAmount(tx) - const { recipient, isTokenTransfer = false, tokenAddress } = getTxData(tx) - return -} - -const TxDescription = ({ tx }: { tx: Transaction }): React.ReactElement => { - const classes = useStyles() - - return ( - - {tx.type === TransactionTypes.SETTINGS && } - {tx.type === TransactionTypes.CUSTOM && } - {tx.type === TransactionTypes.UPGRADE && } - {[TransactionTypes.TOKEN, TransactionTypes.COLLECTIBLE, TransactionTypes.OUTGOING].includes(tx.type) && ( - - )} - - ) -} - -export default TxDescription diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/styles.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/styles.ts deleted file mode 100644 index d1c1e8d7..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/styles.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createStyles } from '@material-ui/core/styles' -import { lg, md } from 'src/theme/variables' - -export const styles = createStyles({ - txDataContainer: { - paddingTop: lg, - paddingLeft: md, - paddingBottom: md, - }, - txData: { - wordBreak: 'break-all', - }, - txDataParagraph: { - whiteSpace: 'normal', - }, - linkTxData: { - textDecoration: 'underline', - cursor: 'pointer', - }, - multiSendTxData: { - marginTop: `-${lg}`, - marginLeft: `-${md}`, - }, - collapse: { - borderBottom: `2px solid rgb(232, 231, 230)`, - }, - collapseHeaderWrapper: { - display: 'flex', - flexDirection: 'row', - alignContent: 'center', - alignItems: 'center', - justifyContent: 'space-between', - padding: '8px 8px 8px 16px', - borderBottom: '2px solid rgb(232, 231, 230)', - - '&:hover': { - cursor: 'pointer', - }, - }, - address: { - display: 'inline-flex', - }, -}) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts deleted file mode 100644 index 5a702409..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/utils.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { SAFE_METHODS_NAMES, SafeMethods, TokenDecodedParams } from 'src/logic/safe/store/models/types/transactions.d' -import { sameString } from 'src/utils/strings' -import { getNetworkInfo } from 'src/config' - -const getSafeVersion = (data) => { - const contractAddress = data.substr(340, 40).toLowerCase() - - return ( - { - '34cfac646f301356faa8b21e94227e3583fe3f5f': '1.1.1', - }[contractAddress] || 'X.x.x' - ) -} - -interface TxData { - data?: string | null - recipient?: string - module?: string - action?: SafeMethods - addedOwner?: string - removedOwner?: string - newThreshold?: string - tokenId?: string - isTokenTransfer?: boolean - isCollectibleTransfer?: boolean - modifySettingsTx?: boolean - customTx?: boolean - cancellationTx?: boolean - creationTx?: boolean - upgradeTx?: boolean - tokenAddress?: string -} - -const getTxDataForModifySettingsTxs = (tx: Transaction): TxData => { - const txData: TxData = {} - - if (!tx.modifySettingsTx || !tx.decodedParams) { - return txData - } - - txData.recipient = tx.recipient - txData.modifySettingsTx = true - - if (tx.decodedParams[SAFE_METHODS_NAMES.REMOVE_OWNER]) { - const { _threshold, owner } = tx.decodedParams[SAFE_METHODS_NAMES.REMOVE_OWNER] - txData.action = SAFE_METHODS_NAMES.REMOVE_OWNER - txData.removedOwner = owner - txData.newThreshold = _threshold - - return txData - } - if (tx.decodedParams[SAFE_METHODS_NAMES.CHANGE_THRESHOLD]) { - const { _threshold } = tx.decodedParams[SAFE_METHODS_NAMES.CHANGE_THRESHOLD] - txData.action = SAFE_METHODS_NAMES.CHANGE_THRESHOLD - txData.newThreshold = _threshold - return txData - } - if (tx.decodedParams[SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD]) { - const { _threshold, owner } = tx.decodedParams[SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD] - txData.action = SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD - txData.addedOwner = owner - txData.newThreshold = _threshold - return txData - } - - if (tx.decodedParams[SAFE_METHODS_NAMES.SWAP_OWNER]) { - const { newOwner, oldOwner } = tx.decodedParams[SAFE_METHODS_NAMES.SWAP_OWNER] - txData.action = SAFE_METHODS_NAMES.SWAP_OWNER - txData.removedOwner = oldOwner - txData.addedOwner = newOwner - return txData - } - - if (tx.decodedParams[SAFE_METHODS_NAMES.ENABLE_MODULE]) { - const { module } = tx.decodedParams[SAFE_METHODS_NAMES.ENABLE_MODULE] - txData.action = SAFE_METHODS_NAMES.ENABLE_MODULE - txData.module = module - return txData - } - - if (tx.decodedParams[SAFE_METHODS_NAMES.DISABLE_MODULE]) { - const { module } = tx.decodedParams[SAFE_METHODS_NAMES.DISABLE_MODULE] - txData.action = SAFE_METHODS_NAMES.DISABLE_MODULE - txData.module = module - return txData - } - - return txData -} - -const getTxDataForTxsWithDecodedParams = (tx: Transaction): TxData => { - const txData: TxData = {} - - if (!tx.decodedParams) { - return txData - } - - if (tx.isTokenTransfer) { - const { to } = (tx.decodedParams as TokenDecodedParams).transfer || {} - txData.recipient = to - txData.isTokenTransfer = true - txData.tokenAddress = tx.recipient - return txData - } - - if (tx.isCollectibleTransfer) { - const { safeTransferFrom, transfer, transferFrom } = tx.decodedParams as TokenDecodedParams - const { to, value } = safeTransferFrom || transferFrom || transfer || {} - txData.recipient = to - txData.tokenId = value - txData.isCollectibleTransfer = true - - return txData - } - - if (tx.modifySettingsTx) { - return getTxDataForModifySettingsTxs(tx) - } - - if (tx.multiSendTx) { - txData.recipient = tx.recipient - txData.data = tx.data - txData.customTx = true - return txData - } - - txData.recipient = tx.recipient - txData.data = tx.data - txData.customTx = true - - return txData -} - -// @todo (agustin) this function does not makes much sense -// it should be refactored to simplify unnecessary if's checks and re-asigning props to the txData object -export const getTxData = (tx: Transaction): TxData => { - const txData: TxData = {} - - const { nativeCoin } = getNetworkInfo() - if (sameString(tx.type, 'outgoing') && tx.symbol && sameString(tx.symbol, nativeCoin.symbol)) { - txData.isTokenTransfer = true - txData.tokenAddress = nativeCoin.address - } - - if (tx.decodedParams) { - return getTxDataForTxsWithDecodedParams(tx) - } - - if (tx.customTx) { - txData.recipient = tx.recipient - txData.data = tx.data - txData.customTx = true - return txData - } - if (Number(tx.value) > 0) { - txData.recipient = tx.recipient - return txData - } - - if (tx.isCancellationTx) { - txData.cancellationTx = true - return txData - } - - if (tx.creationTx) { - txData.creationTx = true - return txData - } - - if (tx.upgradeTx) { - txData.upgradeTx = true - txData.data = `The contract of this Safe is upgraded to Version ${getSafeVersion(tx.data)}` - - return txData - } - txData.recipient = tx.recipient - - return txData -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx deleted file mode 100644 index 31c6458c..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx +++ /dev/null @@ -1,217 +0,0 @@ -import cn from 'classnames' -import React, { ReactElement, useMemo, useState } from 'react' -import { useSelector } from 'react-redux' -import { EthHashInfo } from '@gnosis.pm/safe-react-components' - -import { ApproveTxModal } from './ApproveTxModal' -import OwnersColumn from './OwnersColumn' -import { RejectTxModal } from './RejectTxModal' -import TxDescription from './TxDescription' -import { IncomingTx } from './IncomingTx' -import { CreationTx } from './CreationTx' -import { OutgoingTx } from './OutgoingTx' -import useStyles from './style' - -import { - getModuleAmount, - NOT_AVAILABLE, - TableData, - TX_TABLE_RAW_CANCEL_TX_ID, - TX_TABLE_RAW_TX_ID, -} from 'src/routes/safe/components/Transactions/TxsTable/columns' -import Block from 'src/components/layout/Block' -import Bold from 'src/components/layout/Bold' -import Col from 'src/components/layout/Col' -import Hairline from 'src/components/layout/Hairline' -import Paragraph from 'src/components/layout/Paragraph' -import Row from 'src/components/layout/Row' -import Span from 'src/components/layout/Span' -import { getWeb3 } from 'src/logic/wallets/getWeb3' -import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransaction' -import { Transaction, TransactionTypes, SafeModuleTransaction } from 'src/logic/safe/store/models/types/transaction' -import IncomingTxDescription from './IncomingTxDescription' -import { getExplorerInfo, getNetworkInfo } from 'src/config' -import TransferDescription from './TxDescription/TransferDescription' -import { sameAddress } from 'src/logic/wallets/ethAddresses' -import { safeNonceSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' -import { useTransactionParameters } from 'src/routes/safe/container/hooks/useTransactionParameters' - -const ExpandedModuleTx = ({ tx }: { tx: SafeModuleTransaction }): ReactElement => { - const classes = useStyles() - - const recipient = useMemo(() => { - if (tx.type === TransactionTypes.SPENDING_LIMIT) { - if (tx.dataDecoded) { - // if `dataDecoded` is defined, then it's a token transfer - return tx.dataDecoded?.parameters[0].value - } else { - // if `data` is not defined, then it's an ETH transfer - return tx.to - } - } - }, [tx.dataDecoded, tx.to, tx.type]) - - const amountWithSymbol = getModuleAmount(tx) - - return ( - - - - -
- Hash: - {tx.executionTxHash ? ( - - ) : ( - 'n/a' - )} -
-
- - - - - -
-
- ) -} - -interface ExpandedSafeTxProps { - cancelTx?: Transaction - tx: Transaction -} - -const { nativeCoin } = getNetworkInfo() - -type ScreenType = 'approveTx' | 'executeRejectTx' | 'rejectTx' - -const ExpandedSafeTx = ({ cancelTx, tx }: ExpandedSafeTxProps): ReactElement => { - const { fromWei, toBN } = getWeb3().utils - const classes = useStyles() - const nonce = useSelector(safeNonceSelector) - const threshold = useSelector(safeThresholdSelector) as number - const [openModal, setOpenModal] = useState() - const txParameters = useTransactionParameters() - - const isIncomingTx = !!INCOMING_TX_TYPES[tx.type] - const isCreationTx = tx.type === TransactionTypes.CREATION - const thresholdReached = !isIncomingTx && threshold <= tx.confirmations.size - const canExecute = !isIncomingTx && nonce === tx.nonce - const cancelThresholdReached = !!cancelTx && threshold <= cancelTx.confirmations?.size - const canExecuteCancel = nonce === tx.nonce - - const openApproveModal = () => setOpenModal('approveTx') - - const closeModal = () => setOpenModal(undefined) - - const openRejectModal = () => { - if (!!cancelTx && nonce === cancelTx.nonce) { - setOpenModal('executeRejectTx') - } else { - setOpenModal('rejectTx') - } - } - - const explorerUrl = tx.executionTxHash ? getExplorerInfo(tx.executionTxHash) : null - - return ( - <> - - - - -
- Hash: - {tx.executionTxHash ? ( - - ) : ( - 'n/a' - )} -
- {!isIncomingTx && !isCreationTx && ( - - Nonce: - {tx.nonce} - - )} - {!isCreationTx ? ( - - Fee: - {tx.fee ? fromWei(toBN(tx.fee)) + ` ${nativeCoin.name}` : 'n/a'} - - ) : null} - - - -
- - {isIncomingTx && } - {!isIncomingTx && !isCreationTx && } - {isCreationTx && } - - {!isIncomingTx && !isCreationTx && ( - - )} -
-
- - {/* Approve TX */} - {openModal === 'approveTx' && ( - - )} - - {/* Reject TX */} - {openModal === 'rejectTx' && } - - {/* Execute the rejection TX */} - {openModal === 'executeRejectTx' && cancelTx && ( - - )} - - ) -} - -export const ExpandedTx = ({ row }: { row: TableData }): ReactElement => { - const isModuleTx = [TransactionTypes.SPENDING_LIMIT, TransactionTypes.MODULE].includes(row.tx.type) - - if (isModuleTx) { - return - } - - return -} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/style.ts b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/style.ts deleted file mode 100644 index 7e85f743..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/style.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { createStyles, makeStyles } from '@material-ui/core' -import { border, lg, md } from 'src/theme/variables' - -export default makeStyles( - createStyles({ - col: { - wordBreak: 'break-word', - whiteSpace: 'normal', - }, - expandedTxBlock: { - borderBottom: `2px solid ${border}`, - }, - txDataContainer: { - padding: `${lg} ${md}`, - }, - txHash: { - paddingRight: '3px', - }, - incomingTxBlock: { - borderRight: '2px solid rgb(232, 231, 230)', - }, - emptyRowDataContainer: { - paddingTop: lg, - paddingLeft: md, - paddingBottom: md, - borderRight: '2px solid rgb(232, 231, 230)', - }, - }), -) diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/custom.svg b/src/routes/safe/components/Transactions/TxsTable/TxType/assets/custom.svg deleted file mode 100644 index ff8de3f4..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/custom.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/incoming.svg b/src/routes/safe/components/Transactions/TxsTable/TxType/assets/incoming.svg deleted file mode 100644 index c08ef2a1..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/incoming.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/outgoing.svg b/src/routes/safe/components/Transactions/TxsTable/TxType/assets/outgoing.svg deleted file mode 100644 index 89b07111..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/outgoing.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/settings.svg b/src/routes/safe/components/Transactions/TxsTable/TxType/assets/settings.svg deleted file mode 100644 index eb64eda0..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/TxType/assets/settings.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx b/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx deleted file mode 100644 index bfe52d2e..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/TxType/index.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Loader } from '@gnosis.pm/safe-react-components' -import React, { useEffect, useState } from 'react' - -import CustomTxIcon from './assets/custom.svg' -import IncomingTxIcon from './assets/incoming.svg' -import OutgoingTxIcon from './assets/outgoing.svg' -import SettingsTxIcon from './assets/settings.svg' - -import CustomIconText from 'src/components/CustomIconText' -import { getAppInfoFromOrigin, getAppInfoFromUrl } from 'src/routes/safe/components/Apps/utils' -import { SafeApp } from 'src/routes/safe/components/Apps/types.d' - -const typeToIcon = { - outgoing: OutgoingTxIcon, - token: OutgoingTxIcon, - collectible: OutgoingTxIcon, - incoming: IncomingTxIcon, - custom: CustomTxIcon, - settings: SettingsTxIcon, - creation: SettingsTxIcon, - cancellation: SettingsTxIcon, - upgrade: SettingsTxIcon, - module: SettingsTxIcon, - spendingLimit: SettingsTxIcon, -} - -const typeToLabel = { - outgoing: 'Outgoing transfer', - token: 'Outgoing transfer', - collectible: 'Outgoing transfer', - incoming: 'Incoming transfer', - custom: 'Contract Interaction', - settings: 'Modify settings', - creation: 'Safe created', - cancellation: 'Cancellation transaction', - upgrade: 'Contract Upgrade', - module: 'Module transaction', - spendingLimit: 'Spending Limit', -} - -interface TxTypeProps { - origin: string | null - txType: keyof typeof typeToLabel -} - -const TxType = ({ origin, txType }: TxTypeProps): React.ReactElement => { - const [loading, setLoading] = useState(true) - const [appInfo, setAppInfo] = useState() - const [forceCustom, setForceCustom] = useState(false) - - useEffect(() => { - const getAppInfo = async (origin: string | null) => { - if (!origin) { - return - } - - const parsedOrigin = getAppInfoFromOrigin(origin) - - if (!parsedOrigin) { - setForceCustom(true) - setLoading(false) - return - } - - const appInfo = await getAppInfoFromUrl(parsedOrigin.url) - - setAppInfo(appInfo) - setLoading(false) - } - - getAppInfo(origin) - }, [origin, txType]) - - if (forceCustom || !origin) { - return - } - - return loading ? : -} -export default TxType diff --git a/src/routes/safe/components/Transactions/TxsTable/columns.tsx b/src/routes/safe/components/Transactions/TxsTable/columns.tsx deleted file mode 100644 index 713fc32c..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/columns.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import { BigNumber } from 'bignumber.js' -import format from 'date-fns/format' -import getTime from 'date-fns/getTime' -import parseISO from 'date-fns/parseISO' -import { List } from 'immutable' -import React from 'react' - -import TxType from './TxType' - -import { buildOrderFieldFrom } from 'src/components/Table/sorting' -import { TableColumn } from 'src/components/Table/types.d' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransaction' -import { SafeModuleTransaction, Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' -import { TokenDecodedParams } from 'src/logic/safe/store/models/types/transactions.d' -import { CancellationTransactions } from 'src/logic/safe/store/reducer/cancellationTransactions' -import { getNetworkInfo } from 'src/config' - -export const TX_TABLE_ID = 'id' -export const TX_TABLE_TYPE_ID = 'type' -export const TX_TABLE_DATE_ID = 'date' -export const TX_TABLE_AMOUNT_ID = 'amount' -export const TX_TABLE_STATUS_ID = 'status' -export const TX_TABLE_RAW_TX_ID = 'tx' -export const TX_TABLE_RAW_CANCEL_TX_ID = 'cancelTx' -export const TX_TABLE_EXPAND_ICON = 'expand' - -export const formatDate = (date: string): string => format(parseISO(date), 'MMM d, yyyy - HH:mm:ss') - -export const NOT_AVAILABLE = 'n/a' - -interface AmountData { - decimals?: number | string - symbol?: string - value: number | string -} - -const getAmountWithSymbol = ( - { decimals = 0, symbol = NOT_AVAILABLE, value }: AmountData, - formatted = false, -): string => { - const nonFormattedValue = new BigNumber(value).times(`1e-${decimals}`).toFixed() - const finalValue = formatted ? formatAmount(nonFormattedValue).toString() : nonFormattedValue - const txAmount = finalValue === 'NaN' ? NOT_AVAILABLE : finalValue - - return `${txAmount} ${symbol}` -} - -export const getIncomingTxAmount = (tx: Transaction, formatted = true): string => { - // simple workaround to avoid displaying unexpected values for incoming NFT transfer - if (INCOMING_TX_TYPES[tx.type] === INCOMING_TX_TYPES.ERC721_TRANSFER) { - return `1 ${tx.symbol}` - } - - return getAmountWithSymbol( - { decimals: tx.decimals as string, symbol: tx.symbol as string, value: tx.value }, - formatted, - ) -} - -export const getTxAmount = (tx: Transaction, formatted = true): string => { - const { decimals = 18, decodedParams, isTokenTransfer, symbol } = tx - const tokenDecodedTransfer = isTokenTransfer && (decodedParams as TokenDecodedParams)?.transfer - const { value } = tokenDecodedTransfer || tx - - if (tx.isCollectibleTransfer) { - return `1 ${tx.symbol}` - } - - if (!isTokenTransfer && !(Number(value) > 0)) { - return NOT_AVAILABLE - } - - return getAmountWithSymbol({ decimals: decimals as string, symbol: symbol as string, value }, formatted) -} - -export const getModuleAmount = (tx: SafeModuleTransaction, formatted = true): string => { - if (tx.type === TransactionTypes.SPENDING_LIMIT && tx.tokenInfo) { - const { decimals, symbol } = tx.tokenInfo - - let value - - if (tx.dataDecoded) { - // if `dataDecoded` is defined, then it's a token transfer - const [, amount] = tx.dataDecoded.parameters - value = amount.value - } else { - // if `dataDecoded` is not defined, then it's an ETH transfer - value = tx.value - } - - return getAmountWithSymbol({ decimals, symbol, value }, formatted) - } - - return NOT_AVAILABLE -} - -export const getRawTxAmount = (tx: Transaction): string => { - const { decimals, decodedParams, isTokenTransfer } = tx - const { nativeCoin } = getNetworkInfo() - const tokenDecodedTransfer = isTokenTransfer && (decodedParams as TokenDecodedParams)?.transfer - const { value } = tokenDecodedTransfer || tx - - if (tx.isCollectibleTransfer) { - return '1' - } - - if (!isTokenTransfer && !(Number(value) > 0)) { - return NOT_AVAILABLE - } - - const tokenDecimals = decimals ?? nativeCoin.decimals - const finalValue = new BigNumber(value).times(`1e-${tokenDecimals}`).toFixed() - - return finalValue === 'NaN' ? NOT_AVAILABLE : finalValue -} - -export interface TableData { - amount: string - cancelTx?: Transaction - date: string - dateOrder?: number - id: string - status: string - tx: Transaction | SafeModuleTransaction - type: any -} - -const getModuleTxTableData = (tx: SafeModuleTransaction): TableData => ({ - [TX_TABLE_ID]: tx.blockNumber?.toString() ?? '', - [TX_TABLE_TYPE_ID]: , - [TX_TABLE_DATE_ID]: formatDate(tx.executionDate), - [buildOrderFieldFrom(TX_TABLE_DATE_ID)]: getTime(parseISO(tx.executionDate)), - [TX_TABLE_AMOUNT_ID]: getModuleAmount(tx), - [TX_TABLE_STATUS_ID]: tx.status, - [TX_TABLE_RAW_TX_ID]: tx, -}) - -const getIncomingTxTableData = (tx: Transaction): TableData => ({ - [TX_TABLE_ID]: tx.blockNumber?.toString() ?? '', - [TX_TABLE_TYPE_ID]: , - [TX_TABLE_DATE_ID]: formatDate(tx.executionDate || '0'), - [buildOrderFieldFrom(TX_TABLE_DATE_ID)]: getTime(parseISO(tx.executionDate || '0')), - [TX_TABLE_AMOUNT_ID]: getIncomingTxAmount(tx), - [TX_TABLE_STATUS_ID]: tx.status, - [TX_TABLE_RAW_TX_ID]: tx, -}) - -// This follows the approach of calculating the tx information closest to the presentation components. -// Instead of populating tx in the store with another flag, Spending Limit tx is inferred here. -const getTxType = (tx: Transaction): TransactionTypes => { - const SET_ALLOWANCE_HASH = 'beaeb388' - const DELETE_ALLOWANCE_HASH = '885133e3' - - return tx.data?.includes(SET_ALLOWANCE_HASH) || tx.data?.includes(DELETE_ALLOWANCE_HASH) - ? TransactionTypes.SPENDING_LIMIT - : tx.type -} - -const getTransactionTableData = (tx: Transaction, cancelTx?: Transaction): TableData => { - const txDate = tx.submissionDate - const txType = getTxType(tx) - - return { - [TX_TABLE_ID]: tx.blockNumber?.toString() ?? '', - [TX_TABLE_TYPE_ID]: , - [TX_TABLE_DATE_ID]: txDate ? formatDate(txDate) : '', - [buildOrderFieldFrom(TX_TABLE_DATE_ID)]: txDate ? getTime(parseISO(txDate)) : null, - [TX_TABLE_AMOUNT_ID]: getTxAmount(tx), - [TX_TABLE_STATUS_ID]: tx.status, - [TX_TABLE_RAW_TX_ID]: tx, - [TX_TABLE_RAW_CANCEL_TX_ID]: cancelTx, - } -} - -export const getTxTableData = ( - transactions: List, - cancelTxs: CancellationTransactions, -): List => { - return transactions.map((tx) => { - const isModuleTx = [TransactionTypes.SPENDING_LIMIT, TransactionTypes.MODULE].includes(tx.type) - const isIncomingTx = INCOMING_TX_TYPES[tx.type] !== undefined - - if (isModuleTx) { - return getModuleTxTableData(tx as SafeModuleTransaction) - } - - if (isIncomingTx) { - return getIncomingTxTableData(tx as Transaction) - } - - return getTransactionTableData(tx as Transaction, cancelTxs.get(`${tx.nonce}`)) - }) -} - -export const generateColumns = (): List => { - const nonceColumn = { - id: TX_TABLE_ID, - disablePadding: false, - label: 'Id', - custom: false, - order: false, - width: 50, - } - - const typeColumn = { - id: TX_TABLE_TYPE_ID, - order: false, - disablePadding: false, - label: 'Type', - custom: false, - width: 200, - } - - const valueColumn = { - id: TX_TABLE_AMOUNT_ID, - order: false, - disablePadding: false, - label: 'Amount', - custom: false, - width: 120, - } - - const dateColumn = { - id: TX_TABLE_DATE_ID, - disablePadding: false, - order: true, - label: 'Date', - custom: false, - } - - const statusColumn = { - id: TX_TABLE_STATUS_ID, - order: false, - disablePadding: false, - label: 'Status', - custom: true, - align: 'right', - } - - const expandIconColumn = { - id: TX_TABLE_EXPAND_ICON, - order: false, - disablePadding: true, - label: '', - custom: true, - width: 50, - static: true, - } - - return List([nonceColumn, typeColumn, valueColumn, dateColumn, statusColumn, expandIconColumn]) -} diff --git a/src/routes/safe/components/Transactions/TxsTable/test/column.test.ts b/src/routes/safe/components/Transactions/TxsTable/test/column.test.ts deleted file mode 100644 index 75f9fffb..00000000 --- a/src/routes/safe/components/Transactions/TxsTable/test/column.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { List, Map } from 'immutable' -import { makeTransaction } from 'src/logic/safe/store/models/transaction' -import { getTxTableData, TX_TABLE_RAW_CANCEL_TX_ID, TableData } from 'src/routes/safe/components/Transactions/TxsTable/columns' - -describe('TxsTable Columns > getTxTableData', () => { - it('should include CancelTx object inside TxTableData', () => { - // Given - const mockedTransaction = makeTransaction({ nonce: 1, blockNumber: 100 }) - const mockedCancelTransaction = makeTransaction({ nonce: 1, blockNumber: 123 }) - - // When - const txTableData = getTxTableData(List([mockedTransaction]), Map( { '1': mockedCancelTransaction })) - const txRow = txTableData.first() as TableData - - // Then - expect(txRow[TX_TABLE_RAW_CANCEL_TX_ID]).toEqual(mockedCancelTransaction) - }) - it('should not include CancelTx object inside TxTableData', () => { - // Given - const mockedTransaction = makeTransaction({ nonce: 1, blockNumber: 100 }) - const mockedCancelTransaction = makeTransaction({ nonce: 2, blockNumber: 123 }) - - // When - const txTableData = getTxTableData(List([mockedTransaction]), Map( { '2': mockedCancelTransaction })) - const txRow = txTableData.first() as TableData - - // Then - expect(txRow[TX_TABLE_RAW_CANCEL_TX_ID]).toBeUndefined() - }) -}) diff --git a/src/routes/safe/container/hooks/useTransactions.ts b/src/routes/safe/container/hooks/useTransactions.ts deleted file mode 100644 index e9699ab6..00000000 --- a/src/routes/safe/container/hooks/useTransactions.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { loadAllTransactions } from 'src/logic/safe/store/actions/allTransactions/loadAllTransactions' - -import { useEffect } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { loadMore } from 'src/logic/safe/store/actions/allTransactions/pagination' -import { - safeAllTransactionsSelector, - safeTotalTransactionsAmountSelector, -} from 'src/logic/safe/store/selectors/allTransactions' -import { Transaction } from 'src/logic/safe/store/models/types/transactions.d' -import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' - -type Props = { - offset: number - limit: number -} - -export const useTransactions = (props: Props): { transactions: Transaction[]; totalTransactionsCount: number } => { - const { offset, limit } = props - const dispatch = useDispatch() - const transactions = useSelector(safeAllTransactionsSelector) - const safeAddress = useSelector(safeParamAddressFromStateSelector) as string - const totalTransactionsCount = useSelector(safeTotalTransactionsAmountSelector) - useEffect(() => { - async function loadNewTxs() { - const { transactions, totalTransactionsAmount } = await loadAllTransactions({ safeAddress, offset, limit }) - if (transactions.length) { - dispatch(loadMore({ transactions, safeAddress, totalTransactionsAmount })) - } - } - loadNewTxs() - }, [dispatch, safeAddress, offset, limit]) - - return { transactions, totalTransactionsCount } -} diff --git a/src/routes/safe/container/index.tsx b/src/routes/safe/container/index.tsx index 6783ca00..2114d7d7 100644 --- a/src/routes/safe/container/index.tsx +++ b/src/routes/safe/container/index.tsx @@ -17,10 +17,10 @@ export const ADDRESS_BOOK_TAB_BTN_TEST_ID = 'address-book-tab-btn' export const SAFE_VIEW_NAME_HEADING_TEST_ID = 'safe-name-heading' export const TRANSACTIONS_TAB_NEW_BTN_TEST_ID = 'transactions-tab-new-btn' -const Apps = React.lazy(() => import('../components/Apps')) -const Settings = React.lazy(() => import('../components/Settings')) -const Balances = React.lazy(() => import('../components/Balances')) -const TxsTable = React.lazy(() => import('src/routes/safe/components/Transactions/GatewayTransactions')) +const Apps = React.lazy(() => import('src/routes/safe/components/Apps')) +const Settings = React.lazy(() => import('src/routes/safe/components/Settings')) +const Balances = React.lazy(() => import('src/routes/safe/components/Balances')) +const TxList = React.lazy(() => import('src/routes/safe/components/Transactions/TxList')) const AddressBookTable = React.lazy(() => import('src/routes/safe/components/AddressBook')) const Container = (): React.ReactElement => { @@ -68,7 +68,7 @@ const Container = (): React.ReactElement => { wrapInSuspense(, null)} + render={() => wrapInSuspense(, null)} /> state[MODULE_TRANSACTIONS_REDUCER_ID] - -export const modulesTransactionsBySafeSelector = createSelector( - moduleTransactionsSelector, - safeParamAddressFromStateSelector, - (moduleTransactions, safeAddress): ModuleTxServiceModel[] => { - // no module tx for the current safe so far - if (!moduleTransactions || !safeAddress || !moduleTransactions[safeAddress]) { - return [] - } - - return moduleTransactions[safeAddress] - }, -) - -// export const safeModuleTransactionsSelector = createSelector( -// tokenListSelector, -// modulesTransactionsBySafeSelector, -// (tokens, safeModuleTransactions): SafeModuleTransaction[] => { -// return safeModuleTransactions.map((moduleTx) => { -// // if not spendingLimit module tx, then it's an generic module tx -// const type = sameAddress(moduleTx.module, SPENDING_LIMIT_MODULE_ADDRESS) -// ? TransactionTypes.SPENDING_LIMIT -// : TransactionTypes.MODULE -// -// // TODO: this is strictly attached to Spending Limit Module. -// // This has to be moved nearest the module info rendering. -// // add token info to the model, so data can be properly displayed in the UI -// let tokenInfo -// if (type === TransactionTypes.SPENDING_LIMIT) { -// if (moduleTx.data) { -// // if `data` is defined, then it's a token transfer -// tokenInfo = tokens.find(({ address }) => sameAddress(address, moduleTx.to)) -// } else { -// // if `data` is not defined, then it's an ETH transfer -// // ETH does not exist in the list of tokens, so we recreate the record here -// tokenInfo = getEthAsToken(0) -// } -// } -// -// return { -// ...moduleTx, -// safeTxHash: moduleTx.transactionHash, -// executionTxHash: moduleTx.transactionHash, -// status: TransactionStatus.SUCCESS, -// tokenInfo, -// type, -// } -// }) -// }, -// ) diff --git a/src/routes/safe/store/actions/transactions/__tests__/utils.test.ts b/src/routes/safe/store/actions/transactions/__tests__/utils.test.ts deleted file mode 100644 index 82579f99..00000000 --- a/src/routes/safe/store/actions/transactions/__tests__/utils.test.ts +++ /dev/null @@ -1,158 +0,0 @@ -import { getLastTx, getNewTxNonce, shouldExecuteTransaction } from 'src/logic/safe/store/actions/utils' -import { getMockedSafeInstance, getMockedTxServiceModel } from 'src/test/utils/safeHelper' -import axios from 'axios' -import { buildTxServiceUrl } from 'src/logic/safe/transactions' - -describe('shouldExecuteTransaction', () => { - it('It should return false if given a safe with a threshold > 1', async () => { - // given - const nonce = '0' - const threshold = '2' - const safeInstance = getMockedSafeInstance({ threshold }) - const lastTx = getMockedTxServiceModel({}) - - // when - const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) - - // then - expect(result).toBe(false) - }) - it('It should return true if given a safe with a threshold === 1 and the previous transaction is already executed', async () => { - // given - const nonce = '1' - const threshold = '1' - const safeInstance = getMockedSafeInstance({ threshold, nonce }) - const lastTx = getMockedTxServiceModel({}) - - // when - const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) - - // then - expect(result).toBe(true) - }) - it('It should return true if given a safe with a threshold === 1 and the previous transaction is already executed', async () => { - // given - const nonce = '10' - const threshold = '1' - const safeInstance = getMockedSafeInstance({ threshold, nonce }) - const lastTx = getMockedTxServiceModel({ isExecuted: true }) - - // when - const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) - - // then - expect(result).toBe(true) - }) - it('It should return false if given a safe with a threshold === 1 and the previous transaction is not yet executed', async () => { - // given - const nonce = '10' - const threshold = '1' - const safeInstance = getMockedSafeInstance({ threshold }) - const lastTx = getMockedTxServiceModel({ isExecuted: false }) - - // when - const result = await shouldExecuteTransaction(safeInstance, nonce, lastTx) - - // then - expect(result).toBe(false) - }) -}) - -describe('getNewTxNonce', () => { - it('It should return 2 if given the last transaction with nonce 1', async () => { - // given - const safeInstance = getMockedSafeInstance({}) - const lastTx = getMockedTxServiceModel({ nonce: 1 }) - const expectedResult = '2' - - // when - const result = await getNewTxNonce(lastTx, safeInstance) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return 0 if given a safe with nonce 0 and no transactions should use safe contract instance for retrieving nonce', async () => { - // given - const safeNonce = '0' - const safeInstance = getMockedSafeInstance({ nonce: safeNonce }) - const expectedResult = '0' - const mockFnCall = jest.fn().mockImplementation(() => safeNonce) - const mockFnNonce = jest.fn().mockImplementation(() => ({ call: mockFnCall })) - - safeInstance.methods.nonce = mockFnNonce - - // when - const result = await getNewTxNonce(null, safeInstance) - - // then - expect(result).toBe(expectedResult) - expect(mockFnNonce).toHaveBeenCalled() - expect(mockFnCall).toHaveBeenCalled() - mockFnNonce.mockRestore() - mockFnCall.mockRestore() - }) - it('Given a Safe and the last transaction, should return nonce of the last transaction + 1', async () => { - // given - const safeInstance = getMockedSafeInstance({}) - const expectedResult = '11' - const lastTx = getMockedTxServiceModel({ nonce: 10 }) - - // when - const result = await getNewTxNonce(lastTx, safeInstance) - - // then - expect(result).toBe(expectedResult) - }) -}) - -jest.mock('axios') -jest.mock('console') -describe('getLastTx', () => { - afterAll(() => { - jest.unmock('axios') - jest.unmock('console') - }) - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - it('It should return the last transaction for a given a safe address', async () => { - // given - const lastTx = getMockedTxServiceModel({ nonce: 1 }) - const url = buildTxServiceUrl(safeAddress) - - // when - // @ts-ignore - axios.get.mockImplementationOnce(() => { - return { - data: { - results: [lastTx], - }, - } - }) - - const result = await getLastTx(safeAddress) - - // then - expect(result).toStrictEqual(lastTx) - expect(axios.get).toHaveBeenCalled() - expect(axios.get).toBeCalledWith(url, { params: { limit: 1 } }) - }) - it('If should return null If catches an error getting last transaction', async () => { - // given - const lastTx = null - const url = buildTxServiceUrl(safeAddress) - - // when - // @ts-ignore - axios.get.mockImplementationOnce(() => { - throw new Error() - }) - console.error = jest.fn() - const result = await getLastTx(safeAddress) - const spyConsole = jest.spyOn(console, 'error').mockImplementation() - - // then - expect(result).toStrictEqual(lastTx) - expect(axios.get).toHaveBeenCalled() - expect(axios.get).toBeCalledWith(url, { params: { limit: 1 } }) - expect(spyConsole).toHaveBeenCalled() - }) -}) diff --git a/src/routes/safe/store/actions/transactions/utils/multiSendDecodedDetails.ts b/src/routes/safe/store/actions/transactions/utils/multiSendDecodedDetails.ts deleted file mode 100644 index 3573c275..00000000 --- a/src/routes/safe/store/actions/transactions/utils/multiSendDecodedDetails.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { TransferDetails } from './transferDetails.d' -import { - DataDecoded, - Operation, - Parameter, - Transfer, - TransferType, -} from 'src/logic/safe/store/models/types/transactions.d' - -import { - extractERC20TransferDetails, - extractERC721TransferDetails, - extractETHTransferDetails, - extractUnknownTransferDetails, -} from './transferDetails' -import { isMultiSendParameter } from './newTransactionHelpers' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' - -export type MultiSendDetails = { - operation: Operation - to: string - data: string | null - dataDecoded: DataDecoded | null - value: number -} - -export type MultiSendDataDecoded = { - txDetails?: MultiSendDetails[] - transfersDetails?: TransferDetails[] -} - -export const extractTransferDetails = (transfer: Transfer): TransferDetails => { - switch (TransferType[transfer.type]) { - case TransferType.ERC20_TRANSFER: - return extractERC20TransferDetails(transfer) - case TransferType.ERC721_TRANSFER: - return extractERC721TransferDetails(transfer) - case TransferType.ETHER_TRANSFER: - return extractETHTransferDetails(transfer) - default: - return extractUnknownTransferDetails(transfer) - } -} - -export const extractMultiSendDetails = (parameter: Parameter): MultiSendDetails[] | undefined => { - if (isMultiSendParameter(parameter)) { - return parameter.valueDecoded.map((valueDecoded) => { - return { - operation: valueDecoded.operation, - to: valueDecoded.to, - value: valueDecoded.value, - dataDecoded: valueDecoded?.dataDecoded ?? null, - data: valueDecoded?.data ?? null, - } - }) - } -} - -export const extractMultiSendDataDecoded = (tx: Transaction): MultiSendDataDecoded => { - const transfersDetails = tx.transfers?.map(extractTransferDetails) - const txDetails = tx.dataDecoded?.parameters[0] ? extractMultiSendDetails(tx.dataDecoded?.parameters[0]) : undefined - - return { txDetails, transfersDetails } -} diff --git a/src/routes/safe/store/actions/transactions/utils/newTransactionHelpers.ts b/src/routes/safe/store/actions/transactions/utils/newTransactionHelpers.ts deleted file mode 100644 index 0b1ddeab..00000000 --- a/src/routes/safe/store/actions/transactions/utils/newTransactionHelpers.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - EthereumTransaction, - ModuleTransaction, - MultiSendMethodParameter, - MultiSigTransaction, - Parameter, - Transaction, - TxType, -} from 'src/routes/safe/store/models/types/transactions.d' - -export const isMultiSigTx = (tx: Transaction): tx is MultiSigTransaction => { - return TxType[tx.txType] === TxType.MULTISIG_TRANSACTION -} - -export const isModuleTx = (tx: Transaction): tx is ModuleTransaction => { - return TxType[tx.txType] === TxType.MODULE_TRANSACTION -} - -export const isEthereumTx = (tx: Transaction): tx is EthereumTransaction => { - return TxType[tx.txType] === TxType.ETHEREUM_TRANSACTION -} - -export const isMultiSendParameter = (parameter: Parameter): parameter is MultiSendMethodParameter => { - return !!(parameter as MultiSendMethodParameter)?.valueDecoded -} diff --git a/src/routes/safe/store/actions/transactions/utils/transferDetails.d.ts b/src/routes/safe/store/actions/transactions/utils/transferDetails.d.ts deleted file mode 100644 index a95f1795..00000000 --- a/src/routes/safe/store/actions/transactions/utils/transferDetails.d.ts +++ /dev/null @@ -1,50 +0,0 @@ -export interface IncomingTransferDetails { - from: string -} - -export interface OutgoingTransferDetails { - to: string -} - -export interface CommonERC20TransferDetails { - tokenAddress: string - value: string - name: string - txHash: string | null -} - -export interface IncomingERC20TransferDetails extends CommonERC20TransferDetails, IncomingTransferDetails {} - -export interface OutgoingERC20TransferDetails extends CommonERC20TransferDetails, OutgoingTransferDetails {} - -export type ERC20TransferDetails = IncomingERC20TransferDetails | OutgoingERC20TransferDetails - -export interface CommonERC721TransferDetails { - tokenAddress: string - tokenId: string | null - txHash: string | null -} - -export interface IncomingERC721TransferDetails extends CommonERC721TransferDetails, IncomingTransferDetails {} - -export interface OutgoingERC721TransferDetails extends CommonERC721TransferDetails, OutgoingTransferDetails {} - -export type ERC721TransferDetails = IncomingERC721TransferDetails | OutgoingERC721TransferDetails - -export interface CommonETHTransferDetails { - value: string - txHash: string | null -} - -export interface IncomingETHTransferDetails extends CommonETHTransferDetails, IncomingTransferDetails {} - -export interface OutgoingETHTransferDetails extends CommonETHTransferDetails, OutgoingTransferDetails {} - -export type ETHTransferDetails = IncomingETHTransferDetails | OutgoingETHTransferDetails - -export interface UnknownTransferDetails extends IncomingTransferDetails, OutgoingTransferDetails { - value: string - txHash: string -} - -export type TransferDetails = ERC20TransferDetails | ERC721TransferDetails | ETHTransferDetails | UnknownTransferDetails diff --git a/src/routes/safe/store/actions/transactions/utils/transferDetails.ts b/src/routes/safe/store/actions/transactions/utils/transferDetails.ts deleted file mode 100644 index 12363dff..00000000 --- a/src/routes/safe/store/actions/transactions/utils/transferDetails.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Transfer, TxConstants } from 'src/routes/safe/store/models/types/transactions.d' -import { sameAddress } from 'src/logic/wallets/ethAddresses' -import { store } from 'src/store' -import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { - ERC20TransferDetails, - ERC721TransferDetails, - ETHTransferDetails, - UnknownTransferDetails, -} from './transferDetails.d' -import { humanReadableValue } from 'src/logic/tokens/utils/humanReadableValue' - -const isIncomingTransfer = (transfer: Transfer): boolean => { - // TODO: prevent using `store` here and receive `safeAddress` as a param - const state = store.getState() - const safeAddress = safeParamAddressFromStateSelector(state) - return sameAddress(transfer.to, safeAddress) -} - -export const extractERC20TransferDetails = (transfer: Transfer): ERC20TransferDetails => { - const erc20TransferDetails = { - tokenAddress: transfer.tokenInfo?.address || TxConstants.UNKNOWN, - value: humanReadableValue(transfer.value || 0, transfer.tokenInfo?.decimals), - name: transfer.tokenInfo?.name || transfer.tokenInfo?.symbol || TxConstants.UNKNOWN, - txHash: transfer.transactionHash, - } - - if (isIncomingTransfer(transfer)) { - return { - ...erc20TransferDetails, - from: transfer.from, - } - } - - return { - ...erc20TransferDetails, - to: transfer.to, - } -} - -export const extractERC721TransferDetails = (transfer: Transfer): ERC721TransferDetails => { - const erc721TransferDetails = { - tokenAddress: transfer.tokenAddress, - tokenId: transfer.tokenId, - txHash: transfer.transactionHash, - } - if (isIncomingTransfer(transfer)) { - return { - ...erc721TransferDetails, - from: transfer.from, - } - } - - return { - ...erc721TransferDetails, - to: transfer.to, - } -} - -export const extractETHTransferDetails = (transfer: Transfer): ETHTransferDetails => { - const ethTransferDetails = { - value: humanReadableValue(transfer.value || 0), - txHash: transfer.transactionHash, - } - if (isIncomingTransfer(transfer)) { - return { - ...ethTransferDetails, - from: transfer.from, - } - } - - return { - ...ethTransferDetails, - to: transfer.to, - } -} - -export const extractUnknownTransferDetails = (transfer: Transfer): UnknownTransferDetails => { - return { - value: transfer?.value || TxConstants.UNKNOWN, - txHash: transfer?.transactionHash || TxConstants.UNKNOWN, - to: transfer?.to || TxConstants.UNKNOWN, - from: transfer?.from || TxConstants.UNKNOWN, - } -} diff --git a/src/routes/safe/store/models/types/transactions.d.ts b/src/routes/safe/store/models/types/transactions.d.ts deleted file mode 100644 index 0ee07282..00000000 --- a/src/routes/safe/store/models/types/transactions.d.ts +++ /dev/null @@ -1,255 +0,0 @@ -// TODO this file is duplicated with src/logic/safe/store/model/types/transaction.d.ts, we should remove it -export enum TxConstants { - MULTI_SEND = 'multiSend', - UNKNOWN = 'UNKNOWN', -} - -export enum Operation { - CALL, - DELEGATE_CALL, - CREATE, -} - -// types comes from: https://github.com/gnosis/safe-client-gateway/blob/752e76b6d1d475791dbd7917b174bb41d2d9d8be/src/utils.rs -export enum TransferMethods { - TRANSFER = 'transfer', - TRANSFER_FROM = 'transferFrom', - SAFE_TRANSFER_FROM = 'safeTransferFrom', -} - -export enum SettingsChangeMethods { - SETUP = 'setup', - SET_FALLBACK_HANDLER = 'setFallbackHandler', - ADD_OWNER_WITH_THRESHOLD = 'addOwnerWithThreshold', - REMOVE_OWNER = 'removeOwner', - REMOVE_OWNER_WITH_THRESHOLD = 'removeOwnerWithThreshold', - SWAP_OWNER = 'swapOwner', - CHANGE_THRESHOLD = 'changeThreshold', - CHANGE_MASTER_COPY = 'changeMasterCopy', - ENABLE_MODULE = 'enableModule', - DISABLE_MODULE = 'disableModule', - EXEC_TRANSACTION_FROM_MODULE = 'execTransactionFromModule', - APPROVE_HASH = 'approveHash', - EXEC_TRANSACTION = 'execTransaction', -} - -// note: this extends SAFE_METHODS_NAMES in /logic/contracts/methodIds.ts, we need to figure out which one we are going to use -export type DataDecodedMethod = TransferMethods | SettingsChangeMethods | string - -export interface ValueDecoded { - operation: Operation - to: string - value: number - data: string - dataDecoded: DataDecoded -} - -export interface SingleTransactionMethodParameter { - name: string - type: string - value: string -} - -export interface MultiSendMethodParameter extends SingleTransactionMethodParameter { - valueDecoded: ValueDecoded[] -} - -export type Parameter = MultiSendMethodParameter | SingleTransactionMethodParameter - -export interface DataDecoded { - method: DataDecodedMethod - parameters: Parameter[] -} - -export enum ConfirmationType { - CONFIRMATION = 'CONFIRMATION', - EXECUTION = 'EXECUTION', -} - -export enum SignatureType { - CONTRACT_SIGNATURE = 'CONTRACT_SIGNATURE', - APPROVED_HASH = 'APPROVED_HASH', - EOA = 'EOA', - ETH_SIGN = 'ETH_SIGN', -} - -export interface Confirmation { - owner: string - submissionDate: string - transactionHash: string | null - confirmationType: ConfirmationType - signature: string - signatureType: SignatureType -} - -export enum TokenType { - ERC20 = 'ERC20', - ERC721 = 'ERC721', - OTHER = 'OTHER', -} - -export interface TokenInfo { - type: TokenType - address: string - name: string - symbol: string - decimals: number - logoUri: string -} - -export enum TransferType { - ETHER_TRANSFER = 'ETHER_TRANSFER', - ERC20_TRANSFER = 'ERC20_TRANSFER', - ERC721_TRANSFER = 'ERC721_TRANSFER', - UNKNOWN = 'UNKNOWN', -} - -export interface Transfer { - type: TransferType - executionDate: string - blockNumber: number - transactionHash: string | null - to: string - value: string | null - tokenId: string | null - tokenAddress: string - tokenInfo: TokenInfo | null - from: string -} - -export enum TxType { - MULTISIG_TRANSACTION = 'MULTISIG_TRANSACTION', - ETHEREUM_TRANSACTION = 'ETHEREUM_TRANSACTION', - MODULE_TRANSACTION = 'MODULE_TRANSACTION', -} - -export interface MultiSigTransaction { - safe: string - to: string - value: string - data: string | null - operation: number - gasToken: string - safeTxGas: number - baseGas: number - gasPrice: string - refundReceiver: string - nonce: number - executionDate: string | null - submissionDate: string - modified: string - blockNumber: number | null - transactionHash: string | null - safeTxHash: string - executor: string | null - isExecuted: boolean - isSuccessful: boolean | null - ethGasPrice: string | null - gasUsed: number | null - fee: string | null - origin: string | null - dataDecoded: DataDecoded | null - confirmationsRequired: number | null - confirmations: Confirmation[] - signatures: string | null - transfers: Transfer[] - txType: TxType.MULTISIG_TRANSACTION -} - -export interface ModuleTransaction { - created: string - executionDate: string - blockNumber: number - transactionHash: string - safe: string - module: string - to: string - value: string - data: string - operation: Operation - transfers: Transfer[] - txType: TxType.MODULE_TRANSACTION -} - -export interface EthereumTransaction { - executionDate: string - to: string - data: string | null - txHash: string - blockNumber: number - transfers: Transfer[] - txType: TxType.ETHEREUM_TRANSACTION - from: string -} - -export type Transaction = MultiSigTransaction | ModuleTransaction | EthereumTransaction - -// SAFE METHODS TO ITS ID -// https://github.com/gnosis/safe-contracts/blob/development/test/safeMethodNaming.js -// https://github.com/gnosis/safe-contracts/blob/development/contracts/GnosisSafe.sol -// [ -// { name: "addOwnerWithThreshold", id: "0x0d582f13" }, -// { name: "DOMAIN_SEPARATOR_TYPEHASH", id: "0x1db61b54" }, -// { name: "isOwner", id: "0x2f54bf6e" }, -// { name: "execTransactionFromModule", id: "0x468721a7" }, -// { name: "signedMessages", id: "0x5ae6bd37" }, -// { name: "enableModule", id: "0x610b5925" }, -// { name: "changeThreshold", id: "0x694e80c3" }, -// { name: "approvedHashes", id: "0x7d832974" }, -// { name: "changeMasterCopy", id: "0x7de7edef" }, -// { name: "SENTINEL_MODULES", id: "0x85e332cd" }, -// { name: "SENTINEL_OWNERS", id: "0x8cff6355" }, -// { name: "getOwners", id: "0xa0e67e2b" }, -// { name: "NAME", id: "0xa3f4df7e" }, -// { name: "nonce", id: "0xaffed0e0" }, -// { name: "getModules", id: "0xb2494df3" }, -// { name: "SAFE_MSG_TYPEHASH", id: "0xc0856ffc" }, -// { name: "SAFE_TX_TYPEHASH", id: "0xccafc387" }, -// { name: "disableModule", id: "0xe009cfde" }, -// { name: "swapOwner", id: "0xe318b52b" }, -// { name: "getThreshold", id: "0xe75235b8" }, -// { name: "domainSeparator", id: "0xf698da25" }, -// { name: "removeOwner", id: "0xf8dc5dd9" }, -// { name: "VERSION", id: "0xffa1ad74" }, -// { name: "setup", id: "0xa97ab18a" }, -// { name: "execTransaction", id: "0x6a761202" }, -// { name: "requiredTxGas", id: "0xc4ca3a9c" }, -// { name: "approveHash", id: "0xd4d9bdcd" }, -// { name: "signMessage", id: "0x85a5affe" }, -// { name: "isValidSignature", id: "0x20c13b0b" }, -// { name: "getMessageHash", id: "0x0a1028c4" }, -// { name: "encodeTransactionData", id: "0xe86637db" }, -// { name: "getTransactionHash", id: "0xd8d11f78" } -// ] - -export const SAFE_METHODS_NAMES = { - ADD_OWNER_WITH_THRESHOLD: 'addOwnerWithThreshold', - CHANGE_THRESHOLD: 'changeThreshold', - REMOVE_OWNER: 'removeOwner', - SWAP_OWNER: 'swapOwner', - ENABLE_MODULE: 'enableModule', - DISABLE_MODULE: 'disableModule', -} - -export const METHOD_TO_ID = { - '0xe318b52b': SAFE_METHODS_NAMES.SWAP_OWNER, - '0x0d582f13': SAFE_METHODS_NAMES.ADD_OWNER_WITH_THRESHOLD, - '0xf8dc5dd9': SAFE_METHODS_NAMES.REMOVE_OWNER, - '0x694e80c3': SAFE_METHODS_NAMES.CHANGE_THRESHOLD, - '0x610b5925': SAFE_METHODS_NAMES.ENABLE_MODULE, - '0xe009cfde': SAFE_METHODS_NAMES.DISABLE_MODULE, -} - -export type SafeMethods = typeof SAFE_METHODS_NAMES[keyof typeof SAFE_METHODS_NAMES] - -type TokenMethods = 'transfer' | 'transferFrom' | 'safeTransferFrom' - -type SafeDecodedParams = { - [key in SafeMethods]?: Record -} - -type TokenDecodedParams = { - [key in TokenMethods]?: Record -} - -export type DecodedParams = SafeDecodedParams | TokenDecodedParams | null diff --git a/src/store/index.ts b/src/store/index.ts index 037d71df..cb3dba2e 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,4 +1,4 @@ -import { List, Map } from 'immutable' +import { Map } from 'immutable' import { connectRouter, routerMiddleware, RouterState } from 'connected-react-router' import { createHashHistory } from 'history' import { applyMiddleware, combineReducers, compose, createStore, CombinedState, PreloadedState, Store } from 'redux' @@ -24,7 +24,6 @@ import currentSession, { } from 'src/logic/currentSession/store/reducer/currentSession' import { Notification } from 'src/logic/notifications' import notifications, { NOTIFICATIONS_REDUCER_ID } from 'src/logic/notifications/store/reducer/notifications' -import { Transaction } from 'src/logic/safe/store/models/types/transaction' import { StoreStructure } from 'src/logic/safe/store/models/types/gateway' import { gatewayTransactions, GATEWAY_TRANSACTIONS_ID } from 'src/logic/safe/store/reducer/gatewayTransactions' import tokens, { TOKEN_REDUCER_ID, TokenState } from 'src/logic/tokens/store/reducer/tokens' @@ -32,23 +31,10 @@ import providerWatcher from 'src/logic/wallets/store/middlewares/providerWatcher import provider, { PROVIDER_REDUCER_ID, ProviderState } from 'src/logic/wallets/store/reducer/provider' import notificationsMiddleware from 'src/logic/safe/store/middleware/notificationsMiddleware' import safeStorage from 'src/logic/safe/store/middleware/safeStorage' -import cancellationTransactions, { - CANCELLATION_TRANSACTIONS_REDUCER_ID, - CancellationTxState, -} from 'src/logic/safe/store/reducer/cancellationTransactions' -import incomingTransactions, { - INCOMING_TRANSACTIONS_REDUCER_ID, -} from 'src/logic/safe/store/reducer/incomingTransactions' import safe, { SAFE_REDUCER_ID } from 'src/logic/safe/store/reducer/safe' -import transactions, { TRANSACTIONS_REDUCER_ID } from 'src/logic/safe/store/reducer/transactions' import { NFTAssets, NFTTokens } from 'src/logic/collectibles/sources/collectibles.d' import { SafeReducerMap } from 'src/routes/safe/store/reducer/types/safe' -import allTransactions, { TRANSACTIONS, TransactionsState } from '../logic/safe/store/reducer/allTransactions' import { AddressBookState } from 'src/logic/addressBook/model/addressBook' -import moduleTransactions, { - MODULE_TRANSACTIONS_REDUCER_ID, - ModuleTransactionsState, -} from 'src/logic/safe/store/reducer/moduleTransactions' export const history = createHashHistory() @@ -74,16 +60,11 @@ const reducers = combineReducers({ [NFT_TOKENS_REDUCER_ID]: nftTokensReducer, [TOKEN_REDUCER_ID]: tokens, [GATEWAY_TRANSACTIONS_ID]: gatewayTransactions, - [TRANSACTIONS_REDUCER_ID]: transactions, - [CANCELLATION_TRANSACTIONS_REDUCER_ID]: cancellationTransactions, - [INCOMING_TRANSACTIONS_REDUCER_ID]: incomingTransactions, - [MODULE_TRANSACTIONS_REDUCER_ID]: moduleTransactions, [NOTIFICATIONS_REDUCER_ID]: notifications, [CURRENCY_VALUES_KEY]: currencyValues, [COOKIES_REDUCER_ID]: cookies, [ADDRESS_BOOK_REDUCER_ID]: addressBook, [CURRENT_SESSION_REDUCER_ID]: currentSession, - [TRANSACTIONS]: allTransactions, }) export type AppReduxState = CombinedState<{ @@ -93,16 +74,11 @@ export type AppReduxState = CombinedState<{ [NFT_TOKENS_REDUCER_ID]: NFTTokens [TOKEN_REDUCER_ID]: TokenState [GATEWAY_TRANSACTIONS_ID]: Record - [TRANSACTIONS_REDUCER_ID]: Map> - [CANCELLATION_TRANSACTIONS_REDUCER_ID]: CancellationTxState - [INCOMING_TRANSACTIONS_REDUCER_ID]: Map> - [MODULE_TRANSACTIONS_REDUCER_ID]: ModuleTransactionsState [NOTIFICATIONS_REDUCER_ID]: Map [CURRENCY_VALUES_KEY]: CurrencyValuesState [COOKIES_REDUCER_ID]: Map [ADDRESS_BOOK_REDUCER_ID]: AddressBookState [CURRENT_SESSION_REDUCER_ID]: CurrentSessionState - [TRANSACTIONS]: TransactionsState router: RouterState }> diff --git a/src/test/safe.dom.funds.thresholdGt1.ts b/src/test/safe.dom.funds.thresholdGt1.ts deleted file mode 100644 index af45d955..00000000 --- a/src/test/safe.dom.funds.thresholdGt1.ts +++ /dev/null @@ -1,78 +0,0 @@ -// -import { fireEvent, waitForElement } from '@testing-library/react' -import { aNewStore } from 'src/store' -import { aMinedSafe } from 'src/test/builder/safe.redux.builder' -import { sendEtherTo } from 'src/test/utils/tokenMovements' -import { renderSafeView } from 'src/test/builder/safe.dom.utils' -import { getWeb3, getBalanceInEtherOf } from 'src/logic/wallets/getWeb3' -import { sleep } from 'src/utils/timer' -import '@testing-library/jest-dom/extend-expect' -import { BALANCE_ROW_TEST_ID } from 'src/routes/safe/components/Balances' -import { fillAndSubmitSendFundsForm, TRANSACTION_ROW_TEST_ID } from './utils/transactions' -import { TRANSACTIONS_TAB_BTN_TEST_ID } from 'src/routes/safe/container' -import { useTestAccountAt, resetTestAccount } from './utils/accounts' -import { APPROVE_TX_MODAL_SUBMIT_BTN_TEST_ID } from 'src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal' -import { CONFIRM_TX_BTN_TEST_ID } from 'src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent' - -afterEach(resetTestAccount) - -describe('DOM > Feature > Sending Funds', () => { - let store - let safeAddress - let accounts - beforeEach(async () => { - store = aNewStore() - // using 4th account because other accounts were used in other tests and paid gas - safeAddress = await aMinedSafe(store, 2, 2) - accounts = await getWeb3().eth.getAccounts() - }) - - it('Sends ETH with threshold = 2', async () => { - // GIVEN - const ethAmount = '5' - await sendEtherTo(safeAddress, ethAmount) - const balanceAfterSendingEthToSafe = await getBalanceInEtherOf(accounts[0]) - - // WHEN - const SafeDom = renderSafeView(store, safeAddress) - await sleep(1300) - - // Open send funds modal - const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID) - expect(balanceRows[0]).toHaveTextContent(`${ethAmount} ETH`) - const sendButton = SafeDom.getByTestId('balance-send-btn') - fireEvent.click(sendButton) - - await fillAndSubmitSendFundsForm(SafeDom, sendButton, ethAmount, accounts[0]) - - // CONFIRM TX - fireEvent.click(SafeDom.getByTestId(TRANSACTIONS_TAB_BTN_TEST_ID)) - await sleep(200) - - useTestAccountAt(1) - await sleep(2200) - const txRows = SafeDom.getAllByTestId(TRANSACTION_ROW_TEST_ID) - expect(txRows.length).toBe(1) - - fireEvent.click(txRows[0]) - - const confirmBtn = await waitForElement(() => SafeDom.getByTestId(CONFIRM_TX_BTN_TEST_ID)) - fireEvent.click(confirmBtn) - - // Travel confirm modal - const approveTxBtn = await waitForElement(() => SafeDom.getByTestId(APPROVE_TX_MODAL_SUBMIT_BTN_TEST_ID)) - fireEvent.click(approveTxBtn) - - await sleep(1000) - - // THEN - const safeFunds = await getBalanceInEtherOf(safeAddress) - expect(Number(safeFunds)).toBe(0) - - const receiverFunds = await getBalanceInEtherOf(accounts[0]) - const ESTIMATED_GASCOSTS = 0.3 - expect(Number(parseInt(receiverFunds, 10) - parseInt(balanceAfterSendingEthToSafe, 10))).toBeGreaterThan( - parseInt(ethAmount, 10) - ESTIMATED_GASCOSTS, - ) - }) -}) diff --git a/src/test/safe.dom.settings.owners.ts b/src/test/safe.dom.settings.owners.ts deleted file mode 100644 index 7e8287b8..00000000 --- a/src/test/safe.dom.settings.owners.ts +++ /dev/null @@ -1,242 +0,0 @@ -// -import { fireEvent, waitForElement } from '@testing-library/react' -import { aNewStore } from 'src/store' -import { aMinedSafe } from 'src/test/builder/safe.redux.builder' -import { renderSafeView } from 'src/test/builder/safe.dom.utils' -import { sleep } from 'src/utils/timer' -import '@testing-library/jest-dom/extend-expect' -import { - checkRegisteredTxAddOwner, - checkRegisteredTxRemoveOwner, - checkRegisteredTxReplaceOwner, -} from './utils/transactions' -import { SETTINGS_TAB_BTN_TEST_ID } from 'src/routes/safe/container' -import { OWNERS_SETTINGS_TAB_TEST_ID } from 'src/routes/safe/components/Settings' -import { - RENAME_OWNER_BTN_TEST_ID, - OWNERS_ROW_TEST_ID, - REMOVE_OWNER_BTN_TEST_ID, - ADD_OWNER_BTN_TEST_ID, - REPLACE_OWNER_BTN_TEST_ID, -} from 'src/routes/safe/components/Settings/ManageOwners' -import { - RENAME_OWNER_INPUT_TEST_ID, - SAVE_OWNER_CHANGES_BTN_TEST_ID, -} from 'src/routes/safe/components/Settings/ManageOwners/EditOwnerModal' -import { REMOVE_OWNER_MODAL_NEXT_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner' -import { REMOVE_OWNER_THRESHOLD_NEXT_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/ThresholdForm' -import { REMOVE_OWNER_REVIEW_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/Review' -import { ADD_OWNER_THRESHOLD_NEXT_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/ThresholdForm' -import { - ADD_OWNER_NAME_INPUT_TEST_ID, - ADD_OWNER_ADDRESS_INPUT_TEST_ID, - ADD_OWNER_NEXT_BTN_TEST_ID, -} from 'src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/OwnerForm' -import { ADD_OWNER_SUBMIT_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review' -import { - REPLACE_OWNER_NEXT_BTN_TEST_ID, - REPLACE_OWNER_NAME_INPUT_TEST_ID, - REPLACE_OWNER_ADDRESS_INPUT_TEST_ID, -} from 'src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm' -import { REPLACE_OWNER_SUBMIT_BTN_TEST_ID } from 'src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review' - -const originalError = console.error -beforeAll(() => { - console.error = (...args) => { - if (/Warning.*not wrapped in act/.test(args[0])) { - return - } - originalError.call(console, ...args) - } -}) - -afterAll(() => { - console.error = originalError -}) - -const travelToOwnerSettings = async (dom) => { - const settingsBtn = await waitForElement(() => dom.getByTestId(SETTINGS_TAB_BTN_TEST_ID)) - fireEvent.click(settingsBtn) - - // click on owners settings - const ownersSettingsBtn = await waitForElement(() => dom.getByTestId(OWNERS_SETTINGS_TAB_TEST_ID)) - fireEvent.click(ownersSettingsBtn) - - await sleep(500) -} - -describe('DOM > Feature > Settings - Manage owners', () => { - let store - let safeAddress - beforeEach(async () => { - store = aNewStore() - safeAddress = await aMinedSafe(store) - }) - - it("Changes owner's name", async () => { - const NEW_OWNER_NAME = 'NEW OWNER NAME' - - const SafeDom = renderSafeView(store, safeAddress) - await sleep(1300) - - // Travel to settings - await travelToOwnerSettings(SafeDom) - - // open rename owner modal - const renameOwnerBtn = await waitForElement(() => SafeDom.getByTestId(RENAME_OWNER_BTN_TEST_ID)) - fireEvent.click(renameOwnerBtn) - - // rename owner - const ownerNameInput = SafeDom.getByTestId(RENAME_OWNER_INPUT_TEST_ID) - const saveOwnerChangesBtn = SafeDom.getByTestId(SAVE_OWNER_CHANGES_BTN_TEST_ID) - fireEvent.change(ownerNameInput, { target: { value: NEW_OWNER_NAME } }) - fireEvent.click(saveOwnerChangesBtn) - await sleep(200) - - // check if the name updated - const ownerRow = SafeDom.getByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRow).toHaveTextContent(NEW_OWNER_NAME) - }) - - it('Removes an owner', async () => { - const twoOwnersSafeAddress = await aMinedSafe(store, 2) - - const SafeDom = renderSafeView(store, twoOwnersSafeAddress) - await sleep(1300) - - // Travel to settings - await travelToOwnerSettings(SafeDom) - - // check if there are 2 owners - let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(2) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account') - expect(ownerRows[1]).toHaveTextContent('0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0') - - // click remove owner btn which opens the modal - const removeOwnerBtn = SafeDom.getAllByTestId(REMOVE_OWNER_BTN_TEST_ID)[1] - fireEvent.click(removeOwnerBtn) - - // modal navigation - const nextBtnStep1 = SafeDom.getByTestId(REMOVE_OWNER_MODAL_NEXT_BTN_TEST_ID) - fireEvent.click(nextBtnStep1) - - const nextBtnStep2 = SafeDom.getByTestId(REMOVE_OWNER_THRESHOLD_NEXT_BTN_TEST_ID) - fireEvent.click(nextBtnStep2) - - const nextBtnStep3 = SafeDom.getByTestId(REMOVE_OWNER_REVIEW_BTN_TEST_ID) - fireEvent.click(nextBtnStep3) - await sleep(1300) - - // check if owner was removed - await travelToOwnerSettings(SafeDom) - - ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(1) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - - // Check that the transaction was registered - await checkRegisteredTxRemoveOwner(SafeDom, '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0') - }) - - it('Adds a new owner', async () => { - const NEW_OWNER_NAME = 'I am a new owner' - const NEW_OWNER_ADDRESS = '0x0E329Fa8d6fCd1BA0cDA495431F1F7ca24F442c3' - - const SafeDom = renderSafeView(store, safeAddress) - await sleep(1300) - - // Travel to settings - await travelToOwnerSettings(SafeDom) - - // check if there is 1 owner - let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(1) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - - // click add owner btn - fireEvent.click(SafeDom.getByTestId(ADD_OWNER_BTN_TEST_ID)) - await sleep(200) - - // fill and travel add owner modal - const ownerNameInput = SafeDom.getByTestId(ADD_OWNER_NAME_INPUT_TEST_ID) - const ownerAddressInput = SafeDom.getByTestId(ADD_OWNER_ADDRESS_INPUT_TEST_ID) - const nextBtn = SafeDom.getByTestId(ADD_OWNER_NEXT_BTN_TEST_ID) - fireEvent.change(ownerNameInput, { target: { value: NEW_OWNER_NAME } }) - fireEvent.change(ownerAddressInput, { target: { value: NEW_OWNER_ADDRESS } }) - fireEvent.click(nextBtn) - await sleep(200) - - fireEvent.click(SafeDom.getByTestId(ADD_OWNER_THRESHOLD_NEXT_BTN_TEST_ID)) - await sleep(200) - fireEvent.click(SafeDom.getByTestId(ADD_OWNER_SUBMIT_BTN_TEST_ID)) - await sleep(1500) - - // check if owner was added - await travelToOwnerSettings(SafeDom) - - ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(2) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_NAME) - expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_ADDRESS) - // Check that the transaction was registered - await checkRegisteredTxAddOwner(SafeDom, NEW_OWNER_ADDRESS) - }) - - it('Replaces an owner', async () => { - const NEW_OWNER_NAME = 'I replaced an old owner' - const NEW_OWNER_ADDRESS = '0x1dF62f291b2E969fB0849d99D9Ce41e2F137006e' - - const twoOwnersSafeAddress = await aMinedSafe(store, 2) - - const SafeDom = renderSafeView(store, twoOwnersSafeAddress) - await sleep(1300) - - // Travel to settings - await travelToOwnerSettings(SafeDom) - - // check if there are 2 owners - let ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(2) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - expect(ownerRows[1]).toHaveTextContent('Adol 2 Eth Account') - expect(ownerRows[1]).toHaveTextContent('0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0') - - // click replace owner btn which opens the modal - const replaceOwnerBtn = SafeDom.getAllByTestId(REPLACE_OWNER_BTN_TEST_ID)[1] - fireEvent.click(replaceOwnerBtn) - - // fill and travel add owner modal - const ownerNameInput = SafeDom.getByTestId(REPLACE_OWNER_NAME_INPUT_TEST_ID) - const ownerAddressInput = SafeDom.getByTestId(REPLACE_OWNER_ADDRESS_INPUT_TEST_ID) - const nextBtn = SafeDom.getByTestId(REPLACE_OWNER_NEXT_BTN_TEST_ID) - fireEvent.change(ownerNameInput, { target: { value: NEW_OWNER_NAME } }) - fireEvent.change(ownerAddressInput, { target: { value: NEW_OWNER_ADDRESS } }) - fireEvent.click(nextBtn) - await sleep(200) - - const replaceSubmitBtn = SafeDom.getByTestId(REPLACE_OWNER_SUBMIT_BTN_TEST_ID) - fireEvent.click(replaceSubmitBtn) - await sleep(1000) - - // check if the owner was replaced - await travelToOwnerSettings(SafeDom) - - ownerRows = SafeDom.getAllByTestId(OWNERS_ROW_TEST_ID) - expect(ownerRows.length).toBe(2) - expect(ownerRows[0]).toHaveTextContent('Adol 1 Eth Account') - expect(ownerRows[0]).toHaveTextContent('0x90F8bf6A479f320ead074411a4B0e7944Ea8c9C1') - expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_NAME) - expect(ownerRows[1]).toHaveTextContent(NEW_OWNER_ADDRESS) - - // Check that the transaction was registered - await checkRegisteredTxReplaceOwner(SafeDom, '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0', NEW_OWNER_ADDRESS) - }) -}) diff --git a/src/test/utils/historyServiceHelper.ts b/src/test/utils/historyServiceHelper.ts index 93f36fc7..39e7a4a8 100644 --- a/src/test/utils/historyServiceHelper.ts +++ b/src/test/utils/historyServiceHelper.ts @@ -1,7 +1,4 @@ -// -import { List, Map } from 'immutable' import { } from 'src/logic/safe/store/models/confirmation' -import { } from 'src/logic/safe/store/models/transaction' import { sameAddress } from 'src/logic/wallets/ethAddresses' export const testSizeOfSafesWith = (transactions, size) => { diff --git a/src/test/utils/safeHelper.ts b/src/test/utils/safeHelper.ts index c260537c..ed0956a3 100644 --- a/src/test/utils/safeHelper.ts +++ b/src/test/utils/safeHelper.ts @@ -7,9 +7,8 @@ import { ConfirmationServiceModel, TxServiceModel, } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' -import { DataDecoded } from 'src/routes/safe/store/models/types/transactions.d' import { List, Map } from 'immutable' -import { PendingActionValues } from 'src/logic/safe/store/models/types/transaction' +import { DataDecoded, PendingActionValues } from 'src/logic/safe/store/models/types/transaction' const mockNonPayableTransactionObject = (callResult?: string): NonPayableTransactionObject => { return { diff --git a/src/test/utils/transactions/index.ts b/src/test/utils/transactions/index.ts index 31ebbccf..53bc5607 100644 --- a/src/test/utils/transactions/index.ts +++ b/src/test/utils/transactions/index.ts @@ -1,4 +1,3 @@ // export * from './moveFunds.helper' -export * from './moveTokens.helper' -export * from './transactionList.helper' +export * from './moveTokens.helper' \ No newline at end of file diff --git a/src/test/utils/transactions/transactionList.helper.ts b/src/test/utils/transactions/transactionList.helper.ts deleted file mode 100644 index c9e47df4..00000000 --- a/src/test/utils/transactions/transactionList.helper.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { fireEvent } from '@testing-library/react' -import { sleep } from 'src/utils/timer' -import { shortVersionOf } from 'src/logic/wallets/ethAddresses' -import { TRANSACTIONS_TAB_BTN_TEST_ID } from 'src/routes/safe/container' -import { - TRANSACTIONS_DESC_SEND_TEST_ID, -} from 'src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription' -import { - TRANSACTIONS_DESC_ADD_OWNER_TEST_ID, - TRANSACTIONS_DESC_REMOVE_OWNER_TEST_ID, -} from 'src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription' - -export const TRANSACTION_ROW_TEST_ID = 'transaction-row' - -export const getLastTransaction = async (SafeDom) => { - // Travel to transactions - const transactionsBtn = SafeDom.getByTestId(TRANSACTIONS_TAB_BTN_TEST_ID) - fireEvent.click(transactionsBtn) - await sleep(200) - - // Check the last transaction was registered - const transactionRows = SafeDom.getAllByTestId(TRANSACTION_ROW_TEST_ID) - expect(transactionRows.length).toBe(1) - fireEvent.click(transactionRows[0]) -} - -export const checkRegisteredTxSend = async ( - SafeDom, - ethAmount, - symbol, - ethAddress, -) => { - await getLastTransaction(SafeDom) - - const txDescription = SafeDom.getAllByTestId(TRANSACTIONS_DESC_SEND_TEST_ID)[0] - expect(txDescription).toHaveTextContent(`Send ${ethAmount} ${symbol} to:${shortVersionOf(ethAddress, 4)}`) -} - -export const checkRegisteredTxAddOwner = async (SafeDom, ownerAddress) => { - await getLastTransaction(SafeDom) - - const txDescription = SafeDom.getAllByTestId(TRANSACTIONS_DESC_ADD_OWNER_TEST_ID)[0] - expect(txDescription).toHaveTextContent(`Add owner:${shortVersionOf(ownerAddress, 4)}`) -} - -export const checkRegisteredTxRemoveOwner = async (SafeDom, ownerAddress) => { - await getLastTransaction(SafeDom) - - const txDescription = SafeDom.getAllByTestId(TRANSACTIONS_DESC_REMOVE_OWNER_TEST_ID)[0] - expect(txDescription).toHaveTextContent(`Remove owner:${shortVersionOf(ownerAddress, 4)}`) -} - -export const checkRegisteredTxReplaceOwner = async ( - SafeDom, - oldOwnerAddress, - newOwnerAddress, -) => { - await getLastTransaction(SafeDom) - - const txDescriptionRemove = SafeDom.getAllByTestId(TRANSACTIONS_DESC_REMOVE_OWNER_TEST_ID)[0] - expect(txDescriptionRemove).toHaveTextContent(`Remove owner:${shortVersionOf(oldOwnerAddress, 4)}`) - const txDescriptionAdd = SafeDom.getAllByTestId(TRANSACTIONS_DESC_ADD_OWNER_TEST_ID)[0] - expect(txDescriptionAdd).toHaveTextContent(`Add owner:${shortVersionOf(newOwnerAddress, 4)}`) -} diff --git a/yarn.lock b/yarn.lock index 1962f9c7..c22c0bf3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,10 +42,10 @@ dependencies: "@babel/highlight" "^7.12.13" -"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.13.tgz#27e19e0ed3726ccf54067ced4109501765e7e2e8" - integrity sha512-U/hshG5R+SIoW7HVWIdmy1cB7s3ki+r3FpyEZiCgpi4tFgPnX/vynY80ZGSASOIrUM6O7VxOgCZgdt7h97bUGg== +"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.8.tgz#5b783b9808f15cef71547f1b691f34f8ff6003a6" + integrity sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog== "@babel/core@7.12.3", "@babel/core@^7.1.0", "@babel/core@^7.12.0", "@babel/core@^7.12.3", "@babel/core@^7.4.5", "@babel/core@^7.7.5", "@babel/core@^7.8.4": version "7.12.17" @@ -68,12 +68,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.17.tgz#9ef1dd792d778b32284411df63f4f668a9957287" - integrity sha512-DSA7ruZrY4WI8VxuS1jWSRezFnghEoYEFrZcw9BizQRmOZiUsiHl59+qEARGPqPikwA/GPTyRCi7isuCK/oyqg== +"@babel/generator@^7.12.17", "@babel/generator@^7.13.0": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== dependencies: - "@babel/types" "^7.12.17" + "@babel/types" "^7.13.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -92,25 +92,25 @@ "@babel/helper-explode-assignable-expression" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.17.tgz#91d83fae61ef390d39c3f0507cb83979bab837c7" - integrity sha512-5EkibqLVYOuZ89BSg2lv+GG8feywLuvMXNYgf0Im4MssE0mFWPztSpJbildNnUgw0bLI2EsIN4MpSHC2iUJkQA== +"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz#02bdb22783439afb11b2f009814bdd88384bd468" + integrity sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A== dependencies: - "@babel/compat-data" "^7.12.13" + "@babel/compat-data" "^7.13.8" "@babel/helper-validator-option" "^7.12.17" browserslist "^4.14.5" - semver "^5.5.0" + semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.12.13", "@babel/helper-create-class-features-plugin@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.17.tgz#704b69c8a78d03fb1c5fcc2e7b593f8a65628944" - integrity sha512-I/nurmTxIxHV0M+rIpfQBF1oN342+yvl2kwZUrQuOClMamHF1w5tknfZubgNOLRoA73SzBFAdFcpb4M9HwOeWQ== +"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.13.0": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.8.tgz#0367bd0a7505156ce018ca464f7ac91ba58c1a04" + integrity sha512-qioaRrKHQbn4hkRKDHbnuQ6kAxmmOF+kzKGnIfxPK4j2rckSJCpKzr/SSTlohSCiE3uAQpNDJ9FIh4baeE8W+w== dependencies: "@babel/helper-function-name" "^7.12.13" - "@babel/helper-member-expression-to-functions" "^7.12.17" + "@babel/helper-member-expression-to-functions" "^7.13.0" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.0" "@babel/helper-split-export-declaration" "^7.12.13" "@babel/helper-create-regexp-features-plugin@^7.12.13": @@ -121,12 +121,26 @@ "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" -"@babel/helper-explode-assignable-expression@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.13.tgz#0e46990da9e271502f77507efa4c9918d3d8634a" - integrity sha512-5loeRNvMo9mx1dA/d6yNi+YiKziJZFylZnCo1nmFF4qPU4yJ14abhWESuSMQSlQxWdxdOFzxXjk/PpfudTtYyw== +"@babel/helper-define-polyfill-provider@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" + integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== dependencies: - "@babel/types" "^7.12.13" + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.12.13": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f" + integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA== + dependencies: + "@babel/types" "^7.13.0" "@babel/helper-function-name@^7.12.13": version "7.12.13" @@ -144,19 +158,20 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-hoist-variables@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.12.13.tgz#13aba58b7480b502362316ea02f52cca0e9796cd" - integrity sha512-KSC5XSj5HreRhYQtZ3cnSnQwDzgnbdUDEFsxkN0m6Q3WrCRt72xrnZ8+h+pX7YxM7hr87zIO3a/v5p/H3TrnVw== +"@babel/helper-hoist-variables@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8" + integrity sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g== dependencies: - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" -"@babel/helper-member-expression-to-functions@^7.12.13", "@babel/helper-member-expression-to-functions@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.17.tgz#f82838eb06e1235307b6d71457b6670ff71ee5ac" - integrity sha512-Bzv4p3ODgS/qpBE0DiJ9qf5WxSmrQ8gVTe8ClMfwwsY2x/rhykxxy3bXzG7AGTnPB2ij37zGJ/Q/6FruxHxsxg== +"@babel/helper-member-expression-to-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz#6aa4bb678e0f8c22f58cdb79451d30494461b091" + integrity sha512-yvRf8Ivk62JwisqV1rFRMxiSMDGnN6KH1/mDMmIrij4jztpQNRoHqqMG3U6apYbGRPJpgPalhva9Yd06HlUxJQ== dependencies: - "@babel/types" "^7.12.17" + "@babel/types" "^7.13.0" "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.13": version "7.12.13" @@ -165,19 +180,19 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-module-transforms@^7.12.13", "@babel/helper-module-transforms@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.17.tgz#7c75b987d6dfd5b48e575648f81eaac891539509" - integrity sha512-sFL+p6zOCQMm9vilo06M4VHuTxUAwa6IxgL56Tq1DVtA0ziAGTH1ThmJq7xwPqdQlgAbKX3fb0oZNbtRIyA5KQ== +"@babel/helper-module-transforms@^7.12.17", "@babel/helper-module-transforms@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.0.tgz#42eb4bd8eea68bab46751212c357bfed8b40f6f1" + integrity sha512-Ls8/VBwH577+pw7Ku1QkUWIyRRNHpYlts7+qSqBBFCW3I8QteB9DxfcZ5YJpOwH6Ihe/wn8ch7fMGOP1OhEIvw== dependencies: "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-replace-supers" "^7.13.0" "@babel/helper-simple-access" "^7.12.13" "@babel/helper-split-export-declaration" "^7.12.13" "@babel/helper-validator-identifier" "^7.12.11" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.17" - "@babel/types" "^7.12.17" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" lodash "^4.17.19" "@babel/helper-optimise-call-expression@^7.12.13": @@ -187,29 +202,29 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.12.13.tgz#174254d0f2424d8aefb4dd48057511247b0a9eeb" - integrity sha512-C+10MXCXJLiR6IeG9+Wiejt9jmtFpxUc3MQqCmPY8hfCjyUGl9kT+B2okzEZrtykiwrc4dbCPdDoz0A/HQbDaA== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" + integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== -"@babel/helper-remap-async-to-generator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.13.tgz#170365f4140e2d20e5c88f8ba23c24468c296878" - integrity sha512-Qa6PU9vNcj1NZacZZI1Mvwt+gXDH6CTfgAkSjeRMLE8HxtDK76+YDId6NQR+z7Rgd5arhD2cIbS74r0SxD6PDA== +"@babel/helper-remap-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209" + integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-wrap-function" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/helper-wrap-function" "^7.13.0" + "@babel/types" "^7.13.0" -"@babel/helper-replace-supers@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz#00ec4fb6862546bd3d0aff9aac56074277173121" - integrity sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg== +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.0.tgz#6034b7b51943094cb41627848cb219cb02be1d24" + integrity sha512-Segd5me1+Pz+rmN/NFBOplMbZG3SqRJOBlY+mA0SxAv6rjj7zJqr1AVr3SfzUVTLCv7ZLU5FycOM/SBGuLPbZw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.13" + "@babel/helper-member-expression-to-functions" "^7.13.0" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" "@babel/helper-simple-access@^7.12.13": version "7.12.13" @@ -242,47 +257,47 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== -"@babel/helper-wrap-function@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.13.tgz#e3ea8cb3ee0a16911f9c1b50d9e99fe8fe30f9ff" - integrity sha512-t0aZFEmBJ1LojdtJnhOaQEVejnzYhyjWHSsNSNo8vOYRbAJNh6r6GQF7pd36SqG7OKGbn+AewVQ/0IfYfIuGdw== +"@babel/helper-wrap-function@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" + integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA== dependencies: "@babel/helper-function-name" "^7.12.13" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" "@babel/helpers@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.17.tgz#71e03d2981a6b5ee16899964f4101dc8471d60bc" - integrity sha512-tEpjqSBGt/SFEsFikKds1sLNChKKGGR17flIgQKXH4fG6m9gTgl3gnOC1giHNyaBCSKuTfxaSzHi7UnvqiVKxg== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.0.tgz#7647ae57377b4f0408bf4f8a7af01c42e41badc0" + integrity sha512-aan1MeFPxFacZeSz6Ld7YZo5aPuqnKlD7+HZY75xQsueczFccP9A7V05+oe0XpLwHK3oLorPe9eaAUljL7WEaQ== dependencies: "@babel/template" "^7.12.13" - "@babel/traverse" "^7.12.17" - "@babel/types" "^7.12.17" + "@babel/traverse" "^7.13.0" + "@babel/types" "^7.13.0" "@babel/highlight@^7.0.0", "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.12.13.tgz#8ab538393e00370b26271b01fa08f7f27f2e795c" - integrity sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww== + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.8.tgz#10b2dac78526424dfc1f47650d0e415dfd9dc481" + integrity sha512-4vrIhfJyfNf+lCtXC2ck1rKSzDwciqF7IWFhXXrSOUC2O5DrVp+w4c6ed4AllTxhTkUP5x2tYj41VaxdVMMRDw== dependencies: "@babel/helper-validator-identifier" "^7.12.11" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.17", "@babel/parser@^7.7.0": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848" - integrity sha512-r1yKkiUTYMQ8LiEI0UcQx5ETw5dpTLn9wijn9hk6KkTtOK95FndDN10M+8/s6k/Ymlbivw0Av9q4SlgF80PtHg== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.17", "@babel/parser@^7.13.0", "@babel/parser@^7.7.0": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.9.tgz#ca34cb95e1c2dd126863a84465ae8ef66114be99" + integrity sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw== -"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.13.tgz#d1c6d841802ffb88c64a2413e311f7345b9e66b5" - integrity sha512-1KH46Hx4WqP77f978+5Ye/VUbuwQld2hph70yaw2hXS2v7ER2f3nlpNMu909HO2rbvP0NKLlMVDPh9KXklVMhA== +"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1" + integrity sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-remap-async-to-generator" "^7.12.13" - "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-proposal-class-properties@7.12.1": version "7.12.1" @@ -292,13 +307,13 @@ "@babel/helper-create-class-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.12.13", "@babel/plugin-proposal-class-properties@^7.7.0": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.13.tgz#3d2ce350367058033c93c098e348161d6dc0d8c8" - integrity sha512-8SCJ0Ddrpwv4T7Gwb33EmW1V9PY5lggTO+A8WjyIwxrSHDUyBw4MtF96ifn1n8H806YlxbVCoKXbbmzD6RD+cA== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.7.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37" + integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-proposal-decorators@7.12.1": version "7.12.1" @@ -309,13 +324,13 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-decorators" "^7.12.1" -"@babel/plugin-proposal-dynamic-import@^7.12.1", "@babel/plugin-proposal-dynamic-import@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.17.tgz#e0ebd8db65acc37eac518fa17bead2174e224512" - integrity sha512-ZNGoFZqrnuy9H2izB2jLlnNDAfVPlGl5NhFEiFe4D84ix9GQGygF+CWMGHKuE+bpyS/AOuDQCnkiRNqW2IzS1Q== +"@babel/plugin-proposal-dynamic-import@^7.12.1", "@babel/plugin-proposal-dynamic-import@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" + integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.12.13": version "7.12.13" @@ -325,20 +340,20 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.13.tgz#ced7888a2db92a3d520a2e35eb421fdb7fcc9b5d" - integrity sha512-v9eEi4GiORDg8x+Dmi5r8ibOe0VXoKDeNPYcTTxdGN4eOWikrJfDJCJrr1l5gKGvsNyGJbrfMftC2dTL6oz7pg== +"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" + integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.13.tgz#575b5d9a08d8299eeb4db6430da6e16e5cf14350" - integrity sha512-fqmiD3Lz7jVdK6kabeSr1PZlWSUVqSitmHEe3Z00dtGTKieWnX9beafvavc32kjORa5Bai4QNHgFDwWJP+WtSQ== +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" + integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-proposal-nullish-coalescing-operator@7.12.1": @@ -349,13 +364,13 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.13.tgz#24867307285cee4e1031170efd8a7ac807deefde" - integrity sha512-Qoxpy+OxhDBI5kRqliJFAl4uWXk3Bn24WeFstPH0iLymFehSAUR8MHpqU7njyXv/qbo7oN6yTy5bfCmXdKpo1Q== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" + integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-proposal-numeric-separator@7.12.1": version "7.12.1" @@ -373,22 +388,24 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.12.13", "@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.13.tgz#f93f3116381ff94bc676fdcb29d71045cd1ec011" - integrity sha512-WvA1okB/0OS/N3Ldb3sziSrXg6sRphsBgqiccfcQq7woEn5wQLNX82Oc4PlaFcdwcWHuQXAtb8ftbS8Fbsg/sg== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.13.8", "@babel/plugin-proposal-object-rest-spread@^7.6.2": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" + integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.13" + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.13.0" -"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.13.tgz#4640520afe57728af14b4d1574ba844f263bcae5" - integrity sha512-9+MIm6msl9sHWg58NvqpNpLtuFbmpFYk37x8kgnGzAHvX35E1FyAwSUt5hIkSoWJFSAH+iwU8bJ4fcD1zKXOzg== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" + integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-proposal-optional-chaining@7.12.1": version "7.12.1" @@ -399,22 +416,22 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.12.17": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.17.tgz#e382becadc2cb16b7913b6c672d92e4b33385b5c" - integrity sha512-TvxwI80pWftrGPKHNfkvX/HnoeSTR7gC4ezWnAL39PuktYUe6r8kEpOLTYnkBTsaoeazXm2jHJ22EQ81sdgfcA== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.8.tgz#e39df93efe7e7e621841babc197982e140e90756" + integrity sha512-hpbBwbTgd7Cz1QryvwJZRo1U0k1q8uyBmeXOSQUjdg/A2TASkhR/rz7AyqZ/kS8kbpsNA80rOYbxySBJAqmhhQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.13.tgz#ea78a12554d784ecf7fc55950b752d469d9c4a71" - integrity sha512-sV0V57uUwpauixvR7s2o75LmwJI6JECwm5oPUY5beZB1nBl2i37hc7CJGqB5G+58fur5Y6ugvl3LRONk5x34rg== +"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787" + integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" @@ -452,7 +469,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-syntax-dynamic-import@^7.2.0", "@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-dynamic-import@^7.2.0", "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -550,21 +567,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.13.tgz#eda5670b282952100c229f8a3bd49e0f6a72e9fe" - integrity sha512-tBtuN6qtCTd+iHzVZVOMNp+L04iIJBpqkdY42tWbmjIT5wvR2kx7gxMBsyhQtFzHwBbyGi9h8J8r9HgnOpQHxg== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae" + integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-async-to-generator@^7.12.1", "@babel/plugin-transform-async-to-generator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.13.tgz#fed8c69eebf187a535bfa4ee97a614009b24f7ae" - integrity sha512-psM9QHcHaDr+HZpRuJcE1PXESuGWSCcbiGFFhhwfzdbTxaGDVzuVtdNYliAwcRo3GFg0Bc8MmI+AvIGYIJG04A== +"@babel/plugin-transform-async-to-generator@^7.12.1", "@babel/plugin-transform-async-to-generator@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f" + integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg== dependencies: "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-remap-async-to-generator" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-remap-async-to-generator" "^7.13.0" "@babel/plugin-transform-block-scoped-functions@^7.12.1", "@babel/plugin-transform-block-scoped-functions@^7.12.13": version "7.12.13" @@ -580,32 +597,32 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.13.tgz#9728edc1838b5d62fc93ad830bd523b1fcb0e1f6" - integrity sha512-cqZlMlhCC1rVnxE5ZGMtIb896ijL90xppMiuWXcwcOAuFczynpd3KYemb91XFFPi3wJSe/OcrX9lXoowatkkxA== +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" + integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" "@babel/helper-function-name" "^7.12.13" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/helper-replace-supers" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.0" "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.12.1", "@babel/plugin-transform-computed-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.13.tgz#6a210647a3d67f21f699cfd2a01333803b27339d" - integrity sha512-dDfuROUPGK1mTtLKyDPUavmj2b6kFu82SmgpztBFEO974KMjJT+Ytj3/oWsTUMBmgPcp9J5Pc1SlcAYRpJ2hRA== +"@babel/plugin-transform-computed-properties@^7.12.1", "@babel/plugin-transform-computed-properties@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed" + integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.13.tgz#fc56c5176940c5b41735c677124d1d20cecc9aeb" - integrity sha512-Dn83KykIFzjhA3FDPA1z4N+yfF3btDGhjnJwxIj0T43tP0flCujnU8fKgEkf0C1biIpSv9NZegPBQ1J6jYkwvQ== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963" + integrity sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4": version "7.12.13" @@ -646,12 +663,12 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-flow" "^7.12.13" -"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.13.tgz#561ff6d74d9e1c8879cb12dbaf4a14cd29d15cf6" - integrity sha512-xCbdgSzXYmHGyVX3+BsQjcd4hv4vA/FDy7Kc8eOpzKmBBPEOTurt0w5fCRQaGl+GSBORKgJdstQ1rHl4jbNseQ== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062" + integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-function-name@^7.12.1", "@babel/plugin-transform-function-name@^7.12.13": version "7.12.13" @@ -675,43 +692,43 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.13.tgz#43db16249b274ee2e551e2422090aa1c47692d56" - integrity sha512-JHLOU0o81m5UqG0Ulz/fPC68/v+UTuGTWaZBUwpEk1fYQ1D9LfKV6MPn4ttJKqRo5Lm460fkzjLTL4EHvCprvA== +"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3" + integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ== dependencies: - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.13.tgz#5043b870a784a8421fa1fd9136a24f294da13e50" - integrity sha512-OGQoeVXVi1259HjuoDnsQMlMkT9UkZT9TpXAsqWplS/M0N1g3TJAn/ByOCeQu7mfjc5WpSsRU+jV1Hd89ts0kQ== +"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" + integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw== dependencies: - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-simple-access" "^7.12.13" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.12.1", "@babel/plugin-transform-modules-systemjs@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.13.tgz#351937f392c7f07493fc79b2118201d50404a3c5" - integrity sha512-aHfVjhZ8QekaNF/5aNdStCGzwTbU7SI5hUybBKlMzqIMC7w7Ho8hx5a4R/DkTHfRfLwHGGxSpFt9BfxKCoXKoA== +"@babel/plugin-transform-modules-systemjs@^7.12.1", "@babel/plugin-transform-modules-systemjs@^7.13.8": + version "7.13.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3" + integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A== dependencies: - "@babel/helper-hoist-variables" "^7.12.13" - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-hoist-variables" "^7.13.0" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.13.tgz#26c66f161d3456674e344b4b1255de4d530cfb37" - integrity sha512-BgZndyABRML4z6ibpi7Z98m4EVLFI9tVsZDADC14AElFaNHHBcJIovflJ6wtCqFxwy2YJ1tJhGRsr0yLPKoN+w== +"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b" + integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw== dependencies: - "@babel/helper-module-transforms" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-named-capturing-groups-regex@^7.12.1", "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": version "7.12.13" @@ -735,12 +752,12 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.13.tgz#461e76dfb63c2dfd327b8a008a9e802818ce9853" - integrity sha512-e7QqwZalNiBRHCpJg/P8s/VJeSRYgmtWySs1JwvfwPqhBbiWfOcHDKdeAi6oAyIimoKWBlwc8oTgbZHdhCoVZA== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" + integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-property-literals@^7.12.1", "@babel/plugin-transform-property-literals@^7.12.13": version "7.12.13" @@ -850,12 +867,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.13.tgz#ca0d5645abbd560719c354451b849f14df4a7949" - integrity sha512-dUCrqPIowjqk5pXsx1zPftSq4sT0aCeZVAxhdgs3AMgyaDmoUT0G+5h3Dzja27t76aUEIJWlFgPJqJ/d4dbTtg== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd" + integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-transform-sticky-regex@^7.12.1", "@babel/plugin-transform-sticky-regex@^7.12.13": @@ -865,12 +882,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.13.tgz#655037b07ebbddaf3b7752f55d15c2fd6f5aa865" - integrity sha512-arIKlWYUgmNsF28EyfmiQHJLJFlAJNYkuQO10jL46ggjBpeb2re1P9K9YGxNJB45BqTbaslVysXDYm/g3sN/Qg== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d" + integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-typeof-symbol@^7.12.1", "@babel/plugin-transform-typeof-symbol@^7.12.13": version "7.12.13" @@ -880,12 +897,12 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-typescript@^7.12.1": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.17.tgz#4aa6a5041888dd2e5d316ec39212b0cf855211bb" - integrity sha512-1bIYwnhRoetxkFonuZRtDZPFEjl1l5r+3ITkxLC3mlMaFja+GQFo94b/WHEPjqWLU9Bc+W4oFZbvCGe9eYMu1g== + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" + integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.17" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-typescript" "^7.12.13" "@babel/plugin-transform-unicode-escapes@^7.12.1", "@babel/plugin-transform-unicode-escapes@^7.12.13": @@ -976,76 +993,78 @@ semver "^5.5.0" "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.4.5", "@babel/preset-env@^7.8.4": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.17.tgz#94a3793ff089c32ee74d76a3c03a7597693ebaaa" - integrity sha512-9PMijx8zFbCwTHrd2P4PJR5nWGH3zWebx2OcpTjqQrHhCiL2ssSR2Sc9ko2BsI2VmVBfoaQmPrlMTCui4LmXQg== + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.9.tgz#3ee5f233316b10d066d7f379c6d1e13a96853654" + integrity sha512-mcsHUlh2rIhViqMG823JpscLMesRt3QbMsv1+jhopXEb3W2wXvQ9QoiOlZI9ZbR3XqPtaFpZwEZKYqGJnGMZTQ== dependencies: - "@babel/compat-data" "^7.12.13" - "@babel/helper-compilation-targets" "^7.12.17" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/compat-data" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-validator-option" "^7.12.17" - "@babel/plugin-proposal-async-generator-functions" "^7.12.13" - "@babel/plugin-proposal-class-properties" "^7.12.13" - "@babel/plugin-proposal-dynamic-import" "^7.12.17" + "@babel/plugin-proposal-async-generator-functions" "^7.13.8" + "@babel/plugin-proposal-class-properties" "^7.13.0" + "@babel/plugin-proposal-dynamic-import" "^7.13.8" "@babel/plugin-proposal-export-namespace-from" "^7.12.13" - "@babel/plugin-proposal-json-strings" "^7.12.13" - "@babel/plugin-proposal-logical-assignment-operators" "^7.12.13" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.13" + "@babel/plugin-proposal-json-strings" "^7.13.8" + "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" "@babel/plugin-proposal-numeric-separator" "^7.12.13" - "@babel/plugin-proposal-object-rest-spread" "^7.12.13" - "@babel/plugin-proposal-optional-catch-binding" "^7.12.13" - "@babel/plugin-proposal-optional-chaining" "^7.12.17" - "@babel/plugin-proposal-private-methods" "^7.12.13" + "@babel/plugin-proposal-object-rest-spread" "^7.13.8" + "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" + "@babel/plugin-proposal-optional-chaining" "^7.13.8" + "@babel/plugin-proposal-private-methods" "^7.13.0" "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" - "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.12.13" - "@babel/plugin-transform-arrow-functions" "^7.12.13" - "@babel/plugin-transform-async-to-generator" "^7.12.13" + "@babel/plugin-transform-arrow-functions" "^7.13.0" + "@babel/plugin-transform-async-to-generator" "^7.13.0" "@babel/plugin-transform-block-scoped-functions" "^7.12.13" "@babel/plugin-transform-block-scoping" "^7.12.13" - "@babel/plugin-transform-classes" "^7.12.13" - "@babel/plugin-transform-computed-properties" "^7.12.13" - "@babel/plugin-transform-destructuring" "^7.12.13" + "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-computed-properties" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.0" "@babel/plugin-transform-dotall-regex" "^7.12.13" "@babel/plugin-transform-duplicate-keys" "^7.12.13" "@babel/plugin-transform-exponentiation-operator" "^7.12.13" - "@babel/plugin-transform-for-of" "^7.12.13" + "@babel/plugin-transform-for-of" "^7.13.0" "@babel/plugin-transform-function-name" "^7.12.13" "@babel/plugin-transform-literals" "^7.12.13" "@babel/plugin-transform-member-expression-literals" "^7.12.13" - "@babel/plugin-transform-modules-amd" "^7.12.13" - "@babel/plugin-transform-modules-commonjs" "^7.12.13" - "@babel/plugin-transform-modules-systemjs" "^7.12.13" - "@babel/plugin-transform-modules-umd" "^7.12.13" + "@babel/plugin-transform-modules-amd" "^7.13.0" + "@babel/plugin-transform-modules-commonjs" "^7.13.8" + "@babel/plugin-transform-modules-systemjs" "^7.13.8" + "@babel/plugin-transform-modules-umd" "^7.13.0" "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" "@babel/plugin-transform-new-target" "^7.12.13" "@babel/plugin-transform-object-super" "^7.12.13" - "@babel/plugin-transform-parameters" "^7.12.13" + "@babel/plugin-transform-parameters" "^7.13.0" "@babel/plugin-transform-property-literals" "^7.12.13" "@babel/plugin-transform-regenerator" "^7.12.13" "@babel/plugin-transform-reserved-words" "^7.12.13" "@babel/plugin-transform-shorthand-properties" "^7.12.13" - "@babel/plugin-transform-spread" "^7.12.13" + "@babel/plugin-transform-spread" "^7.13.0" "@babel/plugin-transform-sticky-regex" "^7.12.13" - "@babel/plugin-transform-template-literals" "^7.12.13" + "@babel/plugin-transform-template-literals" "^7.13.0" "@babel/plugin-transform-typeof-symbol" "^7.12.13" "@babel/plugin-transform-unicode-escapes" "^7.12.13" "@babel/plugin-transform-unicode-regex" "^7.12.13" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.12.17" - core-js-compat "^3.8.0" - semver "^5.5.0" + "@babel/preset-modules" "^0.1.4" + "@babel/types" "^7.13.0" + babel-plugin-polyfill-corejs2 "^0.1.4" + babel-plugin-polyfill-corejs3 "^0.1.3" + babel-plugin-polyfill-regenerator "^0.1.2" + core-js-compat "^3.9.0" + semver "^6.3.0" "@babel/preset-flow@^7.0.0": version "7.12.13" @@ -1055,7 +1074,7 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-flow-strip-types" "^7.12.13" -"@babel/preset-modules@^0.1.3": +"@babel/preset-modules@^0.1.3", "@babel/preset-modules@^0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== @@ -1114,9 +1133,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.12.18" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.18.tgz#af137bd7e7d9705a412b3caaf991fe6aaa97831b" - integrity sha512-BogPQ7ciE6SYAUPtlm9tWbgI9+2AgqSam6QivMgXgAT+fKbgppaj4ZX15MHeLC1PVF5sNk70huBu20XxWOs8Cg== + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.9.tgz#97dbe2116e2630c489f22e0656decd60aaa1fcee" + integrity sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA== dependencies: regenerator-runtime "^0.13.4" @@ -1129,25 +1148,25 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13", "@babel/traverse@^7.12.17", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.17.tgz#40ec8c7ffb502c4e54c7f95492dc11b88d718619" - integrity sha512-LGkTqDqdiwC6Q7fWSwQoas/oyiEYw6Hqjve5KOSykXkmFJFqzvGMb9niaUEag3Rlve492Mkye3gLw9FTv94fdQ== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.17", "@babel/traverse@^7.13.0", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc" + integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.12.17" + "@babel/generator" "^7.13.0" "@babel/helper-function-name" "^7.12.13" "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.12.17" - "@babel/types" "^7.12.17" + "@babel/parser" "^7.13.0" + "@babel/types" "^7.13.0" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963" - integrity sha512-tNMDjcv/4DIcHxErTgwB9q2ZcYyN0sUfgGKUK/mm1FJK7Wz+KstoEekxrl/tBiNDgLK1HGi+sppj1An/1DR4fQ== +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.13.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" + integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== dependencies: "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" @@ -1205,6 +1224,17 @@ global-agent "^2.0.2" global-tunnel-ng "^2.7.1" +"@electron/universal@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@electron/universal/-/universal-1.0.4.tgz#231ac246c39d45b80e159bd21c3f9027dcaa10f5" + integrity sha512-ajZoumi4XwqwmZe8YVhu4XGkZBCPyWZsVCQONPTIe9TUlleSN+dic3YpXlaWcilx/HOzTdldTKtabNTeI0gDoA== + dependencies: + "@malept/cross-spawn-promise" "^1.1.0" + asar "^3.0.3" + debug "^4.3.1" + dir-compare "^2.4.0" + fs-extra "^9.0.1" + "@emotion/cache@^10.0.27": version "10.0.29" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" @@ -1307,19 +1337,25 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@ensdomains/address-encoder@0.1.8": - version "0.1.8" - resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.8.tgz#be022a706cfd39327caaca2fa7f59d19ea2787d9" - integrity sha512-0YwXk/cX7G/qM7YHrOybF9Ht7cwR0/XH37yh0cdPdIOPJ6Y839yymyAWGVC7Sl2ESAhqj4hfoHpb2+QllB7KAQ== +"@ensdomains/address-encoder@0.2.6": + version "0.2.6" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.2.6.tgz#1ea4aefea8c9617ada0a80519bec00589920ffac" + integrity sha512-b0jtq3vx1xxUJRwS9zJMy5SVtH1ixIS18gHm3tFyBR1ehsk/lK80nCoV1lJi0KXgQ/2RD+/KYoWlW5CNZG7AAw== dependencies: bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" crypto-addr-codec "^0.1.7" - eztz-lib "^0.1.2" + js-sha512 "^0.8.0" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + sha3 "^2.1.3" -"@eslint/eslintrc@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.3.0.tgz#d736d6963d7003b6514e6324bec9c602ac340318" - integrity sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg== +"@eslint/eslintrc@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" + integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -1328,7 +1364,6 @@ ignore "^4.0.6" import-fresh "^3.2.1" js-yaml "^3.13.1" - lodash "^4.17.20" minimatch "^3.0.4" strip-json-comments "^3.1.1" @@ -1561,9 +1596,9 @@ solc "0.5.14" truffle "^5.1.21" -"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#fb1a523": +"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#f610327": version "0.5.0" - resolved "https://github.com/gnosis/safe-react-components.git#fb1a523ece12aa54e7e6a1169c7cd13da5bf5b61" + resolved "https://github.com/gnosis/safe-react-components.git#f610327c109810547513079196514b05cda63844" dependencies: classnames "^2.2.6" react-media "^1.10.0" @@ -1827,17 +1862,17 @@ dependencies: invariant "2" -"@ledgerhq/devices@^5.41.0", "@ledgerhq/devices@^5.43.0": - version "5.43.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.43.0.tgz#9b8ca838a7f8ece74098dc84aa6468eb7651972d" - integrity sha512-/M5ZLUBdBK7Vl2T4yNJbES3Z4w55LbPdxD9rcOBAKH/5V3V0obQv6MUasP9b7DSkwGSSLCOGZLohoT2NxK2D2A== +"@ledgerhq/devices@^5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.45.0.tgz#f39f42c2526a98bde2cb42af111848783f2394b1" + integrity sha512-wAtm4kvQ8pAdqdIpDa/OqU9rhtqI0sTdwDGGp4vthHiWNdBwqwPFcKmEki+mUgPCfRqn3SifyqaPqvFpvu+oWw== dependencies: "@ledgerhq/errors" "^5.43.0" "@ledgerhq/logs" "^5.43.0" - rxjs "^6.6.3" + rxjs "^6.6.6" semver "^7.3.4" -"@ledgerhq/errors@^5.34.0", "@ledgerhq/errors@^5.41.0", "@ledgerhq/errors@^5.43.0": +"@ledgerhq/errors@^5.34.0", "@ledgerhq/errors@^5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.43.0.tgz#6bec77ebc31c4333a7f8d13b1f3f4d739b859b75" integrity sha512-ZjKlUQbIn/DHXAefW3Y1VyDrlVhVqqGnXzrqbOXuDbZ2OAIfSe/A1mrlCbWt98jP/8EJQBuCzBOtnmpXIL/nYg== @@ -1853,28 +1888,28 @@ bignumber.js "^9.0.1" rlp "^2.2.6" -"@ledgerhq/hw-transport-node-hid-noevents@^5.41.0": - version "5.43.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.43.0.tgz#42faf14019f5cc4e46335539d0e6e05d5acfc470" - integrity sha512-3TqeVTFslJdaAPgQh9qqRN6MuEkDNA9talEdm6k6osB3aIG3I67TNMTOY32nWdyeGx9VuEw0guUN1KJpxWQ1rg== +"@ledgerhq/hw-transport-node-hid-noevents@^5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.45.0.tgz#a7c6d481d7ef73f03e3feddc6d07498c8de585a1" + integrity sha512-f0c1FKAo9r/bU8fbASAEP2uuU7hbbX7AfyrETu7Lx5yx6GmWzq/IL+FhnmWJyiwlwqH7HR71ivVYoEoM4veWCQ== dependencies: - "@ledgerhq/devices" "^5.43.0" + "@ledgerhq/devices" "^5.45.0" "@ledgerhq/errors" "^5.43.0" - "@ledgerhq/hw-transport" "^5.43.0" + "@ledgerhq/hw-transport" "^5.45.0" "@ledgerhq/logs" "^5.43.0" node-hid "2.1.1" -"@ledgerhq/hw-transport-node-hid-singleton@5.41.0": - version "5.41.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-singleton/-/hw-transport-node-hid-singleton-5.41.0.tgz#d5b0fa4d45dfa6c904e726ab35e30fec025edb99" - integrity sha512-1wF+FQ5m9NTv/aInisiQ7VLgN3JY3xTIhDxn/5S0a4t1JojK0JPJAiOSp9IgEkCKRsKNBEwB4ghOmtB/qD/5EQ== +"@ledgerhq/hw-transport-node-hid-singleton@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-singleton/-/hw-transport-node-hid-singleton-5.45.0.tgz#c29ac64927823493bc93996fc1aa7ed363e0bb1d" + integrity sha512-nJgT4eMTevC2vz/RXOmLn9U0B9Wp2BNSxeM/Z0Sh3lRtSS6dBLia1mZNhVpH+AfwvEnZ3Ta0lWZinUYY+ARH5g== dependencies: - "@ledgerhq/devices" "^5.41.0" - "@ledgerhq/errors" "^5.41.0" - "@ledgerhq/hw-transport" "^5.41.0" - "@ledgerhq/hw-transport-node-hid-noevents" "^5.41.0" - "@ledgerhq/logs" "^5.41.0" - lodash "^4.17.20" + "@ledgerhq/devices" "^5.45.0" + "@ledgerhq/errors" "^5.43.0" + "@ledgerhq/hw-transport" "^5.45.0" + "@ledgerhq/hw-transport-node-hid-noevents" "^5.45.0" + "@ledgerhq/logs" "^5.43.0" + lodash "^4.17.21" node-hid "2.1.1" usb-detection "^4.10.0" @@ -1888,20 +1923,27 @@ "@ledgerhq/logs" "^5.30.0" u2f-api "0.2.7" -"@ledgerhq/hw-transport@^5.34.0", "@ledgerhq/hw-transport@^5.41.0", "@ledgerhq/hw-transport@^5.43.0": - version "5.43.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.43.0.tgz#dc9863706d31bae96aed66f193b8922a876cbf82" - integrity sha512-0S+TGmiEJOqgM2MWnolZQPVKU3oRtoDj4yUFUZts9Owbgby+hmo4dIKTvv0vs8mwknQbOZByUgh3MQOQiK70MQ== +"@ledgerhq/hw-transport@^5.34.0", "@ledgerhq/hw-transport@^5.43.0", "@ledgerhq/hw-transport@^5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.45.0.tgz#5d1e23d61d99664faf29609dbd4a5ca6d1f4c1bc" + integrity sha512-YDkPQ2u5BJaMk2rJ8jcSucCv1JRUhmlaWUOvZ+Q7I8VNnvBM+N5yc9nqRX8TuHRlbPyiFm8xjEkPktVejuTAvQ== dependencies: - "@ledgerhq/devices" "^5.43.0" + "@ledgerhq/devices" "^5.45.0" "@ledgerhq/errors" "^5.43.0" - events "^3.2.0" + events "^3.3.0" -"@ledgerhq/logs@^5.30.0", "@ledgerhq/logs@^5.41.0", "@ledgerhq/logs@^5.43.0": +"@ledgerhq/logs@^5.30.0", "@ledgerhq/logs@^5.43.0": version "5.43.0" resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.43.0.tgz#031bad4b8a3525c5e14210afde0bc09c79564026" integrity sha512-QWfQjea3ekh9ZU+JeL2tJC9cTKLZ/JrcS0JGatLejpRYxQajvnHvHfh0dbHOKXEaXfCskEPTZ3f1kzuts742GA== +"@malept/cross-spawn-promise@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz#504af200af6b98e198bce768bc1730c6936ae01d" + integrity sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ== + dependencies: + cross-spawn "^7.0.1" + "@material-ui/core@^4.11.0": version "4.11.3" resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.3.tgz#f22e41775b0bd075e36a7a093d43951bf7f63850" @@ -2150,10 +2192,10 @@ resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204" integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg== -"@rescripts/cli@^0.0.15": - version "0.0.15" - resolved "https://registry.yarnpkg.com/@rescripts/cli/-/cli-0.0.15.tgz#4ebd51bf506bed7eb97dc6309a3dc8b6851944ba" - integrity sha512-hfOdcfBLIJcUGwETviliTmGU50rfJz2vDUbzxknY6rb6oQm5V16tjnUwE6kNXSevp7K1zWL6uIaJzvIH5qHINA== +"@rescripts/cli@^0.0.16": + version "0.0.16" + resolved "https://registry.yarnpkg.com/@rescripts/cli/-/cli-0.0.16.tgz#dcde29317874f3849b038973d43eff0aa15b0a78" + integrity sha512-F6BRPyOeOAzb0QWPxYat6Y2G3wWqMXKlQKuUfs/kEVo3QOlYWndtWrKUIG7FCdDvAFOSInceyxlWeZUn5sSKqw== dependencies: "@rescripts/utilities" "^0.0.8" ramda "^0.26.0" @@ -2178,9 +2220,9 @@ resolve "^1.14.2" "@rollup/plugin-replace@^2.3.1": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.0.tgz#ec80629a0a922ec53719f2dea2f7714fb9231031" - integrity sha512-QGuKCj9fTegKtLh1zsxNWP5uVmUctbFOG9S8wIir5dDO7qzGyISmwrQjlyEN0H7ptz60+CFeVFi5x4aDQ5+L6g== + version "2.4.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.1.tgz#c411b5ab72809fb1bfc8b487d8d02eef661460d3" + integrity sha512-XwC1oK5rrtRJ0tn1ioLHS6OV5JTluJF7QE1J/q1hN3bquwjnVxjtMyY9iCnoyH9DQbf92CxajB3o98wZbP3oAQ== dependencies: "@rollup/pluginutils" "^3.1.0" magic-string "^0.25.7" @@ -2194,20 +2236,20 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@sentry/browser@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.30.0.tgz#c28f49d551db3172080caef9f18791a7fd39e3b3" - integrity sha512-rOb58ZNVJWh1VuMuBG1mL9r54nZqKeaIlwSlvzJfc89vyfd7n6tQ1UXMN383QBz/MS5H5z44Hy5eE+7pCrYAfw== +"@sentry/browser@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.2.1.tgz#f9f277e6f8cad0c7efd1a01726095d63a47a1c16" + integrity sha512-OAikFZ9EimD3noxMp8tA6Cf6qJcQ2U8k5QSgTPwdx+09nZOGJzbRFteK7WWmrS93ZJdzN61lpSQbg5v+bmmfbQ== dependencies: - "@sentry/core" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" + "@sentry/core" "6.2.1" + "@sentry/types" "6.2.1" + "@sentry/utils" "6.2.1" tslib "^1.9.3" -"@sentry/cli@^1.62.0": - version "1.62.0" - resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.62.0.tgz#2e2d8cacb5ec494f86c188ef95b41745605be028" - integrity sha512-MCkx+zjetdIWhAVaFuEuoD4MOAFlb3/GLR5B5uFZ1AcegcsggasLo/3rb2gq6jYIic/pubtRjH4ltmOL/s3cag== +"@sentry/cli@^1.63.1": + version "1.63.1" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.63.1.tgz#306a0591190432574082d4ce4a72363201972461" + integrity sha512-qksIcrnObkGvtubs1FmW4EMXLo7R43Dobgzuxnyoebo1Y5KfRLziiw6H+ux8D4c1Nui4SuvDGDq0ObAfO5oE6Q== dependencies: https-proxy-agent "^5.0.0" mkdirp "^0.5.5" @@ -2215,69 +2257,69 @@ progress "^2.0.3" proxy-from-env "^1.1.0" -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== +"@sentry/core@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.2.1.tgz#8b177e9bf591e2e7ddcb04f0b1403de3f5aa8755" + integrity sha512-jPqQEtafxxDtLONhCbTHh/Uq8mZRhsfbwJTSVYfPVEe/ELfFZLQK7tP6rOh7zEWKbTkE0mE6XcaoH3ZRAhgrqg== dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" + "@sentry/hub" "6.2.1" + "@sentry/minimal" "6.2.1" + "@sentry/types" "6.2.1" + "@sentry/utils" "6.2.1" tslib "^1.9.3" -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== +"@sentry/hub@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.2.1.tgz#35bc6bf841a93f4354b3a17592c938b3dba20b73" + integrity sha512-pG7wCQeRpzeP6t0bT4T0X029R19dbDS3/qswF8BL6bg0AI3afjfjBAZm/fqn1Uwe/uBoMHVVdbxgJDZeQ5d4rQ== dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" + "@sentry/types" "6.2.1" + "@sentry/utils" "6.2.1" tslib "^1.9.3" -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== +"@sentry/minimal@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.2.1.tgz#8f01480e1b56bc7dd54adf925e5317f233e19384" + integrity sha512-wuSXB4Ayxv9rBEQ4pm7fnG4UU2ZPtPnnChoEfd4/mw1UthXSvmPFEn6O4pdo2G8fTkl8eqm6wT/Q7uIXMEmw+A== dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" + "@sentry/hub" "6.2.1" + "@sentry/types" "6.2.1" tslib "^1.9.3" -"@sentry/react@^5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-5.30.0.tgz#320e05f766b6a26faefa8d76d1101fd50c69f541" - integrity sha512-dvn4mqCgbeEuUXEGp5P9PaW5j4GWTFUSdx/yG8f9IxNZv5zM+7otjog9ukrubFZvlxVxD/PrIxK0MhadfFY/Dw== +"@sentry/react@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.2.1.tgz#26587f3f47e9699003b04ac558d8aa8a2b7416d7" + integrity sha512-emJnYVASM2hej2f8eSjqiDRMljwLsDJDSwa6kVc5HUOs9gnVrE4MR+vSywraACf5tKZbH1YI+NUXCmR++fIB0g== dependencies: - "@sentry/browser" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" + "@sentry/browser" "6.2.1" + "@sentry/minimal" "6.2.1" + "@sentry/types" "6.2.1" + "@sentry/utils" "6.2.1" hoist-non-react-statics "^3.3.2" tslib "^1.9.3" -"@sentry/tracing@^5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== +"@sentry/tracing@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.2.1.tgz#61c18c43c5390c348b35dafe73947ab379252d8f" + integrity sha512-bvStY1SnL08wkSeVK3j9K5rivQQJdKFCPR2VYRFOCaUoleZ6ChPUnBvxQ/E2LXc0hk/y/wo1q4r5B0dfCCY+bQ== dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" + "@sentry/hub" "6.2.1" + "@sentry/minimal" "6.2.1" + "@sentry/types" "6.2.1" + "@sentry/utils" "6.2.1" tslib "^1.9.3" -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== +"@sentry/types@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.2.1.tgz#28c946230b2023f72307b65606d32052ad9e5353" + integrity sha512-h0OV1QT+fv5ojfK5/+iEXClu33HirmvbjcQC2jf05IHj9yXIOWy6EB10S8nBjuLiiFqQiAQYj3FN9Ip4eN8NJA== -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== +"@sentry/utils@6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.2.1.tgz#bfcb12c20d44bf2aeb0073b1264703c11c179ebd" + integrity sha512-6kQgM/yBPdXu+3qbJnI6HBcWztN9QfiMkH++ZiKk4ERhg9d2LYWlze478uTU5Fyo/JQYcp+McpjtjpR9QIrr0g== dependencies: - "@sentry/types" "5.30.0" + "@sentry/types" "6.2.1" tslib "^1.9.3" "@sideway/address@^4.1.0": @@ -3029,10 +3071,10 @@ cbor "^5.1.0" source-map-support "^0.5.19" -"@truffle/codec@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.10.0.tgz#306425897f92b71cf2c9f665a45351e445b4c09b" - integrity sha512-jRqUPQkiiZmXtms34nI2WmEAA4pQnKUhdtJGCeqKUKu2igZ35ZMKoXkpg1stvahawn17XZxo+8DjbFlR0uHq7w== +"@truffle/codec@^0.10.0", "@truffle/codec@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.10.1.tgz#70df52ddf1c64781a23daaccda24e10bfb9dec9d" + integrity sha512-c1lC9Wcp+Z1DLvEYH3dkEtMKnUJx72CirO3kmi0OgFSA5QqTDCtfrVOhAugcb/iMLgqUK05/pexp2whb4oASKA== dependencies: big.js "^5.2.2" bn.js "^5.1.3" @@ -3057,13 +3099,13 @@ debug "^4.3.1" "@truffle/contract@^4.3.0": - version "4.3.8" - resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.3.8.tgz#806c63d683be81e5fd09d54346b52d7bb3940b5b" - integrity sha512-pQjRVUQ9muV1zT/bzhCvyhQXLHQVZobhe/Dwt/sIoj5Alea0ueNPQTeLN6DmMWusNDSlY8fNM7mgXJ+izvdpxw== + version "4.3.9" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.3.9.tgz#caf515df359e72f207edc6f1d4e7b8bca88566a7" + integrity sha512-yd6nejsKEReJrPjOdRHkypfsMr337yc43qxu5b4TF2JAf2Kz7ZAWasHhY3j3xRwra3AqNOm4p3njkq8T+mKytg== dependencies: "@truffle/blockchain-utils" "^0.0.26" "@truffle/contract-schema" "^3.3.4" - "@truffle/debug-utils" "^5.0.10" + "@truffle/debug-utils" "^5.0.11" "@truffle/error" "^0.0.12" "@truffle/interface-adapter" "^0.4.19" bignumber.js "^7.2.1" @@ -3076,12 +3118,12 @@ web3-eth-abi "1.2.9" web3-utils "1.2.9" -"@truffle/debug-utils@^5.0.10": - version "5.0.10" - resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-5.0.10.tgz#8dad322d404870e313b3b92cdaa609ad6212e08e" - integrity sha512-N2jqeHDmVh0xIe/BL2Or0/AAGAHxd2dM55NOAJYFPdekbigQEpmobTZtfUfpZU1oTQe+1yHpXXonkkjf+AKY7w== +"@truffle/debug-utils@^5.0.11": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-5.0.11.tgz#297ff83943212bf593a641180e3b28b230acadaa" + integrity sha512-KurW9r1DcK9c7/I0H21YWGBKu77gWm5HfBW6T+MjuRh5FGpxZ7GPka8oQkJCAZQuZKaQc9r9BoCQYQx1NX8pIg== dependencies: - "@truffle/codec" "^0.10.0" + "@truffle/codec" "^0.10.1" "@trufflesuite/chromafi" "^2.2.2" bn.js "^5.1.3" chalk "^2.4.2" @@ -3255,10 +3297,10 @@ xhr "^2.2.0" xtend "^4.0.1" -"@typechain/web3-v1@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@typechain/web3-v1/-/web3-v1-2.0.0.tgz#71ce7265181c8cbb03b1f7212256a23b9b809472" - integrity sha512-gpl9Tk6Ha38GScuMf7O2BvX7nFvWakSlm4w1LxCZ8BEJgbjarrsBX2YdgrB2jHm2pBZCaBJUZGR5b9qywSJNdw== +"@typechain/web3-v1@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@typechain/web3-v1/-/web3-v1-2.2.0.tgz#fb4edae1bf4ed797be4102f48d46697be0f88998" + integrity sha512-vSJ+qhTXLsgvyx/cRYgHQZEifU7xNJLkWHYw8CSu3TTqankN7mKUwl2pwGNbWkRDY7U9hE0bKs9b0hWuLjB0DA== "@types/anymatch@*": version "1.3.1" @@ -3333,10 +3375,10 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/fs-extra@^9.0.1": - version "9.0.7" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.7.tgz#a9ef2ffdab043def080c5bec94c03402f793577f" - integrity sha512-YGq2A6Yc3bldrLUlm17VNWOnUbnEzJ9CMgOeLFtQF3HOCN5lQBO8VyjG00a5acA5NNSM30kHVGp1trZgnVgi1Q== +"@types/fs-extra@^9.0.7": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-9.0.8.tgz#32c3c07ddf8caa5020f84b5f65a48470519f78ba" + integrity sha512-bnlTVTwq03Na7DpWxFJ1dvnORob+Otb8xHyUqUWhqvz/Ksg8+JXPlR52oeMSZ37YEOa5PyccbgUNutiQdi13TA== dependencies: "@types/node" "*" @@ -3451,10 +3493,10 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^14.14.10": - version "14.14.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055" - integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g== +"@types/node@*", "@types/node@^14.14.30": + version "14.14.32" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.32.tgz#90c5c4a8d72bbbfe53033f122341343249183448" + integrity sha512-/Ctrftx/zp4m8JOujM5ZhwzlWLx22nbQJiVqz8/zE15gOeEW+uly3FSX4fGFpcfEvFzXcMCJwq9lGVWgyARXhg== "@types/node@^10.12.18": version "10.17.54" @@ -3488,10 +3530,18 @@ dependencies: "@types/node" "*" +"@types/plist@^3.0.1": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" + integrity sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw== + dependencies: + "@types/node" "*" + xmlbuilder ">=11.0.1" + "@types/prettier@^2.0.0", "@types/prettier@^2.1.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.1.tgz#374e31645d58cb18a07b3ecd8e9dede4deb2cccd" - integrity sha512-DxZZbyMAM9GWEzXL+BMZROWz9oo6A9EilwwOMET2UVu2uZTqMWS5S69KVtuVKaRjCUpcrOXRalet86/OpG4kqw== + version "2.2.2" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.2.tgz#e2280c89ddcbeef340099d6968d8c86ba155fdf6" + integrity sha512-i99hy7Ki19EqVOl77WplDrvgNugHnsSjECVR/wUrzw2TJXz1zlUfT2ngGckR6xN7yFYaijsMAqPkOLx9HgUqHg== "@types/prop-types@*": version "15.7.3" @@ -3573,12 +3623,13 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^16", "@types/react@^16.9.55": - version "16.14.4" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.4.tgz#365f6a1e117d1eec960ba792c7e1e91ecad38e6f" - integrity sha512-ETj7GbkPGjca/A4trkVeGvoIakmLV6ZtX3J8dcmOpzKzWVybbrOxanwaIPG71GZwImoMDY6Fq4wIe34lEqZ0FQ== +"@types/react@^16", "@types/react@^16.14.5": + version "16.14.5" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.5.tgz#2c39b5cadefaf4829818f9219e5e093325979f4d" + integrity sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw== dependencies: "@types/prop-types" "*" + "@types/scheduler" "*" csstype "^3.0.2" "@types/redux-actions@^2.6.1": @@ -3593,6 +3644,11 @@ dependencies: "@types/node" "*" +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + "@types/secp256k1@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.1.tgz#fb3aa61a1848ad97d7425ff9dcba784549fca5a4" @@ -3600,7 +3656,7 @@ dependencies: "@types/node" "*" -"@types/semver@^7.3.1": +"@types/semver@^7.3.4": version "7.3.4" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== @@ -3643,6 +3699,11 @@ dependencies: source-map "^0.6.1" +"@types/verror@^1.10.3": + version "1.10.4" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.4.tgz#805c0612b3a0c124cf99f517364142946b74ba3b" + integrity sha512-OjJdqx6QlbyZw9LShPwRW+Kmiegeg3eWNI41MQQKaG3vjdU2L9SRElntM51HmHBY1cu7izxQJ1lMYioQh3XMBg== + "@types/webpack-env@^1.15.0": version "1.16.0" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4" @@ -3674,20 +3735,20 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== -"@types/yargs@^15.0.0", "@types/yargs@^15.0.5": +"@types/yargs@^15.0.0", "@types/yargs@^15.0.13": version "15.0.13" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^4.14.0", "@typescript-eslint/eslint-plugin@^4.5.0": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.15.1.tgz#835f64aa0a403e5e9e64c10ceaf8d05c3f015180" - integrity sha512-yW2epMYZSpNJXZy22Biu+fLdTG8Mn6b22kR3TqblVk50HGNV8Zya15WAXuQCr8tKw4Qf1BL4QtI6kv6PCkLoJw== +"@typescript-eslint/eslint-plugin@^4.17.0", "@typescript-eslint/eslint-plugin@^4.5.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.17.0.tgz#6f856eca4e6a52ce9cf127dfd349096ad936aa2d" + integrity sha512-/fKFDcoHg8oNan39IKFOb5WmV7oWhQe1K6CDaAVfJaNWEhmfqlA24g+u1lqU5bMH7zuNasfMId4LaYWC5ijRLw== dependencies: - "@typescript-eslint/experimental-utils" "4.15.1" - "@typescript-eslint/scope-manager" "4.15.1" + "@typescript-eslint/experimental-utils" "4.17.0" + "@typescript-eslint/scope-manager" "4.17.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" lodash "^4.17.15" @@ -3695,15 +3756,27 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.15.1", "@typescript-eslint/experimental-utils@^4.0.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.15.1.tgz#d744d1ac40570a84b447f7aa1b526368afd17eec" - integrity sha512-9LQRmOzBRI1iOdJorr4jEnQhadxK4c9R2aEAsm7WE/7dq8wkKD1suaV0S/JucTL8QlYUPU1y2yjqg+aGC0IQBQ== +"@typescript-eslint/experimental-utils@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.16.1.tgz#da7a396dc7d0e01922acf102b76efff17320b328" + integrity sha512-0Hm3LSlMYFK17jO4iY3un1Ve9x1zLNn4EM50Lia+0EV99NdbK+cn0er7HC7IvBA23mBg3P+8dUkMXy4leL33UQ== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.15.1" - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/typescript-estree" "4.15.1" + "@typescript-eslint/scope-manager" "4.16.1" + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/typescript-estree" "4.16.1" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@4.17.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.17.0.tgz#762c44aaa1a6a3c05b6d63a8648fb89b89f84c80" + integrity sha512-ZR2NIUbnIBj+LGqCFGQ9yk2EBQrpVVFOh9/Kd0Lm6gLpSAcCuLLe5lUCibKGCqyH9HPwYC0GIJce2O1i8VYmWA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.17.0" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/typescript-estree" "4.17.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -3718,33 +3791,46 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^4.14.0", "@typescript-eslint/parser@^4.5.0": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.15.1.tgz#4c91a0602733db63507e1dbf13187d6c71a153c4" - integrity sha512-V8eXYxNJ9QmXi5ETDguB7O9diAXlIyS+e3xzLoP/oVE4WCAjssxLIa0mqCLsCGXulYJUfT+GV70Jv1vHsdKwtA== +"@typescript-eslint/parser@^4.17.0", "@typescript-eslint/parser@^4.5.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.17.0.tgz#141b647ffc72ebebcbf9b0fe6087f65b706d3215" + integrity sha512-KYdksiZQ0N1t+6qpnl6JeK9ycCFprS9xBAiIrw4gSphqONt8wydBw4BXJi3C11ywZmyHulvMaLjWsxDjUSDwAw== dependencies: - "@typescript-eslint/scope-manager" "4.15.1" - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/typescript-estree" "4.15.1" + "@typescript-eslint/scope-manager" "4.17.0" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/typescript-estree" "4.17.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.15.1.tgz#f6511eb38def2a8a6be600c530c243bbb56ac135" - integrity sha512-ibQrTFcAm7yG4C1iwpIYK7vDnFg+fKaZVfvyOm3sNsGAerKfwPVFtYft5EbjzByDJ4dj1WD8/34REJfw/9wdVA== +"@typescript-eslint/scope-manager@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.16.1.tgz#244e2006bc60cfe46987e9987f4ff49c9e3f00d5" + integrity sha512-6IlZv9JaurqV0jkEg923cV49aAn8V6+1H1DRfhRcvZUrptQ+UtSKHb5kwTayzOYTJJ/RsYZdcvhOEKiBLyc0Cw== dependencies: - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/visitor-keys" "4.15.1" + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/visitor-keys" "4.16.1" + +"@typescript-eslint/scope-manager@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.17.0.tgz#f4edf94eff3b52a863180f7f89581bf963e3d37d" + integrity sha512-OJ+CeTliuW+UZ9qgULrnGpPQ1bhrZNFpfT/Bc0pzNeyZwMik7/ykJ0JHnQ7krHanFN9wcnPK89pwn84cRUmYjw== + dependencies: + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/visitor-keys" "4.17.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.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.15.1.tgz#da702f544ef1afae4bc98da699eaecd49cf31c8c" - integrity sha512-iGsaUyWFyLz0mHfXhX4zO6P7O3sExQpBJ2dgXB0G5g/8PRVfBBsmQIc3r83ranEQTALLR3Vko/fnCIVqmH+mPw== +"@typescript-eslint/types@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.16.1.tgz#5ba2d3e38b1a67420d2487519e193163054d9c15" + integrity sha512-nnKqBwMgRlhzmJQF8tnFDZWfunXmJyuXj55xc8Kbfup4PbkzdoDXZvzN8//EiKR27J6vUSU8j4t37yUuYPiLqA== + +"@typescript-eslint/types@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.17.0.tgz#f57d8fc7f31b348db946498a43050083d25f40ad" + integrity sha512-RN5z8qYpJ+kXwnLlyzZkiJwfW2AY458Bf8WqllkondQIcN2ZxQowAToGSd9BlAUZDB5Ea8I6mqL2quGYCLT+2g== "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" @@ -3760,13 +3846,26 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.15.1.tgz#fa9a9ff88b4a04d901ddbe5b248bc0a00cd610be" - integrity sha512-z8MN3CicTEumrWAEB2e2CcoZa3KP9+SMYLIA2aM49XW3cWIaiVSOAGq30ffR5XHxRirqE90fgLw3e6WmNx5uNw== +"@typescript-eslint/typescript-estree@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.16.1.tgz#c2fc46b05a48fbf8bbe8b66a63f0a9ba04b356f1" + integrity sha512-m8I/DKHa8YbeHt31T+UGd/l8Kwr0XCTCZL3H4HMvvLCT7HU9V7yYdinTOv1gf/zfqNeDcCgaFH2BMsS8x6NvJg== dependencies: - "@typescript-eslint/types" "4.15.1" - "@typescript-eslint/visitor-keys" "4.15.1" + "@typescript-eslint/types" "4.16.1" + "@typescript-eslint/visitor-keys" "4.16.1" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/typescript-estree@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.17.0.tgz#b835d152804f0972b80dbda92477f9070a72ded1" + integrity sha512-lRhSFIZKUEPPWpWfwuZBH9trYIEJSI0vYsrxbvVvNyIUDoKWaklOAelsSkeh3E2VBSZiNe9BZ4E5tYBZbUczVQ== + dependencies: + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/visitor-keys" "4.17.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -3780,20 +3879,28 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.15.1": - version "4.15.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.15.1.tgz#c76abbf2a3be8a70ed760f0e5756bf62de5865dd" - integrity sha512-tYzaTP9plooRJY8eNlpAewTOqtWW/4ff/5wBjNVaJ0S0wC4Gpq/zDVRTJa5bq2v1pCNQ08xxMCndcvR+h7lMww== +"@typescript-eslint/visitor-keys@4.16.1": + version "4.16.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.16.1.tgz#d7571fb580749fae621520deeb134370bbfc7293" + integrity sha512-s/aIP1XcMkEqCNcPQtl60ogUYjSM8FU2mq1O7y5cFf3Xcob1z1iXWNB6cC43Op+NGRTFgGolri6s8z/efA9i1w== dependencies: - "@typescript-eslint/types" "4.15.1" + "@typescript-eslint/types" "4.16.1" + eslint-visitor-keys "^2.0.0" + +"@typescript-eslint/visitor-keys@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.17.0.tgz#9c304cfd20287c14a31d573195a709111849b14d" + integrity sha512-WfuMN8mm5SSqXuAr9NM+fItJ0SVVphobWYkWOwQ1odsfC014Vdxk/92t4JwS1Q6fCA/ABfCKpa3AVtpUKTNKGQ== + dependencies: + "@typescript-eslint/types" "4.17.0" eslint-visitor-keys "^2.0.0" "@unstoppabledomains/resolution@^1.17.0": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@unstoppabledomains/resolution/-/resolution-1.18.0.tgz#997b5c08072d29ee1287754d14c006bb76c1dc55" - integrity sha512-PHh3UQ96ivAWaY7ozYe1vpz9uJt51fbYpTqRUxdHB5UfK2lMRrjxgrxFJby6Ia0eeU8jXPQePCR1l9tnGZ+SWg== + version "1.20.0" + resolved "https://registry.yarnpkg.com/@unstoppabledomains/resolution/-/resolution-1.20.0.tgz#b1a8707b18359e98e4b352a7905e70a182f6eaa0" + integrity sha512-UZva7Pi6PrCX+6KsTZKy0hM4fKBny6a2hJ7jgu6zo0+zmtlYe/SjmQN3Asn5RBUm931eB3aI4UN7Kysw+rJ5RQ== dependencies: - "@ensdomains/address-encoder" "0.1.8" + "@ensdomains/address-encoder" "0.2.6" "@ethersproject/abi" "^5.0.1" bip44-constants "^8.0.5" bn.js "^4.4.0" @@ -4347,37 +4454,38 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -app-builder-bin@3.5.10: - version "3.5.10" - resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.10.tgz#4a7f9999fccc0c435b6284ae1366bc76a17c4a7d" - integrity sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ== +app-builder-bin@3.5.12: + version "3.5.12" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.12.tgz#bbe174972cc1f481f73d6d92ad47a8b4c7eb4530" + integrity sha512-lQARM2AielmFoBeIo6LZigAe+58Wwe07ZWkt+wVeDxzyieNmeWjlvz/V5dKzinydwdHd+CNswN86sww46yijjA== -app-builder-lib@22.9.1: - version "22.9.1" - resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.9.1.tgz#ccb8f1a02b628514a5dfab9401fa2a976689415c" - integrity sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A== +app-builder-lib@22.10.5: + version "22.10.5" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.10.5.tgz#24a88581c891e5b187a0d569aa44e7c4a0dc8de2" + integrity sha512-/W8nlGamJCtKlQtsMWwU9vb+cX4pTNY+rJWCuc7oXUykVSMS50W7LhQusIjCelNfymUQ1XCu6cXEY/ylqhX12A== dependencies: "7zip-bin" "~5.0.3" "@develar/schema-utils" "~2.6.5" + "@electron/universal" "1.0.4" async-exit-hook "^2.0.1" bluebird-lst "^1.0.9" - builder-util "22.9.1" - builder-util-runtime "8.7.2" + builder-util "22.10.5" + builder-util-runtime "8.7.3" chromium-pickle-js "^0.2.0" - debug "^4.3.0" - ejs "^3.1.5" - electron-publish "22.9.1" - fs-extra "^9.0.1" - hosted-git-info "^3.0.5" + debug "^4.3.2" + ejs "^3.1.6" + electron-publish "22.10.5" + fs-extra "^9.1.0" + hosted-git-info "^3.0.8" is-ci "^2.0.0" - isbinaryfile "^4.0.6" - js-yaml "^3.14.0" + istextorbinary "^5.12.0" + js-yaml "^4.0.0" lazy-val "^1.0.4" minimatch "^3.0.4" - normalize-package-data "^2.5.0" + normalize-package-data "^3.0.0" read-config-file "6.0.0" sanitize-filename "^1.6.3" - semver "^7.3.2" + semver "^7.3.4" temp-file "^3.3.7" app-module-path@^2.2.0: @@ -4410,10 +4518,10 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -argv@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" - integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== aria-query@^4.2.2: version "4.2.2" @@ -4570,6 +4678,18 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= +asar@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/asar/-/asar-3.0.3.tgz#1fef03c2d6d2de0cbad138788e4f7ae03b129c7b" + integrity sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw== + dependencies: + chromium-pickle-js "^0.2.0" + commander "^5.0.0" + glob "^7.1.6" + minimatch "^3.0.4" + optionalDependencies: + "@types/glob" "^7.1.1" + asn1.js@^5.2.0: version "5.4.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" @@ -4592,11 +4712,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -4743,17 +4858,12 @@ await-semaphore@^0.1.3: resolved "https://registry.yarnpkg.com/await-semaphore/-/await-semaphore-0.1.3.tgz#2b88018cc8c28e06167ae1cdff02504f1f9688d3" integrity sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q== -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= - aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= -aws4@^1.2.1, aws4@^1.8.0: +aws4@^1.8.0: version "1.11.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== @@ -5176,6 +5286,30 @@ babel-plugin-named-asset-import@^0.3.1, babel-plugin-named-asset-import@^0.3.7: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd" integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw== +babel-plugin-polyfill-corejs2@^0.1.4: + version "0.1.10" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz#a2c5c245f56c0cac3dbddbf0726a46b24f0f81d1" + integrity sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA== + dependencies: + "@babel/compat-data" "^7.13.0" + "@babel/helper-define-polyfill-provider" "^0.1.5" + semver "^6.1.1" + +babel-plugin-polyfill-corejs3@^0.1.3: + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" + integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.1.5" + core-js-compat "^3.8.1" + +babel-plugin-polyfill-regenerator@^0.1.2: + version "0.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz#0fe06a026fe0faa628ccc8ba3302da0a6ce02f3f" + integrity sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.1.5" + babel-plugin-react-docgen@^4.0.0, babel-plugin-react-docgen@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" @@ -5716,7 +5850,7 @@ base-x@^3.0.2, base-x@^3.0.8: dependencies: safe-buffer "^5.0.1" -base64-js@^1.0.2, base64-js@^1.3.1: +base64-js@^1.0.2, base64-js@^1.2.3, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -5796,6 +5930,11 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== +binaryextensions@^4.15.0: + version "4.15.0" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-4.15.0.tgz#c63a502e0078ff1b0e9b00a9f74d3c2b0f8bd32e" + integrity sha512-MkUl3szxXolQ2scI1PM14WOT951KnaTNJ0eMKg7WzOI4kvSxyNo/Cygx4LOBNhwyINhAuSQpJW1rYD9aBSxGaw== + bind-decorator@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/bind-decorator/-/bind-decorator-1.0.11.tgz#e41bc06a1f65dd9cec476c91c5daf3978488252f" @@ -5808,21 +5947,10 @@ bindings@^1.2.1, bindings@^1.3.0, bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bip39@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.6.0.tgz#9e3a720b42ec8b3fbe4038f1e445317b6a99321c" - integrity sha512-RrnQRG2EgEoqO24ea+Q/fftuPUZLmrEM3qNhhGsA3PbaXaCW791LTzPuVyx/VprXQcTbPJ3K3UeTna8ZnVl2sg== - dependencies: - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" - safe-buffer "^5.0.1" - unorm "^1.3.3" - bip44-constants@^8.0.5: - version "8.0.100" - resolved "https://registry.yarnpkg.com/bip44-constants/-/bip44-constants-8.0.100.tgz#c81ea768a37e6b9a55750338daa2333142ef7dd8" - integrity sha512-VXIs2gFj0YOJCINrNWy1iMr+Uy1GhCda4D29mdQsd1myxdsi56Si2cU4dXpTtYIrGtKkaU8MOsaOrOlt+a0bVg== + version "8.0.103" + resolved "https://registry.yarnpkg.com/bip44-constants/-/bip44-constants-8.0.103.tgz#fc8c6718a2d8f38bf7fdb689732250e32333ba8b" + integrity sha512-wuGsY9IKUS9GC5Sf/Acb5jLJZI3Z8qsMoQHWldnQyoVUlij4y8e5srh28Iqul1HwK+elPsAYGNYKtYhovjvNxA== bip66@^1.1.5: version "1.1.5" @@ -5878,19 +6006,19 @@ bn.js@5.1.2: integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA== bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.1, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.4.0, bn.js@^4.8.0: - version "4.11.9" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" - integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" - integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -bnc-onboard@1.19.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/bnc-onboard/-/bnc-onboard-1.19.2.tgz#bc293dfebfeadc834c4219b3eae7ff827f9ff9f9" - integrity sha512-+vsc70ViYz2mJbhTXhIuVMHIqlmvGVKZVWTkI8+5xnUVoFh65GubdxuN55l/J+kgEodUHejPecswgYWUTElz8A== +bnc-onboard@~1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/bnc-onboard/-/bnc-onboard-1.20.0.tgz#436aa89a2839d6d0702a7689a9ca60f4a957d3cf" + integrity sha512-bt1pfEBFLnkuxzTQsvous/a28WufVJNVyi3MQwaSlC8IkIsZdih2dwiuhUd1HzGNzUFVk1xe9huxwb/7wEDl0w== dependencies: "@ledgerhq/hw-app-eth" "^5.21.0" "@ledgerhq/hw-transport-u2f" "^5.21.0" @@ -5902,6 +6030,7 @@ bnc-onboard@1.19.2: bnc-sdk "^3.1.0" bowser "^2.10.0" eth-lattice-keyring "^0.2.7" + eth-provider "^0.6.1" ethereumjs-tx "^2.1.2" ethereumjs-util "^7.0.3" fortmatic "^2.2.1" @@ -5958,19 +6087,12 @@ boolean@^3.0.1: resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.2.tgz#df1baa18b6a2b0e70840475e1d93ec8fe75b2570" integrity sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g== -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= - dependencies: - hoek "2.x.x" - bowser@^2.10.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== -boxen@^4.1.0, boxen@^4.2.0: +boxen@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== @@ -5984,6 +6106,20 @@ boxen@^4.1.0, boxen@^4.2.0: type-fest "^0.8.1" widest-line "^3.1.0" +boxen@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.0.0.tgz#64fe9b16066af815f51057adcc800c3730120854" + integrity sha512-5bvsqw+hhgUi3oYGK0Vf4WpIkyemp60WBInn7+WNfoISzAqk/HX4L7WNROq38E6UR/y3YADpv6pEm4BfkeEAdA== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.0" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -6145,7 +6281,7 @@ bs58@^4.0.0, bs58@^4.0.1: dependencies: base-x "^3.0.2" -bs58check@^2.1.1, bs58check@^2.1.2: +bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== @@ -6184,6 +6320,11 @@ buffer-crc32@~0.2.3: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= +buffer-equal@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= + buffer-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" @@ -6241,30 +6382,30 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.2.0" -builder-util-runtime@8.7.2: - version "8.7.2" - resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz#d93afc71428a12789b437e13850e1fa7da956d72" - integrity sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA== +builder-util-runtime@8.7.3: + version "8.7.3" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.3.tgz#0aaafa52d25295c939496f62231ca9ff06c30e40" + integrity sha512-1Q2ReBqFblimF5g/TLg2+0M5Xzv0Ih5LxJ/BMWXvEy/e6pQKeeEpbkPMGsN6OiQgkygaZo5VXCXIjOkOQG5EoQ== dependencies: - debug "^4.1.1" + debug "^4.3.2" sax "^1.2.4" -builder-util@22.9.1: - version "22.9.1" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.9.1.tgz#b7087a5cde477f90d718ca5d7fafb6ae261b16af" - integrity sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw== +builder-util@22.10.5: + version "22.10.5" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.10.5.tgz#8d0b04a3be6acc74938679aa90dcb3181b1ae86b" + integrity sha512-/MkLhmyo1gU3xMwXJxccQaRj/9tm5eTd6ZyebTf8SYouY4r3hRser+LxhOm/f8Z9W6oJvfPe0jc9TFsxYfMcsg== dependencies: "7zip-bin" "~5.0.3" "@types/debug" "^4.1.5" - "@types/fs-extra" "^9.0.1" - app-builder-bin "3.5.10" + "@types/fs-extra" "^9.0.7" + app-builder-bin "3.5.12" bluebird-lst "^1.0.9" - builder-util-runtime "8.7.2" + builder-util-runtime "8.7.3" chalk "^4.1.0" - debug "^4.3.0" - fs-extra "^9.0.1" + debug "^4.3.2" + fs-extra "^9.1.0" is-ci "^2.0.0" - js-yaml "^3.14.0" + js-yaml "^4.0.0" source-map-support "^0.5.19" stat-mode "^1.0.0" temp-file "^3.3.7" @@ -6483,9 +6624,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.30001181: - version "1.0.30001191" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001191.tgz#bacb432b6701f690c8c5f7c680166b9a9f0843d9" - integrity sha512-xJJqzyd+7GCJXkcoBiQ1GuxEiOBCLQ0aVW9HMekifZsAVGdj5eJ4mFB9fEhSHipq9IOk/QXFJUiIr9lZT+EsGw== + version "1.0.30001196" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001196.tgz#00518a2044b1abf3e0df31fadbe5ed90b63f4e64" + integrity sha512-CPvObjD3ovWrNBaXlAIGWmg2gQQuJ5YhuciUOjPRox6hIQttu8O+b51dx6VIpIY9ESd2d0Vac1RKpICdG4rGUg== capture-exit@^2.0.0: version "2.0.0" @@ -6499,11 +6640,6 @@ case-sensitive-paths-webpack-plugin@2.3.0, case-sensitive-paths-webpack-plugin@^ resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" - integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= - caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -6526,7 +6662,7 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= @@ -6795,7 +6931,7 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-boxes@^2.2.0: +cli-boxes@^2.2.0, cli-boxes@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== @@ -6824,6 +6960,14 @@ cli-table3@0.5.1: optionalDependencies: colors "^1.1.2" +cli-truncate@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" + integrity sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA== + dependencies: + slice-ansi "^1.0.0" + string-width "^2.0.0" + cli-truncate@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" @@ -6930,15 +7074,6 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codecov@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/codecov/-/codecov-2.3.1.tgz#7dda945cd58a1f6081025b5b03ee01a2ef20f86e" - integrity sha1-fdqUXNWKH2CBAltbA+4Bou8g+G4= - dependencies: - argv "0.0.2" - request "2.77.0" - urlgrey "0.4.4" - collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -7002,17 +7137,22 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.4" -colorette@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" - integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= colors@^1.1.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -7038,12 +7178,19 @@ command-line-args@^4.0.7: find-replace "^1.0.3" typical "^2.6.1" +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + commander@3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== -commander@^2.19.0, commander@^2.20.0, commander@^2.9.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== @@ -7053,6 +7200,11 @@ commander@^4.0.1, commander@^4.1.1: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== + commander@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -7277,10 +7429,10 @@ copy-to-clipboard@^3.0.8: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.6.2, core-js-compat@^3.8.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.0.tgz#29da39385f16b71e1915565aa0385c4e0963ad56" - integrity sha512-YK6fwFjCOKWwGnjFUR3c544YsnA/7DoLL0ysncuOJ4pwbriAtOpvM2bygdlcXbvQCQZ7bBU9CL4t7tGl7ETRpQ== +core-js-compat@^3.6.2, core-js-compat@^3.8.1, core-js-compat@^3.9.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.1.tgz#4e572acfe90aff69d76d8c37759d21a5c59bb455" + integrity sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA== dependencies: browserslist "^4.16.3" semver "7.0.0" @@ -7296,9 +7448,9 @@ core-js@^2.4.0, core-js@^2.5.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5: - version "3.9.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.0.tgz#790b1bb11553a2272b36e2625c7179db345492f8" - integrity sha512-PyFBJaLq93FlyYdsndE5VaueA9K5cNB7CGzeCj191YYLhkQM0gdZR2SKihM70oF0wdqKSKClv/tEBOpoRmdOVQ== + version "3.9.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae" + integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -7372,6 +7524,13 @@ crc-32@^1.2.0: exit-on-epipe "~1.0.1" printj "~1.1.0" +crc@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" + integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== + dependencies: + buffer "^5.1.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -7446,13 +7605,6 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= - dependencies: - boom "2.x.x" - crypto-addr-codec@^0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae" @@ -7875,10 +8027,10 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.0, debug@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" @@ -7896,7 +8048,7 @@ debug@=3.1.0: dependencies: ms "2.0.0" -debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5: +debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -8154,6 +8306,16 @@ dijkstrajs@^1.0.1: resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.1.tgz#d3cd81221e3ea40742cfcde556d4e99e98ddc71b" integrity sha1-082BIh4+pAdCz83lVtTpnpjdxxs= +dir-compare@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/dir-compare/-/dir-compare-2.4.0.tgz#785c41dc5f645b34343a4eafc50b79bac7f11631" + integrity sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA== + dependencies: + buffer-equal "1.0.0" + colors "1.0.3" + commander "2.9.0" + minimatch "3.0.4" + dir-glob@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" @@ -8169,17 +8331,34 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dmg-builder@22.9.1: - version "22.9.1" - resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.9.1.tgz#64647224f37ee47fc9bd01947c21cc010a30511f" - integrity sha512-jc+DAirqmQrNT6KbDHdfEp8D1kD0DBTnsLhwUR3MX+hMBun5bT134LQzpdK0GKvd22GqF8L1Cz/NOgaVjscAXQ== +dmg-builder@22.10.5: + version "22.10.5" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.10.5.tgz#65a33c106ead5a350c7de8997c546559bd6e0e7c" + integrity sha512-58FEpfH8PEFqjbUNka4bYr52snRT8+LSXrP4gy6EZWOVICbOlmTOYj988pfoLam5C5iXb3odmyUQqwWOxlsEUw== dependencies: - app-builder-lib "22.9.1" - builder-util "22.9.1" - fs-extra "^9.0.1" + app-builder-lib "22.10.5" + builder-util "22.10.5" + fs-extra "^9.1.0" iconv-lite "^0.6.2" - js-yaml "^3.14.0" + js-yaml "^4.0.0" sanitize-filename "^1.6.3" + optionalDependencies: + dmg-license "^1.0.8" + +dmg-license@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/dmg-license/-/dmg-license-1.0.8.tgz#d52e234815f1a07a59706e5f2a2fea71991cf784" + integrity sha512-47GOb6b4yVzpovXC34heXElpH++ICg9GuWBeOTaokUNLAoAdWpE4VehudYEEtu96j2jXsgQWYf78nW7r+0Y3eg== + dependencies: + "@types/plist" "^3.0.1" + "@types/verror" "^1.10.3" + ajv "^6.10.0" + cli-truncate "^1.1.0" + crc "^3.8.0" + iconv-corefoundation "^1.1.5" + plist "^3.0.1" + smart-buffer "^4.0.2" + verror "^1.10.0" dns-equal@^1.0.0: version "1.0.0" @@ -8436,6 +8615,14 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +editions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/editions/-/editions-6.1.0.tgz#ba6c6cf9f4bb571d9e53ea34e771a602e5a66549" + integrity sha512-h6nWEyIocfgho9J3sTSuhU/WoFOu1hTX75rPBebNrbF38Y9QFDjCDizYXdikHTySW7Y3mSxli8bpDz9RAtc7rA== + dependencies: + errlop "^4.0.0" + version-range "^1.0.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -8446,32 +8633,32 @@ ejs@^2.6.1, ejs@^2.7.4: resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.7.4.tgz#48661287573dcc53e366c7a1ae52c3a120eec9ba" integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA== -ejs@^3.1.5: +ejs@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== dependencies: jake "^10.6.1" -electron-builder@22.9.1: - version "22.9.1" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.9.1.tgz#a2962db6f2757bc01d02489f38fafe0809f68f60" - integrity sha512-GXPt8l5Mxwm1QKYopUM6/Tdh9W3695G6Ax+IFyj5pQ51G4SD5L1uq4/RkPSsOgs3rP7jNSV6g6OfDzdtVufPdA== +electron-builder@22.10.5: + version "22.10.5" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.10.5.tgz#03b156b93e6012609027c3aaa69201a3ad21e454" + integrity sha512-0q/289UUJUhRou6lZKDz/wzK6WprIQ6VXMTmaI+w9qXvSNugPC9UA5s2zXInOkjZOvO/xKnjeyiavrVSHYF3tA== dependencies: - "@types/yargs" "^15.0.5" - app-builder-lib "22.9.1" + "@types/yargs" "^15.0.13" + app-builder-lib "22.10.5" bluebird-lst "^1.0.9" - builder-util "22.9.1" - builder-util-runtime "8.7.2" + builder-util "22.10.5" + builder-util-runtime "8.7.3" chalk "^4.1.0" - dmg-builder "22.9.1" - fs-extra "^9.0.1" + dmg-builder "22.10.5" + fs-extra "^9.1.0" is-ci "^2.0.0" lazy-val "^1.0.4" read-config-file "6.0.0" sanitize-filename "^1.6.3" - update-notifier "^4.1.1" - yargs "^16.0.3" + update-notifier "^5.1.0" + yargs "^16.2.0" electron-is-dev@^1.2.0: version "1.2.0" @@ -8491,19 +8678,19 @@ electron-notarize@1.0.0: debug "^4.1.1" fs-extra "^9.0.1" -electron-publish@22.9.1: - version "22.9.1" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.9.1.tgz#7cc76ac4cc53efd29ee31c1e5facb9724329068e" - integrity sha512-ducLjRJLEeU87FaTCWaUyDjCoLXHkawkltP2zqS/n2PyGke54ZIql0tBuUheht4EpR8AhFbVJ11spSn1gy8r6w== +electron-publish@22.10.5: + version "22.10.5" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.10.5.tgz#9cbe46266b6c79d8c6e99840755682e2262d3543" + integrity sha512-dHyuazv3P3j1Xyv7pdwTwAvxWab2pCb0G0Oa6qWQoCc4b1/mRGY00M7AvYW1cPuUijj9zYAf1HmXfM6MifaMlA== dependencies: - "@types/fs-extra" "^9.0.1" + "@types/fs-extra" "^9.0.7" bluebird-lst "^1.0.9" - builder-util "22.9.1" - builder-util-runtime "8.7.2" + builder-util "22.10.5" + builder-util-runtime "8.7.3" chalk "^4.1.0" - fs-extra "^9.0.1" + fs-extra "^9.1.0" lazy-val "^1.0.4" - mime "^2.4.6" + mime "^2.5.0" electron-settings@^4.0.2: version "4.0.2" @@ -8518,27 +8705,27 @@ 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.649: - version "1.3.671" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.671.tgz#8feaed6eae42d279fa4611f58c42a5a1eb81b2a0" - integrity sha512-RTD97QkdrJKaKwRv9h/wGAaoR2lGxNXEcBXS31vjitgTPwTWAbLdS7cEsBK68eEQy7p6YyT8D5BxBEYHu2SuwQ== + version "1.3.681" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.681.tgz#facd915ae46a020e8be566a2ecdc0b9444439be9" + integrity sha512-W6uYvSUTHuyX2DZklIESAqx57jfmGjUkd7Z3RWqLdj9Mmt39ylhBuvFXlskQnvBHj0MYXIeQI+mjiwVddZLSvA== -electron-updater@4.3.5: - version "4.3.5" - resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15" - integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ== +electron-updater@4.3.8: + version "4.3.8" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.8.tgz#94f1731682a756385726183e2b04b959cb319456" + integrity sha512-/tB82Ogb2LqaXrUzAD8waJC+TZV52Pr0Znfj7w+i4D+jA2GgrKFI3Pxjp+36y9FcBMQz7kYsMHcB6c5zBJao+A== dependencies: - "@types/semver" "^7.3.1" - builder-util-runtime "8.7.2" - fs-extra "^9.0.1" - js-yaml "^3.14.0" + "@types/semver" "^7.3.4" + builder-util-runtime "8.7.3" + fs-extra "^9.1.0" + js-yaml "^4.0.0" lazy-val "^1.0.4" lodash.isequal "^4.5.0" - semver "^7.3.2" + semver "^7.3.4" electron@^9.4.0: - version "9.4.3" - resolved "https://registry.yarnpkg.com/electron/-/electron-9.4.3.tgz#9fb6c0a900bdf80cc473def9fbcc8c213a9e7e74" - integrity sha512-FQjVH0jdFj9EIxpHk/CK6nKmPawdayZ01N+o0sVHAGK0qcvTVCkBZT/1qbsJaTBPD1yf3PcN2frpwfTDBCn9GA== + version "9.4.4" + resolved "https://registry.yarnpkg.com/electron/-/electron-9.4.4.tgz#2a74a0655a74bd326216672c5ae6ed3a44451446" + integrity sha512-dcPlTrMWQu5xuSm6sYV42KK/BRIqh3erM8v/WtZqaDmG7pkCeJpvw26Dgbqhdt78XmqqGiN96giEe6A3S9vpAQ== dependencies: "@electron/get" "^1.0.1" "@types/node" "^12.0.12" @@ -8706,6 +8893,11 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== +errlop@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/errlop/-/errlop-4.1.0.tgz#8e7b8f4f1bf0a6feafce4d14f0c0cf4bf5ef036b" + integrity sha512-vul6gGBuVt0M2TPi1/WrcL86+Hb3Q2Tpu3TME3sbVhZrYf7J1ZMHCodI25RQKCVurh56qTfvgM0p3w5cT4reSQ== + errno@^0.1.3, errno@~0.1.1, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" @@ -8727,42 +8919,27 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: - version "1.17.7" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" - integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== - dependencies: - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" - is-regex "^1.1.1" - object-inspect "^1.8.0" - object-keys "^1.1.1" - object.assign "^4.1.1" - string.prototype.trimend "^1.0.1" - string.prototype.trimstart "^1.0.1" - -es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.0-next.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.2.tgz#088101a55f0541f595e7e057199e27ddc8f3a5c2" - integrity sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw== +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: + version "1.18.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" + integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" function-bind "^1.1.1" - get-intrinsic "^1.0.2" + get-intrinsic "^1.1.1" has "^1.0.3" - has-symbols "^1.0.1" - is-callable "^1.2.2" + has-symbols "^1.0.2" + is-callable "^1.2.3" is-negative-zero "^2.0.1" - is-regex "^1.1.1" + is-regex "^1.1.2" + is-string "^1.0.5" object-inspect "^1.9.0" object-keys "^1.1.1" object.assign "^4.1.2" - string.prototype.trimend "^1.0.3" - string.prototype.trimstart "^1.0.3" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.0" es-array-method-boxes-properly@^1.0.0: version "1.0.0" @@ -8897,10 +9074,10 @@ esdoc@^1.0.4: minimist "1.2.0" taffydb "2.7.3" -eslint-config-prettier@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz#f4a4bd2832e810e8cc7c1411ec85b3e85c0c53f9" - integrity sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg== +eslint-config-prettier@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.1.0.tgz#4ef1eaf97afe5176e6a75ddfb57c335121abc5a6" + integrity sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw== eslint-config-react-app@^6.0.0: version "6.0.0" @@ -8926,9 +9103,9 @@ eslint-module-utils@^2.6.0: pkg-dir "^2.0.0" eslint-plugin-flowtype@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.2.2.tgz#c6e5dd2fad4e757a1c63e652da6cff597659554f" - integrity sha512-C4PlPYpszr9h1cBfUbTNRI1IdxUCF0qrXAHkXS2+bESp7WUUCnvb3UBBnYlaQLvJYJ2lRz+2SPQQ/WyV7p/Tow== + version "5.3.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.3.1.tgz#df6227e28c61d967b825c1327a27818bbb2ad325" + integrity sha512-mziJD+zw+VTwLtF9qLIxYac0GJCbSEDyqMLP5ENzQeNY5EOxbAfitMFLo+UItjYOISQdh1BCobwE2d4i1o+9Rw== dependencies: lodash "^4.17.15" string-natural-compare "^3.0.1" @@ -9052,7 +9229,7 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint-webpack-plugin@^2.1.0: +eslint-webpack-plugin@^2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.2.tgz#4ee17577d6392bf72048080a1678d6237183db81" integrity sha512-ndD9chZ/kaGnjjx7taRg7c6FK/YKb29SSYzaLtPBIYLYJQmZtuKqtQbAvTS2ymiMQT6X0VW9vZIHK0KLstv93Q== @@ -9064,12 +9241,12 @@ eslint-webpack-plugin@^2.1.0: schema-utils "^3.0.0" eslint@^7.11.0, eslint@^7.17.0: - version "7.20.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.20.0.tgz#db07c4ca4eda2e2316e7aa57ac7fc91ec550bdc7" - integrity sha512-qGi0CTcOGP2OtCQBgWZlQjcTuP0XkIpYFj25XtRTQSHC+umNnp7UMshr2G8SLsRFYDdAPFeHOsiteadmMH02Yw== + version "7.21.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.21.0.tgz#4ecd5b8c5b44f5dedc9b8a110b01bbfeb15d1c83" + integrity sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg== dependencies: "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.3.0" + "@eslint/eslintrc" "^0.4.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -9082,7 +9259,7 @@ eslint@^7.11.0, eslint@^7.17.0: espree "^7.3.1" esquery "^1.4.0" esutils "^2.0.2" - file-entry-cache "^6.0.0" + file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" globals "^12.1.0" @@ -9353,6 +9530,18 @@ eth-lib@^0.1.26: ws "^3.0.0" xhr-request-promise "^0.1.2" +eth-provider@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/eth-provider/-/eth-provider-0.6.1.tgz#795c69205f023678ed79f9139233426afdbc479c" + integrity sha512-0sBNzOBEUSQmo5zHSQ/os25ULh+LeoTTK5nGxiTJpXo8R0OOxOzYiVWLfAWuIuYLhzT1ma5A1wPZWMt+gPGeoA== + dependencies: + ethereum-provider "0.2.2" + events "3.2.0" + oboe "2.1.5" + uuid "8.3.2" + ws "7.4.3" + xhr2-cookies "1.1.0" + eth-query@^2.0.2, eth-query@^2.1.0, eth-query@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/eth-query/-/eth-query-2.1.2.tgz#d6741d9000106b51510c72db92d6365456a6da5e" @@ -9513,6 +9702,13 @@ ethereum-protocol@^1.0.1: resolved "https://registry.yarnpkg.com/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz#b7d68142f4105e0ae7b5e178cf42f8d4dc4b93cf" integrity sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg== +ethereum-provider@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/ethereum-provider/-/ethereum-provider-0.2.2.tgz#37ba0674a6c05915b51afb8e6d13e9bd166f1c33" + integrity sha512-147DaU4nccfYYCAKhrILdgSWTjjZX2NnmcZJx12frM+cNw8cGTbpQPpi4xApagIk7HlN16ZncCP5uyOiZN7n3g== + dependencies: + events "3.2.0" + ethereum-public-key-to-address@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/ethereum-public-key-to-address/-/ethereum-public-key-to-address-0.0.1.tgz#3f0237687d9c2217234dc5683f3eb580abf3f6ce" @@ -9762,11 +9958,16 @@ eventemitter3@4.0.7, eventemitter3@^4.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.0.0, events@^3.2.0: +events@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/events/-/events-3.2.0.tgz#93b87c18f8efcd4202a461aec4dfc0556b639379" integrity sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg== +events@^3.0.0, events@^3.2.0, events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + eventsource@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" @@ -9918,7 +10119,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@^3.0.0, extend@~3.0.0, extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -9966,21 +10167,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -eztz-lib@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eztz-lib/-/eztz-lib-0.1.2.tgz#6e00037f85862f06f9997108302cfa673fe2e703" - integrity sha512-77pr673PMEPvbcHylbRuHwd5P5D3Myc3VC54AC2ovaKTdIVbW/vc6HIrf8D44/a5q9eZzlUpunfKrkBug02OBw== - dependencies: - bignumber.js "^7.2.1" - bip39 "^2.5.0" - bs58check "^2.1.1" - buffer "^5.1.0" - codecov "^2.3.1" - libsodium-wrappers "^0.5.4" - pbkdf2 "^3.0.14" - xhr2 "^0.1.4" - xmlhttprequest "^1.8.0" - fake-merkle-patricia-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz#4b8c3acfb520afadf9860b1f14cd8ce3402cddd3" @@ -10060,9 +10246,9 @@ fast-safe-stringify@^2.0.6: integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== fastq@^1.6.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.10.1.tgz#8b8f2ac8bf3632d67afcd65dac248d5fdc45385e" - integrity sha512-AWuv6Ery3pM+dY7LYS8YIaCiQvUaos9OB1RyNgaOWnaX+Tik7Onvcsf8x8c+YtDeT0maYLniBip2hox5KtEXXA== + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== dependencies: reusify "^1.0.4" @@ -10073,14 +10259,7 @@ fault@^1.0.2: dependencies: format "^0.2.0" -faye-websocket@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= - dependencies: - websocket-driver ">=0.5.1" - -faye-websocket@~0.11.1: +faye-websocket@^0.11.3, faye-websocket@~0.11.1: version "0.11.3" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== @@ -10127,7 +10306,7 @@ figures@^3.0.0, figures@^3.2.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^6.0.0: +file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== @@ -10198,15 +10377,20 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= + final-form-calculate@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/final-form-calculate/-/final-form-calculate-1.3.2.tgz#a5e1908d1aa34eeec6faccdba3fd9516e7fd3d4f" integrity sha512-pon2K9yNbyqmF8UTpDvxwhk+Hvqpl8Fm3qgwkHniNAmCQe+6YxB1aw4cBAHzmRc39jGl2bYsvKyabQOIWLtrPg== -final-form@^4.20.1: - version "4.20.1" - resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.1.tgz#525a7f7f27f55c28d8994b157b24d6104fc560e9" - integrity sha512-IIsOK3JRxJrN72OBj7vFWZxtGt3xc1bYwJVPchjVWmDol9DlzMSAOPB+vwe75TUYsw1JaH0fTQnIgwSQZQ9Acg== +final-form@^4.20.2: + version "4.20.2" + resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.2.tgz#c820b37d7ebb73d71169480256a36c7e6e6c9155" + integrity sha512-5i0IxqwjjPG1nUNCjWhqPCvQJJ2R+QwTwaAnjPmFnLbyjIHWuBPU8u+Ps4G3TcX2Sjno+O5xCZJzYcMJEzzfCQ== dependencies: "@babel/runtime" "^7.10.0" @@ -10291,13 +10475,12 @@ find-versions@^4.0.0: dependencies: semver-regex "^3.1.2" -find-yarn-workspace-root@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-1.2.1.tgz#40eb8e6e7c2502ddfaa2577c176f221422f860db" - integrity sha512-dVtfb0WuQG+8Ag2uWkbG79hOUzEsRrhBzgfn86g2sJPkzmcpGdghbNTfUKGTxymFrY/tLIodDzLoW9nOJ4FY8Q== +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== dependencies: - fs-extra "^4.0.3" - micromatch "^3.1.4" + micromatch "^4.0.2" flat-cache@^3.0.4: version "3.0.4" @@ -10347,9 +10530,9 @@ follow-redirects@1.5.10: debug "=3.1.0" follow-redirects@^1.0.0, follow-redirects@^1.10.0: - version "1.13.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.2.tgz#dd73c8effc12728ba5cf4259d760ea5fb83e3147" - integrity sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA== + version "1.13.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" + integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== for-each@~0.3.3: version "0.3.3" @@ -10421,15 +10604,6 @@ form-data@^2.3.1: combined-stream "^1.0.6" mime-types "^2.1.12" -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -10504,7 +10678,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^4.0.2, fs-extra@^4.0.3: +fs-extra@^4.0.2: version "4.0.3" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== @@ -10531,7 +10705,7 @@ fs-extra@^8.0.1, fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.0.1: +fs-extra@^9.0.1, fs-extra@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -10632,20 +10806,6 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -generate-function@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" - integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== - dependencies: - is-property "^1.0.2" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= - dependencies: - is-property "^1.0.0" - gensync@^1.0.0-beta.1: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -10776,12 +10936,12 @@ global-agent@^2.0.2: semver "^7.3.2" serialize-error "^7.0.1" -global-dirs@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" - integrity sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ== +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== dependencies: - ini "1.3.7" + ini "2.0.0" global-modules@2.0.0: version "2.0.0" @@ -10835,9 +10995,9 @@ globals@^9.18.0: integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== globalthis@^1.0.0, globalthis@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.1.tgz#40116f5d9c071f9e8fb0037654df1ab3a83b7ef9" - integrity sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.2.tgz#2a235d34f4d8036219f7e34929b5de9e18166b8b" + integrity sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ== dependencies: define-properties "^1.1.3" @@ -10938,6 +11098,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + gridplus-sdk@^0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/gridplus-sdk/-/gridplus-sdk-0.7.2.tgz#ea46c565ea7f8e029b7a61283f25e9f175ddfa47" @@ -10998,16 +11163,6 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" - integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= - dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - har-validator@~5.1.3: version "5.1.5" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" @@ -11028,6 +11183,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-bigints@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -11043,10 +11203,10 @@ has-symbol-support-x@^1.4.1: resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== has-to-string-tag-x@^1.2.0: version "1.4.1" @@ -11143,16 +11303,6 @@ hastscript@^5.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - hdkey@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-2.0.1.tgz#0a211d0c510bfc44fa3ec9d44b13b634641cad74" @@ -11216,11 +11366,6 @@ hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= - hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -11246,7 +11391,7 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -hosted-git-info@^3.0.5: +hosted-git-info@^3.0.6, hosted-git-info@^3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== @@ -11442,15 +11587,6 @@ http-proxy@^1.17.0: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -11478,7 +11614,7 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== -husky@^4.3.0: +husky@~4.3.8: version "4.3.8" resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.8.tgz#31144060be963fd6850e5cc8f019a1dfe194296d" integrity sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow== @@ -11507,6 +11643,14 @@ ice-cap@0.0.4: cheerio "0.20.0" color-logger "0.0.3" +iconv-corefoundation@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.5.tgz#90596d444a579aeb109f5ca113f6bb665a41be2b" + integrity sha512-hI4m7udfV04OcjleOmDaR4gwXnH4xumxN+ZmywHDiKf2CmAzsT9SVYe7Y4pdnQbyZfXwAQyrElykbE5PrPRfmQ== + dependencies: + cli-truncate "^1.1.0" + node-addon-api "^1.6.3" + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -11582,10 +11726,10 @@ immer@1.10.0: resolved "https://registry.yarnpkg.com/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== -immer@7.0.9: - version "7.0.9" - resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.9.tgz#28e7552c21d39dd76feccd2b800b7bc86ee4a62e" - integrity sha512-Vs/gxoM4DqNAYR7pugIxi0Xc8XAun/uy7AQu4fLLqaTBHxjOP9pJ266Q9MWA/ly4z6rAFZbvViOtihxUZ7O28A== +immer@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" + integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== immortal-db@^1.1.0: version "1.1.0" @@ -11706,10 +11850,10 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" - integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" @@ -11876,6 +12020,11 @@ is-arrayish@^0.3.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" + integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -11890,6 +12039,13 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" + is-buffer@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" @@ -11905,7 +12061,7 @@ is-buffer@^2.0.2, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.2: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== @@ -12096,13 +12252,13 @@ is-in-browser@^1.0.2, is-in-browser@^1.1.3: resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" integrity sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU= -is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" is-lower-case@^1.1.0: version "1.1.3" @@ -12121,31 +12277,20 @@ is-module@^1.0.0: resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= -is-my-ip-valid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" - integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ== - -is-my-json-valid@^2.12.4: - version "2.20.5" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.5.tgz#5eca6a8232a687f68869b7361be1612e7512e5df" - integrity sha512-VTPuvvGQtxvCeghwspQu1rBgjYUT6FGxPlvFKbYuFtgc4ADsX3U5ihZOYN0qyU6u+d4X9xXb0IT5O6QpXKt87A== - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - is-my-ip-valid "^1.0.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" - is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== -is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + +is-number-object@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" + integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== is-number@^3.0.0: version "3.0.0" @@ -12193,7 +12338,7 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.0.2" -is-path-inside@^3.0.1: +is-path-inside@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== @@ -12220,12 +12365,7 @@ is-potential-custom-element-name@^1.0.0: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= -is-property@^1.0.0, is-property@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= - -is-regex@^1.0.4, is-regex@^1.1.1: +is-regex@^1.0.4, is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== @@ -12364,11 +12504,6 @@ isarray@^2.0.1, isarray@^2.0.5: resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isbinaryfile@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.6.tgz#edcb62b224e2b4710830b67498c8e4e5a4d2610b" - integrity sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -12437,6 +12572,15 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +istextorbinary@^5.12.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-5.12.0.tgz#2f84777838668fdf524c305a2363d6057aaeec84" + integrity sha512-wLDRWD7qpNTYubk04+q3en1+XZGS4vYWK0+SxNSXJLaITMMEK+J3o/TlOMyULeH1qozVZ9uUkKcyMA8odyxz8w== + dependencies: + binaryextensions "^4.15.0" + editions "^6.1.0" + textextensions "^5.11.0" + isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -12937,6 +13081,11 @@ js-sha3@0.8.0, js-sha3@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== +js-sha512@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha512/-/js-sha512-0.8.0.tgz#dd22db8d02756faccf19f218e3ed61ec8249f7d4" + integrity sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -12955,7 +13104,7 @@ js-yaml@3.14.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.13.1, js-yaml@^3.14.0: +js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -12963,6 +13112,13 @@ js-yaml@^3.13.1, js-yaml@^3.14.0: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f" + integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q== + dependencies: + argparse "^2.0.1" + jsan@^3.1.13: version "3.1.13" resolved "https://registry.yarnpkg.com/jsan/-/jsan-3.1.13.tgz#4de8c7bf8d1cfcd020c313d438f930cec4b91d86" @@ -13150,7 +13306,7 @@ json2mq@^0.2.0: dependencies: string-convert "^0.2.0" -json3@^3.3.2: +json3@^3.3.2, json3@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== @@ -13202,11 +13358,6 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonpointer@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.1.0.tgz#501fb89986a2389765ba09e6053299ceb4f2c2cc" - integrity sha512-CXcRvMyTlnR53xMcKnuMzfCA5i/nfblTnnr74CZb6C4vG39eu6w51t7nKmU5MfLfbTgGItliNyjO/ciNPDqClg== - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -13424,7 +13575,7 @@ last-call-webpack-plugin@^3.0.0: lodash "^4.17.5" webpack-sources "^1.1.0" -latest-version@^5.0.0: +latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== @@ -13533,18 +13684,6 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libsodium-wrappers@^0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.5.4.tgz#0059bf219c3a37b228f823342399b1607a4c5ba4" - integrity sha512-dAYsfQgh6XwR4I65y7T5qDgb2XNKDpzXEXz229sDplaJfnAuIBTHBYlQ44jL5DIS4cCUspE3+g0kF4/Xe8286A== - dependencies: - libsodium "0.5.4" - -libsodium@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.5.4.tgz#874413435ee40c512dd59ea6db9b75970f8aec02" - integrity sha512-s1TQ2V23JvGby1gnCQEQncTNTGck/rtJPPA8c0TiBo9z9TpT4eUk5zThte8H1TkdoKQznneqZqyoqdrwu2btWw== - lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -13793,7 +13932,7 @@ lodash.zipwith@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.zipwith/-/lodash.zipwith-4.2.0.tgz#afacf03fd2f384af29e263c3c6bda3b80e3f51fd" integrity sha1-r6zwP9LzhK8p4mPDxr2juA4/Uf0= -"lodash@>=3.5 <5", lodash@^4.1.0, 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@^4.2.1: +"lodash@>=3.5 <5", lodash@^4.1.0, 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.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -14162,7 +14301,7 @@ mime-db@1.46.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== -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, mime-types@~2.1.7: +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.29" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== @@ -14174,7 +14313,7 @@ mime@1.6.0, mime@^1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.4, mime@^2.4.6: +mime@^2.4.4, mime@^2.5.0: version "2.5.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== @@ -14517,6 +14656,11 @@ nan@^2.12.1, nan@^2.13.2, nan@^2.14.0, nan@^2.14.1, nan@^2.2.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha1-ulSMh578+5DaHE2eCX20pGySVe8= + nano-json-stream-parser@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" @@ -14613,6 +14757,11 @@ node-abi@^2.7.0: dependencies: semver "^5.4.1" +node-addon-api@^1.6.3: + version "1.7.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" + integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -14726,14 +14875,9 @@ node-notifier@^8.0.0: which "^2.0.2" node-releases@^1.1.29, node-releases@^1.1.3, node-releases@^1.1.61, node-releases@^1.1.70: - version "1.1.70" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" - integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== - -node-uuid@~1.4.7: - version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" - integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= + version "1.1.71" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" + integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== nofilter@^1.0.4: version "1.0.4" @@ -14762,6 +14906,16 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package- semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-package-data@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.0.tgz#1f8a7c423b3d2e85eb36985eaf81de381d01301a" + integrity sha512-6lUjEI0d3v6kFrtgA/lOx4zHCWULXsFNIjHolnZCKCTLA6m/G625cdn3O7eNmT0iD3jfo6HZ9cdImGZwf21prw== + dependencies: + hosted-git-info "^3.0.6" + resolve "^1.17.0" + semver "^7.3.2" + validate-npm-package-license "^3.0.1" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -14882,11 +15036,6 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= - oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" @@ -14920,7 +15069,7 @@ object-hash@^2.1.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== -object-inspect@^1.8.0, object-inspect@^1.9.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== @@ -14965,7 +15114,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.2: +object.assign@^4.1.0, 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== @@ -15012,13 +15161,13 @@ object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.1.0, object.values@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731" - integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag== + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" + integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" + es-abstract "^1.18.0-next.2" has "^1.0.3" objectorarray@^1.0.4: @@ -15095,7 +15244,7 @@ open@^6.3.0: dependencies: is-wsl "^1.1.0" -open@^7.0.0, open@^7.0.2: +open@^7.0.0, open@^7.0.2, open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -15452,19 +15601,20 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -patch-package@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.2.2.tgz#71d170d650c65c26556f0d0fbbb48d92b6cc5f39" - integrity sha512-YqScVYkVcClUY0v8fF0kWOjDYopzIM8e3bj/RU1DPeEF14+dCGm6UeOYm4jvCyxqIEQ5/eJzmbWfDWnUleFNMg== +patch-package@^6.4.6: + version "6.4.6" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.6.tgz#e61fe9f0d23df509338e3b79be6e89b81d5760e4" + integrity sha512-AO2bh42z8AQL+0OUdcRpS5Z/0X8k9IQ1uc1HzlVye+2RQrtDeNgTk5SbS4rdbLJKtUWRpvPISrYZeyh+OK4AKw== dependencies: "@yarnpkg/lockfile" "^1.1.0" chalk "^2.4.2" cross-spawn "^6.0.5" - find-yarn-workspace-root "^1.2.1" + find-yarn-workspace-root "^2.0.0" fs-extra "^7.0.1" is-ci "^2.0.0" klaw-sync "^6.0.0" minimist "^1.2.0" + open "^7.4.2" rimraf "^2.6.3" semver "^5.6.0" slash "^2.0.0" @@ -15553,7 +15703,7 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pbkdf2@^3.0.14, pbkdf2@^3.0.17, pbkdf2@^3.0.3, pbkdf2@^3.0.9: +pbkdf2@^3.0.17, pbkdf2@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== @@ -15677,6 +15827,15 @@ please-upgrade-node@^3.2.0: dependencies: semver-compare "^1.0.0" +plist@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" + integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== + dependencies: + base64-js "^1.2.3" + xmlbuilder "^9.0.7" + xmldom "0.1.x" + pngjs@^3.3.0: version "3.4.0" resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" @@ -15713,7 +15872,7 @@ polished@^3.3.1: resolved "https://registry.yarnpkg.com/polished/-/polished-3.6.7.tgz#44cbd0047f3187d83db0c479ef0c7d5583af5fb6" integrity sha512-b4OViUOihwV0icb9PHmWbR+vPqaSzSAEbgLskvb7ANPATVXGiYv/TQFHQo65S53WU9i5EQ1I03YDOJW7K0bmYg== dependencies: - "@babel/runtime" "^7.12.5" + "@babel/runtime" "^7.9.2" popper.js@1.16.1-lts: version "1.16.1-lts" @@ -16409,11 +16568,11 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, po supports-color "^6.1.0" postcss@^8.1.0: - version "8.2.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" - integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== + version "8.2.7" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.7.tgz#48ed8d88b4de10afa0dfd1c3f840aa57b55c4d47" + integrity sha512-DsVLH3xJzut+VT+rYr0mtvOtpTjSyqDwPf5EZWXcb0uAKfitGpTY9Ec+afi2+TgdN8rWS9Cs88UDYehKo/RvOw== dependencies: - colorette "^1.2.1" + colorette "^1.2.2" nanoid "^3.1.20" source-map "^0.6.1" @@ -16729,7 +16888,7 @@ punycode@2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" integrity sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0= -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.2.4: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= @@ -16739,7 +16898,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pupa@^2.0.1: +pupa@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== @@ -16793,11 +16952,6 @@ qs@^6.5.1, qs@^6.6.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== -qs@~6.3.0: - version "6.3.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" - integrity sha1-51vV9uJoEioqDgvaYwslUMFmUCw= - qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -16812,12 +16966,13 @@ query-string@6.13.5: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -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== +query-string@6.14.1: + version "6.14.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" + integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== dependencies: decode-uri-component "^0.2.0" + filter-obj "^1.1.0" split-on-first "^1.0.0" strict-uri-encode "^2.0.0" @@ -16957,10 +17112,10 @@ react-clientside-effect@^1.2.2: dependencies: "@babel/runtime" "^7.12.13" -react-dev-utils@^11.0.2: - version "11.0.2" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.2.tgz#98aed16ef50f808ee17b32def75eb15f89655802" - integrity sha512-xG7GlMoYkrgc2M1kDCHKRywXMDbFnjOB+/VzpytQyYBusEzR8NlGTMmUbvN86k94yyKu5XReHB8eZC2JZrNchQ== +react-dev-utils@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.3.tgz#b61ed499c7d74f447d4faddcc547e5e671e97c08" + integrity sha512-4lEA5gF4OHrcJLMUV1t+4XbNDiJbsAWCH5Z2uqlTqW6dD7Cf5nEASkeXrCI/Mz83sI2o527oBIFKVMXtRf1Vtg== dependencies: "@babel/code-frame" "7.10.4" address "1.1.2" @@ -16975,7 +17130,7 @@ react-dev-utils@^11.0.2: global-modules "2.0.0" globby "11.0.1" gzip-size "5.1.1" - immer "7.0.9" + immer "8.0.1" is-root "2.1.0" loader-utils "2.0.0" open "^7.0.2" @@ -17305,9 +17460,9 @@ react-router@5.2.0: tiny-warning "^1.0.0" react-scripts@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.2.tgz#530fd934dfdf31c355e366df40bf488347c28de7" - integrity sha512-okaWNaGDGtnXyM2CLMUl8gYZnAubgxEulC40FYjsxn5bbj+G/mDINdy24wHz4Vypb/LWtIe8rdBU78k/74v8Mw== + version "4.0.3" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345" + integrity sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A== dependencies: "@babel/core" "7.12.3" "@pmmmwh/react-refresh-webpack-plugin" "0.4.3" @@ -17334,7 +17489,7 @@ react-scripts@^4.0.1: eslint-plugin-react "^7.21.5" eslint-plugin-react-hooks "^4.2.0" eslint-plugin-testing-library "^3.9.2" - eslint-webpack-plugin "^2.1.0" + eslint-webpack-plugin "^2.5.2" file-loader "6.1.1" fs-extra "^9.0.1" html-webpack-plugin "4.5.0" @@ -17353,7 +17508,7 @@ react-scripts@^4.0.1: postcss-safe-parser "5.0.2" prompts "2.4.0" react-app-polyfill "^2.0.0" - react-dev-utils "^11.0.2" + react-dev-utils "^11.0.3" react-refresh "^0.8.3" resolve "1.18.1" resolve-url-loader "^3.1.2" @@ -17364,7 +17519,7 @@ react-scripts@^4.0.1: ts-pnp "1.2.0" url-loader "4.1.1" webpack "4.44.2" - webpack-dev-server "3.11.0" + webpack-dev-server "3.11.1" webpack-manifest-plugin "2.2.0" workbox-webpack-plugin "5.1.4" optionalDependencies: @@ -17521,17 +17676,7 @@ read-pkg@^5.2.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.1: - version "1.1.13" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" - integrity sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^1.0.33: +readable-stream@1.1, readable-stream@^1.0.33: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= @@ -17890,32 +18035,6 @@ request-promise-native@^1.0.8: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@2.77.0: - version "2.77.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.77.0.tgz#2b00d82030ededcc97089ffa5d8810a9c2aa314b" - integrity sha1-KwDYIDDt7cyXCJ/6XYgQqcKqMUs= - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - request@^2.55.0, request@^2.79.0, request@^2.85.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" @@ -18148,7 +18267,7 @@ ripemd160-min@0.0.6: resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== -ripemd160@^2.0.0, ripemd160@^2.0.1: +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== @@ -18258,10 +18377,10 @@ 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.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== +rxjs@^6.1.0, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.6.0, rxjs@^6.6.3, rxjs@^6.6.6: + version "6.6.6" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70" + integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg== dependencies: tslib "^1.9.0" @@ -18461,7 +18580,7 @@ select@^1.1.2: resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= -selfsigned@^1.10.7: +selfsigned@^1.10.8: version "1.10.8" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== @@ -18505,7 +18624,7 @@ semver@7.3.2: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -18663,7 +18782,7 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -sha3@^2.1.1: +sha3@^2.1.1, sha3@^2.1.3: version "2.1.4" resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== @@ -18827,6 +18946,13 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + 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" @@ -18845,6 +18971,11 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +smart-buffer@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + snake-case@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" @@ -18882,13 +19013,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= - dependencies: - hoek "2.x.x" - socketcluster-client@^14.2.1: version "14.3.1" resolved "https://registry.yarnpkg.com/socketcluster-client/-/socketcluster-client-14.3.1.tgz#bfc3591c0cad2668e7b3512a102f3844f5f2e84d" @@ -18929,14 +19053,26 @@ sockjs-client@1.4.0: json3 "^3.3.2" url-parse "^1.4.3" -sockjs@0.3.20: - version "0.3.20" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855" - integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA== +sockjs-client@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add" + integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q== dependencies: - faye-websocket "^0.10.0" + debug "^3.2.6" + eventsource "^1.0.7" + faye-websocket "^0.11.3" + inherits "^2.0.4" + json3 "^3.3.3" + url-parse "^1.4.7" + +sockjs@^0.3.21: + version "0.3.21" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" + integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== + dependencies: + faye-websocket "^0.11.3" uuid "^3.4.0" - websocket-driver "0.6.5" + websocket-driver "^0.7.4" solc@0.5.14: version "0.5.14" @@ -19265,7 +19401,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -19283,9 +19419,9 @@ string-width@^3.0.0, string-width@^3.1.0: strip-ansi "^5.1.0" string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" @@ -19331,20 +19467,20 @@ string.prototype.trim@~1.2.1: define-properties "^1.1.3" es-abstract "^1.18.0-next.2" -string.prototype.trimend@^1.0.1, string.prototype.trimend@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" - integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.1, string.prototype.trimstart@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" - integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" string_decoder@^1.0.0, string_decoder@^1.1.1: @@ -19375,11 +19511,6 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -stringstream@~0.0.4: - version "0.0.6" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" - integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== - strip-ansi@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" @@ -19876,6 +20007,11 @@ text-table@0.2.0, text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +textextensions@^5.11.0: + version "5.12.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-5.12.0.tgz#b908120b5c1bd4bb9eba41423d75b176011ab68a" + integrity sha512-IYogUDaP65IXboCiPPC0jTLLBzYlhhw2Y4b0a2trPgbHNGGGEfuHE6tds+yDcCf4mpNDaGISFzwSSezcXt+d6w== + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -20061,13 +20197,6 @@ tough-cookie@^3.0.1: psl "^1.1.28" punycode "^2.1.1" -tough-cookie@~2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== - dependencies: - punycode "^1.4.1" - tr46@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" @@ -20200,11 +20329,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= - tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" @@ -20254,6 +20378,11 @@ type-fest@^0.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" @@ -20288,9 +20417,9 @@ type@^2.0.0: integrity sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg== typechain@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-4.0.2.tgz#31a961bf1fc43b8cde39193247439715e43ce5d3" - integrity sha512-SopnfdQrS5ek6sTbvymsnBACA+70FstX/ZLWY8lQWNdLUXGyoGFoa73Y+1hKlbz2DfCnO39bQ551qUMhk5GYSw== + version "4.0.3" + resolved "https://registry.yarnpkg.com/typechain/-/typechain-4.0.3.tgz#e8fcd6c984676858c64eeeb155ea783a10b73779" + integrity sha512-tmoHQeXZWHxIdeLK+i6dU0CU0vOd9Cndr3jFTZIMzak5/YpFZ8XoiYpTZcngygGBqZo+Z1EUmttLbW9KkFZLgQ== dependencies: command-line-args "^4.0.7" debug "^4.1.1" @@ -20336,10 +20465,10 @@ typescript-tuple@^2.2.1: dependencies: typescript-compare "^0.0.2" -typescript@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7" - integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== +typescript@4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" + integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== typical@^2.6.0, typical@^2.6.1: version "2.6.1" @@ -20361,6 +20490,16 @@ ultron@~1.1.0: resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== +unbox-primitive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.0.tgz#eeacbc4affa28e9b3d36b5eaeccc50b3251b1d3f" + integrity sha512-P/51NX+JXyxK/aigg1/ZgyccdAxm5K1+n8+tvqSntjOivPt19gvm1VC49RWYetsiub8WViUchdxl/KWHHB0kzA== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.0" + has-symbols "^1.0.0" + which-boxed-primitive "^1.0.1" + underscore@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" @@ -20457,11 +20596,6 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unorm@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.6.0.tgz#029b289661fba714f1a9af439eb51d9b16c205af" - integrity sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA== - unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -20485,22 +20619,23 @@ upath@^1.1.1, upath@^1.1.2, upath@^1.2.0: resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== -update-notifier@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" - integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== dependencies: - boxen "^4.2.0" - chalk "^3.0.0" + boxen "^5.0.0" + chalk "^4.1.0" configstore "^5.0.1" has-yarn "^2.1.0" import-lazy "^2.1.0" is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" semver-diff "^3.1.1" xdg-basedir "^4.0.0" @@ -20560,7 +20695,7 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.3: +url-parse@^1.4.3, url-parse@^1.4.7: version "1.5.1" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== @@ -20586,11 +20721,6 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -urlgrey@0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" - integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8= - usb-detection@^4.10.0: version "4.10.0" resolved "https://registry.yarnpkg.com/usb-detection/-/usb-detection-4.10.0.tgz#0f8a3b8965a5e4e7fbee1667971ca97e455ed11f" @@ -20715,16 +20845,16 @@ uuid@7.0.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6" integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw== +uuid@8.3.2, uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.3.0: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - uuidv4@6.0.6: version "6.0.6" resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-6.0.6.tgz#6966e8dd15760528a0f954843d24fdfdfda5a329" @@ -20774,7 +20904,7 @@ vendors@^1.0.0: resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== -verror@1.10.0: +verror@1.10.0, verror@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= @@ -20783,6 +20913,18 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +version-compare@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/version-compare/-/version-compare-1.1.0.tgz#7b3e67e7e6cec5c72d9c9e586f8854e419ade17c" + integrity sha512-zVKtPOJTC9x23lzS4+4D7J+drq80BXVYAmObnr5zqxxFVH7OffJ1lJlAS7LYsQNV56jx/wtbw0UV7XHLrvd6kQ== + +version-range@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/version-range/-/version-range-1.1.0.tgz#1c233064202ee742afc9d56e21da3b2e15260acf" + integrity sha512-R1Ggfg2EXamrnrV3TkZ6yBNgITDbclB3viwSjbZ3+eK0VVNK4ajkYJTnDz5N0bIMYDtK9MUBvXJUnKO5RWWJ6w== + dependencies: + version-compare "^1.0.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -21704,10 +21846,10 @@ webpack-dev-middleware@^3.7.0, webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c" - integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg== +webpack-dev-server@3.11.1: + version "3.11.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0" + integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ== dependencies: ansi-html "0.0.7" bonjour "^3.5.0" @@ -21729,11 +21871,11 @@ webpack-dev-server@3.11.0: p-retry "^3.0.1" portfinder "^1.0.26" schema-utils "^1.0.0" - selfsigned "^1.10.7" + selfsigned "^1.10.8" semver "^6.3.0" serve-index "^1.9.1" - sockjs "0.3.20" - sockjs-client "1.4.0" + sockjs "^0.3.21" + sockjs-client "^1.5.0" spdy "^4.0.2" strip-ansi "^3.0.1" supports-color "^6.1.0" @@ -21852,14 +21994,7 @@ webrtc-adapter@^7.2.1: rtcpeerconnection-shim "^1.2.15" sdp "^2.12.0" -websocket-driver@0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" - integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY= - dependencies: - websocket-extensions ">=0.1.1" - -websocket-driver@>=0.5.1: +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== @@ -21898,9 +22033,9 @@ whatwg-fetch@2.0.4: integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== whatwg-fetch@^3.4.1, whatwg-fetch@^3.5.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.1.tgz#93bc4005af6c2cc30ba3e42ec3125947c8f54ed3" - integrity sha512-IEmN/ZfmMw6G1hgZpVd0LuZXOQDisrMOZrzYd5x3RAK4bMPlJohKUZWZ9t/QsTvH0dV9TbPDcc2OSuIDcihnHA== + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== whatwg-mimetype@^2.3.0: version "2.3.0" @@ -21923,6 +22058,17 @@ whatwg-url@^8.0.0: tr46 "^2.0.2" webidl-conversions "^6.1.0" +which-boxed-primitive@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -22222,6 +22368,11 @@ ws@7.3.0: resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.0.tgz#4b2f7f219b3d3737bc1a2fbf145d825b94d38ffd" integrity sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w== +ws@7.4.3, ws@^7.2.3: + version "7.4.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd" + integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA== + ws@^3.0.0: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -22245,11 +22396,6 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.2.3: - version "7.4.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.3.tgz#1f9643de34a543b8edb124bdcbc457ae55a6e5cd" - integrity sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA== - xdg-basedir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" @@ -22282,11 +22428,6 @@ xhr2-cookies@1.1.0: dependencies: cookiejar "^2.1.1" -xhr2@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" - integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= - xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: version "2.6.0" resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" @@ -22307,12 +22448,27 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xmlbuilder@>=11.0.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" + integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== + +xmlbuilder@^9.0.7: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xmlhttprequest@1.8.0, xmlhttprequest@^1.8.0: +xmldom@0.1.x: + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" + integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== + +xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= @@ -22456,7 +22612,7 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.0.3: +yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==