From 4d699b72f8d94c8a777dc2638d40c7c841e25bac Mon Sep 17 00:00:00 2001 From: JosephBagaric Date: Tue, 23 Jun 2020 10:39:06 +0200 Subject: [PATCH 01/19] feat: Support for Volta and EWC --- src/components/EtherscanBtn/index.tsx | 4 +- src/config/index.ts | 18 +++-- src/logic/wallets/getWeb3.ts | 65 ++++++++++++++----- src/logic/wallets/utils/walletList.ts | 2 +- src/routes/opening/components/Footer.tsx | 6 +- .../Settings/RemoveSafeModal/index.tsx | 4 +- 6 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/components/EtherscanBtn/index.tsx b/src/components/EtherscanBtn/index.tsx index c81d0be868..5a987e82d4 100644 --- a/src/components/EtherscanBtn/index.tsx +++ b/src/components/EtherscanBtn/index.tsx @@ -6,7 +6,7 @@ import React from 'react' import EtherscanOpenIcon from './img/etherscan-open.svg' import Img from 'src/components/layout/Img' -import { getEtherScanLink } from 'src/logic/wallets/getWeb3' +import { getExplorerLink } from 'src/logic/wallets/getWeb3' import { xs } from 'src/theme/variables' const useStyles = makeStyles({ @@ -49,7 +49,7 @@ const EtherscanBtn = ({ aria-label="Show details on Etherscan" className={cn(classes.container, className)} onClick={(event) => event.stopPropagation()} - href={getEtherScanLink(type, value)} + href={getExplorerLink(type, value)} rel="noopener noreferrer" target="_blank" > diff --git a/src/config/index.ts b/src/config/index.ts index 929cbf1b38..ec5559716e 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,6 @@ import { checksumAddress } from 'src/utils/checksumAddress'; import { ensureOnce } from 'src/utils/singleton' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS } from 'src/logic/wallets/getWeb3' import { RELAY_API_URL, SIGNATURES_VIA_METAMASK, @@ -15,6 +15,8 @@ import mainnetDevConfig from './development-mainnet' import mainnetProdConfig from './production-mainnet' import mainnetStagingConfig from './staging-mainnet' +const DEFAULT_NETWORK = ETHEREUM_NETWORK.RINKEBY + const configuration = () => { if (process.env.NODE_ENV === 'test') { return testConfig @@ -37,13 +39,15 @@ const configuration = () => { : devConfig } -export const getNetwork = () => - process.env.REACT_APP_NETWORK === 'mainnet' - ? ETHEREUM_NETWORK.MAINNET - : ETHEREUM_NETWORK.RINKEBY +export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[process.env.REACT_APP_NETWORK.toUpperCase()] ?? DEFAULT_NETWORK + +export const getNetworkId = (): number => { + const findNetworkId = (networkName: string) => Object.keys(ETHEREUM_NETWORK_IDS).find( + key => ETHEREUM_NETWORK_IDS[key] === networkName.toUpperCase() + ) -export const getNetworkId = () => - process.env.REACT_APP_NETWORK === 'mainnet' ? 1 : 4 + return parseInt(findNetworkId(process.env.REACT_APP_NETWORK) ?? findNetworkId(DEFAULT_NETWORK)) +} const getConfig = ensureOnce(configuration) diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index c3c7b0f407..87a8730cae 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -8,14 +8,16 @@ import { ContentHash } from 'web3-eth-ens' import { provider as Provider } from 'web3-core' import { ProviderProps } from './store/model/provider' -export const ETHEREUM_NETWORK = { - MAINNET: 'MAINNET' as const, - MORDEN: 'MORDEN' as const, - ROPSTEN: 'ROPSTEN' as const, - RINKEBY: 'RINKEBY' as const, - GOERLI: 'GOERLI' as const, - KOVAN: 'KOVAN' as const, - UNKNOWN: 'UNKNOWN' as const, +export enum ETHEREUM_NETWORK { + MAINNET = 'MAINNET', + MORDEN = 'MORDEN', + ROPSTEN = 'ROPSTEN', + RINKEBY = 'RINKEBY', + GOERLI = 'GOERLI', + KOVAN = 'KOVAN', + UNKNOWN = 'UNKNOWN', + ENERGY_WEB_CHAIN = 'ENERGY_WEB_CHAIN', + VOLTA = 'VOLTA', } export type EthereumNetworks = typeof ETHEREUM_NETWORK[keyof typeof ETHEREUM_NETWORK] @@ -45,26 +47,59 @@ export const ETHEREUM_NETWORK_IDS = { 4: ETHEREUM_NETWORK.RINKEBY, 5: ETHEREUM_NETWORK.GOERLI, 42: ETHEREUM_NETWORK.KOVAN, + // $FlowFixMe + 246: ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, + // $FlowFixMe + 73799: ETHEREUM_NETWORK.VOLTA, } -export const getEtherScanLink = (type: string, value: string): string => { +export enum ExplorerTypes { + Tx = 'tx', + Address = 'address', +} + +export const getExplorerLink = (type: ExplorerTypes, value: string): string => { const network = getNetwork() - return `https://${ - network.toLowerCase() === 'mainnet' ? '' : `${network.toLowerCase()}.` - }etherscan.io/${type}/${value}` + + const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, value: string) => + `https://${network === ETHEREUM_NETWORK.MAINNET ? '' : `${network.toLowerCase()}.`}etherscan.io/${type}/${value}` + + switch (network) { + case ETHEREUM_NETWORK.MAINNET: + return getEtherScanLink(ETHEREUM_NETWORK.MAINNET, type, value) + case ETHEREUM_NETWORK.RINKEBY: + return getEtherScanLink(ETHEREUM_NETWORK.RINKEBY, type, value) + case ETHEREUM_NETWORK.ENERGY_WEB_CHAIN: + return 'https://explorer.energyweb.org' + case ETHEREUM_NETWORK.VOLTA: + return 'https://volta-explorer.energyweb.org' + default: + return getEtherScanLink(network, type, value) + } } -export const getInfuraUrl = (): string => { - const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' +export const getInfuraUrl = (networkName: string): string => { + const isMainnet = networkName.toUpperCase() === ETHEREUM_NETWORK.MAINNET return `https://${isMainnet ? 'mainnet' : 'rinkeby'}.infura.io:443/v3/${process.env.REACT_APP_INFURA_TOKEN}` } +export const RPC_URLS = { + [ETHEREUM_NETWORK.MAINNET]: getInfuraUrl(process.env.REACT_APP_NETWORK), + [ETHEREUM_NETWORK.MORDEN]: '', + [ETHEREUM_NETWORK.ROPSTEN]: '', + [ETHEREUM_NETWORK.RINKEBY]: getInfuraUrl(process.env.REACT_APP_NETWORK), + [ETHEREUM_NETWORK.GOERLI]: '', + [ETHEREUM_NETWORK.KOVAN]: '', + [ETHEREUM_NETWORK.ENERGY_WEB_CHAIN]: 'https://rpc.energyweb.org', + [ETHEREUM_NETWORK.VOLTA]: 'https://volta-rpc.energyweb.org', +} + // With some wallets from web3connect you have to use their provider instance only for signing // And our own one to fetch data export const web3ReadOnly = process.env.NODE_ENV !== 'test' - ? new Web3(new Web3.providers.HttpProvider(getInfuraUrl())) + ? new Web3(new Web3.providers.HttpProvider(getInfuraUrl(process.env.REACT_APP_NETWORK))) : new Web3(window.web3?.currentProvider || 'ws://localhost:8545') let web3 = web3ReadOnly diff --git a/src/logic/wallets/utils/walletList.ts b/src/logic/wallets/utils/walletList.ts index 70452f18b9..7944b24448 100644 --- a/src/logic/wallets/utils/walletList.ts +++ b/src/logic/wallets/utils/walletList.ts @@ -6,7 +6,7 @@ const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f // const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78' const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40' -const infuraUrl = getInfuraUrl() +const infuraUrl = getInfuraUrl(process.env.REACT_APP_NETWORK) const wallets = [ { walletName: 'metamask', preferred: true, desktop: false }, diff --git a/src/routes/opening/components/Footer.tsx b/src/routes/opening/components/Footer.tsx index 292000e375..9cce9819b2 100644 --- a/src/routes/opening/components/Footer.tsx +++ b/src/routes/opening/components/Footer.tsx @@ -2,7 +2,7 @@ import React, { SyntheticEvent } from 'react' import styled from 'styled-components' import Button from 'src/components/layout/Button' -import { getEtherScanLink } from 'src/logic/wallets/getWeb3' +import { getExplorerLink, ExplorerTypes } from 'src/logic/wallets/getWeb3' import { connected } from 'src/theme/variables' const EtherScanLink = styled.a` @@ -19,8 +19,8 @@ export const GenericFooter = ({ safeCreationTxHash }: { safeCreationTxHash: stri

Follow the progress on{' '} { const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const dispatch = useDispatch() - const etherScanLink = getEtherScanLink('address', safeAddress) + const etherScanLink = getExplorerLink(ExplorerTypes.Address, safeAddress) return ( Date: Tue, 23 Jun 2020 12:16:16 +0200 Subject: [PATCH 02/19] chore: Store network ID in the ETHEREUM_NETWORK enum itself --- .../Header/components/NetworkLabel.tsx | 6 +- .../ProviderDetails/UserDetails.tsx | 3 +- src/components/ConnectButton/index.tsx | 4 +- .../ProviderInfo/ProviderAccessible.tsx | 0 src/config/index.ts | 10 +-- src/logic/wallets/getWeb3.ts | 79 +++++++++---------- .../wallets/store/actions/fetchProvider.ts | 4 +- src/logic/wallets/store/model/provider.ts | 5 +- src/logic/wallets/store/selectors/index.ts | 10 ++- src/logic/wallets/utils/walletList.ts | 7 +- 10 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 src/components/Header/components/ProviderInfo/ProviderAccessible.tsx diff --git a/src/components/AppLayout/Header/components/NetworkLabel.tsx b/src/components/AppLayout/Header/components/NetworkLabel.tsx index 594c0ceef6..7d63134cfd 100644 --- a/src/components/AppLayout/Header/components/NetworkLabel.tsx +++ b/src/components/AppLayout/Header/components/NetworkLabel.tsx @@ -4,10 +4,11 @@ import * as React from 'react' import Col from 'src/components/layout/Col' import Paragraph from 'src/components/layout/Paragraph' import { getNetwork } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { border, md, screenSm, sm, xs } from 'src/theme/variables' -const interfaceNetwork = getNetwork() -const formatNetwork = (network: string): string => network[0].toUpperCase() + network.substring(1).toLowerCase() +const network = getNetwork() +const formattedNetwork = network[ETHEREUM_NETWORK.UNKNOWN]?.toUpperCase() //+ network.substring(1).toLowerCase() const useStyles = makeStyles({ container: { @@ -37,7 +38,6 @@ interface NetworkLabelProps { const NetworkLabel = ({ network = interfaceNetwork }: NetworkLabelProps): React.ReactElement => { const classes = useStyles() - const formattedNetwork = formatNetwork(network) return ( diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index 1319e05f9d..d22bf41aea 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -14,6 +14,7 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { background, connected as connectedBg, lg, md, sm, warning, xs } from 'src/theme/variables' import { upperFirst } from 'src/utils/css' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' const dot = require('../../assets/dotRinkeby.svg') const walletIcon = require('../../assets/wallet.svg') @@ -140,7 +141,7 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, Network - {upperFirst(network)} + {upperFirst(ETHEREUM_NETWORK[network])} diff --git a/src/components/ConnectButton/index.tsx b/src/components/ConnectButton/index.tsx index a719776f04..db81d05ce9 100644 --- a/src/components/ConnectButton/index.tsx +++ b/src/components/ConnectButton/index.tsx @@ -2,7 +2,7 @@ import Onboard from 'bnc-onboard' import React from 'react' import Button from 'src/components/layout/Button' -import { getNetworkId } from 'src/config' +import { getNetwork } from 'src/config' import { getWeb3, setWeb3 } from 'src/logic/wallets/getWeb3' import { fetchProvider } from 'src/logic/wallets/store/actions' import transactionDataCheck from 'src/logic/wallets/transactionDataCheck' @@ -20,7 +20,7 @@ const wallets = getSupportedWallets() export const onboard = Onboard({ dappId: BLOCKNATIVE_API_KEY, - networkId: getNetworkId(), + networkId: getNetwork(), subscriptions: { wallet: (wallet) => { if (wallet.provider) { diff --git a/src/components/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/Header/components/ProviderInfo/ProviderAccessible.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/config/index.ts b/src/config/index.ts index ec5559716e..7e277f3e98 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,6 @@ import { checksumAddress } from 'src/utils/checksumAddress'; import { ensureOnce } from 'src/utils/singleton' -import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { RELAY_API_URL, SIGNATURES_VIA_METAMASK, @@ -41,14 +41,6 @@ const configuration = () => { export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[process.env.REACT_APP_NETWORK.toUpperCase()] ?? DEFAULT_NETWORK -export const getNetworkId = (): number => { - const findNetworkId = (networkName: string) => Object.keys(ETHEREUM_NETWORK_IDS).find( - key => ETHEREUM_NETWORK_IDS[key] === networkName.toUpperCase() - ) - - return parseInt(findNetworkId(process.env.REACT_APP_NETWORK) ?? findNetworkId(DEFAULT_NETWORK)) -} - const getConfig = ensureOnce(configuration) export const getTxServiceHost = () => { diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index 87a8730cae..c82adb74d5 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -9,15 +9,15 @@ import { provider as Provider } from 'web3-core' import { ProviderProps } from './store/model/provider' export enum ETHEREUM_NETWORK { - MAINNET = 'MAINNET', - MORDEN = 'MORDEN', - ROPSTEN = 'ROPSTEN', - RINKEBY = 'RINKEBY', - GOERLI = 'GOERLI', - KOVAN = 'KOVAN', - UNKNOWN = 'UNKNOWN', - ENERGY_WEB_CHAIN = 'ENERGY_WEB_CHAIN', - VOLTA = 'VOLTA', + MAINNET = 1, + MORDEN = 2, + ROPSTEN = 3, + RINKEBY = 4, + GOERLI = 5, + KOVAN = 42, + ENERGY_WEB_CHAIN = 246, + VOLTA = 73799, + UNKNOWN = 0, } export type EthereumNetworks = typeof ETHEREUM_NETWORK[keyof typeof ETHEREUM_NETWORK] @@ -40,30 +40,19 @@ export const WALLET_PROVIDER = { TREZOR: 'TREZOR', } -export const ETHEREUM_NETWORK_IDS = { - 1: ETHEREUM_NETWORK.MAINNET, - 2: ETHEREUM_NETWORK.MORDEN, - 3: ETHEREUM_NETWORK.ROPSTEN, - 4: ETHEREUM_NETWORK.RINKEBY, - 5: ETHEREUM_NETWORK.GOERLI, - 42: ETHEREUM_NETWORK.KOVAN, - // $FlowFixMe - 246: ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, - // $FlowFixMe - 73799: ETHEREUM_NETWORK.VOLTA, -} - export enum ExplorerTypes { Tx = 'tx', Address = 'address', } +export const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, value: string): string => + `https://${ + network === ETHEREUM_NETWORK.MAINNET ? '' : `${network[network].toLowerCase()}.` + }etherscan.io/${type}/${value}` + export const getExplorerLink = (type: ExplorerTypes, value: string): string => { const network = getNetwork() - const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, value: string) => - `https://${network === ETHEREUM_NETWORK.MAINNET ? '' : `${network.toLowerCase()}.`}etherscan.io/${type}/${value}` - switch (network) { case ETHEREUM_NETWORK.MAINNET: return getEtherScanLink(ETHEREUM_NETWORK.MAINNET, type, value) @@ -78,29 +67,35 @@ export const getExplorerLink = (type: ExplorerTypes, value: string): string => { } } -export const getInfuraUrl = (networkName: string): string => { - const isMainnet = networkName.toUpperCase() === ETHEREUM_NETWORK.MAINNET +export const getInfuraUrl = (network: ETHEREUM_NETWORK): string => + `https://${network === ETHEREUM_NETWORK.MAINNET ? 'mainnet' : 'rinkeby'}.infura.io:443/v3/${ + process.env.REACT_APP_INFURA_TOKEN + }` - return `https://${isMainnet ? 'mainnet' : 'rinkeby'}.infura.io:443/v3/${process.env.REACT_APP_INFURA_TOKEN}` -} - -export const RPC_URLS = { - [ETHEREUM_NETWORK.MAINNET]: getInfuraUrl(process.env.REACT_APP_NETWORK), - [ETHEREUM_NETWORK.MORDEN]: '', - [ETHEREUM_NETWORK.ROPSTEN]: '', - [ETHEREUM_NETWORK.RINKEBY]: getInfuraUrl(process.env.REACT_APP_NETWORK), - [ETHEREUM_NETWORK.GOERLI]: '', - [ETHEREUM_NETWORK.KOVAN]: '', - [ETHEREUM_NETWORK.ENERGY_WEB_CHAIN]: 'https://rpc.energyweb.org', - [ETHEREUM_NETWORK.VOLTA]: 'https://volta-rpc.energyweb.org', +export const getRPCUrl = (network: ETHEREUM_NETWORK): string => { + switch (network) { + case ETHEREUM_NETWORK.MAINNET: + return getInfuraUrl(network) + case ETHEREUM_NETWORK.RINKEBY: + return getInfuraUrl(network) + case ETHEREUM_NETWORK.ENERGY_WEB_CHAIN: + return 'https://rpc.energyweb.org' + case ETHEREUM_NETWORK.VOLTA: + return 'https://volta-rpc.energyweb.org' + default: + return '' + } } // With some wallets from web3connect you have to use their provider instance only for signing // And our own one to fetch data -export const web3ReadOnly = +export const web3ReadOnly = new Web3( process.env.NODE_ENV !== 'test' - ? new Web3(new Web3.providers.HttpProvider(getInfuraUrl(process.env.REACT_APP_NETWORK))) - : new Web3(window.web3?.currentProvider || 'ws://localhost:8545') + ? new Web3.providers.HttpProvider( + getRPCUrl(ETHEREUM_NETWORK[process.env.REACT_APP_NETWORK.toUpperCase()] ?? ETHEREUM_NETWORK.RINKEBY), + ) + : window.web3?.currentProvider || 'ws://localhost:8545', +) let web3 = web3ReadOnly export const getWeb3 = (): Web3 => web3 diff --git a/src/logic/wallets/store/actions/fetchProvider.ts b/src/logic/wallets/store/actions/fetchProvider.ts index 3a7573fcd4..9e2390fdaa 100644 --- a/src/logic/wallets/store/actions/fetchProvider.ts +++ b/src/logic/wallets/store/actions/fetchProvider.ts @@ -5,7 +5,7 @@ import addProvider from './addProvider' import { getNetwork } from 'src/config' import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications' import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS, getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK, 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' import { Dispatch } from 'redux' @@ -24,7 +24,7 @@ const handleProviderNotification = (provider, dispatch) => { return } - if (ETHEREUM_NETWORK_IDS[network] !== getNetwork()) { + if (network !== getNetwork()) { dispatch(enqueueSnackbar(NOTIFICATIONS.WRONG_NETWORK_MSG)) return } diff --git a/src/logic/wallets/store/model/provider.ts b/src/logic/wallets/store/model/provider.ts index 1e8ad09af1..dd7c4c389a 100644 --- a/src/logic/wallets/store/model/provider.ts +++ b/src/logic/wallets/store/model/provider.ts @@ -1,11 +1,12 @@ import { Record, RecordOf } from 'immutable' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' export type ProviderProps = { name: string loaded: boolean available: boolean account: string - network: number + network: ETHEREUM_NETWORK smartContractWallet: boolean hardwareWallet: boolean } @@ -15,7 +16,7 @@ export const makeProvider = Record({ loaded: false, available: false, account: '', - network: 0, + network: ETHEREUM_NETWORK.UNKNOWN, smartContractWallet: false, hardwareWallet: false, }) diff --git a/src/logic/wallets/store/selectors/index.ts b/src/logic/wallets/store/selectors/index.ts index ed147c3859..78b23730d3 100644 --- a/src/logic/wallets/store/selectors/index.ts +++ b/src/logic/wallets/store/selectors/index.ts @@ -1,6 +1,7 @@ import { createSelector } from 'reselect' -import { ETHEREUM_NETWORK, ETHEREUM_NETWORK_IDS, EthereumNetworks } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK, EthereumNetworks } from 'src/logic/wallets/getWeb3' import { PROVIDER_REDUCER_ID, ProviderState } from 'src/logic/wallets/store/reducer/provider' import { AppReduxState } from 'src/store' @@ -16,14 +17,19 @@ export const providerNameSelector = createSelector(providerSelector, (provider: return name ? name.toLowerCase() : undefined }) +export const networkSelector = createSelector(providerSelector, (provider) => { export const networkSelector = createSelector( providerSelector, (provider: ProviderState): EthereumNetworks => { const networkId = provider.get('network') - return ETHEREUM_NETWORK_IDS[networkId] || ETHEREUM_NETWORK.UNKNOWN + + return networkId ?? ETHEREUM_NETWORK.UNKNOWN }, ) + return networkId ?? ETHEREUM_NETWORK.UNKNOWN +}) + export const loadedSelector = createSelector(providerSelector, (provider: ProviderState): boolean => provider.get('loaded'), ) diff --git a/src/logic/wallets/utils/walletList.ts b/src/logic/wallets/utils/walletList.ts index 7944b24448..0921a76ae9 100644 --- a/src/logic/wallets/utils/walletList.ts +++ b/src/logic/wallets/utils/walletList.ts @@ -1,4 +1,5 @@ -import { getInfuraUrl } from '../getWeb3' +import { getInfuraUrl, getRPCUrl } from '../getWeb3' +import { getNetwork } from 'src/config' const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' @@ -6,7 +7,8 @@ const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f // const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78' const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40' -const infuraUrl = getInfuraUrl(process.env.REACT_APP_NETWORK) +const network = getNetwork() +const infuraUrl = getInfuraUrl(network) const wallets = [ { walletName: 'metamask', preferred: true, desktop: false }, @@ -14,6 +16,7 @@ const wallets = [ walletName: 'walletConnect', preferred: true, infuraKey: process.env.REACT_APP_INFURA_TOKEN, + rpc: { [network]: getRPCUrl(network) }, desktop: true, bridge: 'https://safe-walletconnect.gnosis.io/', }, From a2491fe9c01a87b8a737062c87323331a07310fa Mon Sep 17 00:00:00 2001 From: JosephBagaric Date: Tue, 23 Jun 2020 14:28:52 +0200 Subject: [PATCH 03/19] chore: forward tx and address to non-etherscan explorers --- src/logic/wallets/getWeb3.ts | 4 ++-- src/routes/opening/components/Footer.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index c82adb74d5..3e8ad5ffff 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -59,9 +59,9 @@ export const getExplorerLink = (type: ExplorerTypes, value: string): string => { case ETHEREUM_NETWORK.RINKEBY: return getEtherScanLink(ETHEREUM_NETWORK.RINKEBY, type, value) case ETHEREUM_NETWORK.ENERGY_WEB_CHAIN: - return 'https://explorer.energyweb.org' + return `https://explorer.energyweb.org/${type}/${value}` case ETHEREUM_NETWORK.VOLTA: - return 'https://volta-explorer.energyweb.org' + return `https://volta-explorer.energyweb.org/${type}/${value}` default: return getEtherScanLink(network, type, value) } diff --git a/src/routes/opening/components/Footer.tsx b/src/routes/opening/components/Footer.tsx index 9cce9819b2..bd531c1edb 100644 --- a/src/routes/opening/components/Footer.tsx +++ b/src/routes/opening/components/Footer.tsx @@ -19,7 +19,7 @@ export const GenericFooter = ({ safeCreationTxHash }: { safeCreationTxHash: stri

Follow the progress on{' '} Date: Tue, 29 Sep 2020 20:33:48 -0300 Subject: [PATCH 04/19] fixes after rebase --- src/components/AddressInfo/index.tsx | 5 ++-- src/components/App/ReceiveModal.tsx | 3 +- .../Header/components/NetworkLabel.tsx | 8 +++-- .../ProviderInfo/ProviderAccessible.tsx | 3 +- .../AppLayout/Sidebar/SafeHeader/index.tsx | 3 +- src/components/EtherscanBtn/index.tsx | 4 +-- src/components/EtherscanLink/index.tsx | 3 +- .../ProviderInfo/ProviderAccessible.tsx | 0 src/config/index.ts | 3 +- src/logic/collectibles/sources/OpenSea.ts | 2 +- src/logic/wallets/getWeb3.ts | 7 ++--- src/logic/wallets/store/selectors/index.ts | 5 ---- .../load/components/OwnerList/index.tsx | 21 ++++++------- .../components/ReviewInformation/index.tsx | 7 +++-- src/routes/load/container/Load.tsx | 8 ++++- .../components/ReviewInformation/index.tsx | 10 +++---- .../Apps/hooks/useIframeMessageHandler.ts | 3 +- src/routes/safe/components/Apps/index.tsx | 5 ++-- .../ReviewCustomTx/index.tsx | 16 +++++----- .../SendCustomTx/index.tsx | 23 +++++++------- .../screens/ReviewCollectible/index.tsx | 16 +++++----- .../SendModal/screens/ReviewTx/index.tsx | 18 +++++------ .../screens/SendCollectible/index.tsx | 17 ++++++----- .../SendModal/screens/SendFunds/index.tsx | 17 ++++++----- .../Settings/Advanced/RemoveModuleModal.tsx | 30 +++++++++---------- .../AddOwnerModal/screens/Review/index.tsx | 12 ++++---- .../ManageOwners/EditOwnerModal/index.tsx | 15 +++++----- .../OwnerAddressTableCell/index.tsx | 7 +++-- .../screens/CheckOwner/index.tsx | 7 +++-- .../RemoveOwnerModal/screens/Review/index.tsx | 14 ++++----- .../screens/OwnerForm/index.tsx | 11 +++---- .../screens/Review/index.tsx | 18 +++++------ .../IncomingTxDescription/index.tsx | 3 +- .../TxDescription/SettingsDescription.tsx | 19 ++++++------ .../TxDescription/TransferDescription.tsx | 11 +++---- src/utils/constants.ts | 4 +-- 36 files changed, 189 insertions(+), 169 deletions(-) delete mode 100644 src/components/Header/components/ProviderInfo/ProviderAccessible.tsx diff --git a/src/components/AddressInfo/index.tsx b/src/components/AddressInfo/index.tsx index efd40e50e0..44aba892f9 100644 --- a/src/components/AddressInfo/index.tsx +++ b/src/components/AddressInfo/index.tsx @@ -1,5 +1,4 @@ import React from 'react' -import styled from 'styled-components' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -7,7 +6,9 @@ import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' import Bold from 'src/components/layout/Bold' import Paragraph from 'src/components/layout/Paragraph' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { border, xs } from 'src/theme/variables' +import styled from 'styled-components' const Wrapper = styled.div` display: flex; @@ -59,7 +60,7 @@ const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactE {safeAddress} - + {ethBalance && ( diff --git a/src/components/App/ReceiveModal.tsx b/src/components/App/ReceiveModal.tsx index 535a50bd7f..6aa6c4d575 100644 --- a/src/components/App/ReceiveModal.tsx +++ b/src/components/App/ReceiveModal.tsx @@ -13,6 +13,7 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { lg, md, screenSm, secondaryText, sm } from 'src/theme/variables' import { copyToClipboard } from 'src/utils/clipboard' @@ -115,7 +116,7 @@ const ReceiveModal = ({ onClose, safeAddress, safeName }: Props) => { {safeAddress} - + diff --git a/src/components/AppLayout/Header/components/NetworkLabel.tsx b/src/components/AppLayout/Header/components/NetworkLabel.tsx index 7d63134cfd..2ff24a5a73 100644 --- a/src/components/AppLayout/Header/components/NetworkLabel.tsx +++ b/src/components/AppLayout/Header/components/NetworkLabel.tsx @@ -7,8 +7,9 @@ import { getNetwork } from 'src/config' import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { border, md, screenSm, sm, xs } from 'src/theme/variables' -const network = getNetwork() -const formattedNetwork = network[ETHEREUM_NETWORK.UNKNOWN]?.toUpperCase() //+ network.substring(1).toLowerCase() +const interfaceNetwork = getNetwork() +const formatNetwork = (network: number): string => + ETHEREUM_NETWORK[network][0].toUpperCase() + ETHEREUM_NETWORK[network].substring(1).toLowerCase() const useStyles = makeStyles({ container: { @@ -33,11 +34,12 @@ const useStyles = makeStyles({ }) interface NetworkLabelProps { - network?: string + network?: number } const NetworkLabel = ({ network = interfaceNetwork }: NetworkLabelProps): React.ReactElement => { const classes = useStyles() + const formattedNetwork = formatNetwork(network) return ( diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index 07989c052a..3d2e0912c7 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -62,7 +62,8 @@ const useStyles = makeStyles({ interface ProviderInfoProps { connected: boolean provider: string - network: string + // TODO: [xDai] Review. This may cause some issues with EthHashInfo. + network: number userAddress: string } diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index 9d3c2f3f6f..273a1476b2 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -1,4 +1,5 @@ import React from 'react' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { Icon, @@ -128,7 +129,7 @@ const SafeHeader = ({ - + {granted ? null : ( diff --git a/src/components/EtherscanBtn/index.tsx b/src/components/EtherscanBtn/index.tsx index 5a987e82d4..294e8473b0 100644 --- a/src/components/EtherscanBtn/index.tsx +++ b/src/components/EtherscanBtn/index.tsx @@ -6,7 +6,7 @@ import React from 'react' import EtherscanOpenIcon from './img/etherscan-open.svg' import Img from 'src/components/layout/Img' -import { getExplorerLink } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getExplorerLink } from 'src/logic/wallets/getWeb3' import { xs } from 'src/theme/variables' const useStyles = makeStyles({ @@ -30,7 +30,7 @@ const useStyles = makeStyles({ interface EtherscanBtnProps { className?: string increaseZindex?: boolean - type: 'tx' | 'address' + type: ExplorerTypes value: string } diff --git a/src/components/EtherscanLink/index.tsx b/src/components/EtherscanLink/index.tsx index fe33a953d2..59585b9ee7 100644 --- a/src/components/EtherscanLink/index.tsx +++ b/src/components/EtherscanLink/index.tsx @@ -1,6 +1,7 @@ import { makeStyles } from '@material-ui/core/styles' import cn from 'classnames' import React from 'react' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -17,7 +18,7 @@ interface EtherscanLinkProps { className?: string cut?: number knownAddress?: boolean - type: 'tx' | 'address' + type: ExplorerTypes value: string } diff --git a/src/components/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/Header/components/ProviderInfo/ProviderAccessible.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/config/index.ts b/src/config/index.ts index 7e277f3e98..d34123508a 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -14,6 +14,7 @@ import prodConfig from './production' import mainnetDevConfig from './development-mainnet' import mainnetProdConfig from './production-mainnet' import mainnetStagingConfig from './staging-mainnet' +import { NETWORK } from 'src/utils/constants'; const DEFAULT_NETWORK = ETHEREUM_NETWORK.RINKEBY @@ -39,7 +40,7 @@ const configuration = () => { : devConfig } -export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[process.env.REACT_APP_NETWORK.toUpperCase()] ?? DEFAULT_NETWORK +export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] ?? DEFAULT_NETWORK const getConfig = ensureOnce(configuration) diff --git a/src/logic/collectibles/sources/OpenSea.ts b/src/logic/collectibles/sources/OpenSea.ts index d626e82531..2175ec59af 100644 --- a/src/logic/collectibles/sources/OpenSea.ts +++ b/src/logic/collectibles/sources/OpenSea.ts @@ -136,7 +136,7 @@ class OpenSea { * @param {string} network * @returns {Promise} */ - async fetchAllUserCollectiblesByCategoryAsync(safeAddress: string, network: string): Promise { + async fetchAllUserCollectiblesByCategoryAsync(safeAddress: string, network: ETHEREUM_NETWORK): Promise { // eslint-disable-next-line no-underscore-dangle const metadataSourceUrl = this._endpointsUrls[network] const url = `${metadataSourceUrl}/assets/?owner=${safeAddress}` diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index 3e8ad5ffff..a67f1da2a8 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -1,9 +1,10 @@ +import { NETWORK } from 'src/utils/constants' import Web3 from 'web3' import { sameAddress } from './ethAddresses' import { EMPTY_DATA } from './ethTransactions' -import { getNetwork } from '../../config' +import { getNetwork } from 'src/config' import { ContentHash } from 'web3-eth-ens' import { provider as Provider } from 'web3-core' import { ProviderProps } from './store/model/provider' @@ -91,9 +92,7 @@ export const getRPCUrl = (network: ETHEREUM_NETWORK): string => { // And our own one to fetch data export const web3ReadOnly = new Web3( process.env.NODE_ENV !== 'test' - ? new Web3.providers.HttpProvider( - getRPCUrl(ETHEREUM_NETWORK[process.env.REACT_APP_NETWORK.toUpperCase()] ?? ETHEREUM_NETWORK.RINKEBY), - ) + ? new Web3.providers.HttpProvider(getRPCUrl(ETHEREUM_NETWORK[NETWORK] ?? ETHEREUM_NETWORK.RINKEBY)) : window.web3?.currentProvider || 'ws://localhost:8545', ) diff --git a/src/logic/wallets/store/selectors/index.ts b/src/logic/wallets/store/selectors/index.ts index 78b23730d3..3bc5d4cf51 100644 --- a/src/logic/wallets/store/selectors/index.ts +++ b/src/logic/wallets/store/selectors/index.ts @@ -1,6 +1,5 @@ import { createSelector } from 'reselect' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { ETHEREUM_NETWORK, EthereumNetworks } from 'src/logic/wallets/getWeb3' import { PROVIDER_REDUCER_ID, ProviderState } from 'src/logic/wallets/store/reducer/provider' import { AppReduxState } from 'src/store' @@ -17,7 +16,6 @@ export const providerNameSelector = createSelector(providerSelector, (provider: return name ? name.toLowerCase() : undefined }) -export const networkSelector = createSelector(providerSelector, (provider) => { export const networkSelector = createSelector( providerSelector, (provider: ProviderState): EthereumNetworks => { @@ -27,9 +25,6 @@ export const networkSelector = createSelector( }, ) - return networkId ?? ETHEREUM_NETWORK.UNKNOWN -}) - export const loadedSelector = createSelector(providerSelector, (provider: ProviderState): boolean => provider.get('loaded'), ) diff --git a/src/routes/load/components/OwnerList/index.tsx b/src/routes/load/components/OwnerList/index.tsx index a172328f4d..a7919100b1 100644 --- a/src/routes/load/components/OwnerList/index.tsx +++ b/src/routes/load/components/OwnerList/index.tsx @@ -1,28 +1,29 @@ -import TableContainer from '@material-ui/core/TableContainer' import { makeStyles } from '@material-ui/core/styles' +import TableContainer from '@material-ui/core/TableContainer' import React, { useEffect, useState } from 'react' +import { useSelector } from 'react-redux' + import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import OpenPaper from 'src/components/Stepper/OpenPaper' import Field from 'src/components/forms/Field' import TextField from 'src/components/forms/TextField' import { composeValidators, minMaxLength, required } from 'src/components/forms/validator' +import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' 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 { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' -import { FIELD_LOAD_ADDRESS, THRESHOLD } from 'src/routes/load/components/fields' -import { getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields' - -import { useSelector } from 'react-redux' +import OpenPaper from 'src/components/Stepper/OpenPaper' +import { AddressBookEntry } from 'src/logic/addressBook/model/addressBook' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { formatAddressListToAddressBookNames } from 'src/logic/addressBook/utils' -import { AddressBookEntry } from 'src/logic/addressBook/model/addressBook' +import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' +import { FIELD_LOAD_ADDRESS, THRESHOLD } from 'src/routes/load/components/fields' +import { getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields' import { styles } from './styles' const calculateSafeValues = (owners, threshold, values) => { @@ -112,7 +113,7 @@ const OwnerListComponent = (props) => { {address} - + diff --git a/src/routes/load/components/ReviewInformation/index.tsx b/src/routes/load/components/ReviewInformation/index.tsx index 49a7588f9e..7c728bcf04 100644 --- a/src/routes/load/components/ReviewInformation/index.tsx +++ b/src/routes/load/components/ReviewInformation/index.tsx @@ -5,13 +5,14 @@ import React from 'react' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' -import OpenPaper from 'src/components/Stepper/OpenPaper' import Block from 'src/components/layout/Block' 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 OpenPaper from 'src/components/Stepper/OpenPaper' import { shortVersionOf } from 'src/logic/wallets/ethAddresses' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME, THRESHOLD } from 'src/routes/load/components/fields' import { getNumOwnersFrom, getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields' import { getAccountsFrom } from 'src/routes/open/utils/safeDataExtractor' @@ -76,7 +77,7 @@ const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => {shortVersionOf(safeAddress, 4)} - + @@ -121,7 +122,7 @@ const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => {address} - + diff --git a/src/routes/load/container/Load.tsx b/src/routes/load/container/Load.tsx index a3452bfd1e..efa6ba79ca 100644 --- a/src/routes/load/container/Load.tsx +++ b/src/routes/load/container/Load.tsx @@ -1,5 +1,6 @@ import * as React from 'react' import { useDispatch, useSelector } from 'react-redux' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import Layout from 'src/routes/load/components/Layout' import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME } from '../components/fields' @@ -77,7 +78,12 @@ const Load = (): React.ReactElement => { return ( - + ) } diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index c5d6c4c1ce..f76792b79b 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -2,21 +2,21 @@ import TableContainer from '@material-ui/core/TableContainer' import classNames from 'classnames' import React, { useEffect, useState } from 'react' -import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' -import OpenPaper from 'src/components/Stepper/OpenPaper' import Block from 'src/components/layout/Block' 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 OpenPaper from 'src/components/Stepper/OpenPaper' import { estimateGasForDeployingSafe } from 'src/logic/contracts/safeContracts' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' import { getAccountsFrom, getNamesFrom } from 'src/routes/open/utils/safeDataExtractor' + +import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' import { useStyles } from './styles' type ReviewComponentProps = { @@ -118,7 +118,7 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { {addresses[index]} - + diff --git a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts index a1a0e69523..590402807b 100644 --- a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts +++ b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts @@ -18,6 +18,7 @@ import { safeNameSelector, safeParamAddressFromStateSelector, } from 'src/logic/safe/store/selectors' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { networkSelector } from 'src/logic/wallets/store/selectors' import { SafeApp } from 'src/routes/safe/components/Apps/types.d' @@ -90,7 +91,7 @@ const useIframeMessageHandler = ( messageId: INTERFACE_MESSAGES.ON_SAFE_INFO, data: { safeAddress: safeAddress as string, - network: network.toLowerCase() as LowercaseNetworks, + network: ETHEREUM_NETWORK[network].toLowerCase() as LowercaseNetworks, ethBalance: ethBalance as string, }, } diff --git a/src/routes/safe/components/Apps/index.tsx b/src/routes/safe/components/Apps/index.tsx index d34d8dd4db..9de471bdac 100644 --- a/src/routes/safe/components/Apps/index.tsx +++ b/src/routes/safe/components/Apps/index.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react' import { INTERFACE_MESSAGES, Transaction, RequestId, LowercaseNetworks } from '@gnosis.pm/safe-apps-sdk' import { Card, IconText, Loader, Menu, Title } from '@gnosis.pm/safe-react-components' import { useSelector } from 'react-redux' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled, { css } from 'styled-components' import ManageApps from './components/ManageApps' @@ -155,7 +156,7 @@ const Apps = (): React.ReactElement => { messageId: INTERFACE_MESSAGES.ON_SAFE_INFO, data: { safeAddress: safeAddress as string, - network: network.toLowerCase() as LowercaseNetworks, + network: ETHEREUM_NETWORK[network].toLowerCase() as LowercaseNetworks, ethBalance: ethBalance as string, }, }) @@ -185,7 +186,7 @@ const Apps = (): React.ReactElement => { granted={granted} selectedApp={selectedApp} safeAddress={safeAddress} - network={network} + network={ETHEREUM_NETWORK[network]} appIsLoading={appIsLoading} onIframeLoad={handleIframeLoad} /> diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index b47b8f2f97..4b8129ee4b 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -4,10 +4,6 @@ import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import ArrowDown from '../../assets/arrow-down.svg' - -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -18,17 +14,21 @@ 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 createTransaction from 'src/logic/safe/store/actions/createTransaction' +import { safeSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' -import { getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' -import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' import { sm } from 'src/theme/variables' +import ArrowDown from '../../assets/arrow-down.svg' + +import { styles } from './style' + type Props = { onClose: () => void onPrev: () => void @@ -122,7 +122,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { {tx.contractAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx index 99bbd1008f..e53bca0d60 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx @@ -1,25 +1,20 @@ import IconButton from '@material-ui/core/IconButton' import InputAdornment from '@material-ui/core/InputAdornment' -import Switch from '@material-ui/core/Switch' import { makeStyles } from '@material-ui/core/styles' +import Switch from '@material-ui/core/Switch' import Close from '@material-ui/icons/Close' import React, { useState } from 'react' import { useSelector } from 'react-redux' -import ArrowDown from '../../assets/arrow-down.svg' - -import { styles } from './style' - import QRIcon from 'src/assets/icons/qrcode.svg' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import ScanQRModal from 'src/components/ScanQRModal' import Field from 'src/components/forms/Field' import GnoForm from 'src/components/forms/GnoForm' -import TextField from 'src/components/forms/TextField' import TextareaField from 'src/components/forms/TextareaField' -import { composeValidators, maxValue, mustBeFloat, minValue } from 'src/components/forms/validator' +import TextField from 'src/components/forms/TextField' +import { composeValidators, maxValue, minValue, mustBeFloat } from 'src/components/forms/validator' +import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' import ButtonLink from 'src/components/layout/ButtonLink' @@ -28,11 +23,17 @@ 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 ScanQRModal from 'src/components/ScanQRModal' +import { safeSelector } from 'src/logic/safe/store/selectors' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' -import { safeSelector } from 'src/logic/safe/store/selectors' import { sm } from 'src/theme/variables' +import ArrowDown from '../../assets/arrow-down.svg' + +import { styles } from './style' + export interface CreatedTx { contractAddress: string data: string @@ -177,7 +178,7 @@ const SendCustomTx: React.FC = ({ initialValues, onClose, onNext, contrac - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index 1b7cb68d8b..b9783e58a3 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -5,10 +5,6 @@ import { withSnackbar } from 'notistack' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import ArrowDown from '../assets/arrow-down.svg' - -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -20,6 +16,8 @@ import Img from 'src/components/layout/Img' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { nftTokensSelector } from 'src/logic/collectibles/store/selectors' +import createTransaction from 'src/logic/safe/store/actions/createTransaction' +import { safeSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { @@ -29,14 +27,16 @@ import { } from 'src/logic/tokens/store/actions/fetchTokens' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH } from 'src/logic/tokens/utils/tokenHelpers' -import { getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' -import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' import { sm } from 'src/theme/variables' import { textShortener } from 'src/utils/strings' +import ArrowDown from '../assets/arrow-down.svg' + +import { styles } from './style' + const useStyles = makeStyles(styles as any) const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { @@ -135,7 +135,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx {tx.recipientAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx index 0ee764bbe5..0fe167da22 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -3,13 +3,9 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import { BigNumber } from 'bignumber.js' import { withSnackbar } from 'notistack' -import React, { useEffect, useState, useMemo } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import ArrowDown from '../assets/arrow-down.svg' - -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -20,20 +16,24 @@ 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 createTransaction from 'src/logic/safe/store/actions/createTransaction' +import { safeSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchTokens' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { ETH_ADDRESS } from 'src/logic/tokens/utils/tokenHelpers' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { getWeb3 } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { extendedSafeTokensSelector } from 'src/routes/safe/container/selector' -import createTransaction from 'src/logic/safe/store/actions/createTransaction' -import { safeSelector } from 'src/logic/safe/store/selectors' import { sm } from 'src/theme/variables' +import ArrowDown from '../assets/arrow-down.svg' + +import { styles } from './style' + const useStyles = makeStyles(styles as any) const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { @@ -149,7 +149,7 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { {tx.recipientAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx index 14c54f06cb..22ca6d03ca 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx @@ -4,31 +4,32 @@ import Close from '@material-ui/icons/Close' import React, { useState } from 'react' import { useSelector } from 'react-redux' -import ArrowDown from '../assets/arrow-down.svg' - -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' -import WhenFieldChanges from 'src/components/WhenFieldChanges' import GnoForm from 'src/components/forms/GnoForm' +import Identicon from 'src/components/Identicon' 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 Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' +import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' +import WhenFieldChanges from 'src/components/WhenFieldChanges' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { getNameFromAddressBook } from 'src/logic/addressBook/utils' import { nftTokensSelector, safeActiveSelectorMap } from 'src/logic/collectibles/store/selectors' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' import CollectibleSelectField from 'src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField' import TokenSelectField from 'src/routes/safe/components/Balances/SendModal/screens/SendCollectible/TokenSelectField' import { sm } from 'src/theme/variables' +import ArrowDown from '../assets/arrow-down.svg' + +import { styles } from './style' + const formMutators = { setMax: (args, state, utils) => { utils.changeValue(state, 'amount', () => args[0]) @@ -171,7 +172,7 @@ const SendCollectible = ({ - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx index 27db52e9e4..4d1ea8e3b1 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx @@ -6,18 +6,13 @@ import React, { useState } from 'react' import { OnChange } from 'react-final-form-listeners' import { useSelector } from 'react-redux' -import ArrowDown from '../assets/arrow-down.svg' - -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import Field from 'src/components/forms/Field' import GnoForm from 'src/components/forms/GnoForm' import TextField from 'src/components/forms/TextField' -import { composeValidators, minValue, maxValue, mustBeFloat, required } from 'src/components/forms/validator' +import { composeValidators, maxValue, minValue, mustBeFloat, required } from 'src/components/forms/validator' +import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' import ButtonLink from 'src/components/layout/ButtonLink' @@ -25,8 +20,10 @@ 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 { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { getNameFromAddressBook } from 'src/logic/addressBook/utils' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' @@ -34,6 +31,10 @@ import TokenSelectField from 'src/routes/safe/components/Balances/SendModal/scre import { extendedSafeTokensSelector } from 'src/routes/safe/container/selector' import { sm } from 'src/theme/variables' +import ArrowDown from '../assets/arrow-down.svg' + +import { styles } from './style' + const formMutators = { setMax: (args, state, utils) => { utils.changeValue(state, 'amount', () => args[0]) @@ -184,7 +185,7 @@ const SendFunds = ({ - + diff --git a/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx b/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx index e630c45d5f..9b33f83324 100644 --- a/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx +++ b/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx @@ -6,25 +6,25 @@ import OpenInNew from '@material-ui/icons/OpenInNew' import cn from 'classnames' import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import styled from 'styled-components' - -import { styles } from './style' +import Identicon from 'src/components/Identicon' +import Block from 'src/components/layout/Block' +import Col from 'src/components/layout/Col' +import Hairline from 'src/components/layout/Hairline' +import Link from 'src/components/layout/Link' +import Paragraph from 'src/components/layout/Paragraph' +import Row from 'src/components/layout/Row' +import Modal from 'src/components/Modal' +import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' +import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { ModulePair } from 'src/logic/safe/store/models/safe' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' -import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import Modal from 'src/components/Modal' -import Row from 'src/components/layout/Row' -import Paragraph from 'src/components/layout/Paragraph' -import Hairline from 'src/components/layout/Hairline' -import Block from 'src/components/layout/Block' -import Col from 'src/components/layout/Col' -import Identicon from 'src/components/Identicon' -import Link from 'src/components/layout/Link' -import { getEtherScanLink } from 'src/logic/wallets/getWeb3' +import { ExplorerTypes, getExplorerLink } from 'src/logic/wallets/getWeb3' import { md, secondary } from 'src/theme/variables' +import styled from 'styled-components' + +import { styles } from './style' const useStyles = makeStyles(styles) @@ -104,7 +104,7 @@ const RemoveModuleModal = ({ onClose, selectedModule }: RemoveModuleModal): Reac diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index dde8e118dc..cd5a6cb9ac 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -5,8 +5,6 @@ import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -17,10 +15,12 @@ import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' +import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' -import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' + +import { styles } from './style' export const ADD_OWNER_SUBMIT_BTN_TEST_ID = 'add-owner-submit-btn' @@ -118,7 +118,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => {owner.address} - + @@ -146,7 +146,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => {values.ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx index 7f6fbec5fc..1d0794ea9c 100644 --- a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx @@ -4,28 +4,29 @@ import Close from '@material-ui/icons/Close' import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import Modal from 'src/components/Modal' import Field from 'src/components/forms/Field' import GnoForm from 'src/components/forms/GnoForm' import TextField from 'src/components/forms/TextField' import { composeValidators, minMaxLength, required } from 'src/components/forms/validator' +import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' 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 Modal from 'src/components/Modal' import { makeAddressBookEntry } from 'src/logic/addressBook/model/addressBook' +import { addOrUpdateAddressBookEntry } from 'src/logic/addressBook/store/actions/addOrUpdateAddressBookEntry' import { NOTIFICATIONS } from 'src/logic/notifications' +import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' import editSafeOwner from 'src/logic/safe/store/actions/editSafeOwner' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { sm } from 'src/theme/variables' -import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { addOrUpdateAddressBookEntry } from 'src/logic/addressBook/store/actions/addOrUpdateAddressBookEntry' + +import { styles } from './style' export const RENAME_OWNER_INPUT_TEST_ID = 'rename-owner-input' export const SAVE_OWNER_CHANGES_BTN_TEST_ID = 'save-owner-changes-btn' @@ -93,7 +94,7 @@ const EditOwnerComponent = ({ isOpen, onClose, ownerAddress, selectedOwnerName } {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx index 13313a5496..4bd3d8d22e 100644 --- a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx @@ -1,12 +1,13 @@ import * as React from 'react' +import { useEffect, useState } from 'react' import EtherScanLink from 'src/components/EtherscanLink' import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' import Paragraph from 'src/components/layout/Paragraph' -import { useWindowDimensions } from 'src/logic/hooks/useWindowDimensions' -import { useEffect, useState } from 'react' import { getValidAddressBookName } from 'src/logic/addressBook/utils' +import { useWindowDimensions } from 'src/logic/hooks/useWindowDimensions' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' type OwnerAddressTableCellProps = { address: string @@ -36,7 +37,7 @@ const OwnerAddressTableCell = (props: OwnerAddressTableCellProps): React.ReactEl {showLinks ? (

{userName && getValidAddressBookName(userName)} - +
) : ( {address} diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx index eb2853abd1..f3ab823304 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx @@ -4,8 +4,6 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames/bind' import React from 'react' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -15,6 +13,9 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' + +import { styles } from './style' export const REMOVE_OWNER_MODAL_NEXT_BTN_TEST_ID = 'remove-owner-next-btn' @@ -53,7 +54,7 @@ const CheckOwner = ({ classes, onClose, onSubmit, ownerAddress, ownerName }) => {ownerAddress} - + 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 8328f9399e..f10e362041 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 @@ -5,8 +5,6 @@ import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -16,11 +14,13 @@ 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 { SENTINEL_ADDRESS, getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' +import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts' +import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' -import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' + +import { styles } from './style' export const REMOVE_OWNER_REVIEW_BTN_TEST_ID = 'remove-owner-review-btn' @@ -120,7 +120,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {owner.address} - + @@ -149,7 +149,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx index c8ce72bfd8..a66965cc87 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx @@ -5,24 +5,25 @@ import classNames from 'classnames/bind' import React from 'react' import { useSelector } from 'react-redux' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' -import Identicon from 'src/components/Identicon' -import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import AddressInput from 'src/components/forms/AddressInput' import Field from 'src/components/forms/Field' import GnoForm from 'src/components/forms/GnoForm' import TextField from 'src/components/forms/TextField' import { composeValidators, minMaxLength, required, uniqueAddress } from 'src/components/forms/validator' +import Identicon from 'src/components/Identicon' 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 Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' +import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import { safeOwnersSelector } from 'src/logic/safe/store/selectors' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' + +import { styles } from './style' export const REPLACE_OWNER_NAME_INPUT_TEST_ID = 'replace-owner-name-input' export const REPLACE_OWNER_ADDRESS_INPUT_TEST_ID = 'replace-owner-address-testid' @@ -94,7 +95,7 @@ const OwnerForm = ({ classes, onClose, onSubmit, ownerAddress, ownerName }) => { {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 80939f2110..3b1ce84db6 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -5,8 +5,6 @@ import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import { styles } from './style' - import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -16,16 +14,18 @@ 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 { SENTINEL_ADDRESS, getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' -import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { getWeb3 } from 'src/logic/wallets/getWeb3' +import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/safeContracts' import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector, safeThresholdSelector, } from 'src/logic/safe/store/selectors' +import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' +import { formatAmount } from 'src/logic/tokens/utils/formatAmount' +import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' + +import { styles } from './style' export const REPLACE_OWNER_SUBMIT_BTN_TEST_ID = 'replace-owner-submit-btn' @@ -124,7 +124,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {owner.address} - + @@ -153,7 +153,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {ownerAddress} - + @@ -178,7 +178,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {values.ownerAddress} - + diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx index bab3846617..6ab5fc723f 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx @@ -6,6 +6,7 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' 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' @@ -28,7 +29,7 @@ const TransferDescription = ({ from, txFromName, value = '' }) => ( {txFromName ? ( ) : ( - + )} ) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx index 596f3224e1..6075415789 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx @@ -1,12 +1,13 @@ -import { useSelector } from 'react-redux' import React from 'react' - -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' +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 OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' -import EtherscanLink from 'src/components/EtherscanLink' import Paragraph from 'src/components/layout/Paragraph' + +import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' +import { ExplorerTypes } from 'src/logic/wallets/getWeb3' +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' @@ -29,7 +30,7 @@ const RemovedOwner = ({ removedOwner }: RemovedOwnerProps): React.ReactElement = {ownerChangedName ? ( ) : ( - + )} ) @@ -48,7 +49,7 @@ const AddedOwner = ({ addedOwner }: AddedOwnerProps): React.ReactElement => { {ownerChangedName ? ( ) : ( - + )} ) @@ -74,7 +75,7 @@ interface AddModuleProps { const AddModule = ({ module }: AddModuleProps): React.ReactElement => ( Add module: - + ) @@ -85,7 +86,7 @@ interface RemoveModuleProps { const RemoveModule = ({ module }: RemoveModuleProps): React.ReactElement => ( Remove module: - + ) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx index 4fc0be9780..1128d07103 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx @@ -1,12 +1,13 @@ import React from 'react' import { useSelector } from 'react-redux' - -import { TRANSACTIONS_DESC_SEND_TEST_ID } from './index' -import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' +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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' -import EtherscanLink from 'src/components/EtherscanLink' + +import { TRANSACTIONS_DESC_SEND_TEST_ID } from './index' interface TransferDescriptionProps { amount: string @@ -21,7 +22,7 @@ const TransferDescription = ({ amount = '', recipient }: TransferDescriptionProp {recipientName ? ( ) : ( - + )} ) diff --git a/src/utils/constants.ts b/src/utils/constants.ts index a21a6b6c9d..b873693fb3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,6 +1,4 @@ -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' - -export const NETWORK = process.env.REACT_APP_NETWORK || ETHEREUM_NETWORK.RINKEBY +export const NETWORK = process.env.REACT_APP_NETWORK || 'RINKEBY' export const GOOGLE_ANALYTICS_ID_RINKEBY = process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY export const GOOGLE_ANALYTICS_ID_MAINNET = process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET export const INTERCOM_ID = process.env.REACT_APP_INTERCOM_ID From 580c7e9b07eff7532ff9820b41dcaad02a61e312 Mon Sep 17 00:00:00 2001 From: fernandomg Date: Wed, 30 Sep 2020 18:33:55 -0300 Subject: [PATCH 05/19] fix test, avoid assingning enum to const --- src/config/index.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/config/index.ts b/src/config/index.ts index d34123508a..b6847acd91 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -14,9 +14,7 @@ import prodConfig from './production' import mainnetDevConfig from './development-mainnet' import mainnetProdConfig from './production-mainnet' import mainnetStagingConfig from './staging-mainnet' -import { NETWORK } from 'src/utils/constants'; - -const DEFAULT_NETWORK = ETHEREUM_NETWORK.RINKEBY +import { NETWORK } from 'src/utils/constants' const configuration = () => { if (process.env.NODE_ENV === 'test') { @@ -40,7 +38,7 @@ const configuration = () => { : devConfig } -export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] ?? DEFAULT_NETWORK +export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] ?? ETHEREUM_NETWORK.RINKEBY const getConfig = ensureOnce(configuration) From cfe727ea2e32014c9a3bec55afccbdb08130ceb0 Mon Sep 17 00:00:00 2001 From: fernandomg Date: Thu, 1 Oct 2020 20:00:37 -0300 Subject: [PATCH 06/19] fix typing errors --- .../ProviderDetails/UserDetails.tsx | 8 +++++- .../ProviderInfo/ProviderAccessible.tsx | 3 ++- .../SafeListSidebar/SafeList/index.tsx | 3 ++- src/logic/cookies/utils/index.ts | 3 ++- src/logic/notifications/notificationTypes.ts | 3 ++- src/logic/wallets/getWeb3.ts | 4 +-- src/logic/wallets/store/selectors/index.ts | 4 +-- .../TxsTable/ExpandedTx/CreationTx/index.tsx | 25 ++++++++++++++++--- .../OwnersColumn/OwnerComponent.tsx | 3 ++- .../TxDescription/CustomDescription.tsx | 11 ++++++-- .../ExpandedTx/TxDescription/Value.tsx | 9 ++++++- .../TxsTable/ExpandedTx/index.tsx | 4 +-- src/utils/storage/index.ts | 3 ++- 13 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index d22bf41aea..f651eeef50 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -105,7 +105,13 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, {userAddress ? ( - + ) : ( 'Address not available' )} diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index 3d2e0912c7..8253833781 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -1,6 +1,7 @@ import { makeStyles } from '@material-ui/core/styles' import * as React from 'react' import { EthHashInfo, Text } from '@gnosis.pm/safe-react-components' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import NetworkLabel from '../NetworkLabel' import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' @@ -94,7 +95,7 @@ const ProviderInfo = ({ connected, provider, userAddress, network }: ProviderInf identiconSize="xs" textColor={addressColor} textSize="sm" - network={network} + network={ETHEREUM_NETWORK[network]} /> ) : ( diff --git a/src/components/SafeListSidebar/SafeList/index.tsx b/src/components/SafeListSidebar/SafeList/index.tsx index 23ecd43609..f0875334de 100644 --- a/src/components/SafeListSidebar/SafeList/index.tsx +++ b/src/components/SafeListSidebar/SafeList/index.tsx @@ -3,6 +3,7 @@ import ListItem from '@material-ui/core/ListItem' import { makeStyles } from '@material-ui/core/styles' import { EthHashInfo, Icon, Text, ButtonLink } from '@gnosis.pm/safe-react-components' import * as React from 'react' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { SafeRecord } from 'src/logic/safe/store/models/safe' @@ -114,7 +115,7 @@ const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe name={safe.name} showIdenticon shortenHash={4} - network={getNetwork()} + network={ETHEREUM_NETWORK[getNetwork()]} /> diff --git a/src/logic/cookies/utils/index.ts b/src/logic/cookies/utils/index.ts index 08313a649e..6be77a0ae8 100644 --- a/src/logic/cookies/utils/index.ts +++ b/src/logic/cookies/utils/index.ts @@ -1,8 +1,9 @@ import Cookies from 'js-cookie' import { getNetwork } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' -const PREFIX = `v1_${getNetwork()}` +const PREFIX = `v1_${ETHEREUM_NETWORK[getNetwork()]}` export const loadFromCookie = async (key) => { try { diff --git a/src/logic/notifications/notificationTypes.ts b/src/logic/notifications/notificationTypes.ts index 7d4536afa7..62fbe24744 100644 --- a/src/logic/notifications/notificationTypes.ts +++ b/src/logic/notifications/notificationTypes.ts @@ -1,6 +1,7 @@ import { OptionsObject } from 'notistack' import { getNetwork } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { capitalize } from 'src/utils/css' export const SUCCESS = 'success' @@ -198,7 +199,7 @@ export const NOTIFICATIONS: Record = { options: { variant: WARNING, persist: true, preventDuplicate: true }, }, WRONG_NETWORK_MSG: { - message: `Wrong network: Please use ${capitalize(getNetwork())}`, + message: `Wrong network: Please use ${capitalize(ETHEREUM_NETWORK[getNetwork()])}`, options: { variant: WARNING, persist: true, preventDuplicate: true }, }, diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index a67f1da2a8..e1867cd876 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -21,8 +21,6 @@ export enum ETHEREUM_NETWORK { UNKNOWN = 0, } -export type EthereumNetworks = typeof ETHEREUM_NETWORK[keyof typeof ETHEREUM_NETWORK] - export const WALLET_PROVIDER = { SAFE: 'SAFE', METAMASK: 'METAMASK', @@ -48,7 +46,7 @@ export enum ExplorerTypes { export const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, value: string): string => `https://${ - network === ETHEREUM_NETWORK.MAINNET ? '' : `${network[network].toLowerCase()}.` + network === ETHEREUM_NETWORK.MAINNET ? '' : `${ETHEREUM_NETWORK[network].toLowerCase()}.` }etherscan.io/${type}/${value}` export const getExplorerLink = (type: ExplorerTypes, value: string): string => { diff --git a/src/logic/wallets/store/selectors/index.ts b/src/logic/wallets/store/selectors/index.ts index 3bc5d4cf51..51a0474006 100644 --- a/src/logic/wallets/store/selectors/index.ts +++ b/src/logic/wallets/store/selectors/index.ts @@ -1,6 +1,6 @@ import { createSelector } from 'reselect' -import { ETHEREUM_NETWORK, EthereumNetworks } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { PROVIDER_REDUCER_ID, ProviderState } from 'src/logic/wallets/store/reducer/provider' import { AppReduxState } from 'src/store' @@ -18,7 +18,7 @@ export const providerNameSelector = createSelector(providerSelector, (provider: export const networkSelector = createSelector( providerSelector, - (provider: ProviderState): EthereumNetworks => { + (provider: ProviderState): ETHEREUM_NETWORK => { const networkId = provider.get('network') return networkId ?? ETHEREUM_NETWORK.UNKNOWN diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx index d4e609b76f..181722bda6 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx @@ -4,6 +4,7 @@ import { EthHashInfo } from '@gnosis.pm/safe-react-components' import { getNetwork } from 'src/config' import { Transaction } from 'src/logic/safe/store/models/types/transaction' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { formatDate } from 'src/routes/safe/components/Transactions/TxsTable/columns' import Bold from 'src/components/layout/Bold' import Paragraph from 'src/components/layout/Paragraph' @@ -46,7 +47,13 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Creator: {tx.creator ? ( - + ) : ( 'n/a' )} @@ -54,7 +61,13 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Factory: {tx.factoryAddress ? ( - + ) : ( 'n/a' )} @@ -62,7 +75,13 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Mastercopy: {tx.masterCopy ? ( - + ) : ( 'n/a' )} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx index 8ba79a839e..0d2348d022 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx @@ -4,6 +4,7 @@ import React from 'react' import { useSelector } from 'react-redux' import { EthHashInfo } from '@gnosis.pm/safe-react-components' import { getNetwork } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import CancelSmallFilledCircle from './assets/cancel-small-filled.svg' import ConfirmSmallFilledCircle from './assets/confirm-small-filled.svg' @@ -183,7 +184,7 @@ const OwnerComponent = (props: OwnerComponentProps): React.ReactElement => { showIdenticon showCopyBtn showEtherscanBtn - network={getNetwork()} + network={ETHEREUM_NETWORK[getNetwork()]} /> {owner === userAddress && {isCancelTx ? rejectButton() : confirmButton()}} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx index 0ed87bec5f..030f00a7f5 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx @@ -1,6 +1,7 @@ import { IconText, Text, EthHashInfo } from '@gnosis.pm/safe-react-components' import { makeStyles } from '@material-ui/core/styles' import React from 'react' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { styles } from './styles' @@ -85,7 +86,13 @@ const MultiSendCustomDataAction = ({ tx, order }: { tx: MultiSendDetails; order: Send {humanReadableValue(tx.value)} ETH to: - + {!!tx.data && } @@ -189,7 +196,7 @@ const GenericCustomData = ({ amount = '0', data, recipient, storedTx }: GenericC showIdenticon showCopyBtn showEtherscanBtn - network={getNetwork()} + network={ETHEREUM_NETWORK[getNetwork()]} /> diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx index 7a0108e2c4..ae46d2e15e 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx @@ -1,5 +1,6 @@ import { Text, EthHashInfo } from '@gnosis.pm/safe-react-components' import React from 'react' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { getNetwork } from 'src/config' @@ -52,7 +53,13 @@ const GenericValue = ({ method, type, value }: RenderValueProps): React.ReactEle const Value = ({ type, ...props }: RenderValueProps): React.ReactElement => { if (isAddress(type)) { return ( - + ) } diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx index 2bc2c2bb2b..ce655808a2 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx @@ -21,7 +21,7 @@ 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 { ETHEREUM_NETWORK, getWeb3 } from 'src/logic/wallets/getWeb3' import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransaction' import { safeNonceSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' @@ -73,7 +73,7 @@ const ExpandedTx = ({ cancelTx, tx }: ExpandedTxProps): React.ReactElement => { shortenHash={4} showCopyBtn showEtherscanBtn - network={getNetwork()} + network={ETHEREUM_NETWORK[getNetwork()]} /> ) : ( 'n/a' diff --git a/src/utils/storage/index.ts b/src/utils/storage/index.ts index d2dff5b7e7..dcc3f5564b 100644 --- a/src/utils/storage/index.ts +++ b/src/utils/storage/index.ts @@ -1,6 +1,7 @@ import { ImmortalStorage, IndexedDbStore, LocalStorageStore } from 'immortal-db' import { getNetwork } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' // Don't use sessionStorage and cookieStorage // https://github.com/gruns/ImmortalDB/issues/22 @@ -8,7 +9,7 @@ import { getNetwork } from 'src/config' const stores = [IndexedDbStore, LocalStorageStore] export const storage = new ImmortalStorage(stores) -const PREFIX = `v2_${getNetwork()}` +const PREFIX = `v2_${ETHEREUM_NETWORK[getNetwork()]}` export const loadFromStorage = async (key: string): Promise => { try { From 6a4e353645e9447012d0f92631d81170b522e7ad Mon Sep 17 00:00:00 2001 From: Fernando Date: Fri, 2 Oct 2020 16:52:27 -0300 Subject: [PATCH 07/19] (Feature) [xDai] - Create network-based configurations (#1420) Co-authored-by: Matias Dastugue Co-authored-by: Mati Dastugue --- package.json | 3 +- .../networks/__tests__/networks.test.ts | 109 ++++++++++++++++++ src/config/networks/mainnet.ts | 44 +++++++ src/config/networks/network.d.ts | 58 ++++++++++ src/config/networks/rinkeby.ts | 44 +++++++ src/config/networks/xdai.ts | 30 +++++ src/logic/wallets/getWeb3.ts | 1 + 7 files changed, 287 insertions(+), 2 deletions(-) create mode 100644 src/config/networks/__tests__/networks.test.ts create mode 100644 src/config/networks/mainnet.ts create mode 100644 src/config/networks/network.d.ts create mode 100644 src/config/networks/rinkeby.ts create mode 100644 src/config/networks/xdai.ts diff --git a/package.json b/package.json index 7ca2a4bbc2..764d2ba6e9 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,7 @@ "src/**/*.{js,jsx,ts,tsx}", "!src/**/*.{.test.*}", "!src/**/test/**/*", - "!src/**/assets/**", - "!src/config/**/*" + "!src/**/assets/**" ] }, "productName": "Safe Multisig", diff --git a/src/config/networks/__tests__/networks.test.ts b/src/config/networks/__tests__/networks.test.ts new file mode 100644 index 0000000000..bb29462d0c --- /dev/null +++ b/src/config/networks/__tests__/networks.test.ts @@ -0,0 +1,109 @@ +import fs from 'fs' + +import { NetworkConfig } from 'src/config/networks/network.d' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { isValidURL } from 'src/utils/url' + +describe('Networks config files test', () => { + const NETWORKS_PATH = 'src/config/networks/' + const configFiles = fs.readdirSync(NETWORKS_PATH) + const networksFileNames = configFiles + .filter((file) => !fs.lstatSync(`${NETWORKS_PATH}${file}`).isDirectory()) + .filter((file) => { + const [, extension] = file.split('.') + return extension === 'ts' + }) + const environments = ['dev', 'staging', 'production'] + + environments.forEach((environment) => { + networksFileNames.forEach((networkFileName) => { + it(`should validate "${environment}" environment URIs for ${networkFileName} config`, async () => { + // Given + const { default: networkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + + // When + const networkConfigElement = networkConfig.environment[environment] + if (!networkConfigElement) { + return + } + + const environmentConfigKeys = Object + .keys(networkConfigElement) + .filter((environmentConfigKey) => + environmentConfigKey.endsWith('Uri') && !!networkConfigElement[environmentConfigKey] + ) + + // Then + environmentConfigKeys.forEach((environmentConfigKey) => { + const networkConfigElementUri = networkConfigElement[environmentConfigKey] + const isValid = isValidURL(networkConfigElementUri) + + if (!isValid) { + console.log(`Invalid URI in "${networkFileName}" at ${environment}.${environmentConfigKey}:`, networkConfigElementUri) + } + + expect(isValid).toBeTruthy() + }) + }) + }) + }) + + networksFileNames.forEach((networkFileName) => { + it(`should have a valid 'decimal' value for 'nativeToken'`, async() => { + // Given + const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + + // When + const { decimals } = networkConfig.network.nativeCoin + + // Then + const isValid = Number.isInteger(decimals) && decimals >= 0 + + if (!isValid) { + console.log(`Invalid value in "${networkFileName}" at network.decimals:`, decimals) + } + + expect(isValid).toBeTruthy() + }) + }) + + networksFileNames.forEach((networkFileName) => { + it(`should have one of 'ETHEREUM_NETWORK' values for 'network.id'`, async() => { + // Given + const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + + // When + const { id } = networkConfig.network + + // Then + const isValid = ETHEREUM_NETWORK[id] + + if (!isValid) { + console.log(`Invalid value in "${networkFileName}" at network.id:`, id) + } + + expect(isValid).toBeTruthy() + }) + }) + + networksFileNames.forEach((networkFileName) => { + it(`should have a valid CSS color defined for 'network.color'`, async() => { + // Given + const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + + // When + const { color } = networkConfig.network + + // Then + const s = new Option().style + s.color = color + const isValid = s.color !== '' + + if (!isValid) { + console.log(`Invalid value in "${networkFileName}" at network.color:`, color) + } + + expect(isValid).toBeTruthy() + }) + }) +}) diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts new file mode 100644 index 0000000000..d9f0fcf3ab --- /dev/null +++ b/src/config/networks/mainnet.ts @@ -0,0 +1,44 @@ +import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import { EnvironmentSettings, NetworkConfig } from 'src/config/networks/network.d' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' + +const baseConfig: EnvironmentSettings = { + txServiceUrl: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/', + safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com/', + gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', + rpcServiceUrl: 'https://mainnet.infura.io:443/v3/', + networkExplorerName: 'Etherscan', + networkExplorerUrl: 'https://etherscan.io/', + networkExplorerApiUrl: 'https://api.etherscan.io/api', +} + +const mainnet: NetworkConfig = { + environment: { + dev: { + ...baseConfig, + }, + staging: { + ...baseConfig, + safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com', + }, + production: { + ...baseConfig, + txServiceUrl: 'https://safe-transaction.mainnet.gnosis.io/api/v1/', + safeAppsUrl: 'https://apps.gnosis-safe.io/', + }, + }, + network: { + id: ETHEREUM_NETWORK.MAINNET, + color: '#E8E7E6', + label: 'Mainnet', + nativeCoin: { + address: '0x000', + name: 'Ether', + symbol: 'ETH', + decimals: 18, + logoUri: EtherLogo, + }, + } +} + +export default mainnet diff --git a/src/config/networks/network.d.ts b/src/config/networks/network.d.ts new file mode 100644 index 0000000000..0d061a20c0 --- /dev/null +++ b/src/config/networks/network.d.ts @@ -0,0 +1,58 @@ +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' + +// matches src/logic/tokens/store/model/token.ts `TokenProps` type +type Token = { + address: string + name: string + symbol: string + decimals: number + logoUri?: string +} + +type NetworkSettings = { + id: ETHEREUM_NETWORK, + color: string, + label: string, + nativeCoin: Token, +} + +// something around this to display or not some critical sections in the app, depending on the network support +// I listed the ones that may conflict with the network. +// If non is present, all the sections are available. +type SafeFeatures = { + safeApps?: boolean, + collectibles?: boolean, + contractInteraction?: boolean +} + +type GasPrice = { + gasPrice: number + gasPriceOracleUrl?: string +} | { + gasPrice?: number + // for infura there's a REST API Token required stored in: `REACT_APP_INFURA_TOKEN` + gasPriceOracleUrl: string +} + +export type EnvironmentSettings = GasPrice & { + txServiceUrl: string + // Shall we keep a reference to the relay? + relayApiUrl?: string + safeAppsUrl: string + rpcServiceUrl: string + networkExplorerName: string + networkExplorerUrl: string + networkExplorerApiUrl: string +} + +type SafeEnvironments = { + dev?: EnvironmentSettings + staging?: EnvironmentSettings + production: EnvironmentSettings +} + +export interface NetworkConfig { + network: NetworkSettings + features?: SafeFeatures + environment: SafeEnvironments +} diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts new file mode 100644 index 0000000000..b37f04e002 --- /dev/null +++ b/src/config/networks/rinkeby.ts @@ -0,0 +1,44 @@ +import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import { EnvironmentSettings, NetworkConfig } from 'src/config/networks/network.d' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' + +const baseConfig: EnvironmentSettings = { + txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1/', + safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com/', + gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', + rpcServiceUrl: 'https://rinkeby.infura.io:443/v3/', + networkExplorerName: 'Etherscan', + networkExplorerUrl: 'https://rinkeby.etherscan.io/', + networkExplorerApiUrl: 'https://api-rinkeby.etherscan.io/api', +} + +const rinkeby: NetworkConfig = { + environment: { + dev: { + ...baseConfig, + }, + staging: { + ...baseConfig, + safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com', + }, + production: { + ...baseConfig, + txServiceUrl: 'https://safe-transaction.rinkeby.gnosis.io/api/v1/', + safeAppsUrl: 'https://apps.gnosis-safe.io/', + }, + }, + network: { + id: ETHEREUM_NETWORK.RINKEBY, + color: '#E8673C', + label: 'Rinkeby', + nativeCoin: { + address: '0x000', + name: 'Ether', + symbol: 'ETH', + decimals: 18, + logoUri: EtherLogo, + }, + }, +} + +export default rinkeby diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts new file mode 100644 index 0000000000..05a8aef442 --- /dev/null +++ b/src/config/networks/xdai.ts @@ -0,0 +1,30 @@ +import { NetworkConfig } from 'src/config/networks/network.d' +import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' + +const xDai: NetworkConfig = { + environment: { + production: { + txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1/', + safeAppsUrl: 'https://apps.gnosis-safe.io/', + gasPrice: 1e9, + rpcServiceUrl: 'https://rpc.xdaichain.com/', + networkExplorerName: 'Blockscout', + networkExplorerUrl: 'https://blockscout.com/poa/xdai/', + networkExplorerApiUrl: 'https://blockscout.com/poa/xdai/api', + }, + }, + network: { + id: ETHEREUM_NETWORK.XDAI, + color: '#48A8A6', + label: 'xDai STAKE', + nativeCoin: { + address: '0x000', + name: 'xDai', + symbol: 'xDai', + decimals: 18, + logoUri: '', + }, + } +} + +export default xDai diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index e1867cd876..fbe9854362 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -16,6 +16,7 @@ export enum ETHEREUM_NETWORK { RINKEBY = 4, GOERLI = 5, KOVAN = 42, + XDAI = 100, ENERGY_WEB_CHAIN = 246, VOLTA = 73799, UNKNOWN = 0, From ab2d1cf382a8cc7c05b068f638d46fcb158658cd Mon Sep 17 00:00:00 2001 From: Fernando Date: Mon, 5 Oct 2020 14:44:20 -0300 Subject: [PATCH 08/19] (Feature) [xDai] Use generic config (#1422) Co-authored-by: Matias Dastugue Co-authored-by: Mati Dastugue --- src/components/App/index.tsx | 8 +- .../Header/components/NetworkLabel.tsx | 6 +- .../ProviderDetails/UserDetails.tsx | 2 +- .../ProviderInfo/ProviderAccessible.tsx | 2 +- .../AppLayout/Sidebar/SafeHeader/index.tsx | 5 +- src/components/ConnectButton/index.tsx | 4 +- .../SafeListSidebar/SafeList/index.tsx | 5 +- src/config/__tests__/config.test.ts | 136 ++++++++++++++++++ src/config/development-mainnet.ts | 11 -- src/config/development.ts | 11 -- src/config/index.ts | 135 +++++++++-------- src/config/names.ts | 4 - .../networks/__tests__/networks.test.ts | 40 ++++-- src/config/networks/index.ts | 11 ++ src/config/networks/local.ts | 35 +++++ src/config/networks/mainnet.ts | 5 +- src/config/networks/network.d.ts | 21 ++- src/config/networks/rinkeby.ts | 3 +- src/config/networks/xdai.ts | 3 +- src/config/production-mainnet.ts | 11 -- src/config/production.ts | 10 -- src/config/staging-mainnet.ts | 11 -- src/config/staging.ts | 10 -- src/config/testing.ts | 10 -- src/logic/collectibles/sources/OpenSea.ts | 2 +- .../store/actions/fetchCollectibles.ts | 4 +- .../sources/EtherscanService.ts | 2 +- src/logic/cookies/utils/index.ts | 5 +- .../__tests__/fetchSafeTokens.test.ts | 4 +- .../api/fetchCurrenciesRates.ts | 4 +- .../api/fetchTokenCurrenciesBalances.ts | 4 +- src/logic/notifications/notificationTypes.ts | 6 +- .../allTransactions/loadAllTransactions.ts | 4 +- .../safe/transactions/incomingTxHistory.ts | 4 +- src/logic/safe/transactions/txHistory.ts | 4 +- src/logic/safe/utils/safeVersion.ts | 4 +- src/logic/tokens/api/fetchTokenBalanceList.ts | 4 +- src/logic/wallets/getWeb3.ts | 25 +--- .../wallets/store/actions/fetchProvider.ts | 9 +- src/logic/wallets/store/model/provider.ts | 3 +- src/logic/wallets/store/selectors/index.ts | 2 +- src/logic/wallets/utils/walletList.ts | 4 +- src/routes/load/container/Load.tsx | 2 +- .../Apps/hooks/useIframeMessageHandler.ts | 6 +- src/routes/safe/components/Apps/index.tsx | 2 +- src/routes/safe/components/Apps/utils.ts | 2 +- .../ContractInteraction/utils/index.ts | 4 +- .../TxsTable/ExpandedTx/CreationTx/index.tsx | 21 +-- .../OwnersColumn/OwnerComponent.tsx | 5 +- .../TxDescription/CustomDescription.tsx | 13 +- .../ExpandedTx/TxDescription/Value.tsx | 5 +- .../TxsTable/ExpandedTx/index.tsx | 6 +- src/utils/constants.ts | 16 ++- src/utils/intercom.ts | 4 +- src/utils/storage/index.ts | 5 +- 55 files changed, 389 insertions(+), 295 deletions(-) create mode 100644 src/config/__tests__/config.test.ts delete mode 100644 src/config/development-mainnet.ts delete mode 100644 src/config/development.ts delete mode 100644 src/config/names.ts create mode 100644 src/config/networks/index.ts create mode 100644 src/config/networks/local.ts delete mode 100644 src/config/production-mainnet.ts delete mode 100644 src/config/production.ts delete mode 100644 src/config/staging-mainnet.ts delete mode 100644 src/config/staging.ts delete mode 100644 src/config/testing.ts diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index ee90992af8..eda52cb2ee 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -16,8 +16,8 @@ import CookiesBanner from 'src/components/CookiesBanner' import Notifier from 'src/components/Notifier' import Backdrop from 'src/components/layout/Backdrop' import Img from 'src/components/layout/Img' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { getNetworkId } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { networkSelector } from 'src/logic/wallets/store/selectors' import { SAFELIST_ADDRESS, WELCOME_ADDRESS } from 'src/routes/routes' import { safeNameSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' @@ -26,7 +26,7 @@ import SendModal from 'src/routes/safe/components/Balances/SendModal' import { useLoadSafe } from 'src/logic/safe/hooks/useLoadSafe' import { useSafeScheduledUpdates } from 'src/logic/safe/hooks/useSafeScheduledUpdates' import useSafeActions from 'src/logic/safe/hooks/useSafeActions' -import { currentCurrencySelector, safeFiatBalancesTotalSelector } from 'src/logic/currencyValues/store/selectors/index' +import { currentCurrencySelector, safeFiatBalancesTotalSelector } from 'src/logic/currencyValues/store/selectors' import { formatAmountInUsFormat } from 'src/logic/tokens/utils/formatAmount' import { grantedSelector } from 'src/routes/safe/container/selector' @@ -55,7 +55,7 @@ const Frame = styled.div` max-width: 100%; ` -const desiredNetwork = getNetwork() +const desiredNetwork = getNetworkId() const useStyles = makeStyles(notificationStyles) diff --git a/src/components/AppLayout/Header/components/NetworkLabel.tsx b/src/components/AppLayout/Header/components/NetworkLabel.tsx index 2ff24a5a73..d68da3fb65 100644 --- a/src/components/AppLayout/Header/components/NetworkLabel.tsx +++ b/src/components/AppLayout/Header/components/NetworkLabel.tsx @@ -3,11 +3,11 @@ import * as React from 'react' import Col from 'src/components/layout/Col' import Paragraph from 'src/components/layout/Paragraph' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { getNetworkId } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { border, md, screenSm, sm, xs } from 'src/theme/variables' -const interfaceNetwork = getNetwork() +const interfaceNetwork = getNetworkId() const formatNetwork = (network: number): string => ETHEREUM_NETWORK[network][0].toUpperCase() + ETHEREUM_NETWORK[network].substring(1).toLowerCase() diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index f651eeef50..8540335b64 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -14,7 +14,7 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { background, connected as connectedBg, lg, md, sm, warning, xs } from 'src/theme/variables' import { upperFirst } from 'src/utils/css' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' const dot = require('../../assets/dotRinkeby.svg') const walletIcon = require('../../assets/wallet.svg') diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index 8253833781..0ae85a2a15 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -1,8 +1,8 @@ import { makeStyles } from '@material-ui/core/styles' import * as React from 'react' import { EthHashInfo, Text } from '@gnosis.pm/safe-react-components' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import NetworkLabel from '../NetworkLabel' import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' import Col from 'src/components/layout/Col' diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index 273a1476b2..f00c03adaf 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -1,5 +1,4 @@ import React from 'react' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { Icon, @@ -12,7 +11,7 @@ import { EtherscanButton, } from '@gnosis.pm/safe-react-components' -import { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' import FlexSpacer from 'src/components/FlexSpacer' export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN' @@ -129,7 +128,7 @@ const SafeHeader = ({ - + {granted ? null : ( diff --git a/src/components/ConnectButton/index.tsx b/src/components/ConnectButton/index.tsx index db81d05ce9..a719776f04 100644 --- a/src/components/ConnectButton/index.tsx +++ b/src/components/ConnectButton/index.tsx @@ -2,7 +2,7 @@ import Onboard from 'bnc-onboard' import React from 'react' import Button from 'src/components/layout/Button' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' import { getWeb3, setWeb3 } from 'src/logic/wallets/getWeb3' import { fetchProvider } from 'src/logic/wallets/store/actions' import transactionDataCheck from 'src/logic/wallets/transactionDataCheck' @@ -20,7 +20,7 @@ const wallets = getSupportedWallets() export const onboard = Onboard({ dappId: BLOCKNATIVE_API_KEY, - networkId: getNetwork(), + networkId: getNetworkId(), subscriptions: { wallet: (wallet) => { if (wallet.provider) { diff --git a/src/components/SafeListSidebar/SafeList/index.tsx b/src/components/SafeListSidebar/SafeList/index.tsx index f0875334de..f2327a8698 100644 --- a/src/components/SafeListSidebar/SafeList/index.tsx +++ b/src/components/SafeListSidebar/SafeList/index.tsx @@ -3,13 +3,12 @@ import ListItem from '@material-ui/core/ListItem' import { makeStyles } from '@material-ui/core/styles' import { EthHashInfo, Icon, Text, ButtonLink } from '@gnosis.pm/safe-react-components' import * as React from 'react' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { SafeRecord } from 'src/logic/safe/store/models/safe' import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' -import { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' import DefaultBadge from './DefaultBadge' import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' @@ -115,7 +114,7 @@ const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe name={safe.name} showIdenticon shortenHash={4} - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> diff --git a/src/config/__tests__/config.test.ts b/src/config/__tests__/config.test.ts new file mode 100644 index 0000000000..021a4a20e7 --- /dev/null +++ b/src/config/__tests__/config.test.ts @@ -0,0 +1,136 @@ +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { default as networks } from 'src/config/networks' + +const { mainnet, xdai } = networks + +describe('Config Services', () => { + beforeEach(() => { + jest.resetModules() + }) + + it(`should load 'test' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: 'test', + })) + const { getNetworkInfo } = require('src/config') + + // When + const networkInfo = getNetworkInfo() + + // Then + expect(networkInfo.id).toBe(ETHEREUM_NETWORK.LOCAL) + }) + + it(`should load 'mainnet' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: '', + NETWORK: 'MAINNET', + })) + const { getNetworkInfo } = require('src/config') + + // When + const networkInfo = getNetworkInfo() + + // Then + expect(networkInfo.id).toBe(ETHEREUM_NETWORK.MAINNET) + }) + + it(`should load 'mainnet.dev' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: '', + NETWORK: 'MAINNET', + })) + const { getTxServiceUrl, getGnosisSafeAppsUrl } = require('src/config') + const TX_SERVICE_URL = mainnet.environment.dev?.txServiceUrl + const SAFE_APPS_URL = mainnet.environment.dev?.safeAppsUrl + + // When + const txServiceUrl = getTxServiceUrl() + const safeAppsUrl = getGnosisSafeAppsUrl() + + // Then + expect(TX_SERVICE_URL).toBe(txServiceUrl) + expect(SAFE_APPS_URL).toBe(safeAppsUrl) + }) + + it(`should load 'mainnet.staging' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: 'production', + NETWORK: 'MAINNET', + })) + const { getTxServiceUrl, getGnosisSafeAppsUrl } = require('src/config') + const TX_SERVICE_URL = mainnet.environment.staging?.txServiceUrl + const SAFE_APPS_URL = mainnet.environment.staging?.safeAppsUrl + + // When + const txServiceUrl = getTxServiceUrl() + const safeAppsUrl = getGnosisSafeAppsUrl() + + // Then + expect(TX_SERVICE_URL).toBe(txServiceUrl) + expect(SAFE_APPS_URL).toBe(safeAppsUrl) + }) + + it(`should load 'mainnet.production' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: 'production', + NETWORK: 'MAINNET', + APP_ENV: 'production' + })) + const { getTxServiceUrl, getGnosisSafeAppsUrl } = require('src/config') + const TX_SERVICE_URL = mainnet.environment.production.txServiceUrl + const SAFE_APPS_URL = mainnet.environment.production.safeAppsUrl + + // When + const txServiceUrl = getTxServiceUrl() + const safeAppsUrl = getGnosisSafeAppsUrl() + + // Then + expect(TX_SERVICE_URL).toBe(txServiceUrl) + expect(SAFE_APPS_URL).toBe(safeAppsUrl) + }) + + it(`should load 'xdai.production' network config`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: 'production', + NETWORK: 'XDAI', + APP_ENV: 'production' + })) + const { getTxServiceUrl, getGnosisSafeAppsUrl } = require('src/config') + const TX_SERVICE_URL = xdai.environment.production.txServiceUrl + const SAFE_APPS_URL = xdai.environment.production.safeAppsUrl + + // When + const txServiceUrl = getTxServiceUrl() + const safeAppsUrl = getGnosisSafeAppsUrl() + + // Then + expect(TX_SERVICE_URL).toBe(txServiceUrl) + expect(SAFE_APPS_URL).toBe(safeAppsUrl) + }) + + it(`should default to 'xdai.production' network config if no environment is found`, () => { + // Given + jest.mock('src/utils/constants', () => ({ + NODE_ENV: '', + NETWORK: 'XDAI', + })) + const { getTxServiceUrl, getGnosisSafeAppsUrl } = require('src/config') + const TX_SERVICE_URL = xdai.environment.production.txServiceUrl + const SAFE_APPS_URL = xdai.environment.production.safeAppsUrl + + // When + const txServiceUrl = getTxServiceUrl() + const safeAppsUrl = getGnosisSafeAppsUrl() + + // Then + expect(TX_SERVICE_URL).toBe(txServiceUrl) + expect(SAFE_APPS_URL).toBe(safeAppsUrl) + }) +}) diff --git a/src/config/development-mainnet.ts b/src/config/development-mainnet.ts deleted file mode 100644 index a26a7075ae..0000000000 --- a/src/config/development-mainnet.ts +++ /dev/null @@ -1,11 +0,0 @@ -// -import devConfig from './development' -import { TX_SERVICE_HOST, RELAY_API_URL } from 'src/config/names' - -const devMainnetConfig = { - ...devConfig, - [TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/', - [RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/', -} - -export default devMainnetConfig diff --git a/src/config/development.ts b/src/config/development.ts deleted file mode 100644 index fa26777e48..0000000000 --- a/src/config/development.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL, SAFE_APPS_URL } from 'src/config/names' - -const devConfig = { - [TX_SERVICE_HOST]: 'https://safe-transaction.staging.gnosisdev.com/api/v1/', - [SIGNATURES_VIA_METAMASK]: false, - [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/', - [SAFE_APPS_URL]: 'https://safe-apps.dev.gnosisdev.com/' - //[SAFE_APPS_URL]: 'http://localhost:3002/' -} - -export default devConfig diff --git a/src/config/index.ts b/src/config/index.ts index b6847acd91..ec5c367d34 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,96 +1,95 @@ -import { checksumAddress } from 'src/utils/checksumAddress'; -import { ensureOnce } from 'src/utils/singleton' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import networks from 'src/config/networks' import { - RELAY_API_URL, - SIGNATURES_VIA_METAMASK, - TX_SERVICE_HOST, - SAFE_APPS_URL -} from 'src/config/names' -import devConfig from './development' -import testConfig from './testing' -import stagingConfig from './staging' -import prodConfig from './production' -import mainnetDevConfig from './development-mainnet' -import mainnetProdConfig from './production-mainnet' -import mainnetStagingConfig from './staging-mainnet' -import { NETWORK } from 'src/utils/constants' - -const configuration = () => { - if (process.env.NODE_ENV === 'test') { - return testConfig - } + EnvironmentSettings, + ETHEREUM_NETWORK, + NetworkSettings, + SafeFeatures, +} from 'src/config/networks/network.d' +import { checksumAddress } from 'src/utils/checksumAddress' +import { GOOGLE_ANALYTICS_ID, NETWORK, APP_ENV, NODE_ENV } from 'src/utils/constants' +import { ensureOnce } from 'src/utils/singleton' - if (process.env.NODE_ENV === 'production') { - if (process.env.REACT_APP_NETWORK === 'mainnet') { - return process.env.REACT_APP_ENV === 'production' - ? mainnetProdConfig - : mainnetStagingConfig - } +export const getNetworkId = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] - return process.env.REACT_APP_ENV === 'production' - ? prodConfig - : stagingConfig +export const getNetworkName = (): string => ETHEREUM_NETWORK[getNetworkId()] + +const getCurrentEnvironment = (): string => { + switch (NODE_ENV) { + case 'test': { + return 'test' + } + case 'production': { + return APP_ENV === 'production' ? 'production' : 'staging' + } + default: { + return 'dev' + } } +} - return process.env.REACT_APP_NETWORK === 'mainnet' - ? mainnetDevConfig - : devConfig +type NetworkSpecificConfiguration = EnvironmentSettings & { + network: NetworkSettings, + features?: SafeFeatures, } -export const getNetwork = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] ?? ETHEREUM_NETWORK.RINKEBY +const configuration = (): NetworkSpecificConfiguration => { + const currentEnvironment = getCurrentEnvironment() -const getConfig = ensureOnce(configuration) + // special case for test environment + if (currentEnvironment === 'test') { + const configFile = networks.local -export const getTxServiceHost = () => { - const config = getConfig() + return { + ...configFile.environment.production, + network: configFile.network, + features: configFile.features, + } + } - return config[TX_SERVICE_HOST] -} + // lookup the config file based on the network specified in the NETWORK variable + const configFile = networks[getNetworkName().toLowerCase()] + // defaults to 'production' as it's the only environment that is required for the network configs + const networkBaseConfig = configFile.environment[currentEnvironment] ?? configFile.environment.production -export const getTxServiceUriFrom = (safeAddress) => - `safes/${safeAddress}/transactions/` + return { + ...networkBaseConfig, + network: configFile.network, + features: configFile.features, + } +} -export const getIncomingTxServiceUriTo = (safeAddress) => - `safes/${safeAddress}/incoming-transfers/` +const getConfig: () => NetworkSpecificConfiguration = ensureOnce(configuration) -export const getAllTransactionsUriFrom = (safeAddress: string): string => - `safes/${safeAddress}/all-transactions/` +export const getTxServiceUrl = (): string => getConfig()?.txServiceUrl -export const getSafeCreationTxUri = (safeAddress) => `safes/${safeAddress}/creation/` +export const getRelayUrl = (): string | undefined => getConfig()?.relayApiUrl -export const getRelayUrl = () => getConfig()[RELAY_API_URL] +export const getGnosisSafeAppsUrl = (): string => getConfig()?.safeAppsUrl -export const signaturesViaMetamask = () => { - const config = getConfig() +export const getRpcServiceUrl = (): string => getConfig()?.rpcServiceUrl - return config[SIGNATURES_VIA_METAMASK] -} +export const getNetworkExplorerInfo = (): { name: string; url: string; apiUrl: string } => ({ + name: getConfig()?.networkExplorerName, + url: getConfig()?.networkExplorerUrl, + apiUrl: getConfig()?.networkExplorerApiUrl, +}) -export const getGnosisSafeAppsUrl = () => { - const config = getConfig() +export const getNetworkConfigFeatures = (): SafeFeatures | undefined => getConfig()?.features - return config[SAFE_APPS_URL] -} +export const getNetworkInfo = (): NetworkSettings => getConfig()?.network -export const getGoogleAnalyticsTrackingID = () => - getNetwork() === ETHEREUM_NETWORK.MAINNET - ? process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET - : process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY +export const getTxServiceUriFrom = (safeAddress: string) => `safes/${safeAddress}/transactions/` -export const getIntercomId = () => - process.env.REACT_APP_ENV === 'production' - ? process.env.REACT_APP_INTERCOM_ID - : 'plssl1fl' +export const getIncomingTxServiceUriTo = (safeAddress: string) => `safes/${safeAddress}/incoming-transfers/` -export const getExchangeRatesUrl = () => 'https://api.exchangeratesapi.io/latest' +export const getAllTransactionsUriFrom = (safeAddress: string) => `safes/${safeAddress}/all-transactions/` -export const getExchangeRatesUrlFallback = () => 'https://api.coinbase.com/v2/exchange-rates' +export const getSafeCreationTxUri = (safeAddress: string) => `safes/${safeAddress}/creation/` -export const getSafeLastVersion = () => process.env.REACT_APP_LATEST_SAFE_VERSION || '1.1.1' +export const getGoogleAnalyticsTrackingID = (): string => GOOGLE_ANALYTICS_ID[getNetworkName()] -export const buildSafeCreationTxUrl = (safeAddress) => { - const host = getTxServiceHost() +export const buildSafeCreationTxUrl = (safeAddress: string) => { + const host = getTxServiceUrl() const address = checksumAddress(safeAddress) const base = getSafeCreationTxUri(address) diff --git a/src/config/names.ts b/src/config/names.ts deleted file mode 100644 index 3390fbecb8..0000000000 --- a/src/config/names.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const TX_SERVICE_HOST = 'tsh' -export const SIGNATURES_VIA_METAMASK = 'svm' -export const RELAY_API_URL = 'rau' -export const SAFE_APPS_URL = 'sau' diff --git a/src/config/networks/__tests__/networks.test.ts b/src/config/networks/__tests__/networks.test.ts index bb29462d0c..c49514bf8e 100644 --- a/src/config/networks/__tests__/networks.test.ts +++ b/src/config/networks/__tests__/networks.test.ts @@ -1,25 +1,39 @@ import fs from 'fs' -import { NetworkConfig } from 'src/config/networks/network.d' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import networks from 'src/config/networks' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { isValidURL } from 'src/utils/url' describe('Networks config files test', () => { + const environments = ['dev', 'staging', 'production'] + const NETWORKS_PATH = 'src/config/networks/' const configFiles = fs.readdirSync(NETWORKS_PATH) const networksFileNames = configFiles .filter((file) => !fs.lstatSync(`${NETWORKS_PATH}${file}`).isDirectory()) .filter((file) => { - const [, extension] = file.split('.') - return extension === 'ts' + const [fileName, extension] = file.split('.') + return extension === 'ts' && fileName !== 'index' }) - const environments = ['dev', 'staging', 'production'] + .map((file) => file.split('.')[0]) + + it(`should verify that the network file is exported in the networks/index.ts file`, () => { + networksFileNames.forEach((networkFileName) => { + const isValid = !!networks[networkFileName] + + if (!isValid) { + console.log(`Network file "${networkFileName}" is not exported in "networks/index.ts"`) + } + + expect(isValid).toBeTruthy() + }) + }) environments.forEach((environment) => { networksFileNames.forEach((networkFileName) => { - it(`should validate "${environment}" environment URIs for ${networkFileName} config`, async () => { + it(`should validate "${environment}" environment URIs for ${networkFileName} config`, () => { // Given - const { default: networkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + const networkConfig = networks[networkFileName] // When const networkConfigElement = networkConfig.environment[environment] @@ -49,9 +63,9 @@ describe('Networks config files test', () => { }) networksFileNames.forEach((networkFileName) => { - it(`should have a valid 'decimal' value for 'nativeToken'`, async() => { + it(`should have a valid 'decimal' value for 'nativeToken'`, () => { // Given - const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + const networkConfig = networks[networkFileName] // When const { decimals } = networkConfig.network.nativeCoin @@ -68,9 +82,9 @@ describe('Networks config files test', () => { }) networksFileNames.forEach((networkFileName) => { - it(`should have one of 'ETHEREUM_NETWORK' values for 'network.id'`, async() => { + it(`should have one of 'ETHEREUM_NETWORK' values for 'network.id'`, () => { // Given - const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + const networkConfig = networks[networkFileName] // When const { id } = networkConfig.network @@ -87,9 +101,9 @@ describe('Networks config files test', () => { }) networksFileNames.forEach((networkFileName) => { - it(`should have a valid CSS color defined for 'network.color'`, async() => { + it(`should have a valid CSS color defined for 'network.color'`, () => { // Given - const { default: networkConfig }: { default: NetworkConfig } = await import(`${NETWORKS_PATH}${networkFileName}`) + const networkConfig = networks[networkFileName] // When const { color } = networkConfig.network diff --git a/src/config/networks/index.ts b/src/config/networks/index.ts new file mode 100644 index 0000000000..8944d16d91 --- /dev/null +++ b/src/config/networks/index.ts @@ -0,0 +1,11 @@ +import local from './local' +import mainnet from './mainnet' +import rinkeby from './rinkeby' +import xdai from './xdai' + +export default { + local, + mainnet, + rinkeby, + xdai, +} diff --git a/src/config/networks/local.ts b/src/config/networks/local.ts new file mode 100644 index 0000000000..195e315e38 --- /dev/null +++ b/src/config/networks/local.ts @@ -0,0 +1,35 @@ +import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' + +const baseConfig: EnvironmentSettings = { + txServiceUrl: 'http://localhost:8000/api/v1/', + relayApiUrl: 'https://safe-relay.staging.gnosisdev.com/api/v1', + safeAppsUrl: 'http://localhost:3002/', + gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', + rpcServiceUrl: 'http://localhost:4447/', + networkExplorerName: 'Etherscan', + networkExplorerUrl: 'https://rinkeby.etherscan.io/', + networkExplorerApiUrl: 'https://api-rinkeby.etherscan.io/api', +} + +const local: NetworkConfig = { + environment: { + production: { + ...baseConfig, + }, + }, + network: { + id: ETHEREUM_NETWORK.LOCAL, + color: '#E8673C', + label: 'LocalRPC', + nativeCoin: { + address: '0x000', + name: 'Ether', + symbol: 'ETH', + decimals: 18, + logoUri: EtherLogo, + }, + }, +} + +export default local diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index d9f0fcf3ab..7635ada83e 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -1,6 +1,5 @@ import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' -import { EnvironmentSettings, NetworkConfig } from 'src/config/networks/network.d' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { txServiceUrl: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/', @@ -19,7 +18,7 @@ const mainnet: NetworkConfig = { }, staging: { ...baseConfig, - safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com', + safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com/', }, production: { ...baseConfig, diff --git a/src/config/networks/network.d.ts b/src/config/networks/network.d.ts index 0d061a20c0..fd632d035b 100644 --- a/src/config/networks/network.d.ts +++ b/src/config/networks/network.d.ts @@ -1,5 +1,3 @@ -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' - // matches src/logic/tokens/store/model/token.ts `TokenProps` type type Token = { address: string @@ -9,7 +7,22 @@ type Token = { logoUri?: string } -type NetworkSettings = { +export enum ETHEREUM_NETWORK { + MAINNET = 1, + MORDEN = 2, + ROPSTEN = 3, + RINKEBY = 4, + GOERLI = 5, + KOVAN = 42, + XDAI = 100, + ENERGY_WEB_CHAIN = 246, + VOLTA = 73799, + UNKNOWN = 0, + LOCAL = 4447, +} + +export type NetworkSettings = { + // TODO: id now seems to be unnecessary id: ETHEREUM_NETWORK, color: string, label: string, @@ -19,7 +32,7 @@ type NetworkSettings = { // something around this to display or not some critical sections in the app, depending on the network support // I listed the ones that may conflict with the network. // If non is present, all the sections are available. -type SafeFeatures = { +export type SafeFeatures = { safeApps?: boolean, collectibles?: boolean, contractInteraction?: boolean diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index b37f04e002..7a6d78325f 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -1,6 +1,5 @@ import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' -import { EnvironmentSettings, NetworkConfig } from 'src/config/networks/network.d' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1/', diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index 05a8aef442..d3a29a93e9 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -1,5 +1,4 @@ -import { NetworkConfig } from 'src/config/networks/network.d' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const xDai: NetworkConfig = { environment: { diff --git a/src/config/production-mainnet.ts b/src/config/production-mainnet.ts deleted file mode 100644 index d24d20e19a..0000000000 --- a/src/config/production-mainnet.ts +++ /dev/null @@ -1,11 +0,0 @@ -// -import prodConfig from './production' -import { TX_SERVICE_HOST, RELAY_API_URL } from 'src/config/names' - -const prodMainnetConfig = { - ...prodConfig, - [TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.gnosis.io/api/v1/', - [RELAY_API_URL]: 'https://safe-relay.gnosis.io/api/v1/', -} - -export default prodMainnetConfig diff --git a/src/config/production.ts b/src/config/production.ts deleted file mode 100644 index 246fcb9c71..0000000000 --- a/src/config/production.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL, SAFE_APPS_URL } from 'src/config/names' - -const prodConfig = { - [TX_SERVICE_HOST]: 'https://safe-transaction.rinkeby.gnosis.io/api/v1/', - [SIGNATURES_VIA_METAMASK]: false, - [RELAY_API_URL]: 'https://safe-relay.rinkeby.gnosis.io/api/v1/', - [SAFE_APPS_URL]: 'https://apps.gnosis-safe.io/' -} - -export default prodConfig diff --git a/src/config/staging-mainnet.ts b/src/config/staging-mainnet.ts deleted file mode 100644 index 08f225fad6..0000000000 --- a/src/config/staging-mainnet.ts +++ /dev/null @@ -1,11 +0,0 @@ -// -import stagingConfig from './staging' -import { TX_SERVICE_HOST, RELAY_API_URL } from 'src/config/names' - -const stagingMainnetConfig = { - ...stagingConfig, - [TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/', - [RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/', -} - -export default stagingMainnetConfig diff --git a/src/config/staging.ts b/src/config/staging.ts deleted file mode 100644 index 61b4ebca25..0000000000 --- a/src/config/staging.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL, SAFE_APPS_URL } from 'src/config/names' - -const stagingConfig = { - [TX_SERVICE_HOST]: 'https://safe-transaction.staging.gnosisdev.com/api/v1/', - [SIGNATURES_VIA_METAMASK]: false, - [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/', - [SAFE_APPS_URL]: 'https://safe-apps.staging.gnosisdev.com' -} - -export default stagingConfig diff --git a/src/config/testing.ts b/src/config/testing.ts deleted file mode 100644 index cce8aa963a..0000000000 --- a/src/config/testing.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL, SAFE_APPS_URL } from 'src/config/names' - -const testConfig = { - [TX_SERVICE_HOST]: 'http://localhost:8000/api/v1/', - [SIGNATURES_VIA_METAMASK]: false, - [RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1', - [SAFE_APPS_URL]: 'http://localhost:3002/' -} - -export default testConfig diff --git a/src/logic/collectibles/sources/OpenSea.ts b/src/logic/collectibles/sources/OpenSea.ts index 2175ec59af..9e2c1a5076 100644 --- a/src/logic/collectibles/sources/OpenSea.ts +++ b/src/logic/collectibles/sources/OpenSea.ts @@ -1,6 +1,6 @@ import { RateLimit } from 'async-sema' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import NFTIcon from 'src/routes/safe/components/Balances/assets/nft_icon.png' import { OPENSEA_API_KEY } from 'src/utils/constants' diff --git a/src/logic/collectibles/store/actions/fetchCollectibles.ts b/src/logic/collectibles/store/actions/fetchCollectibles.ts index c87e51df06..feb4dc2df1 100644 --- a/src/logic/collectibles/store/actions/fetchCollectibles.ts +++ b/src/logic/collectibles/store/actions/fetchCollectibles.ts @@ -1,13 +1,13 @@ import { batch } from 'react-redux' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' import { getConfiguredSource } from 'src/logic/collectibles/sources' import { addNftAssets, addNftTokens } from 'src/logic/collectibles/store/actions/addCollectibles' import { Dispatch } from 'redux' const fetchCollectibles = (safeAddress: string) => async (dispatch: Dispatch): Promise => { try { - const network = getNetwork() + const network = getNetworkId() const source = getConfiguredSource() const collectibles = await source.fetchAllUserCollectiblesByCategoryAsync(safeAddress, network) diff --git a/src/logic/contractInteraction/sources/EtherscanService.ts b/src/logic/contractInteraction/sources/EtherscanService.ts index d9e7bfc5df..0c60e4092b 100644 --- a/src/logic/contractInteraction/sources/EtherscanService.ts +++ b/src/logic/contractInteraction/sources/EtherscanService.ts @@ -1,7 +1,7 @@ import { RateLimit } from 'async-sema' import memoize from 'lodash.memoize' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { ETHERSCAN_API_KEY } from 'src/utils/constants' class EtherscanService { diff --git a/src/logic/cookies/utils/index.ts b/src/logic/cookies/utils/index.ts index 6be77a0ae8..7b9f8ce7ea 100644 --- a/src/logic/cookies/utils/index.ts +++ b/src/logic/cookies/utils/index.ts @@ -1,9 +1,8 @@ import Cookies from 'js-cookie' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { getNetworkName } from 'src/config' -const PREFIX = `v1_${ETHEREUM_NETWORK[getNetwork()]}` +const PREFIX = `v1_${getNetworkName()}` export const loadFromCookie = async (key) => { try { diff --git a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts index 32bf362ff5..7d9f35d0e4 100644 --- a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts +++ b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts @@ -1,7 +1,7 @@ import { aNewStore } from 'src/store' import fetchTokenCurrenciesBalances from 'src/logic/currencyValues/api/fetchTokenCurrenciesBalances' import axios from 'axios' -import { getTxServiceHost } from 'src/config' +import { getTxServiceUrl } from 'src/config' jest.mock('axios') describe('fetchTokenCurrenciesBalances', () => { @@ -38,7 +38,7 @@ describe('fetchTokenCurrenciesBalances', () => { usdConversion: '1.188', }, ] - const apiUrl = getTxServiceHost() + const apiUrl = getTxServiceUrl() // @ts-ignore axios.get.mockImplementationOnce(() => Promise.resolve(expectedResult)) diff --git a/src/logic/currencyValues/api/fetchCurrenciesRates.ts b/src/logic/currencyValues/api/fetchCurrenciesRates.ts index 00e2c48a1d..6f0c0f59f2 100644 --- a/src/logic/currencyValues/api/fetchCurrenciesRates.ts +++ b/src/logic/currencyValues/api/fetchCurrenciesRates.ts @@ -1,6 +1,6 @@ import axios from 'axios' -import { getExchangeRatesUrl } from 'src/config' +import { EXCHANGE_RATE_URL } from 'src/utils/constants' import { AVAILABLE_CURRENCIES } from '../store/model/currencyValues' import fetchTokenCurrenciesBalances from './fetchTokenCurrenciesBalances' import BigNumber from 'bignumber.js' @@ -25,7 +25,7 @@ const fetchCurrenciesRates = async ( } try { - const url = `${getExchangeRatesUrl()}?base=${baseCurrency}&symbols=${targetCurrencyValue}` + const url = `${EXCHANGE_RATE_URL}?base=${baseCurrency}&symbols=${targetCurrencyValue}` const result = await axios.get(url) if (result?.data) { const { rates } = result.data diff --git a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts index c2804708a9..28eba7e05d 100644 --- a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts +++ b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts @@ -1,6 +1,6 @@ import axios, { AxiosResponse } from 'axios' -import { getTxServiceHost } from 'src/config' +import { getTxServiceUrl } from 'src/config' import { TokenProps } from 'src/logic/tokens/store/model/token' export type BalanceEndpoint = { @@ -15,7 +15,7 @@ const fetchTokenCurrenciesBalances = ( safeAddress: string, excludeSpamTokens = true, ): Promise> => { - const apiUrl = getTxServiceHost() + const apiUrl = getTxServiceUrl() const url = `${apiUrl}safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}` return axios.get(url, { diff --git a/src/logic/notifications/notificationTypes.ts b/src/logic/notifications/notificationTypes.ts index 62fbe24744..d1b1b90cd7 100644 --- a/src/logic/notifications/notificationTypes.ts +++ b/src/logic/notifications/notificationTypes.ts @@ -1,8 +1,6 @@ import { OptionsObject } from 'notistack' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' -import { capitalize } from 'src/utils/css' +import { getNetworkName } from 'src/config' export const SUCCESS = 'success' export const ERROR = 'error' @@ -199,7 +197,7 @@ export const NOTIFICATIONS: Record = { options: { variant: WARNING, persist: true, preventDuplicate: true }, }, WRONG_NETWORK_MSG: { - message: `Wrong network: Please use ${capitalize(ETHEREUM_NETWORK[getNetwork()])}`, + message: `Wrong network: Please use ${getNetworkName()}`, options: { variant: WARNING, persist: true, preventDuplicate: true }, }, diff --git a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts b/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts index b054b123e8..6265ff024e 100644 --- a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts +++ b/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts @@ -1,6 +1,6 @@ import axios, { AxiosResponse } from 'axios' -import { getAllTransactionsUriFrom, getTxServiceHost } from 'src/config' +import { getAllTransactionsUriFrom, getTxServiceUrl } from 'src/config' import { checksumAddress } from 'src/utils/checksumAddress' import { Transaction } from '../../models/types/transactions.d' @@ -21,7 +21,7 @@ type TransactionDTO = { } const getAllTransactionsUri = (safeAddress: string): string => { - const host = getTxServiceHost() + const host = getTxServiceUrl() const address = checksumAddress(safeAddress) const base = getAllTransactionsUriFrom(address) diff --git a/src/logic/safe/transactions/incomingTxHistory.ts b/src/logic/safe/transactions/incomingTxHistory.ts index c7d78e5476..e4597eb067 100644 --- a/src/logic/safe/transactions/incomingTxHistory.ts +++ b/src/logic/safe/transactions/incomingTxHistory.ts @@ -1,8 +1,8 @@ -import { getIncomingTxServiceUriTo, getTxServiceHost } from 'src/config' +import { getIncomingTxServiceUriTo, getTxServiceUrl } from 'src/config' import { checksumAddress } from 'src/utils/checksumAddress' export const buildIncomingTxServiceUrl = (safeAddress: string): string => { - const host = getTxServiceHost() + const host = getTxServiceUrl() const address = checksumAddress(safeAddress) const base = getIncomingTxServiceUriTo(address) diff --git a/src/logic/safe/transactions/txHistory.ts b/src/logic/safe/transactions/txHistory.ts index eeb144364f..b12300d2eb 100644 --- a/src/logic/safe/transactions/txHistory.ts +++ b/src/logic/safe/transactions/txHistory.ts @@ -1,7 +1,7 @@ import axios from 'axios' import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' -import { getTxServiceHost, getTxServiceUriFrom } from 'src/config' +import { getTxServiceUrl, getTxServiceUriFrom } from 'src/config' import { checksumAddress } from 'src/utils/checksumAddress' const calculateBodyFrom = async ( @@ -45,7 +45,7 @@ const calculateBodyFrom = async ( } export const buildTxServiceUrl = (safeAddress: string): string => { - const host = getTxServiceHost() + const host = getTxServiceUrl() const address = checksumAddress(safeAddress) const base = getTxServiceUriFrom(address) return `${host}${base}?has_confirmations=True` diff --git a/src/logic/safe/utils/safeVersion.ts b/src/logic/safe/utils/safeVersion.ts index 5fe5ee3460..25618a557b 100644 --- a/src/logic/safe/utils/safeVersion.ts +++ b/src/logic/safe/utils/safeVersion.ts @@ -3,8 +3,8 @@ import semverSatisfies from 'semver/functions/satisfies' import semverValid from 'semver/functions/valid' import { GnosisSafe } from 'src/types/contracts/GnosisSafe.d' -import { getSafeLastVersion } from 'src/config' import { getGnosisSafeInstanceAt, getSafeMasterContract } from 'src/logic/contracts/safeContracts' +import { LATEST_SAFE_VERSION } from 'src/utils/constants' export const FEATURES = [ { name: 'ERC721', validVersion: '>=1.1.1' }, @@ -64,7 +64,7 @@ export const getCurrentMasterContractLastVersion = async (): Promise => } catch (err) { // Default in case that it's not possible to obtain the version from the contract, returns a hardcoded value or an // env variable - safeMasterVersion = getSafeLastVersion() + safeMasterVersion = LATEST_SAFE_VERSION } return safeMasterVersion } diff --git a/src/logic/tokens/api/fetchTokenBalanceList.ts b/src/logic/tokens/api/fetchTokenBalanceList.ts index c446858c45..91bdc399df 100644 --- a/src/logic/tokens/api/fetchTokenBalanceList.ts +++ b/src/logic/tokens/api/fetchTokenBalanceList.ts @@ -1,9 +1,9 @@ import axios from 'axios' -import { getTxServiceHost } from 'src/config/index' +import { getTxServiceUrl } from 'src/config/index' const fetchTokenBalanceList = (safeAddress) => { - const apiUrl = getTxServiceHost() + const apiUrl = getTxServiceUrl() const url = `${apiUrl}safes/${safeAddress}/balances/` return axios.get(url, { diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index fbe9854362..0b303d660e 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -1,27 +1,14 @@ -import { NETWORK } from 'src/utils/constants' import Web3 from 'web3' +import { provider as Provider } from 'web3-core' +import { ContentHash } from 'web3-eth-ens' +import { getNetworkId } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { NETWORK } from 'src/utils/constants' import { sameAddress } from './ethAddresses' import { EMPTY_DATA } from './ethTransactions' - -import { getNetwork } from 'src/config' -import { ContentHash } from 'web3-eth-ens' -import { provider as Provider } from 'web3-core' import { ProviderProps } from './store/model/provider' -export enum ETHEREUM_NETWORK { - MAINNET = 1, - MORDEN = 2, - ROPSTEN = 3, - RINKEBY = 4, - GOERLI = 5, - KOVAN = 42, - XDAI = 100, - ENERGY_WEB_CHAIN = 246, - VOLTA = 73799, - UNKNOWN = 0, -} - export const WALLET_PROVIDER = { SAFE: 'SAFE', METAMASK: 'METAMASK', @@ -51,7 +38,7 @@ export const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, }etherscan.io/${type}/${value}` export const getExplorerLink = (type: ExplorerTypes, value: string): string => { - const network = getNetwork() + const network = getNetworkId() switch (network) { case ETHEREUM_NETWORK.MAINNET: diff --git a/src/logic/wallets/store/actions/fetchProvider.ts b/src/logic/wallets/store/actions/fetchProvider.ts index 9e2390fdaa..c2907c67dc 100644 --- a/src/logic/wallets/store/actions/fetchProvider.ts +++ b/src/logic/wallets/store/actions/fetchProvider.ts @@ -2,10 +2,11 @@ import ReactGA from 'react-ga' import addProvider from './addProvider' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications' import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { ETHEREUM_NETWORK, getProviderInfo, getWeb3 } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +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' import { Dispatch } from 'redux' @@ -24,11 +25,11 @@ const handleProviderNotification = (provider, dispatch) => { return } - if (network !== getNetwork()) { + if (network !== getNetworkId()) { dispatch(enqueueSnackbar(NOTIFICATIONS.WRONG_NETWORK_MSG)) return } - if (ETHEREUM_NETWORK.RINKEBY === getNetwork()) { + if (ETHEREUM_NETWORK.RINKEBY === getNetworkId()) { dispatch(enqueueSnackbar(enhanceSnackbarForAction(NOTIFICATIONS.RINKEBY_VERSION_MSG))) } diff --git a/src/logic/wallets/store/model/provider.ts b/src/logic/wallets/store/model/provider.ts index dd7c4c389a..146b2ddb70 100644 --- a/src/logic/wallets/store/model/provider.ts +++ b/src/logic/wallets/store/model/provider.ts @@ -1,5 +1,6 @@ import { Record, RecordOf } from 'immutable' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' + +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' export type ProviderProps = { name: string diff --git a/src/logic/wallets/store/selectors/index.ts b/src/logic/wallets/store/selectors/index.ts index 51a0474006..56e41f67c8 100644 --- a/src/logic/wallets/store/selectors/index.ts +++ b/src/logic/wallets/store/selectors/index.ts @@ -1,6 +1,6 @@ import { createSelector } from 'reselect' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { PROVIDER_REDUCER_ID, ProviderState } from 'src/logic/wallets/store/reducer/provider' import { AppReduxState } from 'src/store' diff --git a/src/logic/wallets/utils/walletList.ts b/src/logic/wallets/utils/walletList.ts index 0921a76ae9..8fcf755c3e 100644 --- a/src/logic/wallets/utils/walletList.ts +++ b/src/logic/wallets/utils/walletList.ts @@ -1,5 +1,5 @@ import { getInfuraUrl, getRPCUrl } from '../getWeb3' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' @@ -7,7 +7,7 @@ const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f // const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78' const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40' -const network = getNetwork() +const network = getNetworkId() const infuraUrl = getInfuraUrl(network) const wallets = [ diff --git a/src/routes/load/container/Load.tsx b/src/routes/load/container/Load.tsx index efa6ba79ca..6e4b530568 100644 --- a/src/routes/load/container/Load.tsx +++ b/src/routes/load/container/Load.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import Layout from 'src/routes/load/components/Layout' import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME } from '../components/fields' diff --git a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts index 590402807b..966c988bda 100644 --- a/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts +++ b/src/routes/safe/components/Apps/hooks/useIframeMessageHandler.ts @@ -12,13 +12,13 @@ import { } from '@gnosis.pm/safe-apps-sdk' import { useDispatch, useSelector } from 'react-redux' import { useEffect, useCallback, MutableRefObject } from 'react' -import { getTxServiceHost } from 'src/config/' +import { getTxServiceUrl } from 'src/config/' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { safeEthBalanceSelector, safeNameSelector, safeParamAddressFromStateSelector, } from 'src/logic/safe/store/selectors' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { networkSelector } from 'src/logic/wallets/store/selectors' import { SafeApp } from 'src/routes/safe/components/Apps/types.d' @@ -98,7 +98,7 @@ const useIframeMessageHandler = ( const envInfoMessage = { messageId: INTERFACE_MESSAGES.ENV_INFO, data: { - txServiceUrl: getTxServiceHost(), + txServiceUrl: getTxServiceUrl(), }, } diff --git a/src/routes/safe/components/Apps/index.tsx b/src/routes/safe/components/Apps/index.tsx index 9de471bdac..bc72ec224e 100644 --- a/src/routes/safe/components/Apps/index.tsx +++ b/src/routes/safe/components/Apps/index.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react' import { INTERFACE_MESSAGES, Transaction, RequestId, LowercaseNetworks } from '@gnosis.pm/safe-apps-sdk' import { Card, IconText, Loader, Menu, Title } from '@gnosis.pm/safe-react-components' import { useSelector } from 'react-redux' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import styled, { css } from 'styled-components' import ManageApps from './components/ManageApps' diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index beeba0c089..74358ab12b 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -3,7 +3,7 @@ import memoize from 'lodash.memoize' import { SafeApp } from './types.d' -import { getGnosisSafeAppsUrl } from 'src/config/index' +import { getGnosisSafeAppsUrl } from 'src/config' import { getContentFromENS } from 'src/logic/wallets/getWeb3' import appsIconSvg from 'src/routes/safe/components/Transactions/TxsTable/TxType/assets/appsIcon.svg' diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts index 52922fd024..125462fc02 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils/index.ts @@ -3,7 +3,7 @@ import createDecorator from 'final-form-calculate' import { ContractSendMethod } from 'web3-eth-contract' import { mustBeEthereumAddress, mustBeEthereumContractAddress } from 'src/components/forms/validator' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' import { getConfiguredSource } from 'src/logic/contractInteraction/sources' import { AbiItemExtended } from 'src/logic/contractInteraction/sources/ABIService' import { getAddressFromENS, getWeb3 } from 'src/logic/wallets/getWeb3' @@ -23,7 +23,7 @@ export const abiExtractor = createDecorator({ ) { return } - const network = getNetwork() + const network = getNetworkId() const source = getConfiguredSource() return source.getContractABI(contractAddress, network) }, diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx index 181722bda6..d70ac9d498 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx @@ -1,10 +1,9 @@ import { makeStyles } from '@material-ui/core/styles' import React from 'react' import { EthHashInfo } from '@gnosis.pm/safe-react-components' -import { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' import { Transaction } from 'src/logic/safe/store/models/types/transaction' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import { formatDate } from 'src/routes/safe/components/Transactions/TxsTable/columns' import Bold from 'src/components/layout/Bold' import Paragraph from 'src/components/layout/Paragraph' @@ -47,13 +46,7 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Creator: {tx.creator ? ( - + ) : ( 'n/a' )} @@ -66,7 +59,7 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { shortenHash={4} showCopyBtn showEtherscanBtn - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> ) : ( 'n/a' @@ -75,13 +68,7 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Mastercopy: {tx.masterCopy ? ( - + ) : ( 'n/a' )} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx index 0d2348d022..fc973f8670 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx @@ -3,8 +3,6 @@ import cn from 'classnames' import React from 'react' import { useSelector } from 'react-redux' import { EthHashInfo } from '@gnosis.pm/safe-react-components' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import CancelSmallFilledCircle from './assets/cancel-small-filled.svg' import ConfirmSmallFilledCircle from './assets/confirm-small-filled.svg' @@ -14,6 +12,7 @@ import ConfirmSmallRedCircle from './assets/confirm-small-red.svg' import PendingSmallYellowCircle from './assets/confirm-small-yellow.svg' import { styles } from './style' +import { getNetworkName } from 'src/config' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' import Img from 'src/components/layout/Img' @@ -184,7 +183,7 @@ const OwnerComponent = (props: OwnerComponentProps): React.ReactElement => { showIdenticon showCopyBtn showEtherscanBtn - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> {owner === userAddress && {isCancelTx ? rejectButton() : confirmButton()}} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx index 030f00a7f5..10353ded90 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx @@ -1,7 +1,6 @@ import { IconText, Text, EthHashInfo } from '@gnosis.pm/safe-react-components' import { makeStyles } from '@material-ui/core/styles' import React from 'react' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' import { styles } from './styles' @@ -24,7 +23,7 @@ import { Transaction } from 'src/logic/safe/store/models/types/transaction' import { DataDecoded } from 'src/routes/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 { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' export const TRANSACTIONS_DESC_CUSTOM_VALUE_TEST_ID = 'tx-description-custom-value' export const TRANSACTIONS_DESC_CUSTOM_DATA_TEST_ID = 'tx-description-custom-data' @@ -86,13 +85,7 @@ const MultiSendCustomDataAction = ({ tx, order }: { tx: MultiSendDetails; order: Send {humanReadableValue(tx.value)} ETH to: - + {!!tx.data && } @@ -196,7 +189,7 @@ const GenericCustomData = ({ amount = '0', data, recipient, storedTx }: GenericC showIdenticon showCopyBtn showEtherscanBtn - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx index ae46d2e15e..d773789a88 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx @@ -1,9 +1,8 @@ import { Text, EthHashInfo } from '@gnosis.pm/safe-react-components' import React from 'react' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' import styled from 'styled-components' -import { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' import { isAddress, isArrayParameter, @@ -58,7 +57,7 @@ const Value = ({ type, ...props }: RenderValueProps): React.ReactElement => { showCopyBtn showEtherscanBtn shortenHash={4} - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> ) } diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx index ce655808a2..b9b31884aa 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx @@ -13,7 +13,7 @@ import { CreationTx } from './CreationTx' import { OutgoingTx } from './OutgoingTx' import { styles } from './style' -import { getNetwork } from 'src/config' +import { getNetworkName } from 'src/config' import Block from 'src/components/layout/Block' import Bold from 'src/components/layout/Bold' import Col from 'src/components/layout/Col' @@ -21,7 +21,7 @@ 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 { ETHEREUM_NETWORK, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransaction' import { safeNonceSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' @@ -73,7 +73,7 @@ const ExpandedTx = ({ cancelTx, tx }: ExpandedTxProps): React.ReactElement => { shortenHash={4} showCopyBtn showEtherscanBtn - network={ETHEREUM_NETWORK[getNetwork()]} + network={getNetworkName()} /> ) : ( 'n/a' diff --git a/src/utils/constants.ts b/src/utils/constants.ts index b873693fb3..44fb98ee27 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,14 +1,20 @@ -export const NETWORK = process.env.REACT_APP_NETWORK || 'RINKEBY' -export const GOOGLE_ANALYTICS_ID_RINKEBY = process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY -export const GOOGLE_ANALYTICS_ID_MAINNET = process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET -export const INTERCOM_ID = process.env.REACT_APP_INTERCOM_ID +export const APP_ENV = process.env.REACT_APP_ENV +export const NODE_ENV = process.env.NODE_ENV +export const NETWORK = process.env.REACT_APP_NETWORK?.toUpperCase() || 'RINKEBY' +export const GOOGLE_ANALYTICS_ID = { + RINKEBY: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY, + MAINNET: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET, +} +export const INTERCOM_ID = process.env.REACT_APP_ENV === 'production' ? process.env.REACT_APP_INTERCOM_ID : 'plssl1fl' export const PORTIS_ID = process.env.REACT_APP_PORTIS_ID export const SQUARELINK_ID = process.env.REACT_APP_SQUARELINK_ID export const FORTMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY export const INFURA_TOKEN = process.env.REACT_APP_INFURA_TOKEN || '' -export const LATEST_SAFE_VERSION = process.env.REACT_APP_LATEST_SAFE_VERSION || 'not-defined' +export const LATEST_SAFE_VERSION = process.env.REACT_APP_LATEST_SAFE_VERSION || '1.1.1' export const APP_VERSION = process.env.REACT_APP_APP_VERSION || 'not-defined' export const OPENSEA_API_KEY = process.env.REACT_APP_OPENSEA_API_KEY || '' export const COLLECTIBLES_SOURCE = process.env.REACT_APP_COLLECTIBLES_SOURCE || 'OpenSea' export const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 5000 export const ETHERSCAN_API_KEY = process.env.REACT_APP_ETHERSCAN_API_KEY +export const EXCHANGE_RATE_URL = 'https://api.exchangeratesapi.io/latest' +export const EXCHANGE_RATE_URL_FALLBACK = 'https://api.coinbase.com/v2/exchange-rates' diff --git a/src/utils/intercom.ts b/src/utils/intercom.ts index 6fb98cbf97..68035e7d98 100644 --- a/src/utils/intercom.ts +++ b/src/utils/intercom.ts @@ -1,8 +1,8 @@ -import { getIntercomId } from 'src/config' +import { INTERCOM_ID } from 'src/utils/constants' // eslint-disable-next-line consistent-return export const loadIntercom = () => { - const APP_ID = getIntercomId() + const APP_ID = INTERCOM_ID if (!APP_ID) { console.error('[Intercom] - In order to use Intercom you need to add an appID') return null diff --git a/src/utils/storage/index.ts b/src/utils/storage/index.ts index dcc3f5564b..d9f7a13328 100644 --- a/src/utils/storage/index.ts +++ b/src/utils/storage/index.ts @@ -1,7 +1,6 @@ import { ImmortalStorage, IndexedDbStore, LocalStorageStore } from 'immortal-db' -import { getNetwork } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' +import { getNetworkName } from 'src/config' // Don't use sessionStorage and cookieStorage // https://github.com/gruns/ImmortalDB/issues/22 @@ -9,7 +8,7 @@ import { ETHEREUM_NETWORK } from 'src/logic/wallets/getWeb3' const stores = [IndexedDbStore, LocalStorageStore] export const storage = new ImmortalStorage(stores) -const PREFIX = `v2_${ETHEREUM_NETWORK[getNetwork()]}` +const PREFIX = `v2_${getNetworkName()}` export const loadFromStorage = async (key: string): Promise => { try { From c86a0ea31614e92527fb172482bf8fa0fdb2893b Mon Sep 17 00:00:00 2001 From: fernandomg Date: Mon, 5 Oct 2020 20:46:26 -0300 Subject: [PATCH 09/19] fix function name after merge development --- .../screens/ContractInteraction/ContractABI/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx index 57168b1605..cea9902db7 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx @@ -5,7 +5,7 @@ import TextareaField from 'src/components/forms/TextareaField' import { mustBeEthereumAddress, mustBeEthereumContractAddress } from 'src/components/forms/validator' import Col from 'src/components/layout/Col' import Row from 'src/components/layout/Row' -import { getNetwork } from 'src/config' +import { getNetworkId } from 'src/config' import { getConfiguredSource } from 'src/logic/contractInteraction/sources' import { extractUsefulMethods } from 'src/logic/contractInteraction/sources/ABIService' @@ -36,7 +36,7 @@ const ContractABI = (): React.ReactElement => { const isEthereumContractAddress = (await mustBeEthereumContractAddress(contractAddress)) === undefined if (isEthereumAddress && isEthereumContractAddress) { - const network = getNetwork() + const network = getNetworkId() const source = getConfiguredSource() const abi = await source.getContractABI(contractAddress, network) const isValidABI = hasUsefulMethods(abi) === undefined From 52785278eab091b7592f332840289fd541a974f3 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Tue, 6 Oct 2020 13:14:45 -0300 Subject: [PATCH 10/19] (Feature) [xDai] - Contract interaction abi lookup (#1429) --- src/config/index.ts | 56 ++++++++++++++++- .../sources/EtherscanService.ts | 60 ------------------- .../contractInteraction/sources/index.ts | 7 --- .../ContractInteraction/ContractABI/index.tsx | 7 +-- 4 files changed, 57 insertions(+), 73 deletions(-) delete mode 100644 src/logic/contractInteraction/sources/EtherscanService.ts delete mode 100644 src/logic/contractInteraction/sources/index.ts diff --git a/src/config/index.ts b/src/config/index.ts index ec5c367d34..ca398af093 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -6,8 +6,9 @@ import { SafeFeatures, } from 'src/config/networks/network.d' import { checksumAddress } from 'src/utils/checksumAddress' -import { GOOGLE_ANALYTICS_ID, NETWORK, APP_ENV, NODE_ENV } from 'src/utils/constants' +import { GOOGLE_ANALYTICS_ID, NETWORK, APP_ENV, NODE_ENV, ETHERSCAN_API_KEY } from 'src/utils/constants' import { ensureOnce } from 'src/utils/singleton' +import memoize from 'lodash.memoize' export const getNetworkId = (): ETHEREUM_NETWORK => ETHEREUM_NETWORK[NETWORK] @@ -95,3 +96,56 @@ export const buildSafeCreationTxUrl = (safeAddress: string) => { return `${host}${base}` } + +const fetchContractABI = memoize( + async (url: string, contractAddress: string, apiKey?: string) => { + let params: any = { + module: 'contract', + action: 'getAbi', + address: contractAddress, + } + + if (apiKey) { + params = { ...params, apiKey } + } + + const response = await fetch(`${url}?${new URLSearchParams(params)}`) + + if (!response.ok) { + return { status: 0, result: [] } + } + + return response.json() + }, + (url, contractAddress) => `${url}_${contractAddress}`, +) + +const getNetworkExplorerApiKey = (networkExplorerName: string): string | undefined=> { + switch (networkExplorerName.toLowerCase()) { + case 'etherscan': { + return ETHERSCAN_API_KEY + } + default: { + return undefined + } + } +} + +export const getContractABI = async (contractAddress: string) =>{ + const { apiUrl, name } = getNetworkExplorerInfo() + + const apiKey = getNetworkExplorerApiKey(name) + + try { + const { result, status } = await fetchContractABI(apiUrl, contractAddress, apiKey) + + if (status === '0') { + return [] + } + + return result + } catch (e) { + console.error('Failed to retrieve ABI', e) + return undefined + } +} diff --git a/src/logic/contractInteraction/sources/EtherscanService.ts b/src/logic/contractInteraction/sources/EtherscanService.ts deleted file mode 100644 index 0c60e4092b..0000000000 --- a/src/logic/contractInteraction/sources/EtherscanService.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { RateLimit } from 'async-sema' -import memoize from 'lodash.memoize' - -import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' -import { ETHERSCAN_API_KEY } from 'src/utils/constants' - -class EtherscanService { - _rateLimit = async () => {} - - _endpointsUrls = { - [ETHEREUM_NETWORK.MAINNET]: 'https://api.etherscan.io/api', - [ETHEREUM_NETWORK.RINKEBY]: 'https://api-rinkeby.etherscan.io/api', - } - - _fetch = memoize( - async (url: string, contractAddress: string) => { - let params: any = { - module: 'contract', - action: 'getAbi', - address: contractAddress, - } - - if (ETHERSCAN_API_KEY) { - const apiKey = ETHERSCAN_API_KEY - params = { ...params, apiKey } - } - - const response = await fetch(`${url}?${new URLSearchParams(params)}`) - - if (!response.ok) { - return { status: 0, result: [] } - } - - return response.json() - }, - (url, contractAddress) => `${url}_${contractAddress}`, - ) - - constructor(options) { - this._rateLimit = RateLimit(options.rps) - } - - async getContractABI(contractAddress, network) { - const etherscanUrl = this._endpointsUrls[network] - try { - const { result, status } = await this._fetch(etherscanUrl, contractAddress) - - if (status === '0') { - return [] - } - - return result - } catch (e) { - console.error('Failed to retrieve ABI', e) - return undefined - } - } -} - -export default EtherscanService diff --git a/src/logic/contractInteraction/sources/index.ts b/src/logic/contractInteraction/sources/index.ts deleted file mode 100644 index b5bc4f3fd1..0000000000 --- a/src/logic/contractInteraction/sources/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -import EtherscanService from 'src/logic/contractInteraction/sources/EtherscanService' - -const sources = { - etherscan: new EtherscanService({ rps: 4 }), -} - -export const getConfiguredSource = () => sources['etherscan'] diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx index cea9902db7..0df470c87a 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI/index.tsx @@ -5,8 +5,7 @@ import TextareaField from 'src/components/forms/TextareaField' import { mustBeEthereumAddress, mustBeEthereumContractAddress } from 'src/components/forms/validator' import Col from 'src/components/layout/Col' import Row from 'src/components/layout/Row' -import { getNetworkId } from 'src/config' -import { getConfiguredSource } from 'src/logic/contractInteraction/sources' +import { getContractABI } from 'src/config' import { extractUsefulMethods } from 'src/logic/contractInteraction/sources/ABIService' export const NO_DATA = 'no data' @@ -36,9 +35,7 @@ const ContractABI = (): React.ReactElement => { const isEthereumContractAddress = (await mustBeEthereumContractAddress(contractAddress)) === undefined if (isEthereumAddress && isEthereumContractAddress) { - const network = getNetworkId() - const source = getConfiguredSource() - const abi = await source.getContractABI(contractAddress, network) + const abi = await getContractABI(contractAddress) const isValidABI = hasUsefulMethods(abi) === undefined // this check may help in scenarios where the user first pastes the ABI, From 74cb6cf47637cf879edd16194561b8a2e3b899d8 Mon Sep 17 00:00:00 2001 From: nicolas Date: Tue, 6 Oct 2020 13:42:27 -0300 Subject: [PATCH 11/19] Filter Apps by network (#1433) * Filter apps by network * add missing network --- .../safe/components/Apps/hooks/useAppList.ts | 20 +++- src/routes/safe/components/Apps/utils.ts | 95 ++++++++++++++++--- 2 files changed, 97 insertions(+), 18 deletions(-) diff --git a/src/routes/safe/components/Apps/hooks/useAppList.ts b/src/routes/safe/components/Apps/hooks/useAppList.ts index fc48a71682..c2f13c1393 100644 --- a/src/routes/safe/components/Apps/hooks/useAppList.ts +++ b/src/routes/safe/components/Apps/hooks/useAppList.ts @@ -2,6 +2,7 @@ import { useState, useEffect, useCallback } from 'react' import { loadFromStorage, saveToStorage } from 'src/utils/storage' import { getAppInfoFromUrl, staticAppsList } from '../utils' import { SafeApp, StoredSafeApp } from '../types' +import { getNetworkId } from 'src/config' const APPS_STORAGE_KEY = 'APPS_STORAGE_KEY' @@ -28,18 +29,29 @@ const useAppList = (): UseAppListReturnType => { // * third-party apps added by the user // * disabled status for both static and third-party apps const persistedAppList = (await loadFromStorage(APPS_STORAGE_KEY)) || [] - const list: (StoredSafeApp & { isDeletable?: boolean })[] = persistedAppList.map((a) => ({ + let list: (StoredSafeApp & { isDeletable: boolean; networks?: number[] })[] = persistedAppList.map((a) => ({ ...a, isDeletable: true, })) + // merge stored apps with static apps (apps added manually can be deleted by the user) staticAppsList.forEach((staticApp) => { const app = list.find((persistedApp) => persistedApp.url === staticApp.url) - if (!app) { - list.push({ ...staticApp, isDeletable: false }) - } else { + if (app) { app.isDeletable = false + app.networks = staticApp.networks + } else { + list.push({ ...staticApp, isDeletable: false }) + } + }) + + // filter app by network + list = list.filter((app) => { + // if the app does not expose supported networks, include them. (backward compatible) + if (!app.networks) { + return true } + return app.networks.includes(getNetworkId()) }) let apps: SafeApp[] = [] diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index 74358ab12b..af670e6737 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -6,6 +6,7 @@ import { SafeApp } from './types.d' import { getGnosisSafeAppsUrl } from 'src/config' import { getContentFromENS } from 'src/logic/wallets/getWeb3' import appsIconSvg from 'src/routes/safe/components/Transactions/TxsTable/TxType/assets/appsIcon.svg' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' const removeLastTrailingSlash = (url) => { if (url.substr(-1) === '/') { @@ -15,33 +16,99 @@ const removeLastTrailingSlash = (url) => { } const gnosisAppsUrl = removeLastTrailingSlash(getGnosisSafeAppsUrl()) -export const staticAppsList: Array<{ url: string; disabled: boolean }> = [ +export const staticAppsList: Array<{ url: string; disabled: boolean; networks: number[] }> = [ // 1inch - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmUDTSghr154kCCGguyA3cbG5HRVd2tQgNR7yD69bcsjm5`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmUDTSghr154kCCGguyA3cbG5HRVd2tQgNR7yD69bcsjm5`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET], + }, // Aave - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmY1MUZo44UkT8EokYHs7xDvWEziYSn7n3c4ojVB6qo3SM`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmY1MUZo44UkT8EokYHs7xDvWEziYSn7n3c4ojVB6qo3SM`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET], + }, //Balancer Exchange - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmfPLXne1UrY399RQAcjD1dmBhQrPGZWgp311CDLLW3VTn`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmfPLXne1UrY399RQAcjD1dmBhQrPGZWgp311CDLLW3VTn`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET], + }, //Balancer Pool - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmaTucdZYLKTqaewwJduVMM8qfCDhyaEqjd8tBNae26K1J`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmaTucdZYLKTqaewwJduVMM8qfCDhyaEqjd8tBNae26K1J`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET], + }, // Compound - { url: `${gnosisAppsUrl}/compound`, disabled: false }, + { url: `${gnosisAppsUrl}/compound`, disabled: false, networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY] }, // Idle - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmZ3oug89a3BaVqdJrJEA8CKmLF4M8snuAnphR6z1yq8V8`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmZ3oug89a3BaVqdJrJEA8CKmLF4M8snuAnphR6z1yq8V8`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY], + }, // request - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmTBBaiDQyGa17DJ7DdviyHbc51fTVgf6Z5PW5w2YUTkgR`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmTBBaiDQyGa17DJ7DdviyHbc51fTVgf6Z5PW5w2YUTkgR`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY], + }, // Sablier - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmeHa5CS6eAMRvQfTBwWfcXKrXZ7itZTpWSM6625ZZ522N`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmeHa5CS6eAMRvQfTBwWfcXKrXZ7itZTpWSM6625ZZ522N`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY], + }, // Synthetix - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmXLxxczMH4MBEYDeeN9zoiHDzVkeBmB5rBjA3UniPEFcA`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmXLxxczMH4MBEYDeeN9zoiHDzVkeBmB5rBjA3UniPEFcA`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY], + }, // OpenZeppelin - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmQovvfYYMUXjZfNbysQDUEXR8nr55iJRwcYgJQGJR7KEA`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/QmQovvfYYMUXjZfNbysQDUEXR8nr55iJRwcYgJQGJR7KEA`, + disabled: false, + networks: [ + ETHEREUM_NETWORK.MAINNET, + ETHEREUM_NETWORK.RINKEBY, + ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, + ETHEREUM_NETWORK.VOLTA, + ETHEREUM_NETWORK.XDAI, + ], + }, // TX-Builder - { url: `${gnosisAppsUrl}/tx-builder`, disabled: false }, + { + url: `${gnosisAppsUrl}/tx-builder`, + disabled: false, + networks: [ + ETHEREUM_NETWORK.MAINNET, + ETHEREUM_NETWORK.RINKEBY, + ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, + ETHEREUM_NETWORK.VOLTA, + ETHEREUM_NETWORK.XDAI, + ], + }, // Wallet-Connect - { url: `${gnosisAppsUrl}/walletConnect`, disabled: false }, + { + url: `${gnosisAppsUrl}/walletConnect`, + disabled: false, + networks: [ + ETHEREUM_NETWORK.MAINNET, + ETHEREUM_NETWORK.RINKEBY, + ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, + ETHEREUM_NETWORK.VOLTA, + ETHEREUM_NETWORK.XDAI, + ], + }, // Yearn Vaults - { url: `${process.env.REACT_APP_IPFS_GATEWAY}/Qme9HuPPhgCtgfj1CktvaDKhTesMueGCV2Kui1Sqna3Xs9`, disabled: false }, + { + url: `${process.env.REACT_APP_IPFS_GATEWAY}/Qme9HuPPhgCtgfj1CktvaDKhTesMueGCV2Kui1Sqna3Xs9`, + disabled: false, + networks: [ETHEREUM_NETWORK.MAINNET], + }, ] export const getAppInfoFromOrigin = (origin: string): Record | null => { From 8c16bce8e3f92d6914e821888a6c43ababd1e829 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Tue, 6 Oct 2020 13:51:23 -0300 Subject: [PATCH 12/19] (Feature) [xDai] - Parametrize ethscan values (#1424) --- package.json | 2 +- .../ProviderDetails/UserDetails.tsx | 11 +-- .../ProviderInfo/ProviderAccessible.tsx | 2 - .../AppLayout/Sidebar/SafeHeader/index.tsx | 8 +- .../SafeList/AddresWrapper.tsx | 79 +++++++++++++++++++ .../SafeListSidebar/SafeList/index.tsx | 73 +---------------- src/config/index.ts | 20 +++++ .../TxsTable/ExpandedTx/CreationTx/index.tsx | 23 ++---- .../OwnersColumn/OwnerComponent.tsx | 7 +- .../TxDescription/CustomDescription.tsx | 13 +-- .../ExpandedTx/TxDescription/Value.tsx | 13 +-- .../TxsTable/ExpandedTx/index.tsx | 12 +-- yarn.lock | 6 +- 13 files changed, 138 insertions(+), 131 deletions(-) create mode 100644 src/components/SafeListSidebar/SafeList/AddresWrapper.tsx diff --git a/package.json b/package.json index f338b848c4..184e8fcb7e 100644 --- a/package.json +++ b/package.json @@ -165,7 +165,7 @@ "dependencies": { "@gnosis.pm/safe-apps-sdk": "0.4.0", "@gnosis.pm/safe-contracts": "1.1.1-dev.2", - "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#1bf397f", + "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#70e57bdd1e0fd5dfdf5768076577c1e000b5fe28", "@gnosis.pm/util-contracts": "2.0.6", "@ledgerhq/hw-transport-node-hid": "5.22.0", "@material-ui/core": "4.11.0", diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index 8540335b64..03c43c859a 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -15,6 +15,7 @@ import Row from 'src/components/layout/Row' import { background, connected as connectedBg, lg, md, sm, warning, xs } from 'src/theme/variables' import { upperFirst } from 'src/utils/css' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { getExplorerInfo } from 'src/config' const dot = require('../../assets/dotRinkeby.svg') const walletIcon = require('../../assets/wallet.svg') @@ -92,7 +93,7 @@ const styles = () => ({ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, provider, userAddress }) => { const status = connected ? 'Connected' : 'Connection error' const color = connected ? 'primary' : 'warning' - + const explorerUrl = getExplorerInfo(userAddress) return ( <> @@ -105,13 +106,7 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, {userAddress ? ( - + ) : ( 'Address not available' )} diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index 0ae85a2a15..cc226e695a 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -2,7 +2,6 @@ import { makeStyles } from '@material-ui/core/styles' import * as React from 'react' import { EthHashInfo, Text } from '@gnosis.pm/safe-react-components' -import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import NetworkLabel from '../NetworkLabel' import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' import Col from 'src/components/layout/Col' @@ -95,7 +94,6 @@ const ProviderInfo = ({ connected, provider, userAddress, network }: ProviderInf identiconSize="xs" textColor={addressColor} textSize="sm" - network={ETHEREUM_NETWORK[network]} /> ) : ( diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index f00c03adaf..0ccc5984be 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -8,11 +8,11 @@ import { Identicon, Button, CopyToClipboardBtn, - EtherscanButton, + ExplorerButton, } from '@gnosis.pm/safe-react-components' -import { getNetworkName } from 'src/config' import FlexSpacer from 'src/components/FlexSpacer' +import { getExplorerInfo } from 'src/config' export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN' @@ -110,7 +110,7 @@ const SafeHeader = ({ ) } - + const explorerUrl = getExplorerInfo(address) return ( @@ -128,7 +128,7 @@ const SafeHeader = ({ - + {granted ? null : ( diff --git a/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx b/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx new file mode 100644 index 0000000000..2dda0e11aa --- /dev/null +++ b/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx @@ -0,0 +1,79 @@ +import React from 'react' +import styled from 'styled-components' +import { ButtonLink, EthHashInfo, Text } from '@gnosis.pm/safe-react-components' +import { formatAmount } from 'src/logic/tokens/utils/formatAmount' +import { sameAddress } from 'src/logic/wallets/ethAddresses' +import DefaultBadge from './DefaultBadge' +import { SafeRecordProps } from 'src/logic/safe/store/models/safe' +import { getExplorerInfo } from 'src/config' +import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' +import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' +import { makeStyles } from '@material-ui/core/styles' + +const StyledButtonLink = styled(ButtonLink)` + visibility: hidden; + white-space: nowrap; +` +const useStyles = makeStyles({ + wrapper: { + display: 'flex', + padding: '5px 0', + width: '100%', + justifyContent: 'space-between', + '& > nth-child(2)': { + display: 'flex', + alignItems: 'center', + }, + }, + addressDetails: { + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + width: '175px', + '& div': { + marginLeft: '0px', + padding: '5px 20px', + '& img': { + marginRight: '5px', + }, + '& p': { + marginTop: '3px', + }, + }, + }, +}) + +type Props = { + safe: SafeRecordProps + defaultSafe: DefaultSafe + setDefaultSafe: SetDefaultSafe +} + +export const AddressWrapper = (props: Props): React.ReactElement => { + const classes = useStyles() + const { safe, defaultSafe, setDefaultSafe } = props + const explorerUrl = getExplorerInfo(safe.address) + return ( +
+ + +
+ {`${formatAmount(safe.ethBalance)} ETH`} + {sameAddress(defaultSafe, safe.address) ? ( + + ) : ( + { + setDefaultSafe(safe.address) + }} + color="primary" + > + Make default + + )} +
+
+ ) +} diff --git a/src/components/SafeListSidebar/SafeList/index.tsx b/src/components/SafeListSidebar/SafeList/index.tsx index f2327a8698..57b60238da 100644 --- a/src/components/SafeListSidebar/SafeList/index.tsx +++ b/src/components/SafeListSidebar/SafeList/index.tsx @@ -1,62 +1,22 @@ import MuiList from '@material-ui/core/List' import ListItem from '@material-ui/core/ListItem' import { makeStyles } from '@material-ui/core/styles' -import { EthHashInfo, Icon, Text, ButtonLink } from '@gnosis.pm/safe-react-components' +import { Icon } from '@gnosis.pm/safe-react-components' import * as React from 'react' import styled from 'styled-components' - import { SafeRecord } from 'src/logic/safe/store/models/safe' import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' -import { getNetworkName } from 'src/config' -import DefaultBadge from './DefaultBadge' import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' -import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { sameAddress } from 'src/logic/wallets/ethAddresses' import { SAFELIST_ADDRESS } from 'src/routes/routes' - +import { AddressWrapper } from './AddresWrapper' export const SIDEBAR_SAFELIST_ROW_TESTID = 'SIDEBAR_SAFELIST_ROW_TESTID' const StyledIcon = styled(Icon)` margin-right: 4px; ` -const AddressWrapper = styled.div` - display: flex; - padding: 5px 0; - width: 100%; - justify-content: space-between; - - > nth-child(2) { - display: flex; - align-items: center; - } -` - -const StyledButtonLink = styled(ButtonLink)` - visibility: hidden; - white-space: nowrap; -` - -const AddressDetails = styled.div` - display: flex; - align-items: center; - justify-content: space-between; - width: 175px; - - div { - margin-left: 0px; - padding: 5px 20px; - - img { - margin-right: 5px; - } - - p { - margin-top: 3px; - } - } -` const useStyles = makeStyles({ list: { @@ -107,34 +67,7 @@ const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe ) : (
placeholder
)} - - - - - - {`${formatAmount(safe.ethBalance)} ETH`} - {sameAddress(defaultSafe, safe.address) ? ( - - ) : ( - { - setDefaultSafe(safe.address) - }} - color="primary" - > - Make default - - )} - - + diff --git a/src/config/index.ts b/src/config/index.ts index ca398af093..d790d2a11b 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -149,3 +149,23 @@ export const getContractABI = async (contractAddress: string) =>{ return undefined } } + +export type BlockScanInfo = () => { + alt: string + url: string +} + +export const getExplorerInfo = (hash: string): BlockScanInfo => { + const { name, url } = getNetworkExplorerInfo() + + const blockScanInfo = () => { + const type = hash.length > 42 ? 'tx' : 'address' + + return { + url: `${url}${type}/${hash}`, + alt: name || '', + } + } + + return blockScanInfo +} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx index d70ac9d498..874224ea5f 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/CreationTx/index.tsx @@ -1,14 +1,15 @@ import { makeStyles } from '@material-ui/core/styles' import React from 'react' import { EthHashInfo } from '@gnosis.pm/safe-react-components' -import { getNetworkName } from 'src/config' 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: { @@ -30,10 +31,12 @@ type Props = { export const CreationTx = ({ tx }: Props): React.ReactElement | null => { const classes = useStyles() - if (!tx) { return null } + const explorerUrl = getExplorerInfo(tx.creator) + const scanBlockFactoryAddressUrl = getExplorerInfo(tx.factoryAddress) + const scanBlockMasterCopyUrl = getExplorerInfo(tx.masterCopy) const isCreationTx = tx.type === TransactionTypes.CREATION @@ -45,22 +48,12 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Creator: - {tx.creator ? ( - - ) : ( - 'n/a' - )} + {tx.creator ? : 'n/a'} Factory: {tx.factoryAddress ? ( - + ) : ( 'n/a' )} @@ -68,7 +61,7 @@ export const CreationTx = ({ tx }: Props): React.ReactElement | null => { Mastercopy: {tx.masterCopy ? ( - + ) : ( 'n/a' )} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx index fc973f8670..06bbaec641 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/OwnersColumn/OwnerComponent.tsx @@ -12,12 +12,12 @@ import ConfirmSmallRedCircle from './assets/confirm-small-red.svg' import PendingSmallYellowCircle from './assets/confirm-small-yellow.svg' import { styles } from './style' -import { getNetworkName } from 'src/config' 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' @@ -163,7 +163,7 @@ const OwnerComponent = (props: OwnerComponentProps): React.ReactElement => { ) } - + const explorerUrl = getExplorerInfo(owner) return (
{ shortenHash={4} showIdenticon showCopyBtn - showEtherscanBtn - network={getNetworkName()} + explorerUrl={explorerUrl} /> {owner === userAddress && {isCancelTx ? rejectButton() : confirmButton()}} diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx index 10353ded90..55f12bd443 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/CustomDescription.tsx @@ -1,6 +1,7 @@ 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' @@ -23,7 +24,8 @@ import { Transaction } from 'src/logic/safe/store/models/types/transaction' import { DataDecoded } from 'src/routes/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 { getNetworkName } from 'src/config' + +import { getExplorerInfo } from 'src/config' export const TRANSACTIONS_DESC_CUSTOM_VALUE_TEST_ID = 'tx-description-custom-value' export const TRANSACTIONS_DESC_CUSTOM_DATA_TEST_ID = 'tx-description-custom-data' @@ -75,7 +77,7 @@ const TxInfoDetails = ({ data }: { data: DataDecoded }): React.ReactElement => ( const MultiSendCustomDataAction = ({ tx, order }: { tx: MultiSendDetails; order: number }): React.ReactElement => { const classes = useStyles() const methodName = tx.data?.method ? ` (${tx.data.method})` : '' - + const explorerUrl = getExplorerInfo(tx.to) return ( Send {humanReadableValue(tx.value)} ETH to: - + {!!tx.data && } @@ -177,7 +179,7 @@ interface GenericCustomDataProps { const GenericCustomData = ({ amount = '0', data, recipient, storedTx }: GenericCustomDataProps): React.ReactElement => { const classes = useStyles() const recipientName = useSelector((state) => getNameFromAddressBookSelector(state, recipient)) - + const explorerUrl = getExplorerInfo(recipient) return ( @@ -188,8 +190,7 @@ const GenericCustomData = ({ amount = '0', data, recipient, storedTx }: GenericC name={recipientName === 'UNKNOWN' ? undefined : recipientName} showIdenticon showCopyBtn - showEtherscanBtn - network={getNetworkName()} + explorerUrl={explorerUrl} /> diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx index d773789a88..9bc97b09c3 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/Value.tsx @@ -2,11 +2,11 @@ import { Text, EthHashInfo } from '@gnosis.pm/safe-react-components' import React from 'react' import styled from 'styled-components' -import { getNetworkName } from 'src/config' import { isAddress, isArrayParameter, } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils' +import { getExplorerInfo } from 'src/config' const NestedWrapper = styled.div` padding-left: 4px; @@ -50,16 +50,9 @@ const GenericValue = ({ method, type, value }: RenderValueProps): React.ReactEle } const Value = ({ type, ...props }: RenderValueProps): React.ReactElement => { + const explorerUrl = getExplorerInfo(props.value as string) if (isAddress(type)) { - return ( - - ) + return } return diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx index b9b31884aa..eaae1cb214 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/index.tsx @@ -13,7 +13,6 @@ import { CreationTx } from './CreationTx' import { OutgoingTx } from './OutgoingTx' import { styles } from './style' -import { getNetworkName } from 'src/config' import Block from 'src/components/layout/Block' import Bold from 'src/components/layout/Bold' import Col from 'src/components/layout/Col' @@ -26,6 +25,7 @@ import { INCOMING_TX_TYPES } from 'src/logic/safe/store/models/incomingTransacti import { safeNonceSelector, safeThresholdSelector } from 'src/logic/safe/store/selectors' import { Transaction, TransactionTypes } from 'src/logic/safe/store/models/types/transaction' import IncomingTxDescription from './IncomingTxDescription' +import { getExplorerInfo } from 'src/config' const useStyles = makeStyles(styles as any) @@ -59,6 +59,8 @@ const ExpandedTx = ({ cancelTx, tx }: ExpandedTxProps): React.ReactElement => { } } + const explorerUrl = tx.executionTxHash ? getExplorerInfo(tx.executionTxHash) : null + return ( <> @@ -68,13 +70,7 @@ const ExpandedTx = ({ cancelTx, tx }: ExpandedTxProps): React.ReactElement => {
Hash: {tx.executionTxHash ? ( - + ) : ( 'n/a' )} diff --git a/yarn.lock b/yarn.lock index 6c51521608..d7657c8007 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1501,9 +1501,9 @@ solc "0.5.14" truffle "^5.1.21" -"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#1bf397f": - version "0.2.0" - resolved "https://github.com/gnosis/safe-react-components.git#1bf397f2bc48ba48906824137943f0bb5804c99c" +"@gnosis.pm/safe-react-components@https://github.com/gnosis/safe-react-components.git#70e57bdd1e0fd5dfdf5768076577c1e000b5fe28": + version "0.4.0" + resolved "https://github.com/gnosis/safe-react-components.git#70e57bdd1e0fd5dfdf5768076577c1e000b5fe28" dependencies: classnames "^2.2.6" polished "3.6.5" From 7d28efdac8a5cc07645a0dbdd09c75e7b6e775f4 Mon Sep 17 00:00:00 2001 From: Fernando Date: Thu, 8 Oct 2020 14:53:02 -0300 Subject: [PATCH 13/19] (Feature) [xDai] - Use parametrized network values (#1437) Co-authored-by: Daniel Sanchez --- src/components/AddressInfo/index.tsx | 3 +- src/components/App/ReceiveModal.tsx | 3 +- src/components/ConnectButton/index.tsx | 9 +- src/components/EtherscanBtn/index.tsx | 15 ++-- src/components/EtherscanLink/index.tsx | 6 +- src/config/index.ts | 30 +++---- src/logic/contracts/safeContracts.ts | 89 ++++++++++--------- .../safe/store/actions/fetchSafeCreationTx.ts | 2 +- .../safe/utils/buildSafeCreationTxUrl.ts | 10 +++ src/logic/safe/utils/safeVersion.ts | 2 +- src/logic/wallets/getWeb3.ts | 56 +----------- src/logic/wallets/utils/walletList.ts | 37 ++++---- .../load/components/DetailsForm/index.tsx | 2 +- .../load/components/OwnerList/index.tsx | 3 +- .../components/ReviewInformation/index.tsx | 5 +- .../components/ReviewInformation/index.tsx | 4 +- src/routes/open/container/Open.tsx | 7 +- src/routes/opening/components/Footer.tsx | 47 +++++----- .../ReviewCustomTx/index.tsx | 4 +- .../SendCustomTx/index.tsx | 3 +- .../screens/ReviewCollectible/index.tsx | 4 +- .../SendModal/screens/ReviewTx/index.tsx | 4 +- .../screens/SendCollectible/index.tsx | 3 +- .../SendModal/screens/SendFunds/index.tsx | 3 +- .../Settings/Advanced/RemoveModuleModal.tsx | 11 ++- .../AddOwnerModal/screens/Review/index.tsx | 6 +- .../ManageOwners/EditOwnerModal/index.tsx | 3 +- .../OwnerAddressTableCell/index.tsx | 3 +- .../screens/CheckOwner/index.tsx | 3 +- .../RemoveOwnerModal/screens/Review/index.tsx | 6 +- .../screens/OwnerForm/index.tsx | 3 +- .../screens/Review/index.tsx | 8 +- .../Settings/RemoveSafeModal/index.tsx | 7 +- .../IncomingTxDescription/index.tsx | 3 +- .../TxDescription/SettingsDescription.tsx | 9 +- .../TxDescription/TransferDescription.tsx | 3 +- src/test/builder/safe.redux.builder.ts | 4 +- src/utils/constants.ts | 36 ++++++-- 38 files changed, 215 insertions(+), 241 deletions(-) create mode 100644 src/logic/safe/utils/buildSafeCreationTxUrl.ts diff --git a/src/components/AddressInfo/index.tsx b/src/components/AddressInfo/index.tsx index 44aba892f9..99f94a0903 100644 --- a/src/components/AddressInfo/index.tsx +++ b/src/components/AddressInfo/index.tsx @@ -6,7 +6,6 @@ import Identicon from 'src/components/Identicon' import Block from 'src/components/layout/Block' import Bold from 'src/components/layout/Bold' import Paragraph from 'src/components/layout/Paragraph' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { border, xs } from 'src/theme/variables' import styled from 'styled-components' @@ -60,7 +59,7 @@ const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactE {safeAddress} - +
{ethBalance && ( diff --git a/src/components/App/ReceiveModal.tsx b/src/components/App/ReceiveModal.tsx index 6aa6c4d575..6281a4b43f 100644 --- a/src/components/App/ReceiveModal.tsx +++ b/src/components/App/ReceiveModal.tsx @@ -13,7 +13,6 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { lg, md, screenSm, secondaryText, sm } from 'src/theme/variables' import { copyToClipboard } from 'src/utils/clipboard' @@ -116,7 +115,7 @@ const ReceiveModal = ({ onClose, safeAddress, safeName }: Props) => { {safeAddress} - +
diff --git a/src/components/ConnectButton/index.tsx b/src/components/ConnectButton/index.tsx index a719776f04..a520594bf8 100644 --- a/src/components/ConnectButton/index.tsx +++ b/src/components/ConnectButton/index.tsx @@ -3,15 +3,16 @@ import React from 'react' import Button from 'src/components/layout/Button' import { getNetworkId } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { getWeb3, setWeb3 } from 'src/logic/wallets/getWeb3' import { fetchProvider } from 'src/logic/wallets/store/actions' import transactionDataCheck from 'src/logic/wallets/transactionDataCheck' import { getSupportedWallets } from 'src/logic/wallets/utils/walletList' import { store } from 'src/store' +import { BLOCKNATIVE_KEY } from 'src/utils/constants' -const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' - -const BLOCKNATIVE_API_KEY = isMainnet ? process.env.REACT_APP_BLOCKNATIVE_KEY : '7fbb9cee-7e97-4436-8770-8b29a9a8814c' +const networkId = getNetworkId() +const BLOCKNATIVE_API_KEY = BLOCKNATIVE_KEY[networkId] ?? BLOCKNATIVE_KEY[ETHEREUM_NETWORK.RINKEBY] let lastUsedAddress = '' let providerName @@ -20,7 +21,7 @@ const wallets = getSupportedWallets() export const onboard = Onboard({ dappId: BLOCKNATIVE_API_KEY, - networkId: getNetworkId(), + networkId: networkId, subscriptions: { wallet: (wallet) => { if (wallet.provider) { diff --git a/src/components/EtherscanBtn/index.tsx b/src/components/EtherscanBtn/index.tsx index 294e8473b0..f760948943 100644 --- a/src/components/EtherscanBtn/index.tsx +++ b/src/components/EtherscanBtn/index.tsx @@ -6,8 +6,8 @@ import React from 'react' import EtherscanOpenIcon from './img/etherscan-open.svg' import Img from 'src/components/layout/Img' -import { ExplorerTypes, getExplorerLink } from 'src/logic/wallets/getWeb3' import { xs } from 'src/theme/variables' +import { getExplorerInfo } from 'src/config' const useStyles = makeStyles({ container: { @@ -30,26 +30,23 @@ const useStyles = makeStyles({ interface EtherscanBtnProps { className?: string increaseZindex?: boolean - type: ExplorerTypes value: string } -const EtherscanBtn = ({ - className = '', - increaseZindex = false, - type, - value, -}: EtherscanBtnProps): React.ReactElement => { +const EtherscanBtn = ({ className = '', increaseZindex = false, value }: EtherscanBtnProps): React.ReactElement => { const classes = useStyles() const customClasses = increaseZindex ? { popper: classes.increasedPopperZindex } : {} + const explorerInfo = getExplorerInfo(value) + const { url } = explorerInfo() + return ( event.stopPropagation()} - href={getExplorerLink(type, value)} + href={url} rel="noopener noreferrer" target="_blank" > diff --git a/src/components/EtherscanLink/index.tsx b/src/components/EtherscanLink/index.tsx index 59585b9ee7..e37beeefea 100644 --- a/src/components/EtherscanLink/index.tsx +++ b/src/components/EtherscanLink/index.tsx @@ -1,7 +1,6 @@ import { makeStyles } from '@material-ui/core/styles' import cn from 'classnames' import React from 'react' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -18,11 +17,10 @@ interface EtherscanLinkProps { className?: string cut?: number knownAddress?: boolean - type: ExplorerTypes value: string } -const EtherscanLink = ({ className, cut, knownAddress, type, value }: EtherscanLinkProps): React.ReactElement => { +const EtherscanLink = ({ className, cut, knownAddress, value }: EtherscanLinkProps): React.ReactElement => { const classes = useStyles() return ( @@ -31,7 +29,7 @@ const EtherscanLink = ({ className, cut, knownAddress, type, value }: EtherscanL {cut ? shortVersionOf(value, cut) : value} - + {knownAddress !== undefined ? : null}
) diff --git a/src/config/index.ts b/src/config/index.ts index d790d2a11b..5c9223eddb 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,12 +1,6 @@ import networks from 'src/config/networks' -import { - EnvironmentSettings, - ETHEREUM_NETWORK, - NetworkSettings, - SafeFeatures, -} from 'src/config/networks/network.d' -import { checksumAddress } from 'src/utils/checksumAddress' -import { GOOGLE_ANALYTICS_ID, NETWORK, APP_ENV, NODE_ENV, ETHERSCAN_API_KEY } from 'src/utils/constants' +import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkSettings, SafeFeatures } from 'src/config/networks/network.d' +import { APP_ENV, ETHERSCAN_API_KEY, GOOGLE_ANALYTICS_ID, INFURA_TOKEN, NETWORK, NODE_ENV } from 'src/utils/constants' import { ensureOnce } from 'src/utils/singleton' import memoize from 'lodash.memoize' @@ -67,7 +61,15 @@ export const getRelayUrl = (): string | undefined => getConfig()?.relayApiUrl export const getGnosisSafeAppsUrl = (): string => getConfig()?.safeAppsUrl -export const getRpcServiceUrl = (): string => getConfig()?.rpcServiceUrl +export const getRpcServiceUrl = (): string => { + const usesInfuraRPC = [ETHEREUM_NETWORK.MAINNET, ETHEREUM_NETWORK.RINKEBY].includes(getNetworkId()) + + if (usesInfuraRPC) { + return getConfig()?.rpcServiceUrl + INFURA_TOKEN + } + + return getConfig()?.rpcServiceUrl +} export const getNetworkExplorerInfo = (): { name: string; url: string; apiUrl: string } => ({ name: getConfig()?.networkExplorerName, @@ -87,15 +89,7 @@ export const getAllTransactionsUriFrom = (safeAddress: string) => `safes/${safeA export const getSafeCreationTxUri = (safeAddress: string) => `safes/${safeAddress}/creation/` -export const getGoogleAnalyticsTrackingID = (): string => GOOGLE_ANALYTICS_ID[getNetworkName()] - -export const buildSafeCreationTxUrl = (safeAddress: string) => { - const host = getTxServiceUrl() - const address = checksumAddress(safeAddress) - const base = getSafeCreationTxUri(address) - - return `${host}${base}` -} +export const getGoogleAnalyticsTrackingID = (): string => GOOGLE_ANALYTICS_ID[getNetworkId()] const fetchContractABI = memoize( async (url: string, contractAddress: string, apiKey?: string) => { diff --git a/src/logic/contracts/safeContracts.ts b/src/logic/contracts/safeContracts.ts index 68d971f92b..5d1aa9086f 100644 --- a/src/logic/contracts/safeContracts.ts +++ b/src/logic/contracts/safeContracts.ts @@ -1,17 +1,17 @@ -import { AbiItem } from 'web3-utils' -import contract from 'truffle-contract' -import Web3 from 'web3' -import ProxyFactorySol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafeProxyFactory.json' import GnosisSafeSol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafe.json' import SafeProxy from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafeProxy.json' -import { ensureOnce } from 'src/utils/singleton' +import ProxyFactorySol from '@gnosis.pm/safe-contracts/build/contracts/GnosisSafeProxyFactory.json' import memoize from 'lodash.memoize' -import { getWeb3, getNetworkIdFrom } from 'src/logic/wallets/getWeb3' -import { calculateGasOf, calculateGasPrice } from 'src/logic/wallets/ethTransactions' -import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' + +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { isProxyCode } from 'src/logic/contracts/historicProxyCode' -import { GnosisSafeProxyFactory } from 'src/types/contracts/GnosisSafeProxyFactory.d'; +import { ZERO_ADDRESS } from 'src/logic/wallets/ethAddresses' +import { calculateGasOf, calculateGasPrice } 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' +import Web3 from 'web3' +import { AbiItem } from 'web3-utils' export const SENTINEL_ADDRESS = '0x0000000000000000000000000000000000000001' export const MULTI_SEND_ADDRESS = '0x8d29be29923b68abfdd21e541b9374737b49cdad' @@ -20,24 +20,39 @@ export const DEFAULT_FALLBACK_HANDLER_ADDRESS = '0xd5D82B6aDDc9027B22dCA772Aa68D export const SAFE_MASTER_COPY_ADDRESS_V10 = '0xb6029EA3B2c51D09a50B53CA8012FeEB05bDa35A' -let proxyFactoryMaster -let safeMaster - -const createGnosisSafeContract = (web3: Web3) => { - const gnosisSafe = contract(GnosisSafeSol) - gnosisSafe.setProvider(web3.currentProvider) - - return gnosisSafe +let proxyFactoryMaster: GnosisSafeProxyFactory +let safeMaster: GnosisSafe + +/** + * Creates a Contract instance of the GnosisSafe contract + * @param {Web3} web3 + * @param {ETHEREUM_NETWORK} networkId + */ +const createGnosisSafeContract = (web3: Web3, networkId: ETHEREUM_NETWORK) => { + const networks = GnosisSafeSol.networks + // TODO: this may not be the most scalable approach, + // but up until v1.2.0 the address is the same for all the networks. + // So, if we can't find the network in the Contract artifact, we fallback to MAINNET. + const contractAddress = networks[networkId]?.address ?? networks[ETHEREUM_NETWORK.MAINNET].address + return new web3.eth.Contract(GnosisSafeSol.abi as AbiItem[], contractAddress) as unknown as GnosisSafe } -const createProxyFactoryContract = (web3: Web3, networkId: number): GnosisSafeProxyFactory => { - const contractAddress = ProxyFactorySol.networks[networkId].address - const proxyFactory = new web3.eth.Contract(ProxyFactorySol.abi as AbiItem[], contractAddress) as unknown as GnosisSafeProxyFactory - - return proxyFactory +/** + * Creates a Contract instance of the GnosisSafeProxyFactory contract + * @param {Web3} web3 + * @param {ETHEREUM_NETWORK} networkId + */ +const createProxyFactoryContract = (web3: Web3, networkId: ETHEREUM_NETWORK): GnosisSafeProxyFactory => { + const networks = ProxyFactorySol.networks + // TODO: this may not be the most scalable approach, + // but up until v1.2.0 the address is the same for all the networks. + // So, if we can't find the network in the Contract artifact, we fallback to MAINNET. + const contractAddress = networks[networkId]?.address ?? networks[ETHEREUM_NETWORK.MAINNET].address + return new web3.eth.Contract(ProxyFactorySol.abi as AbiItem[], contractAddress) as unknown as GnosisSafeProxyFactory } export const getGnosisSafeContract = memoize(createGnosisSafeContract) + const getCreateProxyFactoryContract = memoize(createProxyFactoryContract) const instantiateMasterCopies = async () => { @@ -47,25 +62,11 @@ const instantiateMasterCopies = async () => { // Create ProxyFactory Master Copy proxyFactoryMaster = getCreateProxyFactoryContract(web3, networkId) - // Initialize Safe master copy - const GnosisSafe = getGnosisSafeContract(web3) - safeMaster = await GnosisSafe.deployed() -} - -// ONLY USED IN TEST ENVIRONMENT -const createMasterCopies = async () => { - const web3 = getWeb3() - const accounts = await web3.eth.getAccounts() - const userAccount = accounts[0] - - const ProxyFactory = getCreateProxyFactoryContract(web3, 4441) - proxyFactoryMaster = await ProxyFactory.deploy({ data: GnosisSafeSol.bytecode }).send({ from: userAccount, gas: 5000000 }) - - const GnosisSafe = getGnosisSafeContract(web3) - safeMaster = await GnosisSafe.new({ from: userAccount, gas: '7000000' }) + // Create Safe Master copy + safeMaster = getGnosisSafeContract(web3, networkId) } -export const initContracts = process.env.NODE_ENV === 'test' ? ensureOnce(createMasterCopies) : instantiateMasterCopies +export const initContracts = instantiateMasterCopies export const getSafeMasterContract = async () => { await initContracts() @@ -74,11 +75,11 @@ export const getSafeMasterContract = async () => { } export const getSafeDeploymentTransaction = (safeAccounts, numConfirmations) => { - const gnosisSafeData = safeMaster.contract.methods + const gnosisSafeData = safeMaster.methods .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() - return proxyFactoryMaster.methods.createProxy(safeMaster.address, gnosisSafeData) + return proxyFactoryMaster.methods.createProxy(safeMaster.options.address, gnosisSafeData) } export const estimateGasForDeployingSafe = async ( @@ -86,13 +87,13 @@ export const estimateGasForDeployingSafe = async ( numConfirmations, userAccount, ) => { - const gnosisSafeData = await safeMaster.contract.methods + const gnosisSafeData = await safeMaster.methods .setup(safeAccounts, numConfirmations, ZERO_ADDRESS, '0x', DEFAULT_FALLBACK_HANDLER_ADDRESS, ZERO_ADDRESS, 0, ZERO_ADDRESS) .encodeABI() const proxyFactoryData = proxyFactoryMaster.methods - .createProxy(safeMaster.address, gnosisSafeData) + .createProxy(safeMaster.options.address, gnosisSafeData) .encodeABI() - const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.address) + const gas = await calculateGasOf(proxyFactoryData, userAccount, proxyFactoryMaster.options.address) const gasPrice = await calculateGasPrice() return gas * parseInt(gasPrice, 10) diff --git a/src/logic/safe/store/actions/fetchSafeCreationTx.ts b/src/logic/safe/store/actions/fetchSafeCreationTx.ts index d0e79de406..6504d22600 100644 --- a/src/logic/safe/store/actions/fetchSafeCreationTx.ts +++ b/src/logic/safe/store/actions/fetchSafeCreationTx.ts @@ -1,7 +1,7 @@ import axios from 'axios' import { List } from 'immutable' -import { buildSafeCreationTxUrl } from 'src/config' +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' diff --git a/src/logic/safe/utils/buildSafeCreationTxUrl.ts b/src/logic/safe/utils/buildSafeCreationTxUrl.ts new file mode 100644 index 0000000000..19554e563a --- /dev/null +++ b/src/logic/safe/utils/buildSafeCreationTxUrl.ts @@ -0,0 +1,10 @@ +import { getTxServiceUrl, getSafeCreationTxUri } from 'src/config' +import { checksumAddress } from 'src/utils/checksumAddress' + +export const buildSafeCreationTxUrl = (safeAddress: string): string => { + const host = getTxServiceUrl() + const address = checksumAddress(safeAddress) + const base = getSafeCreationTxUri(address) + + return `${host}${base}` +} diff --git a/src/logic/safe/utils/safeVersion.ts b/src/logic/safe/utils/safeVersion.ts index 25618a557b..de6fc60b03 100644 --- a/src/logic/safe/utils/safeVersion.ts +++ b/src/logic/safe/utils/safeVersion.ts @@ -60,7 +60,7 @@ export const getCurrentMasterContractLastVersion = async (): Promise => const safeMaster = await getSafeMasterContract() let safeMasterVersion try { - safeMasterVersion = await safeMaster.VERSION() + safeMasterVersion = await safeMaster.methods.VERSION().call() } catch (err) { // Default in case that it's not possible to obtain the version from the contract, returns a hardcoded value or an // env variable diff --git a/src/logic/wallets/getWeb3.ts b/src/logic/wallets/getWeb3.ts index 0b303d660e..c6c61ab4c4 100644 --- a/src/logic/wallets/getWeb3.ts +++ b/src/logic/wallets/getWeb3.ts @@ -2,12 +2,11 @@ import Web3 from 'web3' import { provider as Provider } from 'web3-core' import { ContentHash } from 'web3-eth-ens' -import { getNetworkId } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' -import { NETWORK } from 'src/utils/constants' import { sameAddress } from './ethAddresses' import { EMPTY_DATA } from './ethTransactions' import { ProviderProps } from './store/model/provider' +import { NODE_ENV } from 'src/utils/constants' +import { getRpcServiceUrl } from 'src/config' export const WALLET_PROVIDER = { SAFE: 'SAFE', @@ -27,58 +26,11 @@ export const WALLET_PROVIDER = { TREZOR: 'TREZOR', } -export enum ExplorerTypes { - Tx = 'tx', - Address = 'address', -} - -export const getEtherScanLink = (network: ETHEREUM_NETWORK, type: ExplorerTypes, value: string): string => - `https://${ - network === ETHEREUM_NETWORK.MAINNET ? '' : `${ETHEREUM_NETWORK[network].toLowerCase()}.` - }etherscan.io/${type}/${value}` - -export const getExplorerLink = (type: ExplorerTypes, value: string): string => { - const network = getNetworkId() - - switch (network) { - case ETHEREUM_NETWORK.MAINNET: - return getEtherScanLink(ETHEREUM_NETWORK.MAINNET, type, value) - case ETHEREUM_NETWORK.RINKEBY: - return getEtherScanLink(ETHEREUM_NETWORK.RINKEBY, type, value) - case ETHEREUM_NETWORK.ENERGY_WEB_CHAIN: - return `https://explorer.energyweb.org/${type}/${value}` - case ETHEREUM_NETWORK.VOLTA: - return `https://volta-explorer.energyweb.org/${type}/${value}` - default: - return getEtherScanLink(network, type, value) - } -} - -export const getInfuraUrl = (network: ETHEREUM_NETWORK): string => - `https://${network === ETHEREUM_NETWORK.MAINNET ? 'mainnet' : 'rinkeby'}.infura.io:443/v3/${ - process.env.REACT_APP_INFURA_TOKEN - }` - -export const getRPCUrl = (network: ETHEREUM_NETWORK): string => { - switch (network) { - case ETHEREUM_NETWORK.MAINNET: - return getInfuraUrl(network) - case ETHEREUM_NETWORK.RINKEBY: - return getInfuraUrl(network) - case ETHEREUM_NETWORK.ENERGY_WEB_CHAIN: - return 'https://rpc.energyweb.org' - case ETHEREUM_NETWORK.VOLTA: - return 'https://volta-rpc.energyweb.org' - default: - return '' - } -} - // With some wallets from web3connect you have to use their provider instance only for signing // And our own one to fetch data export const web3ReadOnly = new Web3( process.env.NODE_ENV !== 'test' - ? new Web3.providers.HttpProvider(getRPCUrl(ETHEREUM_NETWORK[NETWORK] ?? ETHEREUM_NETWORK.RINKEBY)) + ? new Web3.providers.HttpProvider(getRpcServiceUrl()) : window.web3?.currentProvider || 'ws://localhost:8545', ) @@ -92,7 +44,7 @@ export const resetWeb3 = (): void => { export const getAccountFrom = async (web3Provider: Web3): Promise => { const accounts = await web3Provider.eth.getAccounts() - if (process.env.NODE_ENV === 'test' && window.testAccountIndex) { + if (NODE_ENV === 'test' && window.testAccountIndex) { return accounts[window.testAccountIndex] } diff --git a/src/logic/wallets/utils/walletList.ts b/src/logic/wallets/utils/walletList.ts index 8fcf755c3e..1939a1c3d8 100644 --- a/src/logic/wallets/utils/walletList.ts +++ b/src/logic/wallets/utils/walletList.ts @@ -1,22 +1,25 @@ -import { getInfuraUrl, getRPCUrl } from '../getWeb3' -import { getNetworkId } from 'src/config' +import { WalletInitOptions } from 'bnc-onboard/dist/src/interfaces' -const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet' +import { getNetworkId, getRpcServiceUrl } from 'src/config' +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { FORTMATIC_KEY, PORTIS_ID } from 'src/utils/constants' -const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f28b-4463-80cb-846d7ec5806b' -// const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78' -const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40' +const networkId = getNetworkId() +const PORTIS_DAPP_ID = PORTIS_ID[networkId] ?? PORTIS_ID[ETHEREUM_NETWORK.RINKEBY] +const FORTMATIC_API_KEY = FORTMATIC_KEY[networkId] ?? FORTMATIC_KEY[ETHEREUM_NETWORK.RINKEBY] -const network = getNetworkId() -const infuraUrl = getInfuraUrl(network) +type Wallet = WalletInitOptions & { + desktop: boolean +} -const wallets = [ +const rpcUrl = getRpcServiceUrl() +const wallets: Wallet[] = [ { walletName: 'metamask', preferred: true, desktop: false }, { walletName: 'walletConnect', preferred: true, - infuraKey: process.env.REACT_APP_INFURA_TOKEN, - rpc: { [network]: getRPCUrl(network) }, + // as stated in the documentation, `infuraKey` is not mandatory if rpc is provided + rpc: { [networkId]: rpcUrl }, desktop: true, bridge: 'https://safe-walletconnect.gnosis.io/', }, @@ -26,13 +29,13 @@ const wallets = [ preferred: true, email: 'safe@gnosis.io', desktop: true, - rpcUrl: infuraUrl, + rpcUrl, }, { walletName: 'ledger', desktop: true, preferred: true, - rpcUrl: infuraUrl, + rpcUrl, LedgerTransport: (window as any).TransportNodeHid, }, { walletName: 'trust', preferred: true, desktop: false }, @@ -51,16 +54,18 @@ const wallets = [ { walletName: 'torus', desktop: true }, { walletName: 'unilogin', desktop: true }, { walletName: 'coinbase', desktop: false }, - { walletName: 'walletLink', rpcUrl: infuraUrl, desktop: false }, + { walletName: 'walletLink', rpcUrl, desktop: false }, { walletName: 'opera', desktop: false }, { walletName: 'operaTouch', desktop: false }, ] -export const getSupportedWallets = () => { +export const getSupportedWallets = (): WalletInitOptions[] => { const { isDesktop } = window as any /* eslint-disable no-unused-vars */ - if (isDesktop) return wallets.filter((wallet) => wallet.desktop).map(({ desktop, ...rest }) => rest) + if (isDesktop) { + return wallets.filter((wallet) => wallet.desktop).map(({ desktop, ...rest }) => rest) + } return wallets.map(({ desktop, ...rest }) => rest) } diff --git a/src/routes/load/components/DetailsForm/index.tsx b/src/routes/load/components/DetailsForm/index.tsx index 66a198b994..1524f9e122 100644 --- a/src/routes/load/components/DetailsForm/index.tsx +++ b/src/routes/load/components/DetailsForm/index.tsx @@ -73,7 +73,7 @@ export const safeFieldsValidation = async (values): Promise { {address} - + diff --git a/src/routes/load/components/ReviewInformation/index.tsx b/src/routes/load/components/ReviewInformation/index.tsx index 7c728bcf04..2c5ba0759a 100644 --- a/src/routes/load/components/ReviewInformation/index.tsx +++ b/src/routes/load/components/ReviewInformation/index.tsx @@ -12,7 +12,6 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import OpenPaper from 'src/components/Stepper/OpenPaper' import { shortVersionOf } from 'src/logic/wallets/ethAddresses' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { FIELD_LOAD_ADDRESS, FIELD_LOAD_NAME, THRESHOLD } from 'src/routes/load/components/fields' import { getNumOwnersFrom, getOwnerAddressBy, getOwnerNameBy } from 'src/routes/open/components/fields' import { getAccountsFrom } from 'src/routes/open/utils/safeDataExtractor' @@ -77,7 +76,7 @@ const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => {shortVersionOf(safeAddress, 4)} - +
@@ -122,7 +121,7 @@ const ReviewComponent = ({ userAddress, values }: Props): React.ReactElement => {address} - + diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index f76792b79b..2ed3dff91e 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -13,7 +13,7 @@ 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 { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { getAccountsFrom, getNamesFrom } from 'src/routes/open/utils/safeDataExtractor' import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' @@ -118,7 +118,7 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { {addresses[index]} - + diff --git a/src/routes/open/container/Open.tsx b/src/routes/open/container/Open.tsx index 360d388438..9b98eac323 100644 --- a/src/routes/open/container/Open.tsx +++ b/src/routes/open/container/Open.tsx @@ -22,6 +22,7 @@ import { loadFromStorage, removeFromStorage, saveToStorage } from 'src/utils/sto import { userAccountSelector } from 'src/logic/wallets/store/selectors' import { SafeRecordProps } from 'src/logic/safe/store/models/safe' import { addOrUpdateSafe } from 'src/logic/safe/store/actions/addOrUpdateSafe' +import { PromiEvent, TransactionReceipt } from 'web3-core' const SAFE_PENDING_CREATION_STORAGE_KEY = 'SAFE_PENDING_CREATION_STORAGE_KEY' @@ -60,7 +61,7 @@ export const createSafe = (values, userAccount) => { const deploymentTx = getSafeDeploymentTransaction(ownerAddresses, confirmations) - const promiEvent = deploymentTx.send({ from: userAccount, value: 0 }) + const promiEvent = deploymentTx.send({ from: userAccount }) promiEvent .once('transactionHash', (txHash) => { @@ -68,7 +69,7 @@ export const createSafe = (values, userAccount) => { }) .then(async (receipt) => { await checkReceiptStatus(receipt.transactionHash) - const safeAddress = receipt.events.ProxyCreation.returnValues.proxy + const safeAddress = receipt.events?.ProxyCreation.returnValues.proxy const safeProps = await getSafeProps(safeAddress, name, ownersNames, ownerAddresses) // returning info for testing purposes, in app is fully async return { safeAddress: safeProps.address, safeTx: receipt } @@ -83,7 +84,7 @@ export const createSafe = (values, userAccount) => { const Open = (): React.ReactElement => { const [loading, setLoading] = useState(false) const [showProgress, setShowProgress] = useState(false) - const [creationTxPromise, setCreationTxPromise] = useState() + const [creationTxPromise, setCreationTxPromise] = useState>() const [safeCreationPendingInfo, setSafeCreationPendingInfo] = useState() const [safePropsFromUrl, setSafePropsFromUrl] = useState() const userAccount = useSelector(userAccountSelector) diff --git a/src/routes/opening/components/Footer.tsx b/src/routes/opening/components/Footer.tsx index bd531c1edb..8f213484c4 100644 --- a/src/routes/opening/components/Footer.tsx +++ b/src/routes/opening/components/Footer.tsx @@ -2,10 +2,10 @@ import React, { SyntheticEvent } from 'react' import styled from 'styled-components' import Button from 'src/components/layout/Button' -import { getExplorerLink, ExplorerTypes } from 'src/logic/wallets/getWeb3' import { connected } from 'src/theme/variables' +import { getExplorerInfo } from 'src/config' -const EtherScanLink = styled.a` +const ExplorerLink = styled.a` color: ${connected}; ` @@ -13,24 +13,31 @@ const ButtonWithMargin = styled(Button)` margin-right: 16px; ` -export const GenericFooter = ({ safeCreationTxHash }: { safeCreationTxHash: string }) => ( - -

This process should take a couple of minutes.

-

- Follow the progress on{' '} - - Etherscan.io - - . -

-
-) +export const GenericFooter = ({ safeCreationTxHash }: { safeCreationTxHash: string }) => { + const explorerInfo = getExplorerInfo(safeCreationTxHash) + const { url, alt } = explorerInfo() + const match = /(http|https):\/\/(\w+\.\w+)\/.*/i.exec(url) + const explorerDomain = match !== null ? match[2] : 'Network Explorer' + + return ( + +

This process should take a couple of minutes.

+

+ Follow the progress on{' '} + + {explorerDomain} + + . +

+
+ ) +} export const ContinueFooter = ({ continueButtonDisabled, diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx index 4b8129ee4b..4b6ffa401e 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ReviewCustomTx/index.tsx @@ -20,7 +20,7 @@ import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { getEthAsToken } from 'src/logic/tokens/utils/tokenHelpers' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -122,7 +122,7 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { {tx.contractAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx index e53bca0d60..2599f4f358 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/SendCustomTx/index.tsx @@ -25,7 +25,6 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import ScanQRModal from 'src/components/ScanQRModal' import { safeSelector } from 'src/logic/safe/store/selectors' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' import { sm } from 'src/theme/variables' @@ -178,7 +177,7 @@ const SendCustomTx: React.FC = ({ initialValues, onClose, onNext, contrac - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx index b9783e58a3..7a77be83b8 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -27,7 +27,7 @@ import { } from 'src/logic/tokens/store/actions/fetchTokens' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH } from 'src/logic/tokens/utils/tokenHelpers' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -135,7 +135,7 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx {tx.recipientAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx index 0fe167da22..f9e1ff3035 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -24,7 +24,7 @@ import { getHumanFriendlyToken } from 'src/logic/tokens/store/actions/fetchToken import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { ETH_ADDRESS } from 'src/logic/tokens/utils/tokenHelpers' import { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { extendedSafeTokensSelector } from 'src/routes/safe/container/selector' @@ -149,7 +149,7 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { {tx.recipientAddress} - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx index 22ca6d03ca..833f4e9956 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendCollectible/index.tsx @@ -19,7 +19,6 @@ import WhenFieldChanges from 'src/components/WhenFieldChanges' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { getNameFromAddressBook } from 'src/logic/addressBook/utils' import { nftTokensSelector, safeActiveSelectorMap } from 'src/logic/collectibles/store/selectors' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' import CollectibleSelectField from 'src/routes/safe/components/Balances/SendModal/screens/SendCollectible/CollectibleSelectField' @@ -172,7 +171,7 @@ const SendCollectible = ({ - + diff --git a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx index 4d1ea8e3b1..8ccd275e05 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx @@ -23,7 +23,6 @@ import Row from 'src/components/layout/Row' import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import { addressBookSelector } from 'src/logic/addressBook/store/selectors' import { getNameFromAddressBook } from 'src/logic/addressBook/utils' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import AddressBookInput from 'src/routes/safe/components/Balances/SendModal/screens/AddressBookInput' @@ -185,7 +184,7 @@ const SendFunds = ({ - + diff --git a/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx b/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx index 9b33f83324..cfe23ac0fa 100644 --- a/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx +++ b/src/routes/safe/components/Settings/Advanced/RemoveModuleModal.tsx @@ -14,13 +14,13 @@ import Link from 'src/components/layout/Link' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import Modal from 'src/components/Modal' +import { getExplorerInfo } from 'src/config' import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { ModulePair } from 'src/logic/safe/store/models/safe' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { TX_NOTIFICATION_TYPES } from 'src/logic/safe/transactions' -import { ExplorerTypes, getExplorerLink } from 'src/logic/wallets/getWeb3' import { md, secondary } from 'src/theme/variables' import styled from 'styled-components' @@ -49,6 +49,9 @@ const RemoveModuleModal = ({ onClose, selectedModule }: RemoveModuleModal): Reac const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const dispatch = useDispatch() + const explorerInfo = getExplorerInfo(selectedModule[0]) + const { url } = explorerInfo() + const removeSelectedModule = async (): Promise => { try { const safeInstance = await getGnosisSafeInstanceAt(safeAddress) @@ -101,11 +104,7 @@ const RemoveModuleModal = ({ onClose, selectedModule }: RemoveModuleModal): Reac {selectedModule[0]} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx index cd5a6cb9ac..1f659eba39 100644 --- a/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/AddOwnerModal/screens/Review/index.tsx @@ -18,7 +18,7 @@ import { getGnosisSafeInstanceAt } from 'src/logic/contracts/safeContracts' import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -118,7 +118,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => {owner.address} - + @@ -146,7 +146,7 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => {values.ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx index 1d0794ea9c..6d750aed04 100644 --- a/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/EditOwnerModal/index.tsx @@ -23,7 +23,6 @@ import { NOTIFICATIONS } from 'src/logic/notifications' import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' import editSafeOwner from 'src/logic/safe/store/actions/editSafeOwner' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { sm } from 'src/theme/variables' import { styles } from './style' @@ -94,7 +93,7 @@ const EditOwnerComponent = ({ isOpen, onClose, ownerAddress, selectedOwnerName } {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx index 4bd3d8d22e..0caf445ca6 100644 --- a/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell/index.tsx @@ -7,7 +7,6 @@ import Block from 'src/components/layout/Block' import Paragraph from 'src/components/layout/Paragraph' import { getValidAddressBookName } from 'src/logic/addressBook/utils' import { useWindowDimensions } from 'src/logic/hooks/useWindowDimensions' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' type OwnerAddressTableCellProps = { address: string @@ -37,7 +36,7 @@ const OwnerAddressTableCell = (props: OwnerAddressTableCellProps): React.ReactEl {showLinks ? (
{userName && getValidAddressBookName(userName)} - +
) : ( {address} diff --git a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx index f3ab823304..3ab15c42a6 100644 --- a/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/RemoveOwnerModal/screens/CheckOwner/index.tsx @@ -13,7 +13,6 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -54,7 +53,7 @@ const CheckOwner = ({ classes, onClose, onSubmit, ownerAddress, ownerName }) => {ownerAddress} - + 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 f10e362041..0a9b13b336 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 @@ -18,7 +18,7 @@ import { getGnosisSafeInstanceAt, SENTINEL_ADDRESS } from 'src/logic/contracts/s import { safeNameSelector, safeOwnersSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -120,7 +120,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {owner.address} - + @@ -149,7 +149,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx index a66965cc87..c808f411df 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/OwnerForm/index.tsx @@ -21,7 +21,6 @@ import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { ScanQRWrapper } from 'src/components/ScanQRModal/ScanQRWrapper' import { safeOwnersSelector } from 'src/logic/safe/store/selectors' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -95,7 +94,7 @@ const OwnerForm = ({ classes, onClose, onSubmit, ownerAddress, ownerName }) => { {ownerAddress} - + diff --git a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx index 3b1ce84db6..1b1e475243 100644 --- a/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx +++ b/src/routes/safe/components/Settings/ManageOwners/ReplaceOwnerModal/screens/Review/index.tsx @@ -23,7 +23,7 @@ import { } from 'src/logic/safe/store/selectors' import { estimateTxGasCosts } from 'src/logic/safe/transactions/gasNew' import { formatAmount } from 'src/logic/tokens/utils/formatAmount' -import { ExplorerTypes, getWeb3 } from 'src/logic/wallets/getWeb3' +import { getWeb3 } from 'src/logic/wallets/getWeb3' import { styles } from './style' @@ -124,7 +124,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {owner.address} - + @@ -153,7 +153,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {ownerAddress} - + @@ -178,7 +178,7 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre {values.ownerAddress} - + diff --git a/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx b/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx index 35edc8dd72..5524ecd31d 100644 --- a/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx +++ b/src/routes/safe/components/Settings/RemoveSafeModal/index.tsx @@ -5,6 +5,7 @@ import OpenInNew from '@material-ui/icons/OpenInNew' import classNames from 'classnames' import React from 'react' import { useDispatch, useSelector } from 'react-redux' +import { getExplorerInfo } from 'src/config' import { styles } from './style' @@ -17,7 +18,6 @@ import Hairline from 'src/components/layout/Hairline' import Link from 'src/components/layout/Link' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' -import { getExplorerLink, ExplorerTypes } from 'src/logic/wallets/getWeb3' import removeSafe from 'src/logic/safe/store/actions/removeSafe' import { safeNameSelector, safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' import { md, secondary } from 'src/theme/variables' @@ -34,7 +34,8 @@ const RemoveSafeComponent = ({ isOpen, onClose }) => { const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const dispatch = useDispatch() - const etherScanLink = getExplorerLink(ExplorerTypes.Address, safeAddress) + const explorerInfo = getExplorerInfo(safeAddress) + const { url } = explorerInfo() return ( { {safeAddress} - + diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx index 6ab5fc723f..532ce9ac18 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/IncomingTxDescription/index.tsx @@ -6,7 +6,6 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' 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' @@ -29,7 +28,7 @@ const TransferDescription = ({ from, txFromName, value = '' }) => ( {txFromName ? ( ) : ( - + )} ) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx index 6075415789..ccaf06fe80 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/SettingsDescription.tsx @@ -6,7 +6,6 @@ import Bold from 'src/components/layout/Bold' import Paragraph from 'src/components/layout/Paragraph' import { getNameFromAddressBookSelector } from 'src/logic/addressBook/store/selectors' -import { ExplorerTypes } from 'src/logic/wallets/getWeb3' import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' import { SAFE_METHODS_NAMES, SafeMethods } from 'src/routes/safe/store/models/types/transactions.d' @@ -30,7 +29,7 @@ const RemovedOwner = ({ removedOwner }: RemovedOwnerProps): React.ReactElement = {ownerChangedName ? ( ) : ( - + )} ) @@ -49,7 +48,7 @@ const AddedOwner = ({ addedOwner }: AddedOwnerProps): React.ReactElement => { {ownerChangedName ? ( ) : ( - + )} ) @@ -75,7 +74,7 @@ interface AddModuleProps { const AddModule = ({ module }: AddModuleProps): React.ReactElement => ( Add module: - + ) @@ -86,7 +85,7 @@ interface RemoveModuleProps { const RemoveModule = ({ module }: RemoveModuleProps): React.ReactElement => ( Remove module: - + ) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx index 1128d07103..afc5f2c13c 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/TxDescription/TransferDescription.tsx @@ -4,7 +4,6 @@ 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 { ExplorerTypes } from 'src/logic/wallets/getWeb3' import OwnerAddressTableCell from 'src/routes/safe/components/Settings/ManageOwners/OwnerAddressTableCell' import { TRANSACTIONS_DESC_SEND_TEST_ID } from './index' @@ -22,7 +21,7 @@ const TransferDescription = ({ amount = '', recipient }: TransferDescriptionProp {recipientName ? ( ) : ( - + )} ) diff --git a/src/test/builder/safe.redux.builder.ts b/src/test/builder/safe.redux.builder.ts index cf6f297ba6..8a44555ae7 100644 --- a/src/test/builder/safe.redux.builder.ts +++ b/src/test/builder/safe.redux.builder.ts @@ -89,9 +89,7 @@ export const aMinedSafe = async ( form[getOwnerAddressBy(i)] = accounts[i] } - const openSafeProps = await createSafe(form, accounts[0]) - - return openSafeProps.safeAddress + return createSafe(form, accounts[0]).then((receipt) => receipt.events?.ProxyCreation.returnValues.proxy) } export default aSafe diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 44fb98ee27..cb56ff7b04 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -1,14 +1,37 @@ +import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' + export const APP_ENV = process.env.REACT_APP_ENV export const NODE_ENV = process.env.NODE_ENV export const NETWORK = process.env.REACT_APP_NETWORK?.toUpperCase() || 'RINKEBY' +export const INTERCOM_ID = APP_ENV === 'production' ? process.env.REACT_APP_INTERCOM_ID : 'plssl1fl' export const GOOGLE_ANALYTICS_ID = { - RINKEBY: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY, - MAINNET: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET, + [ETHEREUM_NETWORK.RINKEBY]: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_RINKEBY, + [ETHEREUM_NETWORK.MAINNET]: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_MAINNET, + [ETHEREUM_NETWORK.XDAI]: process.env.REACT_APP_GOOGLE_ANALYTICS_ID_XDAI, } -export const INTERCOM_ID = process.env.REACT_APP_ENV === 'production' ? process.env.REACT_APP_INTERCOM_ID : 'plssl1fl' -export const PORTIS_ID = process.env.REACT_APP_PORTIS_ID -export const SQUARELINK_ID = process.env.REACT_APP_SQUARELINK_ID -export const FORTMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY +export const PORTIS_ID = { + [ETHEREUM_NETWORK.RINKEBY]: '852b763d-f28b-4463-80cb-846d7ec5806b', + [ETHEREUM_NETWORK.MAINNET]: process.env.REACT_APP_PORTIS_ID, + [ETHEREUM_NETWORK.XDAI]: process.env.REACT_APP_PORTIS_ID, +} +export const FORTMATIC_KEY = { + [ETHEREUM_NETWORK.RINKEBY]: 'pk_test_CAD437AA29BE0A40', + [ETHEREUM_NETWORK.MAINNET]: process.env.REACT_APP_FORTMATIC_KEY, + [ETHEREUM_NETWORK.XDAI]: process.env.REACT_APP_FORTMATIC_KEY, +} +export const BLOCKNATIVE_KEY = { + [ETHEREUM_NETWORK.RINKEBY]: '7fbb9cee-7e97-4436-8770-8b29a9a8814c', + [ETHEREUM_NETWORK.MAINNET]: process.env.REACT_APP_BLOCKNATIVE_KEY, + [ETHEREUM_NETWORK.XDAI]: process.env.REACT_APP_BLOCKNATIVE_KEY, +} +/* + * Not being used +export const SQUARELINK_ID = { + [ETHEREUM_NETWORK.RINKEBY]: '46ce08fe50913cfa1b78', + [ETHEREUM_NETWORK.MAINNET]: process.env.REACT_APP_SQUARELINK_ID, + [ETHEREUM_NETWORK.XDAI]: process.env.REACT_APP_SQUARELINK_ID, +} + */ export const INFURA_TOKEN = process.env.REACT_APP_INFURA_TOKEN || '' export const LATEST_SAFE_VERSION = process.env.REACT_APP_LATEST_SAFE_VERSION || '1.1.1' export const APP_VERSION = process.env.REACT_APP_APP_VERSION || 'not-defined' @@ -18,3 +41,4 @@ export const TIMEOUT = process.env.NODE_ENV === 'test' ? 1500 : 5000 export const ETHERSCAN_API_KEY = process.env.REACT_APP_ETHERSCAN_API_KEY export const EXCHANGE_RATE_URL = 'https://api.exchangeratesapi.io/latest' export const EXCHANGE_RATE_URL_FALLBACK = 'https://api.coinbase.com/v2/exchange-rates' +export const IPFS_GATEWAY = process.env.REACT_APP_IPFS_GATEWAY From 8f85a2feece16353a8d15e23cea6c625d7b0f6b3 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Thu, 8 Oct 2020 15:53:47 -0300 Subject: [PATCH 14/19] (Feature) [xDai] - Use tx service for loading token info (#1435) Co-authored-by: Daniel Sanchez --- src/config/index.ts | 8 +++---- src/config/networks/local.ts | 8 +++---- src/config/networks/mainnet.ts | 14 +++++------ src/config/networks/rinkeby.ts | 12 +++++----- src/config/networks/xdai.ts | 8 +++---- .../__tests__/fetchSafeTokens.test.ts | 4 +--- .../api/fetchTokenCurrenciesBalances.ts | 8 ++----- .../allTransactions/loadAllTransactions.ts | 2 +- .../safe/transactions/incomingTxHistory.ts | 2 +- src/logic/safe/transactions/txHistory.ts | 2 +- .../api/fetchErc20AndErc721AssetsList.ts | 24 +++++++++++++++++++ src/logic/tokens/api/fetchToken.ts | 16 ------------- src/logic/tokens/api/fetchTokenBalanceList.ts | 8 ++----- src/logic/tokens/api/fetchTokenList.ts | 16 ------------- src/logic/tokens/api/index.ts | 3 +-- src/logic/tokens/store/actions/fetchTokens.ts | 10 ++++---- 16 files changed, 64 insertions(+), 81 deletions(-) create mode 100644 src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts delete mode 100644 src/logic/tokens/api/fetchToken.ts delete mode 100644 src/logic/tokens/api/fetchTokenList.ts diff --git a/src/config/index.ts b/src/config/index.ts index 5c9223eddb..2560cb2af2 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -81,13 +81,13 @@ export const getNetworkConfigFeatures = (): SafeFeatures | undefined => getConfi export const getNetworkInfo = (): NetworkSettings => getConfig()?.network -export const getTxServiceUriFrom = (safeAddress: string) => `safes/${safeAddress}/transactions/` +export const getTxServiceUriFrom = (safeAddress: string) => `/safes/${safeAddress}/transactions/` -export const getIncomingTxServiceUriTo = (safeAddress: string) => `safes/${safeAddress}/incoming-transfers/` +export const getIncomingTxServiceUriTo = (safeAddress: string) => `/safes/${safeAddress}/incoming-transfers/` -export const getAllTransactionsUriFrom = (safeAddress: string) => `safes/${safeAddress}/all-transactions/` +export const getAllTransactionsUriFrom = (safeAddress: string) => `/safes/${safeAddress}/all-transactions/` -export const getSafeCreationTxUri = (safeAddress: string) => `safes/${safeAddress}/creation/` +export const getSafeCreationTxUri = (safeAddress: string) => `/safes/${safeAddress}/creation/` export const getGoogleAnalyticsTrackingID = (): string => GOOGLE_ANALYTICS_ID[getNetworkId()] diff --git a/src/config/networks/local.ts b/src/config/networks/local.ts index 195e315e38..dec9140784 100644 --- a/src/config/networks/local.ts +++ b/src/config/networks/local.ts @@ -2,13 +2,13 @@ import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { - txServiceUrl: 'http://localhost:8000/api/v1/', + txServiceUrl: 'http://localhost:8000/api/v1', relayApiUrl: 'https://safe-relay.staging.gnosisdev.com/api/v1', - safeAppsUrl: 'http://localhost:3002/', + safeAppsUrl: 'http://localhost:3002', gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', - rpcServiceUrl: 'http://localhost:4447/', + rpcServiceUrl: 'http://localhost:4447', networkExplorerName: 'Etherscan', - networkExplorerUrl: 'https://rinkeby.etherscan.io/', + networkExplorerUrl: 'https://rinkeby.etherscan.io', networkExplorerApiUrl: 'https://api-rinkeby.etherscan.io/api', } diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index 7635ada83e..6571e1583f 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -2,12 +2,12 @@ import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { - txServiceUrl: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/', - safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com/', + txServiceUrl: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1', + safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com', gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', - rpcServiceUrl: 'https://mainnet.infura.io:443/v3/', + rpcServiceUrl: 'https://mainnet.infura.io:443/v3', networkExplorerName: 'Etherscan', - networkExplorerUrl: 'https://etherscan.io/', + networkExplorerUrl: 'https://etherscan.io', networkExplorerApiUrl: 'https://api.etherscan.io/api', } @@ -18,12 +18,12 @@ const mainnet: NetworkConfig = { }, staging: { ...baseConfig, - safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com/', + safeAppsUrl: 'https://safe-apps.staging.gnosisdev.com', }, production: { ...baseConfig, - txServiceUrl: 'https://safe-transaction.mainnet.gnosis.io/api/v1/', - safeAppsUrl: 'https://apps.gnosis-safe.io/', + txServiceUrl: 'https://safe-transaction.mainnet.gnosis.io/api/v1', + safeAppsUrl: 'https://apps.gnosis-safe.io', }, }, network: { diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index 7a6d78325f..4da2762194 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -2,12 +2,12 @@ import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { - txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1/', - safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com/', + txServiceUrl: 'https://safe-transaction.staging.gnosisdev.com/api/v1', + safeAppsUrl: 'https://safe-apps.dev.gnosisdev.com', gasPriceOracleUrl: 'https://ethgasstation.info/json/ethgasAPI.json', - rpcServiceUrl: 'https://rinkeby.infura.io:443/v3/', + rpcServiceUrl: 'https://rinkeby.infura.io:443/v3', networkExplorerName: 'Etherscan', - networkExplorerUrl: 'https://rinkeby.etherscan.io/', + networkExplorerUrl: 'https://rinkeby.etherscan.io', networkExplorerApiUrl: 'https://api-rinkeby.etherscan.io/api', } @@ -22,8 +22,8 @@ const rinkeby: NetworkConfig = { }, production: { ...baseConfig, - txServiceUrl: 'https://safe-transaction.rinkeby.gnosis.io/api/v1/', - safeAppsUrl: 'https://apps.gnosis-safe.io/', + txServiceUrl: 'https://safe-transaction.rinkeby.gnosis.io/api/v1', + safeAppsUrl: 'https://apps.gnosis-safe.io', }, }, network: { diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index d3a29a93e9..78cba3b3b2 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -3,12 +3,12 @@ import { ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const xDai: NetworkConfig = { environment: { production: { - txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1/', - safeAppsUrl: 'https://apps.gnosis-safe.io/', + txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1', + safeAppsUrl: 'https://apps.gnosis-safe.io', gasPrice: 1e9, - rpcServiceUrl: 'https://rpc.xdaichain.com/', + rpcServiceUrl: 'https://rpc.xdaichain.com', networkExplorerName: 'Blockscout', - networkExplorerUrl: 'https://blockscout.com/poa/xdai/', + networkExplorerUrl: 'https://blockscout.com/poa/xdai', networkExplorerApiUrl: 'https://blockscout.com/poa/xdai/api', }, }, diff --git a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts index 7d9f35d0e4..2afecf0cfc 100644 --- a/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts +++ b/src/logic/currencyValues/__tests__/fetchSafeTokens.test.ts @@ -49,8 +49,6 @@ describe('fetchTokenCurrenciesBalances', () => { // then expect(result).toStrictEqual(expectedResult) expect(axios.get).toHaveBeenCalled() - expect(axios.get).toBeCalledWith(`${apiUrl}safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}`, { - params: { limit: 3000 }, - }) + expect(axios.get).toBeCalledWith(`${apiUrl}/safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}`) }) }) diff --git a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts index 28eba7e05d..06c290dc8d 100644 --- a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts +++ b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts @@ -16,13 +16,9 @@ const fetchTokenCurrenciesBalances = ( excludeSpamTokens = true, ): Promise> => { const apiUrl = getTxServiceUrl() - const url = `${apiUrl}safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}` + const url = `${apiUrl}/safes/${safeAddress}/balances/usd/?exclude_spam=${excludeSpamTokens}` - return axios.get(url, { - params: { - limit: 3000, - }, - }) + return axios.get(url) } export default fetchTokenCurrenciesBalances diff --git a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts b/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts index 6265ff024e..b06c9ba13f 100644 --- a/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts +++ b/src/logic/safe/store/actions/allTransactions/loadAllTransactions.ts @@ -25,7 +25,7 @@ const getAllTransactionsUri = (safeAddress: string): string => { const address = checksumAddress(safeAddress) const base = getAllTransactionsUriFrom(address) - return `${host}${base}` + return `${host}/${base}` } const fetchAllTransactions = async ( diff --git a/src/logic/safe/transactions/incomingTxHistory.ts b/src/logic/safe/transactions/incomingTxHistory.ts index e4597eb067..8eec0f6f10 100644 --- a/src/logic/safe/transactions/incomingTxHistory.ts +++ b/src/logic/safe/transactions/incomingTxHistory.ts @@ -6,5 +6,5 @@ export const buildIncomingTxServiceUrl = (safeAddress: string): string => { const address = checksumAddress(safeAddress) const base = getIncomingTxServiceUriTo(address) - return `${host}${base}` + return `${host}/${base}` } diff --git a/src/logic/safe/transactions/txHistory.ts b/src/logic/safe/transactions/txHistory.ts index b12300d2eb..ea787b17ee 100644 --- a/src/logic/safe/transactions/txHistory.ts +++ b/src/logic/safe/transactions/txHistory.ts @@ -48,7 +48,7 @@ export const buildTxServiceUrl = (safeAddress: string): string => { const host = getTxServiceUrl() const address = checksumAddress(safeAddress) const base = getTxServiceUriFrom(address) - return `${host}${base}?has_confirmations=True` + return `${host}/${base}?has_confirmations=True` } const SUCCESS_STATUS = 201 // CREATED status diff --git a/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts b/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts new file mode 100644 index 0000000000..b7874b643a --- /dev/null +++ b/src/logic/tokens/api/fetchErc20AndErc721AssetsList.ts @@ -0,0 +1,24 @@ +import axios, { AxiosResponse } from 'axios' + +import { getTxServiceUrl } from 'src/config/index' + +type TokenResult = { + address: string + decimals?: number + logoUri: string + name: string + symbol: string + type: string +} + +export const fetchErc20AndErc721AssetsList = async (): Promise> => { + const apiUrl = getTxServiceUrl() + + const url = `${apiUrl}/tokens/` + + return axios.get<{ results: TokenResult[] }>(url, { + params: { + limit: 3000, + }, + }) +} diff --git a/src/logic/tokens/api/fetchToken.ts b/src/logic/tokens/api/fetchToken.ts deleted file mode 100644 index 7584521ecd..0000000000 --- a/src/logic/tokens/api/fetchToken.ts +++ /dev/null @@ -1,16 +0,0 @@ -import axios from 'axios' - -import { getRelayUrl } from 'src/config/index' - -const fetchToken = (tokenAddress) => { - const apiUrl = getRelayUrl() - const url = `${apiUrl}/tokens/` - - return axios.get(url, { - params: { - address: tokenAddress, - }, - }) -} - -export default fetchToken diff --git a/src/logic/tokens/api/fetchTokenBalanceList.ts b/src/logic/tokens/api/fetchTokenBalanceList.ts index 91bdc399df..6712a09eaf 100644 --- a/src/logic/tokens/api/fetchTokenBalanceList.ts +++ b/src/logic/tokens/api/fetchTokenBalanceList.ts @@ -4,13 +4,9 @@ import { getTxServiceUrl } from 'src/config/index' const fetchTokenBalanceList = (safeAddress) => { const apiUrl = getTxServiceUrl() - const url = `${apiUrl}safes/${safeAddress}/balances/` + const url = `${apiUrl}/safes/${safeAddress}/balances/` - return axios.get(url, { - params: { - limit: 3000, - }, - }) + return axios.get(url) } export default fetchTokenBalanceList diff --git a/src/logic/tokens/api/fetchTokenList.ts b/src/logic/tokens/api/fetchTokenList.ts deleted file mode 100644 index dd9054b039..0000000000 --- a/src/logic/tokens/api/fetchTokenList.ts +++ /dev/null @@ -1,16 +0,0 @@ -import axios from 'axios' - -import { getRelayUrl } from 'src/config/index' - -const fetchTokenList = () => { - const apiUrl = getRelayUrl() - const url = `${apiUrl}tokens/` - - return axios.get(url, { - params: { - limit: 3000, - }, - }) -} - -export default fetchTokenList diff --git a/src/logic/tokens/api/index.ts b/src/logic/tokens/api/index.ts index 7ff3aa7de3..408b30b38e 100644 --- a/src/logic/tokens/api/index.ts +++ b/src/logic/tokens/api/index.ts @@ -1,2 +1 @@ -export { default as fetchTokenList } from './fetchTokenList' -export { default as fetchToken } from './fetchToken' +export { fetchErc20AndErc721AssetsList } from './fetchErc20AndErc721AssetsList' diff --git a/src/logic/tokens/store/actions/fetchTokens.ts b/src/logic/tokens/store/actions/fetchTokens.ts index 5c5bde4959..6bccf77034 100644 --- a/src/logic/tokens/store/actions/fetchTokens.ts +++ b/src/logic/tokens/store/actions/fetchTokens.ts @@ -8,7 +8,7 @@ import contract from 'truffle-contract' import saveTokens from './saveTokens' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' -import { fetchTokenList } from 'src/logic/tokens/api' +import { fetchErc20AndErc721AssetsList } from 'src/logic/tokens/api' import { makeToken, Token } from 'src/logic/tokens/store/model/token' import { tokensSelector } from 'src/logic/tokens/store/selectors' import { getWeb3 } from 'src/logic/wallets/getWeb3' @@ -98,13 +98,15 @@ export const fetchTokens = () => async ( const { data: { results: tokenList }, - } = await fetchTokenList() + } = await fetchErc20AndErc721AssetsList() - if (currentSavedTokens && currentSavedTokens.size === tokenList.length) { + const erc20Tokens = tokenList.filter((token) => token.type.toLowerCase() === 'erc20') + + if (currentSavedTokens?.size === erc20Tokens.length) { return } - const tokens = List(tokenList.map((token) => makeToken(token))) + const tokens = List(erc20Tokens.map((token) => makeToken(token))) dispatch(saveTokens(tokens)) } catch (err) { From dc77aebc32a4ceb92f4bd5b8e27460a9e05d3c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Longoni?= Date: Thu, 8 Oct 2020 19:50:11 -0300 Subject: [PATCH 15/19] (Feature) [xDai] - Visually differentiate networks (#1431) Co-authored-by: fernandomg Co-authored-by: Agustin Pane --- src/components/App/ReceiveModal.tsx | 17 +++- src/components/App/index.tsx | 17 +++- .../AppLayout/Header/components/CircleDot.tsx | 99 ++++--------------- .../AppLayout/Header/components/KeyRing.tsx | 97 ++++++++++++++++++ .../Header/components/NetworkLabel.tsx | 9 +- .../ProviderDetails/ConnectDetails.tsx | 5 +- .../ProviderDetails/UserDetails.tsx | 8 +- .../ProviderInfo/ProviderAccessible.tsx | 4 +- .../ProviderInfo/ProviderDisconnected.tsx | 5 +- .../AppLayout/Sidebar/SafeHeader/index.tsx | 92 ++++++++++------- .../networks/__tests__/networks.test.ts | 27 ++++- src/config/networks/local.ts | 3 +- src/config/networks/mainnet.ts | 3 +- src/config/networks/network.d.ts | 3 +- src/config/networks/rinkeby.ts | 3 +- src/config/networks/xdai.ts | 3 +- src/logic/safe/hooks/useSafeActions.tsx | 12 ++- src/routes/safe/components/Balances/index.tsx | 6 +- 18 files changed, 263 insertions(+), 150 deletions(-) create mode 100644 src/components/AppLayout/Header/components/KeyRing.tsx diff --git a/src/components/App/ReceiveModal.tsx b/src/components/App/ReceiveModal.tsx index 6281a4b43f..f91d341cc7 100644 --- a/src/components/App/ReceiveModal.tsx +++ b/src/components/App/ReceiveModal.tsx @@ -2,7 +2,7 @@ import IconButton from '@material-ui/core/IconButton' import { createStyles, makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import QRCode from 'qrcode.react' -import * as React from 'react' +import React, { ReactElement } from 'react' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -13,9 +13,11 @@ 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 { lg, md, screenSm, secondaryText, sm } from 'src/theme/variables' +import { border, fontColor, lg, md, screenSm, secondaryText, sm } from 'src/theme/variables' import { copyToClipboard } from 'src/utils/clipboard' +import { getNetworkInfo } from 'src/config' +const networkInfo = getNetworkInfo() const useStyles = makeStyles( createStyles({ heading: { @@ -35,6 +37,12 @@ const useStyles = makeStyles( borderRadius: '6px', border: `1px solid ${secondaryText}`, }, + networkInfo: { + backgroundColor: `${networkInfo?.backgroundColor ?? border}`, + color: `${networkInfo?.textColor ?? fontColor}`, + padding: md, + marginBottom: 0, + }, annotation: { margin: lg, marginBottom: 0, @@ -79,7 +87,7 @@ type Props = { safeName: string } -const ReceiveModal = ({ onClose, safeAddress, safeName }: Props) => { +const ReceiveModal = ({ onClose, safeAddress, safeName }: Props): ReactElement => { const classes = useStyles() return ( @@ -93,6 +101,9 @@ const ReceiveModal = ({ onClose, safeAddress, safeName }: Props) => { + + {networkInfo.label} Network only send {networkInfo.label} assets to this Safe. + This is the address of your Safe. Deposit funds by scanning the QR code or copying the address below. Only send ETH and ERC-20 tokens to this address! diff --git a/src/components/App/index.tsx b/src/components/App/index.tsx index eda52cb2ee..a916ac985b 100644 --- a/src/components/App/index.tsx +++ b/src/components/App/index.tsx @@ -30,7 +30,7 @@ import { currentCurrencySelector, safeFiatBalancesTotalSelector } from 'src/logi import { formatAmountInUsFormat } from 'src/logic/tokens/utils/formatAmount' import { grantedSelector } from 'src/routes/safe/container/selector' -import Receive from './ReceiveModal' +import ReceiveModal from './ReceiveModal' import { useSidebarItems } from 'src/components/AppLayout/Sidebar/useSidebarItems' const notificationStyles = { @@ -46,6 +46,12 @@ const notificationStyles = { info: { background: '#fff', }, + receiveModal: { + height: 'auto', + maxWidth: 'calc(100% - 30px)', + minHeight: '544px', + overflow: 'hidden', + }, } const Frame = styled.div` @@ -67,7 +73,7 @@ const App: React.FC = ({ children }) => { const matchSafe = useRouteMatch({ path: `${SAFELIST_ADDRESS}`, strict: false }) const history = useHistory() const safeAddress = useSelector(safeParamAddressFromStateSelector) - const safeName = useSelector(safeNameSelector) + const safeName = useSelector(safeNameSelector) ?? '' const { safeActionsState, onShow, onHide, showSendFunds, hideSendFunds } = useSafeActions() const currentSafeBalance = useSelector(safeFiatBalancesTotalSelector) const currentCurrency = useSelector(currentCurrencySelector) @@ -77,7 +83,7 @@ const App: React.FC = ({ children }) => { useLoadSafe(safeAddress) useSafeScheduledUpdates(safeAddress) - const sendFunds = safeActionsState.sendFunds as { isOpen: boolean; selectedToken: string } + const sendFunds = safeActionsState.sendFunds const formattedTotalBalance = currentSafeBalance ? formatAmountInUsFormat(currentSafeBalance) : '' const balance = !!formattedTotalBalance && !!currentCurrency ? `${formattedTotalBalance} ${currentCurrency}` : undefined @@ -138,10 +144,11 @@ const App: React.FC = ({ children }) => { - + )} diff --git a/src/components/AppLayout/Header/components/CircleDot.tsx b/src/components/AppLayout/Header/components/CircleDot.tsx index 2ae0fe65b7..83ce6a0d2a 100644 --- a/src/components/AppLayout/Header/components/CircleDot.tsx +++ b/src/components/AppLayout/Header/components/CircleDot.tsx @@ -1,86 +1,27 @@ -import { withStyles } from '@material-ui/core/styles' -import Dot from '@material-ui/icons/FiberManualRecord' import * as React from 'react' +import { getNetworkInfo } from 'src/config' -import Block from 'src/components/layout/Block' -import Img from 'src/components/layout/Img' -import { border, fancy, screenSm, warning } from 'src/theme/variables' - -const key = require('../assets/key.svg') -const triangle = require('../assets/triangle.svg') - -const styles = () => ({ - root: { - display: 'none', - [`@media (min-width: ${screenSm}px)`]: { - display: 'flex', - }, - }, - dot: { - position: 'relative', - backgroundColor: '#ffffff', - color: fancy, - }, - key: { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - backgroundColor: border, - }, - warning: { - position: 'relative', - top: '-2px', - }, -}) - -const buildKeyStyleFrom = (size, center, dotSize) => ({ - width: `${size}px`, - height: `${size}px`, - marginLeft: center ? `${dotSize}px` : 'none', - borderRadius: `${size}px`, -}) - -const buildDotStyleFrom = (size, top, right, mode) => ({ - width: `${size}px`, - height: `${size}px`, - borderRadius: `${size}px`, - top: `${top}px`, - right: `${right}px`, - color: mode === 'error' ? fancy : warning, -}) +type Props = { + className: string +} -const KeyRing = ({ - center = false, - circleSize, - classes, - dotRight, - dotSize, - dotTop, - hideDot = false, - keySize, - mode, -}) => { - const keyStyle = buildKeyStyleFrom(circleSize, center, dotSize) - const dotStyle = buildDotStyleFrom(dotSize, dotTop, dotRight, mode) - const isWarning = mode === 'warning' - const img = isWarning ? triangle : key +export const CircleDot = (props: Props): React.ReactElement => { + const networkInfo = getNetworkInfo() return ( - <> - - - Status connection - - {!hideDot && } - - +
+ + + +
) } - -export default withStyles(styles as any)(KeyRing) diff --git a/src/components/AppLayout/Header/components/KeyRing.tsx b/src/components/AppLayout/Header/components/KeyRing.tsx new file mode 100644 index 0000000000..10c39b7494 --- /dev/null +++ b/src/components/AppLayout/Header/components/KeyRing.tsx @@ -0,0 +1,97 @@ +import { createStyles, makeStyles } from '@material-ui/core/styles' +import Dot from '@material-ui/icons/FiberManualRecord' +import * as React from 'react' + +import Block from 'src/components/layout/Block' +import Img from 'src/components/layout/Img' +import { border, fancy, screenSm, warning } from 'src/theme/variables' + +const key = require('../assets/key.svg') +const triangle = require('../assets/triangle.svg') + +const styles = createStyles({ + root: { + display: 'none', + [`@media (min-width: ${screenSm}px)`]: { + display: 'flex', + }, + }, + dot: { + position: 'relative', + backgroundColor: '#ffffff', + color: fancy, + }, + key: { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + backgroundColor: border, + }, + warning: { + position: 'relative', + top: '-2px', + }, +}) + +const useStyles = makeStyles(styles) + +const buildKeyStyleFrom = (size, center, dotSize) => ({ + width: `${size}px`, + height: `${size}px`, + marginLeft: center ? `${dotSize}px` : 'none', + borderRadius: `${size}px`, +}) + +const buildDotStyleFrom = (size, top, right, mode) => ({ + width: `${size}px`, + height: `${size}px`, + borderRadius: `${size}px`, + top: `${top}px`, + right: `${right}px`, + color: mode === 'error' ? fancy : warning, +}) + +type Props = { + center?: boolean + circleSize?: number + dotRight?: number + dotSize?: number + dotTop?: number + hideDot?: boolean + keySize: number + mode?: string +} + +export const KeyRing = ({ + center = false, + circleSize, + dotRight, + dotSize, + dotTop, + hideDot = false, + keySize, + mode, +}: Props): React.ReactElement => { + const classes = useStyles(styles) + const keyStyle = buildKeyStyleFrom(circleSize, center, dotSize) + const dotStyle = buildDotStyleFrom(dotSize, dotTop, dotRight, mode) + const isWarning = mode === 'warning' + const img = isWarning ? triangle : key + + return ( + <> + + + Status connection + + {!hideDot && } + + + ) +} diff --git a/src/components/AppLayout/Header/components/NetworkLabel.tsx b/src/components/AppLayout/Header/components/NetworkLabel.tsx index d68da3fb65..8186a03cbe 100644 --- a/src/components/AppLayout/Header/components/NetworkLabel.tsx +++ b/src/components/AppLayout/Header/components/NetworkLabel.tsx @@ -3,14 +3,16 @@ import * as React from 'react' import Col from 'src/components/layout/Col' import Paragraph from 'src/components/layout/Paragraph' -import { getNetworkId } from 'src/config' +import { getNetworkId, getNetworkInfo } from 'src/config' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' -import { border, md, screenSm, sm, xs } from 'src/theme/variables' +import { border, md, screenSm, sm, xs, fontColor } from 'src/theme/variables' const interfaceNetwork = getNetworkId() const formatNetwork = (network: number): string => ETHEREUM_NETWORK[network][0].toUpperCase() + ETHEREUM_NETWORK[network].substring(1).toLowerCase() +const networkInfo = getNetworkInfo() + const useStyles = makeStyles({ container: { flexGrow: 0, @@ -21,7 +23,8 @@ const useStyles = makeStyles({ }, }, text: { - background: border, + backgroundColor: `${networkInfo?.backgroundColor ?? border}`, + color: `${networkInfo?.textColor ?? fontColor}`, borderRadius: '3px', lineHeight: 'normal', margin: '0', diff --git a/src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails.tsx index 76300a966a..0b52d4e596 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/ConnectDetails.tsx @@ -2,11 +2,12 @@ import { withStyles } from '@material-ui/core/styles' import * as React from 'react' import ConnectButton from 'src/components/ConnectButton' -import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' + import Block from 'src/components/layout/Block' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { lg, md } from 'src/theme/variables' +import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing' const styles = () => ({ container: { @@ -42,7 +43,7 @@ const ConnectDetails = ({ classes }) => (
- + diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index 03c43c859a..272a6013dd 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -4,7 +4,6 @@ import classNames from 'classnames' import * as React from 'react' import { EthHashInfo, Identicon } from '@gnosis.pm/safe-react-components' -import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' import Spacer from 'src/components/Spacer' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' @@ -16,8 +15,9 @@ import { background, connected as connectedBg, lg, md, sm, warning, xs } from 's import { upperFirst } from 'src/utils/css' import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { getExplorerInfo } from 'src/config' +import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing' +import { CircleDot } from '../CircleDot' -const dot = require('../../assets/dotRinkeby.svg') const walletIcon = require('../../assets/wallet.svg') const styles = () => ({ @@ -101,7 +101,7 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, {connected ? ( ) : ( - + )} @@ -140,7 +140,7 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, Network - Network + {upperFirst(ETHEREUM_NETWORK[network])} diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index cc226e695a..675e352974 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -3,11 +3,11 @@ import * as React from 'react' import { EthHashInfo, Text } from '@gnosis.pm/safe-react-components' import NetworkLabel from '../NetworkLabel' -import CircleDot from 'src/components/AppLayout/Header/components/CircleDot' import Col from 'src/components/layout/Col' import Paragraph from 'src/components/layout/Paragraph' import WalletIcon from '../WalletIcon' import { connected as connectedBg, screenSm, sm } from 'src/theme/variables' +import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing' const useStyles = makeStyles({ network: { @@ -72,7 +72,7 @@ const ProviderInfo = ({ connected, provider, userAddress, network }: ProviderInf const addressColor = connected ? 'text' : 'warning' return ( <> - {!connected && } + {!connected && } ({ network: { @@ -27,7 +26,7 @@ const styles = () => ({ const ProviderDisconnected = ({ classes }) => ( <> - + props.networkInfo?.textColor ?? fontColor}; + background-color: ${(props: StyledTextLabelProps) => props.networkInfo?.backgroundColor ?? border}; +` const StyledEthHashInfo = styled(EthHashInfo)` p { color: ${({ theme }) => theme.colors.placeHolder}; @@ -111,42 +126,49 @@ const SafeHeader = ({ ) } const explorerUrl = getExplorerInfo(address) + const networkInfo = getNetworkInfo() + return ( - - - - - - - - - - {safeName} - - - - - - - - - - {granted ? null : ( - - - READ ONLY + <> + + {networkInfo.label} + + + + + + + + + + + {safeName} + + + + + + + + + + {granted ? null : ( + + + READ ONLY + + + )} + + {balance} + + + + New Transaction - - )} - - {balance} - - - - New Transaction - - - + +
+ ) } diff --git a/src/config/networks/__tests__/networks.test.ts b/src/config/networks/__tests__/networks.test.ts index c49514bf8e..00a79dfdf0 100644 --- a/src/config/networks/__tests__/networks.test.ts +++ b/src/config/networks/__tests__/networks.test.ts @@ -101,20 +101,39 @@ describe('Networks config files test', () => { }) networksFileNames.forEach((networkFileName) => { - it(`should have a valid CSS color defined for 'network.color'`, () => { + it(`should have a valid CSS color defined for 'network.backgroundColor'`, () => { // Given const networkConfig = networks[networkFileName] // When - const { color } = networkConfig.network + const { backgroundColor } = networkConfig.network // Then const s = new Option().style - s.color = color + s.color = backgroundColor const isValid = s.color !== '' if (!isValid) { - console.log(`Invalid value in "${networkFileName}" at network.color:`, color) + console.log(`Invalid value in "${networkFileName}" at network.backgroundColor:`, backgroundColor) + } + + expect(isValid).toBeTruthy() + }) + + it(`should have a valid CSS color defined for 'network.textColor'`, () => { + // Given + const networkConfig = networks[networkFileName] + + // When + const { textColor } = networkConfig.network + + // Then + const s = new Option().style + s.color = textColor + const isValid = s.color !== '' + + if (!isValid) { + console.log(`Invalid value in "${networkFileName}" at network.textColor:`, textColor) } expect(isValid).toBeTruthy() diff --git a/src/config/networks/local.ts b/src/config/networks/local.ts index dec9140784..0be103570d 100644 --- a/src/config/networks/local.ts +++ b/src/config/networks/local.ts @@ -20,7 +20,8 @@ const local: NetworkConfig = { }, network: { id: ETHEREUM_NETWORK.LOCAL, - color: '#E8673C', + backgroundColor: '#E8673C', + textColor: '#ffffff', label: 'LocalRPC', nativeCoin: { address: '0x000', diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index 6571e1583f..4876af22d3 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -28,7 +28,8 @@ const mainnet: NetworkConfig = { }, network: { id: ETHEREUM_NETWORK.MAINNET, - color: '#E8E7E6', + backgroundColor: '#E8E7E6', + textColor: '#001428', label: 'Mainnet', nativeCoin: { address: '0x000', diff --git a/src/config/networks/network.d.ts b/src/config/networks/network.d.ts index fd632d035b..77345ea9e8 100644 --- a/src/config/networks/network.d.ts +++ b/src/config/networks/network.d.ts @@ -24,7 +24,8 @@ export enum ETHEREUM_NETWORK { export type NetworkSettings = { // TODO: id now seems to be unnecessary id: ETHEREUM_NETWORK, - color: string, + backgroundColor: string, + textColor: string, label: string, nativeCoin: Token, } diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index 4da2762194..41e2977a4f 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -28,7 +28,8 @@ const rinkeby: NetworkConfig = { }, network: { id: ETHEREUM_NETWORK.RINKEBY, - color: '#E8673C', + backgroundColor: '#E8673C', + textColor: '#ffffff', label: 'Rinkeby', nativeCoin: { address: '0x000', diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index 78cba3b3b2..86dd160429 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -14,7 +14,8 @@ const xDai: NetworkConfig = { }, network: { id: ETHEREUM_NETWORK.XDAI, - color: '#48A8A6', + backgroundColor: '#48A8A6', + textColor: '#ffffff', label: 'xDai STAKE', nativeCoin: { address: '0x000', diff --git a/src/logic/safe/hooks/useSafeActions.tsx b/src/logic/safe/hooks/useSafeActions.tsx index 38bc655bb5..a97e09ab53 100644 --- a/src/logic/safe/hooks/useSafeActions.tsx +++ b/src/logic/safe/hooks/useSafeActions.tsx @@ -1,6 +1,14 @@ import { useState, useMemo } from 'react' -const INITIAL_STATE = { +type SafeActionsState = { + sendFunds: { + isOpen: boolean + selectedToken?: string + } + showReceive: boolean +} + +const INITIAL_STATE: SafeActionsState = { sendFunds: { isOpen: false, selectedToken: undefined, @@ -13,7 +21,7 @@ type Response = { onHide: (action: string) => void showSendFunds: (token: string) => void hideSendFunds: () => void - safeActionsState: Record + safeActionsState: SafeActionsState } const useSafeActions = (): Response => { diff --git a/src/routes/safe/components/Balances/index.tsx b/src/routes/safe/components/Balances/index.tsx index 1f5489c6af..c72c001919 100644 --- a/src/routes/safe/components/Balances/index.tsx +++ b/src/routes/safe/components/Balances/index.tsx @@ -2,7 +2,7 @@ import { makeStyles } from '@material-ui/core/styles' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' -import Receive from 'src/components/App/ReceiveModal' +import ReceiveModal from 'src/components/App/ReceiveModal' import Tokens from './Tokens' import { styles } from './style' @@ -53,7 +53,7 @@ const Balances = (): React.ReactElement => { const address = useSelector(safeParamAddressFromStateSelector) const featuresEnabled = useSelector(safeFeaturesEnabledSelector) - const safeName = useSelector(safeNameSelector) + const safeName = useSelector(safeNameSelector) ?? '' useFetchTokens(address as string) @@ -229,7 +229,7 @@ const Balances = (): React.ReactElement => { paperClassName={receiveModal} title="Receive Tokens" > - onHide('Receive')} /> + onHide('Receive')} /> ) From e941f1f1849c428d783b6754568fa78d5fb35668 Mon Sep 17 00:00:00 2001 From: Agustin Pane Date: Fri, 9 Oct 2020 15:07:25 -0300 Subject: [PATCH 16/19] (Feature) [xDai] - Cosmetic fixes (#1449) --- .../Header/components/NetworkLabel.tsx | 16 ++-------- .../ProviderDetails/UserDetails.tsx | 29 +++++++++++++++---- .../ProviderInfo/ProviderAccessible.tsx | 5 ++-- src/components/AppLayout/Header/index.tsx | 4 +-- .../SafeList/AddresWrapper.tsx | 5 ++-- src/config/networks/local.ts | 1 + src/config/networks/mainnet.ts | 1 + src/config/networks/network.d.ts | 1 + src/config/networks/rinkeby.ts | 1 + src/config/networks/xdai.ts | 3 +- src/logic/notifications/notificationTypes.ts | 6 ++-- .../wallets/store/actions/fetchProvider.ts | 8 ++--- 12 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/components/AppLayout/Header/components/NetworkLabel.tsx b/src/components/AppLayout/Header/components/NetworkLabel.tsx index 8186a03cbe..edd88fe3a6 100644 --- a/src/components/AppLayout/Header/components/NetworkLabel.tsx +++ b/src/components/AppLayout/Header/components/NetworkLabel.tsx @@ -3,14 +3,9 @@ import * as React from 'react' import Col from 'src/components/layout/Col' import Paragraph from 'src/components/layout/Paragraph' -import { getNetworkId, getNetworkInfo } from 'src/config' -import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' +import { getNetworkInfo } from 'src/config' import { border, md, screenSm, sm, xs, fontColor } from 'src/theme/variables' -const interfaceNetwork = getNetworkId() -const formatNetwork = (network: number): string => - ETHEREUM_NETWORK[network][0].toUpperCase() + ETHEREUM_NETWORK[network].substring(1).toLowerCase() - const networkInfo = getNetworkInfo() const useStyles = makeStyles({ @@ -36,18 +31,13 @@ const useStyles = makeStyles({ }, }) -interface NetworkLabelProps { - network?: number -} - -const NetworkLabel = ({ network = interfaceNetwork }: NetworkLabelProps): React.ReactElement => { +const NetworkLabel = (): React.ReactElement => { const classes = useStyles() - const formattedNetwork = formatNetwork(network) return ( - {formattedNetwork} + {networkInfo.label} ) diff --git a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx index 272a6013dd..0f3ff77f0d 100644 --- a/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx +++ b/src/components/AppLayout/Header/components/ProviderDetails/UserDetails.tsx @@ -1,4 +1,4 @@ -import { withStyles } from '@material-ui/core/styles' +import { makeStyles } from '@material-ui/core/styles' import Dot from '@material-ui/icons/FiberManualRecord' import classNames from 'classnames' import * as React from 'react' @@ -17,10 +17,11 @@ import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' import { getExplorerInfo } from 'src/config' import { KeyRing } from 'src/components/AppLayout/Header/components/KeyRing' import { CircleDot } from '../CircleDot' +import { createStyles } from '@material-ui/core' const walletIcon = require('../../assets/wallet.svg') -const styles = () => ({ +const styles = createStyles({ container: { padding: `${md} 12px`, display: 'flex', @@ -90,10 +91,30 @@ const styles = () => ({ }, }) -const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, provider, userAddress }) => { +type Props = { + connected: boolean + network: ETHEREUM_NETWORK + onDisconnect: () => void + openDashboard?: (() => void | null) | boolean + provider?: string + userAddress: string +} + +const useStyles = makeStyles(styles) + +export const UserDetails = ({ + connected, + network, + onDisconnect, + openDashboard, + provider, + userAddress, +}: Props): React.ReactElement => { const status = connected ? 'Connected' : 'Connection error' const color = connected ? 'primary' : 'warning' const explorerUrl = getExplorerInfo(userAddress) + const classes = useStyles() + return ( <> @@ -172,5 +193,3 @@ const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, ) } - -export default withStyles(styles as any)(UserDetails) diff --git a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx index 675e352974..563c3abbb6 100644 --- a/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx +++ b/src/components/AppLayout/Header/components/ProviderInfo/ProviderAccessible.tsx @@ -63,11 +63,10 @@ interface ProviderInfoProps { connected: boolean provider: string // TODO: [xDai] Review. This may cause some issues with EthHashInfo. - network: number userAddress: string } -const ProviderInfo = ({ connected, provider, userAddress, network }: ProviderInfoProps): React.ReactElement => { +const ProviderInfo = ({ connected, provider, userAddress }: ProviderInfoProps): React.ReactElement => { const classes = useStyles() const addressColor = connected ? 'text' : 'warning' return ( @@ -107,7 +106,7 @@ const ProviderInfo = ({ connected, provider, userAddress, network }: ProviderInf - + ) diff --git a/src/components/AppLayout/Header/index.tsx b/src/components/AppLayout/Header/index.tsx index 5636fbd6dc..6c2b8e4390 100644 --- a/src/components/AppLayout/Header/index.tsx +++ b/src/components/AppLayout/Header/index.tsx @@ -3,7 +3,7 @@ import { useSelector, useDispatch } from 'react-redux' import Layout from './components/Layout' import ConnectDetails from './components/ProviderDetails/ConnectDetails' -import UserDetails from './components/ProviderDetails/UserDetails' +import { UserDetails } from './components/ProviderDetails/UserDetails' import ProviderAccessible from './components/ProviderInfo/ProviderAccessible' import ProviderDisconnected from './components/ProviderInfo/ProviderDisconnected' import { @@ -54,7 +54,7 @@ const HeaderComponent = (): React.ReactElement => { return } - return + return } const getProviderDetailsBased = () => { diff --git a/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx b/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx index 2dda0e11aa..dac6c17a6d 100644 --- a/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx +++ b/src/components/SafeListSidebar/SafeList/AddresWrapper.tsx @@ -5,7 +5,6 @@ import { formatAmount } from 'src/logic/tokens/utils/formatAmount' import { sameAddress } from 'src/logic/wallets/ethAddresses' import DefaultBadge from './DefaultBadge' import { SafeRecordProps } from 'src/logic/safe/store/models/safe' -import { getExplorerInfo } from 'src/config' import { DefaultSafe } from 'src/routes/safe/store/reducer/types/safe' import { SetDefaultSafe } from 'src/logic/safe/store/actions/setDefaultSafe' import { makeStyles } from '@material-ui/core/styles' @@ -52,10 +51,10 @@ type Props = { export const AddressWrapper = (props: Props): React.ReactElement => { const classes = useStyles() const { safe, defaultSafe, setDefaultSafe } = props - const explorerUrl = getExplorerInfo(safe.address) + return (
- +
{`${formatAmount(safe.ethBalance)} ETH`} diff --git a/src/config/networks/local.ts b/src/config/networks/local.ts index 0be103570d..ad51c88312 100644 --- a/src/config/networks/local.ts +++ b/src/config/networks/local.ts @@ -23,6 +23,7 @@ const local: NetworkConfig = { backgroundColor: '#E8673C', textColor: '#ffffff', label: 'LocalRPC', + isTestNet: true, nativeCoin: { address: '0x000', name: 'Ether', diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index 4876af22d3..89945ae6af 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -31,6 +31,7 @@ const mainnet: NetworkConfig = { backgroundColor: '#E8E7E6', textColor: '#001428', label: 'Mainnet', + isTestNet: false, nativeCoin: { address: '0x000', name: 'Ether', diff --git a/src/config/networks/network.d.ts b/src/config/networks/network.d.ts index 77345ea9e8..fbdebfca83 100644 --- a/src/config/networks/network.d.ts +++ b/src/config/networks/network.d.ts @@ -27,6 +27,7 @@ export type NetworkSettings = { backgroundColor: string, textColor: string, label: string, + isTestNet: boolean, nativeCoin: Token, } diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index 41e2977a4f..2f0650b0e3 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -31,6 +31,7 @@ const rinkeby: NetworkConfig = { backgroundColor: '#E8673C', textColor: '#ffffff', label: 'Rinkeby', + isTestNet: true, nativeCoin: { address: '0x000', name: 'Ether', diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index 86dd160429..4756b9c409 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -16,7 +16,8 @@ const xDai: NetworkConfig = { id: ETHEREUM_NETWORK.XDAI, backgroundColor: '#48A8A6', textColor: '#ffffff', - label: 'xDai STAKE', + label: 'xDai', + isTestNet: false, nativeCoin: { address: '0x000', name: 'xDai', diff --git a/src/logic/notifications/notificationTypes.ts b/src/logic/notifications/notificationTypes.ts index d1b1b90cd7..9765045660 100644 --- a/src/logic/notifications/notificationTypes.ts +++ b/src/logic/notifications/notificationTypes.ts @@ -45,7 +45,7 @@ const NOTIFICATION_IDS = { SETTINGS_CHANGE_EXECUTED_MSG: 'SETTINGS_CHANGE_EXECUTED_MSG', SETTINGS_CHANGE_EXECUTED_MORE_CONFIRMATIONS_MSG: 'SETTINGS_CHANGE_EXECUTED_MORE_CONFIRMATIONS_MSG', SETTINGS_CHANGE_FAILED_MSG: 'SETTINGS_CHANGE_FAILED_MSG', - RINKEBY_VERSION_MSG: 'RINKEBY_VERSION_MSG', + TESTNET_VERSION_MSG: 'TESTNET_VERSION_MSG', WRONG_NETWORK_MSG: 'WRONG_NETWORK_MSG', ADDRESS_BOOK_NEW_ENTRY_SUCCESS: 'ADDRESS_BOOK_NEW_ENTRY_SUCCESS', ADDRESS_BOOK_EDIT_ENTRY_SUCCESS: 'ADDRESS_BOOK_EDIT_ENTRY_SUCCESS', @@ -192,8 +192,8 @@ export const NOTIFICATIONS: Record = { }, // Network - RINKEBY_VERSION_MSG: { - message: "Rinkeby Version: Don't send Mainnet assets to this Safe", + TESTNET_VERSION_MSG: { + message: "Testnet Version: Don't send production assets to this Safe", options: { variant: WARNING, persist: true, preventDuplicate: true }, }, WRONG_NETWORK_MSG: { diff --git a/src/logic/wallets/store/actions/fetchProvider.ts b/src/logic/wallets/store/actions/fetchProvider.ts index c2907c67dc..79ce447960 100644 --- a/src/logic/wallets/store/actions/fetchProvider.ts +++ b/src/logic/wallets/store/actions/fetchProvider.ts @@ -2,10 +2,9 @@ import ReactGA from 'react-ga' import addProvider from './addProvider' -import { getNetworkId } from 'src/config' +import { getNetworkId, getNetworkInfo } from 'src/config' import { NOTIFICATIONS, enhanceSnackbarForAction } from 'src/logic/notifications' import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { ETHEREUM_NETWORK } from 'src/config/networks/network.d' 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' @@ -29,8 +28,9 @@ const handleProviderNotification = (provider, dispatch) => { dispatch(enqueueSnackbar(NOTIFICATIONS.WRONG_NETWORK_MSG)) return } - if (ETHEREUM_NETWORK.RINKEBY === getNetworkId()) { - dispatch(enqueueSnackbar(enhanceSnackbarForAction(NOTIFICATIONS.RINKEBY_VERSION_MSG))) + + if (getNetworkInfo().isTestNet) { + dispatch(enqueueSnackbar(enhanceSnackbarForAction(NOTIFICATIONS.TESTNET_VERSION_MSG))) } if (available) { From 8fe31d350d8d76bc5e28abc9a73e88026271cb97 Mon Sep 17 00:00:00 2001 From: Daniel Sanchez Date: Fri, 9 Oct 2020 21:05:55 +0200 Subject: [PATCH 17/19] Add staging configuration for deployment using xDai (#1459) * Add staging xDai deployment to travis * Add safe apps production url for xdai * Add travis rule to build xDai on master or integration branch --- .travis.yml | 10 ++++++++-- src/config/networks/xdai.ts | 25 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0804243db5..f374e0adf6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -if: (branch = development) OR (branch = master) OR (type = pull_request) OR (tag IS present) +if: (branch = development) OR (branch = master) OR (feature/#1353-xDai-compatibility) OR (type = pull_request) OR (tag IS present) sudo: required dist: bionic language: node_js @@ -16,6 +16,10 @@ matrix: - env: - REACT_APP_NETWORK='rinkeby' - REACT_APP_GNOSIS_APPS_URL=${REACT_APP_GNOSIS_APPS_URL_STAGING} + - env: + - REACT_APP_NETWORK='xdai' + - STAGING_BUCKET_NAME=${STAGING_XDAI_BUCKET_NAME} + if: ((branch = master OR branch = feature/#1353-xDai-compatibility) AND NOT type = pull_request) OR tag IS present cache: yarn: true before_script: @@ -62,7 +66,9 @@ deploy: upload-dir: current/app region: $AWS_DEFAULT_REGION on: - branch: master + # branch: master + all_branches: true + condition: $TRAVIS_BRANCH =~ ^(master|feature/#1353-xDai-compatibility)$ # Prepare production deployment - provider: s3 diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index 4756b9c409..2d8e41d618 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -1,15 +1,24 @@ -import { ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' +import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' + +const baseConfig: EnvironmentSettings = { + txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1', + safeAppsUrl: 'http://safe-apps-xdai.staging.gnosisdev.com', + gasPrice: 1e9, + rpcServiceUrl: 'https://rpc.xdaichain.com', + networkExplorerName: 'Blockscout', + networkExplorerUrl: 'https://blockscout.com/poa/xdai', + networkExplorerApiUrl: 'https://blockscout.com/poa/xdai/api', +} const xDai: NetworkConfig = { environment: { + staging: { + ...baseConfig + }, production: { - txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1', - safeAppsUrl: 'https://apps.gnosis-safe.io', - gasPrice: 1e9, - rpcServiceUrl: 'https://rpc.xdaichain.com', - networkExplorerName: 'Blockscout', - networkExplorerUrl: 'https://blockscout.com/poa/xdai', - networkExplorerApiUrl: 'https://blockscout.com/poa/xdai/api', + ...baseConfig, + safeAppsUrl: 'http://apps-xdai.gnosis-safe.io', + }, }, network: { From 4d1cecf480334391f79b7022aabd990f79833815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Longoni?= Date: Mon, 12 Oct 2020 05:46:41 -0300 Subject: [PATCH 18/19] (Bugfix) Set min height to ListContentLayout wrapper #1447 (#1451) * fix min-height app containter and margin to info text at bottom * change css unit from % to vh Co-authored-by: nicosampler --- src/components/ListContentLayout/Layout.ts | 2 +- src/routes/safe/components/Apps/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ListContentLayout/Layout.ts b/src/components/ListContentLayout/Layout.ts index feb7d42370..dbb5b2a0f5 100644 --- a/src/components/ListContentLayout/Layout.ts +++ b/src/components/ListContentLayout/Layout.ts @@ -3,7 +3,7 @@ import styled from 'styled-components' export const Wrapper = styled.div` display: grid; grid-template-columns: 245px auto; - min-height: 560px; + min-height: 75vh; .background { box-shadow: 1px 2px 10px 0 rgba(212, 212, 211, 0.59); background-color: white; diff --git a/src/routes/safe/components/Apps/index.tsx b/src/routes/safe/components/Apps/index.tsx index bc72ec224e..40962238e3 100644 --- a/src/routes/safe/components/Apps/index.tsx +++ b/src/routes/safe/components/Apps/index.tsx @@ -42,7 +42,7 @@ const StyledCard = styled(Card)` const CenteredMT = styled.div` ${centerCSS}; - margin-top: 5px; + margin-top: 16px; ` type ConfirmTransactionModalState = { From 720c18510cdbabe28be7a12b039bca1ca48790f6 Mon Sep 17 00:00:00 2001 From: nicosampler Date: Mon, 12 Oct 2020 20:22:18 -0300 Subject: [PATCH 19/19] disable OpenZepplin in xDai --- src/routes/safe/components/Apps/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/safe/components/Apps/utils.ts b/src/routes/safe/components/Apps/utils.ts index af670e6737..c2fd724cff 100644 --- a/src/routes/safe/components/Apps/utils.ts +++ b/src/routes/safe/components/Apps/utils.ts @@ -76,7 +76,7 @@ export const staticAppsList: Array<{ url: string; disabled: boolean; networks: n ETHEREUM_NETWORK.RINKEBY, ETHEREUM_NETWORK.ENERGY_WEB_CHAIN, ETHEREUM_NETWORK.VOLTA, - ETHEREUM_NETWORK.XDAI, + // ETHEREUM_NETWORK.XDAI, ], }, // TX-Builder