diff --git a/src/components/AddressInfo/index.tsx b/src/components/AddressInfo/index.tsx index 99f94a0903..0e618a2a91 100644 --- a/src/components/AddressInfo/index.tsx +++ b/src/components/AddressInfo/index.tsx @@ -1,5 +1,5 @@ import React from 'react' - +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -42,6 +42,8 @@ interface Props { ethBalance?: string } +const { nativeCoin } = getNetworkInfo() + const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactElement => { return ( @@ -64,7 +66,7 @@ const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props): React.ReactE {ethBalance && ( - Balance: {`${ethBalance} ETH`} + Balance: {`${ethBalance} ${nativeCoin.symbol}`} )} diff --git a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx index 48e1c7fc7c..16a0268d1d 100644 --- a/src/components/AppLayout/Sidebar/SafeHeader/index.tsx +++ b/src/components/AppLayout/Sidebar/SafeHeader/index.tsx @@ -13,7 +13,7 @@ import { import FlexSpacer from 'src/components/FlexSpacer' import { getExplorerInfo, getNetworkInfo } from 'src/config' -import { NetworkSettings } from 'src/config/networks/network' +import { NetworkSettings } from 'src/config/networks/network.d' import { border, fontColor } from 'src/theme/variables' export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN' diff --git a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts index ec79aa234a..4accf5dd83 100644 --- a/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts +++ b/src/logic/safe/store/actions/transactions/fetchTransactions/loadIncomingTransactions.ts @@ -1,6 +1,6 @@ import bn from 'bignumber.js' import { List, Map } from 'immutable' - +import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { ALTERNATIVE_TOKEN_ABI } from 'src/logic/tokens/utils/alternativeAbi' import { web3ReadOnly } from 'src/logic/wallets/getWeb3' @@ -43,6 +43,7 @@ const buildIncomingTransactionFrom = ([tx, symbol, decimals, fee]: [ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { const batch = new web3ReadOnly.BatchRequest() + const { nativeCoin } = getNetworkInfo() const whenTxsValues = txs.map((tx) => { const methods = [ @@ -66,8 +67,8 @@ const batchIncomingTxsTokenDataRequest = (txs: IncomingTxServiceModel[]) => { return Promise.all(whenTxsValues).then((txsValues) => txsValues.map(([tx, symbol, decimals, { gasPrice }, { gasUsed }]) => [ tx, - symbol === null ? 'ETH' : symbol, - decimals === null ? '18' : decimals, + symbol === null ? nativeCoin.symbol : symbol, + decimals === null ? nativeCoin.decimals : decimals, new bn(gasPrice).times(gasUsed), ]), ) diff --git a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts index 9ac91d11f4..ad52ebc8b6 100644 --- a/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts +++ b/src/logic/safe/store/actions/transactions/utils/transactionHelpers.ts @@ -1,5 +1,5 @@ import { List, Map } from 'immutable' - +import { getNetworkInfo } from 'src/config' import { TOKEN_REDUCER_ID } from 'src/logic/tokens/store/reducer/tokens' import { getERC20DecimalsAndSymbol, @@ -100,12 +100,13 @@ export const getRefundParams = async ( tx: TxServiceModel, tokenInfo: (string) => Promise<{ decimals: number; symbol: string } | null>, ): Promise => { + const { nativeCoin } = getNetworkInfo() const txGasPrice = Number(tx.gasPrice) let refundParams: RefundParams | null = null if (txGasPrice > 0) { - let refundSymbol = 'ETH' - let refundDecimals = 18 + let refundSymbol = nativeCoin.symbol + let refundDecimals = nativeCoin.decimals if (tx.gasToken !== ZERO_ADDRESS) { const gasToken = await tokenInfo(tx.gasToken) @@ -243,6 +244,7 @@ export const buildTx = async ({ txCode, }: BuildTx): Promise => { const safeAddress = safe.address + const { nativeCoin } = getNetworkInfo() const isModifySettingsTx = isModifySettingsTransaction(tx, safeAddress) const isTxCancelled = isTransactionCancelled(tx, outgoingTxs, cancellationTxs) const isSendERC721Tx = isSendERC721Transaction(tx, txCode, knownTokens) @@ -255,8 +257,8 @@ export const buildTx = async ({ const decodedParams = getDecodedParams(tx) const confirmations = getConfirmations(tx) - let tokenDecimals = 18 - let tokenSymbol = 'ETH' + let tokenDecimals = nativeCoin.decimals + let tokenSymbol = nativeCoin.symbol try { if (isSendERC20Tx) { const { decimals, symbol } = await getERC20DecimalsAndSymbol(tx.to) diff --git a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts index 7afee4ed9e..459e82e0c8 100644 --- a/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts +++ b/src/logic/tokens/utils/__tests__/tokenHelpers.test.ts @@ -1,6 +1,7 @@ import { makeToken } from 'src/logic/tokens/store/model/token' import { getERC20DecimalsAndSymbol, isERC721Contract, isTokenTransfer } from 'src/logic/tokens/utils/tokenHelpers' import { getMockedTxServiceModel } from 'src/test/utils/safeHelper' +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' describe('isTokenTransfer', () => { const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' @@ -171,4 +172,31 @@ describe('isERC721Contract', () => { expect(result).toEqual(expectedResult) expect(standardContractSpy).toHaveBeenCalled() }) + it('It should return the right conversion from unit to token', () => { + // given + const decimals = Number(18) + + const expectedResult = '0.000000003' + const ESTIMATED_GAS_COST = 3e9 // 3 Gwei + + // when + const gasCosts = fromTokenUnit(ESTIMATED_GAS_COST, decimals) + + // then + expect(gasCosts).toEqual(expectedResult) + }) + + it('It should return the right conversion from token to unit', () => { + // given + const decimals = Number(18) + + const expectedResult = '300000000000000000' + const VALUE = 0.3 + + // when + const txValue = toTokenUnit(VALUE, decimals) + + // then + expect(txValue).toEqual(expectedResult) + }) }) diff --git a/src/logic/tokens/utils/humanReadableValue.ts b/src/logic/tokens/utils/humanReadableValue.ts index 7716a1d547..2d2afc1793 100644 --- a/src/logic/tokens/utils/humanReadableValue.ts +++ b/src/logic/tokens/utils/humanReadableValue.ts @@ -3,3 +3,17 @@ import { BigNumber } from 'bignumber.js' export const humanReadableValue = (value: number | string, decimals = 18): string => { return new BigNumber(value).times(`1e-${decimals}`).toFixed() } + +export const fromTokenUnit = (amount: number | string, decimals: string | number): string => + new BigNumber(amount).times(`1e-${decimals}`).toFixed() + +export const toTokenUnit = (amount: number | string, decimals: string | number): string => { + const amountBN = new BigNumber(amount).times(`1e${decimals}`) + const [, amountDecimalPlaces] = amount.toString().split('.') + + if (amountDecimalPlaces?.length >= +decimals) { + return amountBN.toFixed(+decimals, BigNumber.ROUND_DOWN) + } + + return amountBN.toFixed() +} diff --git a/src/logic/tokens/utils/tokenHelpers.ts b/src/logic/tokens/utils/tokenHelpers.ts index 48134bdb2b..186b05a242 100644 --- a/src/logic/tokens/utils/tokenHelpers.ts +++ b/src/logic/tokens/utils/tokenHelpers.ts @@ -1,4 +1,4 @@ -import logo from 'src/assets/icons/icon_etherTokens.svg' +import { getNetworkInfo } from 'src/config' import generateBatchRequests from 'src/logic/contracts/generateBatchRequests' import { getStandardTokenContract, @@ -12,16 +12,12 @@ import { isEmptyData } from 'src/logic/safe/store/actions/transactions/utils/tra import { TxServiceModel } from 'src/logic/safe/store/actions/transactions/fetchTransactions/loadOutgoingTransactions' import { Map } from 'immutable' -export const ETH_ADDRESS = '0x000' export const SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH = '42842e0e' export const getEthAsToken = (balance: string | number): Token => { + const { nativeCoin } = getNetworkInfo() return makeToken({ - address: ETH_ADDRESS, - name: 'Ether', - symbol: 'ETH', - decimals: 18, - logoUri: logo, + ...nativeCoin, balance, }) } diff --git a/src/routes/open/components/ReviewInformation/index.tsx b/src/routes/open/components/ReviewInformation/index.tsx index 2ed3dff91e..e83c786a4a 100644 --- a/src/routes/open/components/ReviewInformation/index.tsx +++ b/src/routes/open/components/ReviewInformation/index.tsx @@ -1,7 +1,8 @@ import TableContainer from '@material-ui/core/TableContainer' import classNames from 'classnames' import React, { useEffect, useState } from 'react' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -13,7 +14,6 @@ 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 { getAccountsFrom, getNamesFrom } from 'src/routes/open/utils/safeDataExtractor' import { FIELD_CONFIRMATIONS, FIELD_NAME, getNumOwnersFrom } from '../fields' @@ -37,11 +37,10 @@ const ReviewComponent = ({ userAccount, values }: ReviewComponentProps) => { if (!addresses.length || !numOwners || !userAccount) { return } - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - const estimatedGasCosts = await estimateGasForDeployingSafe(addresses, numOwners, userAccount) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const { nativeCoin } = getNetworkInfo() + const estimatedGasCosts = (await estimateGasForDeployingSafe(addresses, numOwners, userAccount)).toString() + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) setGasCosts(formattedGasCosts) } diff --git a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx index 5d2d1c1064..d9b76e5474 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Review/index.tsx @@ -2,7 +2,8 @@ import { makeStyles } from '@material-ui/core/styles' import { useSnackbar } from 'notistack' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' - +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import AddressInfo from 'src/components/AddressInfo' import Block from 'src/components/layout/Block' import Button from 'src/components/layout/Button' @@ -16,7 +17,6 @@ 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 { styles } from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/style' import Header from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Header' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' @@ -40,23 +40,23 @@ type Props = { tx: TransactionReviewType } +const { nativeCoin } = getNetworkInfo() + const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const { enqueueSnackbar, closeSnackbar } = useSnackbar() const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - useEffect(() => { let isCurrent = true const estimateGas = async (): Promise => { - const { fromWei, toBN } = getWeb3().utils const txData = tx.data ? tx.data.trim() : '' const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -71,11 +71,9 @@ const ContractInteractionReview = ({ onClose, onPrev, tx }: Props): React.ReactE }, [safeAddress, tx.contractAddress, tx.data]) const submitTx = async () => { - const web3 = getWeb3() const txRecipient = tx.contractAddress const txData = tx.data ? tx.data.trim() : '' - const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0' - + const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0' dispatch( createTransaction({ safeAddress, 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 4b6ffa401e..65bb402eec 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 @@ -3,6 +3,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit, toTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -20,7 +22,6 @@ 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 SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -37,22 +38,22 @@ type Props = { const useStyles = makeStyles(styles) +const { nativeCoin } = getNetworkInfo() + const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} const [gasCosts, setGasCosts] = useState('< 0.001') - useEffect(() => { let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils const txData = tx.data ? tx.data.trim() : '' const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.contractAddress as string, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -67,10 +68,9 @@ const ReviewCustomTx = ({ onClose, onPrev, tx }: Props): React.ReactElement => { }, [safeAddress, tx.data, tx.contractAddress]) const submitTx = async (): Promise => { - const web3 = getWeb3() const txRecipient = tx.contractAddress const txData = tx.data ? tx.data.trim() : '' - const txValue = tx.value ? web3.utils.toWei(tx.value, 'ether') : '0' + const txValue = tx.value ? toTokenUnit(tx.value, nativeCoin.decimals) : '0' dispatch( createTransaction({ 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 7a77be83b8..5a443b9821 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewCollectible/index.tsx @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import { withSnackbar } from 'notistack' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -27,7 +28,6 @@ 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 SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' import { sm } from 'src/theme/variables' @@ -37,6 +37,8 @@ import ArrowDown from '../assets/arrow-down.svg' import { styles } from './style' +const { nativeCoin } = getNetworkInfo() + const useStyles = makeStyles(styles as any) const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { @@ -55,8 +57,6 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils - const supportsSafeTransfer = await containsMethodByHash(tx.assetAddress, SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH) const methodToCall = supportsSafeTransfer ? `0x${SAFE_TRANSFER_FROM_WITHOUT_DATA_HASH}` : 'transfer' const transferParams = [tx.recipientAddress, tx.nftTokenId] @@ -67,8 +67,8 @@ const ReviewCollectible = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx const txData = tokenInstance.contract.methods[methodToCall](...params).encodeABI() const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, tx.recipientAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) 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 f9e1ff3035..23bbc77a02 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/ReviewTx/index.tsx @@ -5,6 +5,8 @@ import { BigNumber } from 'bignumber.js' import { withSnackbar } from 'notistack' import React, { useEffect, useMemo, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { toTokenUnit, fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' @@ -22,9 +24,7 @@ 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 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' @@ -40,20 +40,19 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { const classes = useStyles() const dispatch = useDispatch() const { address: safeAddress } = useSelector(safeSelector) || {} + const { nativeCoin } = getNetworkInfo() const tokens = useSelector(extendedSafeTokensSelector) const [gasCosts, setGasCosts] = useState('< 0.001') const [data, setData] = useState('') const txToken = useMemo(() => tokens.find((token) => token.address === tx.token), [tokens, tx.token]) - const isSendingETH = txToken?.address === ETH_ADDRESS + const isSendingETH = txToken?.address === nativeCoin.address const txRecipient = isSendingETH ? tx.recipientAddress : txToken?.address useEffect(() => { let isCurrent = true const estimateGas = async () => { - const { fromWei, toBN } = getWeb3().utils - if (!txToken) { return } @@ -70,8 +69,8 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { } const estimatedGasCosts = await estimateTxGasCosts(safeAddress as string, txRecipient, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) @@ -84,14 +83,13 @@ const ReviewTx = ({ closeSnackbar, enqueueSnackbar, onClose, onPrev, tx }) => { return () => { isCurrent = false } - }, [isSendingETH, safeAddress, tx.amount, tx.recipientAddress, txRecipient, txToken]) + }, [isSendingETH, nativeCoin.decimals, safeAddress, tx.amount, tx.recipientAddress, txRecipient, txToken]) const submitTx = async () => { - const web3 = getWeb3() // txAmount should be 0 if we send tokens // the real value is encoded in txData and will be used by the contract // if txAmount > 0 it would send ETH from the Safe - const txAmount = isSendingETH ? web3.utils.toWei(tx.amount, 'ether') : '0' + const txAmount = isSendingETH ? toTokenUnit(tx.amount, nativeCoin.decimals) : '0' dispatch( createTransaction({ 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 8ccd275e05..751c21c63e 100644 --- a/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx +++ b/src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.tsx @@ -2,6 +2,7 @@ import IconButton from '@material-ui/core/IconButton' import InputAdornment from '@material-ui/core/InputAdornment' import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' +import { getNetworkInfo } from 'src/config' import React, { useState } from 'react' import { OnChange } from 'react-final-form-listeners' import { useSelector } from 'react-redux' @@ -77,6 +78,7 @@ const SendFunds = ({ const [pristine, setPristine] = useState(true) const [isValidAddress, setIsValidAddress] = useState(false) + const { nativeCoin } = getNetworkInfo() React.useMemo(() => { if (selectedEntry === null && pristine) { @@ -211,7 +213,7 @@ const SendFunds = ({ diff --git a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx index 4d0af38c9e..b1fb65a331 100644 --- a/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx +++ b/src/routes/safe/components/Balances/Tokens/screens/AssetsList/AssetRow.tsx @@ -9,7 +9,7 @@ import React, { memo } from 'react' import { styles } from './style' import Img from 'src/components/layout/Img' -import { ETH_ADDRESS } from 'src/logic/tokens/utils/tokenHelpers' +import { getNetworkInfo } from 'src/config' import { setImageToPlaceholder } from 'src/routes/safe/components/Balances/utils' export const TOGGLE_ASSET_TEST_ID = 'toggle-asset-btn' @@ -20,6 +20,7 @@ const AssetRow = memo(({ classes, data, index, style }: any) => { const asset = assets.get(index) const { address, image, name, symbol } = asset const isActive = activeAssetsAddresses.has(asset.address) + const { nativeCoin } = getNetworkInfo() return (
@@ -28,7 +29,7 @@ const AssetRow = memo(({ classes, data, index, style }: any) => { {name} - {address !== ETH_ADDRESS && ( + {address !== nativeCoin.address && ( { const { activeTokensAddresses, onSwitch, tokens } = data const token = tokens.get(index) const isActive = activeTokensAddresses.has(token.address) - + const { nativeCoin } = getNetworkInfo() return (
@@ -28,7 +28,7 @@ const TokenRow = memo(({ classes, data, index, style }: any) => { {token.name} - {token.address !== ETH_ADDRESS && ( + {token.address !== nativeCoin.address && ( { - if (token.address === ETH_ADDRESS && !tokenAddress) { + const { nativeCoin } = getNetworkInfo() + if (token.address === nativeCoin.address && !tokenAddress) { return true } @@ -54,8 +54,9 @@ export const getBalanceData = ( currencySelected?: AVAILABLE_CURRENCIES, currencyValues?: BalanceCurrencyList, currencyRate?: number, -): List => - activeTokens.map((token) => ({ +): List => { + const { nativeCoin } = getNetworkInfo() + return activeTokens.map((token) => ({ [BALANCE_TABLE_ASSET_ID]: { name: token.name, logoUri: token.logoUri, @@ -65,9 +66,10 @@ export const getBalanceData = ( assetOrder: token.name, [BALANCE_TABLE_BALANCE_ID]: `${formatAmountInUsFormat(token.balance?.toString() || '0')} ${token.symbol}`, balanceOrder: Number(token.balance), - [FIXED]: token.symbol === 'ETH', + [FIXED]: token.symbol === nativeCoin.symbol, [BALANCE_TABLE_VALUE_ID]: getTokenPriceInCurrency(token, currencySelected, currencyValues, currencyRate), })) +} export const generateColumns = (): List => { const assetColumn: TableColumn = { 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 1f659eba39..0572ba3298 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 @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -18,12 +19,13 @@ 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 { styles } from './style' export const ADD_OWNER_SUBMIT_BTN_TEST_ID = 'add-owner-submit-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string @@ -32,15 +34,13 @@ const ReviewAddOwner = ({ classes, onClickBack, onClose, onSubmit, values }) => useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.addOwnerWithThreshold(values.ownerAddress, values.threshold).encodeABI() const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } 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 0a9b13b336..e3dea9b406 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 @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -18,32 +19,30 @@ 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 { getWeb3 } from 'src/logic/wallets/getWeb3' import { styles } from './style' export const REMOVE_OWNER_REVIEW_BTN_TEST_ID = 'remove-owner-review-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const safeName = useSelector(safeNameSelector) const owners = useSelector(safeOwnersSelector) - useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.removeOwner(prevAddress, ownerAddress, values.threshold).encodeABI() const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) 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 1b1e475243..d6221a4e24 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 @@ -4,7 +4,8 @@ import Close from '@material-ui/icons/Close' import classNames from 'classnames' import React, { useEffect, useState } from 'react' import { useSelector } from 'react-redux' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import CopyBtn from 'src/components/CopyBtn' import EtherscanBtn from 'src/components/EtherscanBtn' import Identicon from 'src/components/Identicon' @@ -23,12 +24,13 @@ import { } 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 { styles } from './style' export const REPLACE_OWNER_SUBMIT_BTN_TEST_ID = 'replace-owner-submit-btn' +const { nativeCoin } = getNetworkInfo() + const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddress, ownerName, values }) => { const [gasCosts, setGasCosts] = useState('< 0.001') const safeAddress = useSelector(safeParamAddressFromStateSelector) as string @@ -39,16 +41,14 @@ const ReviewRemoveOwner = ({ classes, onClickBack, onClose, onSubmit, ownerAddre useEffect(() => { let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const gnosisSafe = await getGnosisSafeInstanceAt(safeAddress) const safeOwners = await gnosisSafe.methods.getOwners().call() const index = safeOwners.findIndex((owner) => owner.toLowerCase() === ownerAddress.toLowerCase()) const prevAddress = index === 0 ? SENTINEL_ADDRESS : safeOwners[index - 1] const txData = gnosisSafe.methods.swapOwner(prevAddress, ownerAddress, values.ownerAddress).encodeABI() const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } diff --git a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx index e821d4d3ed..2cc4dfeecd 100644 --- a/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx +++ b/src/routes/safe/components/Settings/ThresholdSettings/ChangeThreshold/index.tsx @@ -3,7 +3,8 @@ import MenuItem from '@material-ui/core/MenuItem' import { withStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' - +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' import Field from 'src/components/forms/Field' @@ -19,22 +20,21 @@ import Row from 'src/components/layout/Row' import { 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' const THRESHOLD_FIELD_NAME = 'threshold' +const { nativeCoin } = getNetworkInfo() + const ChangeThreshold = ({ classes, onChangeThreshold, onClose, owners, safeAddress, threshold }) => { const [gasCosts, setGasCosts] = useState('< 0.001') useEffect(() => { let isCurrent = true const estimateGasCosts = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils const safeInstance = await getGnosisSafeInstanceAt(safeAddress) const txData = safeInstance.methods.changeThreshold('1').encodeABI() const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, txData) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') + const gasCostsAsEth = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) const formattedGasCosts = formatAmount(gasCostsAsEth) if (isCurrent) { setGasCosts(formattedGasCosts) diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx index e6eb22ee76..9518b1f6fa 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/ApproveTxModal/index.tsx @@ -5,6 +5,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' @@ -18,7 +20,6 @@ import Row from 'src/components/layout/Row' 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 { getWeb3 } from 'src/logic/wallets/getWeb3' import { userAccountSelector } from 'src/logic/wallets/store/selectors' import processTransaction from 'src/logic/safe/store/actions/processTransaction' @@ -61,6 +62,7 @@ type Props = { thresholdReached: boolean tx: Transaction } +const { nativeCoin } = getNetworkInfo() const ApproveTxModal = ({ canExecute, @@ -85,9 +87,6 @@ const ApproveTxModal = ({ let isCurrent = true const estimateGas = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - const estimatedGasCosts = await estimateTxGasCosts( safeAddress, tx.recipient, @@ -95,8 +94,8 @@ const ApproveTxModal = ({ tx, approveAndExecute ? userAddress : undefined, ) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) } diff --git a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx index e5372d4c15..f31448e9dd 100644 --- a/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx +++ b/src/routes/safe/components/Transactions/TxsTable/ExpandedTx/RejectTxModal/index.tsx @@ -3,6 +3,8 @@ import { makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' +import { getNetworkInfo } from 'src/config' import { styles } from './style' @@ -17,7 +19,6 @@ 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 { EMPTY_DATA } from 'src/logic/wallets/ethTransactions' -import { getWeb3 } from 'src/logic/wallets/getWeb3' import createTransaction from 'src/logic/safe/store/actions/createTransaction' import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selectors' @@ -31,6 +32,8 @@ type Props = { tx: Transaction } +const { nativeCoin } = getNetworkInfo() + const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { const [gasCosts, setGasCosts] = useState('< 0.001') const dispatch = useDispatch() @@ -40,12 +43,9 @@ const RejectTxModal = ({ isOpen, onClose, tx }: Props): React.ReactElement => { useEffect(() => { let isCurrent = true const estimateGasCosts = async () => { - const web3 = getWeb3() - const { fromWei, toBN } = web3.utils - const estimatedGasCosts = await estimateTxGasCosts(safeAddress, safeAddress, EMPTY_DATA) - const gasCostsAsEth = fromWei(toBN(estimatedGasCosts), 'ether') - const formattedGasCosts = formatAmount(gasCostsAsEth) + const gasCosts = fromTokenUnit(estimatedGasCosts, nativeCoin.decimals) + const formattedGasCosts = formatAmount(gasCosts) if (isCurrent) { setGasCosts(formattedGasCosts) }