From 1125536412a0545a77c7f29ce6628cc7f8db81ad Mon Sep 17 00:00:00 2001 From: Mikhail Mikheev Date: Tue, 9 Apr 2019 18:14:48 +0400 Subject: [PATCH] tokens fetch fixes, disable eth switch in tokens modal --- .../store/actions/fetchTokenBalances.js | 29 +++++++++++++++++-- src/logic/tokens/store/actions/fetchTokens.js | 19 ++---------- .../tokens/store/actions/loadActiveTokens.js | 15 ++++++---- src/logic/tokens/utils/tokenHelpers.js | 10 +++---- .../safe/component/Balances/Tokens/index.jsx | 9 ++++-- src/routes/safe/container/index.jsx | 6 +--- 6 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/logic/tokens/store/actions/fetchTokenBalances.js b/src/logic/tokens/store/actions/fetchTokenBalances.js index 9eefa654..0588ad58 100644 --- a/src/logic/tokens/store/actions/fetchTokenBalances.js +++ b/src/logic/tokens/store/actions/fetchTokenBalances.js @@ -1,11 +1,33 @@ // @flow import type { Dispatch as ReduxDispatch } from 'redux' import { Map, List } from 'immutable' -import { type Token } from '~/logic/tokens/store/model/token' +import { BigNumber } from 'bignumber.js' import { type GlobalState } from '~/store/index' -import { calculateBalanceOf } from './fetchTokens' +import { type Token } from '~/logic/tokens/store/model/token' +import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers' +import { getBalanceInEtherOf } from '~/logic/wallets/getWeb3' +import { getStandardTokenContract } from './fetchTokens' import { addTokens } from './saveTokens' +export const calculateBalanceOf = async (tokenAddress: string, safeAddress: string, decimals: number = 18) => { + if (tokenAddress === ETH_ADDRESS) { + const ethBalance = await getBalanceInEtherOf(safeAddress) + return ethBalance + } + + const erc20Token = await getStandardTokenContract() + let balance = 0 + + try { + const token = await erc20Token.at(tokenAddress) + balance = await token.balanceOf(safeAddress) + } catch (err) { + console.error('Failed to fetch token balances: ', err) + } + + return new BigNumber(balance).div(10 ** decimals).toString() +} + const fetchTokenBalances = (safeAddress: string, tokens: List) => async ( dispatch: ReduxDispatch, ) => { @@ -15,8 +37,9 @@ const fetchTokenBalances = (safeAddress: string, tokens: List) => async ( try { const withBalances = await Promise.all( - tokens.map(async token => token.set('funds', await calculateBalanceOf(token.address, safeAddress))), + tokens.map(async token => token.set('funds', await calculateBalanceOf(token.address, safeAddress, token.decimals))), ) + const tokensMap = Map().withMutations((map) => { withBalances.forEach(token => map.set(token.address, token)) }) diff --git a/src/logic/tokens/store/actions/fetchTokens.js b/src/logic/tokens/store/actions/fetchTokens.js index 10660fda..164f7b06 100644 --- a/src/logic/tokens/store/actions/fetchTokens.js +++ b/src/logic/tokens/store/actions/fetchTokens.js @@ -2,7 +2,6 @@ import { List, Map } from 'immutable' import contract from 'truffle-contract' import axios from 'axios' -import { BigNumber } from 'bignumber.js' import type { Dispatch as ReduxDispatch } from 'redux' import StandardToken from '@gnosis.pm/util-contracts/build/contracts/GnosisStandardToken.json' import HumanFriendlyToken from '@gnosis.pm/util-contracts/build/contracts/HumanFriendlyToken.json' @@ -11,7 +10,7 @@ import { type GlobalState } from '~/store/index' import { makeToken, type Token, type TokenProps } from '~/logic/tokens/store/model/token' import { ensureOnce } from '~/utils/singleton' import { getActiveTokens, getTokens } from '~/logic/tokens/utils/tokensStorage' -import { getSafeEthToken } from '~/logic/tokens/utils/tokenHelpers' +import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers' import saveTokens from './saveTokens' import { getRelayUrl } from '~/config/index' @@ -34,20 +33,6 @@ export const getHumanFriendlyToken = ensureOnce(createHumanFriendlyTokenContract export const getStandardTokenContract = ensureOnce(createStandardTokenContract) -export const calculateBalanceOf = async (tokenAddress: string, address: string, decimals: number = 18) => { - const erc20Token = await getStandardTokenContract() - let balance = 0 - - try { - const token = await erc20Token.at(tokenAddress) - balance = await token.balanceOf(address) - } catch (err) { - console.error('Failed to fetch token balances: ', err) - } - - return new BigNumber(balance).div(10 ** decimals).toString() -} - export const fetchTokensData = async () => { const apiUrl = getRelayUrl() const url = `${apiUrl}/tokens` @@ -57,7 +42,7 @@ export const fetchTokensData = async () => { export const fetchTokens = (safeAddress: string) => async (dispatch: ReduxDispatch) => { const tokens: List = await getActiveTokens(safeAddress) - const ethBalance = await getSafeEthToken(safeAddress) + const ethBalance = await getEthAsToken(safeAddress) const customTokens = await getTokens(safeAddress) const { data: { results }, diff --git a/src/logic/tokens/store/actions/loadActiveTokens.js b/src/logic/tokens/store/actions/loadActiveTokens.js index 068531b5..7f6a4b55 100644 --- a/src/logic/tokens/store/actions/loadActiveTokens.js +++ b/src/logic/tokens/store/actions/loadActiveTokens.js @@ -4,19 +4,22 @@ import { List, Map } from 'immutable' import { type TokenProps, type Token, makeToken } from '~/logic/tokens/store/model/token' import { type GlobalState } from '~/store/index' import { getActiveTokens } from '~/logic/tokens/utils/tokensStorage' +import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers' import saveTokens from './saveTokens' const loadActiveTokens = (safeAddress: string) => async (dispatch: ReduxDispatch) => { try { const tokens: List = await getActiveTokens(safeAddress) - if (tokens.size) { - const tokenRecords: Map = Map().withMutations((map) => { - tokens.forEach(token => map.set(token.address, makeToken(token))) - }) + // ETH is active by default and cannot be disabled + const eth = await getEthAsToken(safeAddress) - dispatch(saveTokens(safeAddress, tokenRecords)) - } + const tokenRecords: Map = Map().withMutations((map) => { + tokens.forEach(token => map.set(token.address, makeToken(token))) + map.set(eth.address, eth) + }) + + dispatch(saveTokens(safeAddress, tokenRecords)) } catch (err) { // eslint-disable-next-line console.error('Error while loading active tokens from storage:', err) diff --git a/src/logic/tokens/utils/tokenHelpers.js b/src/logic/tokens/utils/tokenHelpers.js index 3265af2b..915ea3b1 100644 --- a/src/logic/tokens/utils/tokenHelpers.js +++ b/src/logic/tokens/utils/tokenHelpers.js @@ -4,14 +4,14 @@ import logo from '~/assets/icons/icon_etherTokens.svg' import { getBalanceInEtherOf } from '~/logic/wallets/getWeb3' import { makeToken, type Token } from '~/logic/tokens/store/model/token' -export const ETH_ADDRESS = '0' +export const ETH_ADDRESS = '0x000' export const isEther = (symbol: string) => symbol === 'ETH' -export const getSafeEthToken = async (safeAddress: string) => { +export const getEthAsToken = async (safeAddress: string) => { const balance = await getBalanceInEtherOf(safeAddress) const ethBalance = makeToken({ - address: '0', + address: ETH_ADDRESS, name: 'Ether', symbol: 'ETH', decimals: 18, @@ -23,7 +23,7 @@ export const getSafeEthToken = async (safeAddress: string) => { } export const calculateActiveErc20TokensFrom = (tokens: List) => { - const addresses = List().withMutations(list => tokens.forEach((token: Token) => { + const activeTokens = List().withMutations(list => tokens.forEach((token: Token) => { const isDeactivated = isEther(token.symbol) || !token.status if (isDeactivated) { return @@ -32,5 +32,5 @@ export const calculateActiveErc20TokensFrom = (tokens: List) => { list.push(token) })) - return addresses + return activeTokens } diff --git a/src/routes/safe/component/Balances/Tokens/index.jsx b/src/routes/safe/component/Balances/Tokens/index.jsx index d8ddbca7..f43251d9 100644 --- a/src/routes/safe/component/Balances/Tokens/index.jsx +++ b/src/routes/safe/component/Balances/Tokens/index.jsx @@ -23,6 +23,7 @@ import Divider from '~/components/layout/Divider' import Hairline from '~/components/layout/Hairline' import Spacer from '~/components/Spacer' import Row from '~/components/layout/Row' +import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers' import { type Token } from '~/logic/tokens/store/model/token' import actions, { type Actions } from './actions' import TokenPlaceholder from './assets/token_placeholder.png' @@ -123,9 +124,11 @@ class Tokens extends React.Component { {token.name} - - - + {token.address !== ETH_ADDRESS && ( + + + + )} ))} diff --git a/src/routes/safe/container/index.jsx b/src/routes/safe/container/index.jsx index 20d98945..ac5b506f 100644 --- a/src/routes/safe/container/index.jsx +++ b/src/routes/safe/container/index.jsx @@ -21,11 +21,7 @@ class SafeView extends React.Component { fetchSafe(safeUrl) loadActiveTokens(safeUrl) - - if (activeTokens.size) { - // eslint-disable-next-line - fetchTokenBalances(safeUrl, activeTokens) - } + fetchTokenBalances(safeUrl, activeTokens) this.intervalId = setInterval(() => { // update in another function so it uses up-to-date props values