WA-232 fetching balance of activated custom tokens
This commit is contained in:
parent
95caa29f69
commit
da6345b1cc
|
@ -6,6 +6,7 @@ import FirstPage, { TOKEN_ADDRESS_PARAM } from '~/routes/tokens/component/AddTok
|
|||
import SecondPage, { TOKEN_SYMBOL_PARAM, TOKEN_DECIMALS_PARAM, TOKEN_LOGO_URL_PARAM, TOKEN_NAME_PARAM } from '~/routes/tokens/component/AddToken/SecondPage'
|
||||
import { makeToken, type Token } from '~/routes/tokens/store/model/token'
|
||||
import addTokenAction from '~/routes/tokens/store/actions/addTokens'
|
||||
import enableTokenAction from '~/routes/tokens/store/actions/enabletoken'
|
||||
import Review from './Review'
|
||||
|
||||
export const getSteps = () => [
|
||||
|
@ -15,7 +16,8 @@ export const getSteps = () => [
|
|||
type Props = {
|
||||
tokens: string[],
|
||||
safeAddress: string,
|
||||
addToken: typeof addTokenAction
|
||||
addToken: typeof addTokenAction,
|
||||
enableToken: typeof enableTokenAction,
|
||||
}
|
||||
|
||||
type State = {
|
||||
|
@ -24,7 +26,7 @@ type State = {
|
|||
|
||||
export const ADD_TOKEN_RESET_BUTTON_TEXT = 'RESET'
|
||||
|
||||
export const addTokenFnc = async (values: Object, addToken, safeAddress: string) => {
|
||||
export const addTokenFnc = async (values: Object, addToken, enableToken, safeAddress: string) => {
|
||||
const address = values[TOKEN_ADDRESS_PARAM]
|
||||
const name = values[TOKEN_NAME_PARAM]
|
||||
const symbol = values[TOKEN_SYMBOL_PARAM]
|
||||
|
@ -41,6 +43,7 @@ export const addTokenFnc = async (values: Object, addToken, safeAddress: string)
|
|||
removable: true,
|
||||
})
|
||||
|
||||
await enableToken(safeAddress, token)
|
||||
return addToken(safeAddress, token)
|
||||
}
|
||||
|
||||
|
@ -50,9 +53,9 @@ class AddToken extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
onAddToken = async (values: Object) => {
|
||||
const { addToken, safeAddress } = this.props
|
||||
const { addToken, enableToken, safeAddress } = this.props
|
||||
|
||||
return addTokenFnc(values, addToken, safeAddress)
|
||||
return addTokenFnc(values, addToken, enableToken, safeAddress)
|
||||
}
|
||||
|
||||
onReset = () => {
|
||||
|
|
|
@ -38,10 +38,17 @@ class TokenLayout extends React.PureComponent<TokenProps, State> {
|
|||
}
|
||||
|
||||
onAddToken = () => {
|
||||
const { addresses, safeAddress, addToken } = this.props
|
||||
const {
|
||||
addresses, safeAddress, addToken, enableToken,
|
||||
} = this.props
|
||||
|
||||
this.setState({
|
||||
component: <AddToken addToken={addToken} tokens={addresses.toArray()} safeAddress={safeAddress} />,
|
||||
component: <AddToken
|
||||
addToken={addToken}
|
||||
enableToken={enableToken}
|
||||
tokens={addresses.toArray()}
|
||||
safeAddress={safeAddress}
|
||||
/>,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import { getWeb3 } from '~/wallets/getWeb3'
|
|||
import { type GlobalState } from '~/store/index'
|
||||
import { makeToken, type Token, type TokenProps } from '~/routes/tokens/store/model/token'
|
||||
import { ensureOnce } from '~/utils/singleton'
|
||||
import { getTokens } from '~/utils/localStorage/tokens'
|
||||
import { getActiveTokenAddresses, getTokens } from '~/utils/localStorage/tokens'
|
||||
import { getSafeEthToken } from '~/utils/tokens'
|
||||
import { enhancedFetch } from '~/utils/fetch'
|
||||
import addTokens from './addTokens'
|
||||
|
@ -48,9 +48,9 @@ export const fetchTokensData = async () => {
|
|||
|
||||
export const fetchTokens = (safeAddress: string) =>
|
||||
async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
const tokens: List<string> = getTokens(safeAddress)
|
||||
const tokens: List<string> = getActiveTokenAddresses(safeAddress)
|
||||
const ethBalance = await getSafeEthToken(safeAddress)
|
||||
|
||||
const customTokens = getTokens(safeAddress)
|
||||
const json = await exports.fetchTokensData()
|
||||
|
||||
try {
|
||||
|
@ -61,10 +61,18 @@ export const fetchTokens = (safeAddress: string) =>
|
|||
return makeToken({ ...item, status, funds })
|
||||
}))
|
||||
|
||||
const customTokenRecords = await Promise.all(customTokens.map(async (item: TokenProps) => {
|
||||
const status = tokens.includes(item.address)
|
||||
const funds = status ? await calculateBalanceOf(item.address, safeAddress, item.decimals) : '0'
|
||||
|
||||
return makeToken({ ...item, status, funds })
|
||||
}))
|
||||
|
||||
const balances: Map<string, Token> = Map().withMutations((map) => {
|
||||
balancesRecords.forEach(record => map.set(record.get('address'), record))
|
||||
customTokenRecords.forEach(record => map.set(record.get('address'), record))
|
||||
|
||||
map.set('ETH', ethBalance)
|
||||
map.set(ethBalance.get('address'), ethBalance)
|
||||
})
|
||||
|
||||
return dispatch(addTokens(safeAddress, balances))
|
||||
|
|
|
@ -6,7 +6,7 @@ import addTokens, { ADD_TOKENS } from '~/routes/tokens/store/actions/addTokens'
|
|||
import { type Token } from '~/routes/tokens/store/model/token'
|
||||
import disableToken, { DISABLE_TOKEN } from '~/routes/tokens/store/actions/disableToken'
|
||||
import enableToken, { ENABLE_TOKEN } from '~/routes/tokens/store/actions/enableToken'
|
||||
import { setTokens, getTokens } from '~/utils/localStorage/tokens'
|
||||
import { setActiveTokenAddresses, getActiveTokenAddresses } from '~/utils/localStorage/tokens'
|
||||
import { ensureOnce } from '~/utils/singleton'
|
||||
import { calculateActiveErc20TokensFrom } from '~/utils/tokens'
|
||||
|
||||
|
@ -14,7 +14,7 @@ export const TOKEN_REDUCER_ID = 'tokens'
|
|||
|
||||
export type State = Map<string, Map<string, Token>>
|
||||
|
||||
const setTokensOnce = ensureOnce(setTokens)
|
||||
const setTokensOnce = ensureOnce(setActiveTokenAddresses)
|
||||
|
||||
export default handleActions({
|
||||
[ADD_TOKENS]: (state: State, action: ActionType<typeof addTokens>): State => {
|
||||
|
@ -33,26 +33,26 @@ export default handleActions({
|
|||
},
|
||||
[ADD_TOKEN]: (state: State, action: ActionType<typeof addToken>): State => {
|
||||
const { safeAddress, token } = action.payload
|
||||
const activeTokens = getTokens(safeAddress)
|
||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||
activeTokens.push(token.get('address'))
|
||||
setTokens(activeTokens)
|
||||
setActiveTokenAddresses(activeTokens)
|
||||
|
||||
return state.setIn([safeAddress, token.get('address')], token)
|
||||
},
|
||||
[DISABLE_TOKEN]: (state: State, action: ActionType<typeof disableToken>): State => {
|
||||
const { address, safeAddress, symbol } = action.payload
|
||||
|
||||
const activeTokens = getTokens(safeAddress)
|
||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||
const index = activeTokens.indexOf(address)
|
||||
setTokens(safeAddress, activeTokens.delete(index))
|
||||
setActiveTokenAddresses(safeAddress, activeTokens.delete(index))
|
||||
|
||||
return state.setIn([safeAddress, symbol, 'status'], false)
|
||||
},
|
||||
[ENABLE_TOKEN]: (state: State, action: ActionType<typeof enableToken>): State => {
|
||||
const { address, safeAddress, symbol } = action.payload
|
||||
|
||||
const activeTokens = getTokens(safeAddress)
|
||||
setTokens(safeAddress, activeTokens.push(address))
|
||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||
setActiveTokenAddresses(safeAddress, activeTokens.push(address))
|
||||
|
||||
return state.setIn([safeAddress, symbol, 'status'], true)
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@ import { travelToTokens } from '~/test/builder/safe.dom.utils'
|
|||
import { sleep } from '~/utils/timer'
|
||||
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { tokenListSelector, activeTokensSelector } from '~/routes/tokens/store/selectors'
|
||||
import { getTokens } from '~/utils/localStorage/tokens'
|
||||
import { getActiveTokenAddresses } from '~/utils/localStorage/tokens'
|
||||
import { enableFirstToken, testToken } from '~/test/builder/tokens.dom.utils'
|
||||
import * as fetchTokensModule from '~/routes/tokens/store/actions/fetchTokens'
|
||||
import * as enhancedFetchModule from '~/utils/fetch'
|
||||
|
@ -108,19 +108,19 @@ describe('DOM > Feature > Enable and disable default tokens', () => {
|
|||
it('localStorage always returns a list', async () => {
|
||||
const store = aNewStore()
|
||||
const safeAddress = await aMinedSafe(store)
|
||||
let tokens: List<string> = getTokens(safeAddress)
|
||||
let tokens: List<string> = getActiveTokenAddresses(safeAddress)
|
||||
expect(tokens).toEqual(List([]))
|
||||
|
||||
await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
tokens = getTokens(safeAddress)
|
||||
tokens = getActiveTokenAddresses(safeAddress)
|
||||
expect(tokens.count()).toBe(0)
|
||||
|
||||
await enableFirstToken(store, safeAddress)
|
||||
tokens = getTokens(safeAddress)
|
||||
tokens = getActiveTokenAddresses(safeAddress)
|
||||
expect(tokens.count()).toBe(1)
|
||||
|
||||
await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||
tokens = getTokens(safeAddress)
|
||||
tokens = getActiveTokenAddresses(safeAddress)
|
||||
expect(tokens.count()).toBe(1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -5,7 +5,6 @@ import { type Owner } from '~/routes/safe/store/model/owner'
|
|||
export const SAFES_KEY = 'SAFES'
|
||||
export const TX_KEY = 'TX'
|
||||
export const OWNERS_KEY = 'OWNERS'
|
||||
export const TOKENS_KEY = 'TOKENS'
|
||||
|
||||
export const load = (key: string) => {
|
||||
try {
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { load, TOKENS_KEY } from '~/utils/localStorage'
|
||||
import { load } from '~/utils/localStorage'
|
||||
import { type Token, type TokenProps } from '~/routes/tokens/store/model/token'
|
||||
|
||||
export const ACTIVE_TOKENS_KEY = 'ACTIVE_TOKENS'
|
||||
export const TOKENS_KEY = 'TOKENS'
|
||||
|
||||
const getActiveTokensKey = (safeAddress: string) => `${ACTIVE_TOKENS_KEY}-${safeAddress}`
|
||||
const getTokensKey = (safeAddress: string) => `${TOKENS_KEY}-${safeAddress}`
|
||||
|
||||
export const setTokens = (safeAddress: string, tokens: List<string>) => {
|
||||
export const setActiveTokenAddresses = (safeAddress: string, tokens: List<string>) => {
|
||||
try {
|
||||
const serializedState = JSON.stringify(tokens)
|
||||
const key = getTokensKey(safeAddress)
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
localStorage.setItem(key, serializedState)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
|
@ -15,14 +20,35 @@ export const setTokens = (safeAddress: string, tokens: List<string>) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const getTokens = (safeAddress: string): List<string> => {
|
||||
const key = getTokensKey(safeAddress)
|
||||
export const getActiveTokenAddresses = (safeAddress: string): List<string> => {
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
const data = load(key)
|
||||
|
||||
return data ? List(data) : List()
|
||||
}
|
||||
|
||||
export const storedTokensBefore = (safeAddress: string) => {
|
||||
const key = getTokensKey(safeAddress)
|
||||
const key = getActiveTokensKey(safeAddress)
|
||||
return localStorage.getItem(key) === null
|
||||
}
|
||||
|
||||
export const getTokens: List<TokenProps> = (safeAddress: string) => {
|
||||
const key = getTokensKey(safeAddress)
|
||||
const data = load(key)
|
||||
|
||||
return data ? List(data) : List()
|
||||
}
|
||||
|
||||
export const setToken = (safeAddress: string, token: Token) => {
|
||||
const data: List<Token> = getTokens(safeAddress)
|
||||
data.push(token)
|
||||
|
||||
try {
|
||||
const serializedState = JSON.stringify(data)
|
||||
const key = getTokensKey(safeAddress)
|
||||
localStorage.setItem(key, serializedState)
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.log('Error adding token in localstorage')
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue