WA-232 Fix get balance of custom tokens

This commit is contained in:
Adolfo Panizo 2018-06-28 16:47:01 +02:00
parent 3e2636b02b
commit 9ca0f2e41a
12 changed files with 73 additions and 43 deletions

View File

@ -1,6 +1,6 @@
// @flow
import { aNewStore } from '~/store'
import { addEtherTo } from '~/test/utils/etherMovements'
import { addEtherTo } from '~/test/utils/tokenMovements'
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
import { safeSelector } from '~/routes/safe/store/selectors/index'

View File

@ -1,6 +1,6 @@
// @flow
import fetchSafe from '~/routes/safe/store/actions/fetchSafe'
import fetchBalances from '~/routes/safe/store/actions/fetchBalances'
import { fetchBalances } from '~/routes/safe/store/actions/fetchBalances'
export type Actions = {
fetchSafe: typeof fetchSafe,

View File

@ -1,12 +1,24 @@
// @flow
import { Map } from 'immutable'
import contract from 'truffle-contract'
import type { Dispatch as ReduxDispatch } from 'redux'
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
import ERC20Token from '#/ERC20Token.json'
import { getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3'
import { type GlobalState } from '~/store/index'
import { makeBalance, type Balance } from '~/routes/safe/store/model/balance'
import { makeBalance, type Balance, type BalanceProps } from '~/routes/safe/store/model/balance'
import addBalances from './addBalances'
export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
export const calculateBalanceOf = async (tokenAddress: string, address: string) => {
const web3 = getWeb3()
const erc20Token = await contract(ERC20Token)
erc20Token.setProvider(web3.currentProvider)
return erc20Token.at(tokenAddress)
.then(instance => instance.balanceOf(address).then(funds => funds.toString()))
.catch(() => '0')
}
export const fetchBalances = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
const balance = await getBalanceInEtherOf(safeAddress)
const ethBalance = makeBalance({
address: '0',
@ -32,8 +44,13 @@ export default (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalSta
}
const json = await response.json()
const balancesRecords = await Promise.all(json.map(async (item: BalanceProps) => {
const funds = await calculateBalanceOf(item.address, safeAddress)
return makeBalance({ ...item, funds })
}))
const balances: Map<string, Balance> = Map().withMutations((map) => {
json.forEach(item => map.set(item.symbol, makeBalance(item)))
balancesRecords.forEach(record => map.set(record.get('symbol'), record))
map.set('ETH', ethBalance)
})

View File

@ -5,7 +5,7 @@ import { Provider } from 'react-redux'
import { ConnectedRouter } from 'react-router-redux'
import Button from '~/components/layout/Button'
import { aNewStore, history } from '~/store'
import { addEtherTo } from '~/test/utils/etherMovements'
import { addEtherTo } from '~/test/utils/tokenMovements'
import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import SafeView from '~/routes/safe/component/Safe'

View File

@ -6,7 +6,7 @@ import { ConnectedRouter } from 'react-router-redux'
import { type Match } from 'react-router-dom'
import Button from '~/components/layout/Button'
import { aNewStore, history } from '~/store'
import { addEtherTo } from '~/test/utils/etherMovements'
import { addEtherTo } from '~/test/utils/tokenMovements'
import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import SafeView from '~/routes/safe/component/Safe'

View File

@ -3,7 +3,7 @@ import TestUtils from 'react-dom/test-utils'
import { sleep } from '~/utils/timer'
import { getBalanceInEtherOf } from '~/wallets/getWeb3'
import { ADD_MULTISIG_BUTTON_TEXT, SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx'
import { addEtherTo } from '~/test/utils/etherMovements'
import { addEtherTo } from '~/test/utils/tokenMovements'
import SafeView from '~/routes/safe/component/Safe'
import TransactionsComponent from '~/routes/safe/component/Transactions'
import TransactionComponent from '~/routes/safe/component/Transactions/Transaction'

View File

@ -15,7 +15,7 @@ import { makeProvider } from '~/wallets/store/model/provider'
import AppRoutes from '~/routes'
import { SAFELIST_ADDRESS } from '~/routes/routes'
import { promisify } from '~/utils/promisify'
import { addEtherTo } from '~/test/utils/etherMovements'
import { addEtherTo } from '~/test/utils/tokenMovements'
const fillOpenSafeForm = async (localStore: Store<GlobalState>) => {
const provider = await getProviderInfo()

View File

@ -9,7 +9,7 @@ import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx
import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper'
import { sendWithdrawForm, checkMinedWithdrawTx } from '~/test/utils/transactions/withdraw.helper'
import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions'
import { checkBalanceOf } from '~/test/utils/etherMovements'
import { checkBalanceOf } from '~/test/utils/tokenMovements'
describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => {
let domSafe: DomSafe

View File

@ -1,15 +1,12 @@
// @flow
import contract from 'truffle-contract'
import { Map } from 'immutable'
import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances'
import fetchBalances from '~/routes/safe/store/actions/fetchBalances'
import * as fetchBalancesAction from '~/routes/safe/store/actions/fetchBalances'
import { aNewStore } from '~/store'
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
import { type Balance } from '~/routes/safe/store/model/balance'
import { addEtherTo } from '~/test/utils/etherMovements'
import Token from '#/test/Token.json'
import { getWeb3 } from '~/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
import { type Balance, makeBalance } from '~/routes/safe/store/model/balance'
import addBalances from '~/routes/safe/store/actions/addBalances'
import { addEtherTo, addTknTo } from '~/test/utils/tokenMovements'
describe('Safe Actions[fetchBalance]', () => {
let store
@ -24,7 +21,7 @@ describe('Safe Actions[fetchBalance]', () => {
const tokenList = ['WE', '<3', 'GNO', 'OMG', 'RDN']
// WHEN
await store.dispatch(fetchBalances(address))
await store.dispatch(fetchBalancesAction.fetchBalances(address))
// THEN
const balances: Map<string, Map<string, Balance>> | typeof undefined = store.getState()[BALANCE_REDUCER_ID]
@ -44,7 +41,7 @@ describe('Safe Actions[fetchBalance]', () => {
it('reducer should return 0.03456 ETH as funds to safe with 0.03456 ETH', async () => {
// WHEN
await addEtherTo(address, '0.03456')
await store.dispatch(fetchBalances(address))
await store.dispatch(fetchBalancesAction.fetchBalances(address))
// THEN
const balances: Map<string, Map<string, Balance>> | typeof undefined = store.getState()[BALANCE_REDUCER_ID]
@ -59,29 +56,32 @@ describe('Safe Actions[fetchBalance]', () => {
expect(ethBalance.get('funds')).toBe('0.03456')
})
it('reducer should return 2 GNO when safe has 2 GNO', async () => {
it('reducer should return 100 TKN when safe has 100 TKN', async () => {
// GIVEN
const web3 = getWeb3()
const token = contract(Token)
token.setProvider(web3.currentProvider)
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
const myToken = await token.new({ from: accounts[0], gas: '5000000' })
await myToken.transfer(address, 100, { from: accounts[0], gas: '5000000' })
const numTokens = 100
const tokenAddress = await addTknTo(address, numTokens)
// console.log(await myToken.totalSupply())
// WHEN
await store.dispatch(fetchBalances(address))
const fetchBalancesMock = jest.spyOn(fetchBalancesAction, 'fetchBalances')
const funds = await fetchBalancesAction.calculateBalanceOf(tokenAddress, address)
const balances: Map<string, Balance> = Map().set('TKN', makeBalance({
address: tokenAddress,
name: 'Token',
symbol: 'TKN',
decimals: 18,
logoUrl: 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true',
funds,
}))
fetchBalancesMock.mockImplementation(() => store.dispatch(addBalances(address, balances)))
await store.dispatch(fetchBalancesAction.fetchBalances(address))
fetchBalancesMock.mockRestore()
// THEN
const balances: Map<string, Map<string, Balance>> | typeof undefined = store.getState()[BALANCE_REDUCER_ID]
if (!balances) throw new Error()
const safeBalances = store.getState()[BALANCE_REDUCER_ID].get(address)
expect(safeBalances.size).toBe(1)
const safeBalances: Map<string, Balance> | typeof undefined = balances.get(address)
if (!safeBalances) throw new Error()
expect(safeBalances.size).toBe(6)
const ethBalance = safeBalances.get('ETH')
if (!ethBalance) throw new Error()
expect(ethBalance.get('funds')).toBe('0.03456')
const tknBalance = safeBalances.get('TKN')
expect(tknBalance.get('funds')).toBe(String(numTokens))
})
})

View File

@ -1,8 +1,10 @@
// @flow
import contract from 'truffle-contract'
import { getProviderInfo, getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3'
import { promisify } from '~/utils/promisify'
import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw'
import { type Safe } from '~/routes/safe/store/model/safe'
import Token from '#/test/Token.json'
export const addEtherTo = async (address: string, eth: string) => {
const web3 = getWeb3()
@ -27,3 +29,14 @@ export const checkBalanceOf = async (addressToTest: string, value: string) => {
const safeBalance = await getBalanceInEtherOf(addressToTest)
expect(safeBalance).toBe(value)
}
export const addTknTo = async (safe: string, value: number) => {
const web3 = getWeb3()
const token = contract(Token)
token.setProvider(web3.currentProvider)
const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb))
const myToken = await token.new({ from: accounts[0], gas: '5000000' })
await myToken.transfer(safe, value, { from: accounts[0], gas: '5000000' })
return myToken.address
}

View File

@ -1,7 +1,7 @@
// @flow
import TestUtils from 'react-dom/test-utils'
import { sleep } from '~/utils/timer'
import { checkBalanceOf } from '~/test/utils/etherMovements'
import { checkBalanceOf } from '~/test/utils/tokenMovements'
import { checkMinedTx } from '~/test/builder/safe.dom.utils'
export const sendWithdrawForm = (

View File

@ -2921,14 +2921,14 @@ bignumber.js@^7.2.1:
version "7.2.1"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f"
"bignumber.js@git+https://github.com/debris/bignumber.js#master":
version "2.0.7"
resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9"
"bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2":
version "2.0.7"
resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2"
"bignumber.js@git+https://github.com/debris/bignumber.js.git#master":
version "2.0.7"
resolved "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9"
binary-extensions@^1.0.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"