tokens fetch fixes, disable eth switch in tokens modal
This commit is contained in:
parent
4f5986506b
commit
1125536412
|
@ -1,11 +1,33 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||||
import { Map, List } from 'immutable'
|
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 { 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'
|
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<Token>) => async (
|
const fetchTokenBalances = (safeAddress: string, tokens: List<Token>) => async (
|
||||||
dispatch: ReduxDispatch<GlobalState>,
|
dispatch: ReduxDispatch<GlobalState>,
|
||||||
) => {
|
) => {
|
||||||
|
@ -15,8 +37,9 @@ const fetchTokenBalances = (safeAddress: string, tokens: List<Token>) => async (
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const withBalances = await Promise.all(
|
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) => {
|
const tokensMap = Map().withMutations((map) => {
|
||||||
withBalances.forEach(token => map.set(token.address, token))
|
withBalances.forEach(token => map.set(token.address, token))
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import { List, Map } from 'immutable'
|
import { List, Map } from 'immutable'
|
||||||
import contract from 'truffle-contract'
|
import contract from 'truffle-contract'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { BigNumber } from 'bignumber.js'
|
|
||||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||||
import StandardToken from '@gnosis.pm/util-contracts/build/contracts/GnosisStandardToken.json'
|
import StandardToken from '@gnosis.pm/util-contracts/build/contracts/GnosisStandardToken.json'
|
||||||
import HumanFriendlyToken from '@gnosis.pm/util-contracts/build/contracts/HumanFriendlyToken.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 { makeToken, type Token, type TokenProps } from '~/logic/tokens/store/model/token'
|
||||||
import { ensureOnce } from '~/utils/singleton'
|
import { ensureOnce } from '~/utils/singleton'
|
||||||
import { getActiveTokens, getTokens } from '~/logic/tokens/utils/tokensStorage'
|
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 saveTokens from './saveTokens'
|
||||||
import { getRelayUrl } from '~/config/index'
|
import { getRelayUrl } from '~/config/index'
|
||||||
|
|
||||||
|
@ -34,20 +33,6 @@ export const getHumanFriendlyToken = ensureOnce(createHumanFriendlyTokenContract
|
||||||
|
|
||||||
export const getStandardTokenContract = ensureOnce(createStandardTokenContract)
|
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 () => {
|
export const fetchTokensData = async () => {
|
||||||
const apiUrl = getRelayUrl()
|
const apiUrl = getRelayUrl()
|
||||||
const url = `${apiUrl}/tokens`
|
const url = `${apiUrl}/tokens`
|
||||||
|
@ -57,7 +42,7 @@ export const fetchTokensData = async () => {
|
||||||
|
|
||||||
export const fetchTokens = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
export const fetchTokens = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||||
const tokens: List<TokenProps> = await getActiveTokens(safeAddress)
|
const tokens: List<TokenProps> = await getActiveTokens(safeAddress)
|
||||||
const ethBalance = await getSafeEthToken(safeAddress)
|
const ethBalance = await getEthAsToken(safeAddress)
|
||||||
const customTokens = await getTokens(safeAddress)
|
const customTokens = await getTokens(safeAddress)
|
||||||
const {
|
const {
|
||||||
data: { results },
|
data: { results },
|
||||||
|
|
|
@ -4,19 +4,22 @@ import { List, Map } from 'immutable'
|
||||||
import { type TokenProps, type Token, makeToken } from '~/logic/tokens/store/model/token'
|
import { type TokenProps, type Token, makeToken } from '~/logic/tokens/store/model/token'
|
||||||
import { type GlobalState } from '~/store/index'
|
import { type GlobalState } from '~/store/index'
|
||||||
import { getActiveTokens } from '~/logic/tokens/utils/tokensStorage'
|
import { getActiveTokens } from '~/logic/tokens/utils/tokensStorage'
|
||||||
|
import { getEthAsToken } from '~/logic/tokens/utils/tokenHelpers'
|
||||||
import saveTokens from './saveTokens'
|
import saveTokens from './saveTokens'
|
||||||
|
|
||||||
const loadActiveTokens = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
const loadActiveTokens = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||||
try {
|
try {
|
||||||
const tokens: List<TokenProps> = await getActiveTokens(safeAddress)
|
const tokens: List<TokenProps> = await getActiveTokens(safeAddress)
|
||||||
|
|
||||||
if (tokens.size) {
|
// ETH is active by default and cannot be disabled
|
||||||
const tokenRecords: Map<string, Token> = Map().withMutations((map) => {
|
const eth = await getEthAsToken(safeAddress)
|
||||||
tokens.forEach(token => map.set(token.address, makeToken(token)))
|
|
||||||
})
|
|
||||||
|
|
||||||
dispatch(saveTokens(safeAddress, tokenRecords))
|
const tokenRecords: Map<string, Token> = Map().withMutations((map) => {
|
||||||
}
|
tokens.forEach(token => map.set(token.address, makeToken(token)))
|
||||||
|
map.set(eth.address, eth)
|
||||||
|
})
|
||||||
|
|
||||||
|
dispatch(saveTokens(safeAddress, tokenRecords))
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
console.error('Error while loading active tokens from storage:', err)
|
console.error('Error while loading active tokens from storage:', err)
|
||||||
|
|
|
@ -4,14 +4,14 @@ import logo from '~/assets/icons/icon_etherTokens.svg'
|
||||||
import { getBalanceInEtherOf } from '~/logic/wallets/getWeb3'
|
import { getBalanceInEtherOf } from '~/logic/wallets/getWeb3'
|
||||||
import { makeToken, type Token } from '~/logic/tokens/store/model/token'
|
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 isEther = (symbol: string) => symbol === 'ETH'
|
||||||
|
|
||||||
export const getSafeEthToken = async (safeAddress: string) => {
|
export const getEthAsToken = async (safeAddress: string) => {
|
||||||
const balance = await getBalanceInEtherOf(safeAddress)
|
const balance = await getBalanceInEtherOf(safeAddress)
|
||||||
|
|
||||||
const ethBalance = makeToken({
|
const ethBalance = makeToken({
|
||||||
address: '0',
|
address: ETH_ADDRESS,
|
||||||
name: 'Ether',
|
name: 'Ether',
|
||||||
symbol: 'ETH',
|
symbol: 'ETH',
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
|
@ -23,7 +23,7 @@ export const getSafeEthToken = async (safeAddress: string) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const calculateActiveErc20TokensFrom = (tokens: List<Token>) => {
|
export const calculateActiveErc20TokensFrom = (tokens: List<Token>) => {
|
||||||
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
|
const isDeactivated = isEther(token.symbol) || !token.status
|
||||||
if (isDeactivated) {
|
if (isDeactivated) {
|
||||||
return
|
return
|
||||||
|
@ -32,5 +32,5 @@ export const calculateActiveErc20TokensFrom = (tokens: List<Token>) => {
|
||||||
list.push(token)
|
list.push(token)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return addresses
|
return activeTokens
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import Divider from '~/components/layout/Divider'
|
||||||
import Hairline from '~/components/layout/Hairline'
|
import Hairline from '~/components/layout/Hairline'
|
||||||
import Spacer from '~/components/Spacer'
|
import Spacer from '~/components/Spacer'
|
||||||
import Row from '~/components/layout/Row'
|
import Row from '~/components/layout/Row'
|
||||||
|
import { ETH_ADDRESS } from '~/logic/tokens/utils/tokenHelpers'
|
||||||
import { type Token } from '~/logic/tokens/store/model/token'
|
import { type Token } from '~/logic/tokens/store/model/token'
|
||||||
import actions, { type Actions } from './actions'
|
import actions, { type Actions } from './actions'
|
||||||
import TokenPlaceholder from './assets/token_placeholder.png'
|
import TokenPlaceholder from './assets/token_placeholder.png'
|
||||||
|
@ -123,9 +124,11 @@ class Tokens extends React.Component<Props, State> {
|
||||||
<Img src={token.logoUri} height={28} alt={token.name} onError={this.setImageToPlaceholder} />
|
<Img src={token.logoUri} height={28} alt={token.name} onError={this.setImageToPlaceholder} />
|
||||||
</ListItemIcon>
|
</ListItemIcon>
|
||||||
<ListItemText primary={token.symbol} secondary={token.name} />
|
<ListItemText primary={token.symbol} secondary={token.name} />
|
||||||
<ListItemSecondaryAction>
|
{token.address !== ETH_ADDRESS && (
|
||||||
<Switch onChange={this.onSwitch(token)} checked={token.status} />
|
<ListItemSecondaryAction>
|
||||||
</ListItemSecondaryAction>
|
<Switch onChange={this.onSwitch(token)} checked={token.status} />
|
||||||
|
</ListItemSecondaryAction>
|
||||||
|
)}
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
</MuiList>
|
</MuiList>
|
||||||
|
|
|
@ -21,11 +21,7 @@ class SafeView extends React.Component<Props> {
|
||||||
|
|
||||||
fetchSafe(safeUrl)
|
fetchSafe(safeUrl)
|
||||||
loadActiveTokens(safeUrl)
|
loadActiveTokens(safeUrl)
|
||||||
|
fetchTokenBalances(safeUrl, activeTokens)
|
||||||
if (activeTokens.size) {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
fetchTokenBalances(safeUrl, activeTokens)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.intervalId = setInterval(() => {
|
this.intervalId = setInterval(() => {
|
||||||
// update in another function so it uses up-to-date props values
|
// update in another function so it uses up-to-date props values
|
||||||
|
|
Loading…
Reference in New Issue