WA-232 Fix get balance of custom tokens
This commit is contained in:
parent
3e2636b02b
commit
9ca0f2e41a
|
@ -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'
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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 = (
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue