From 9020ecc1766a10c8ae4c6fdd14756b8aebba56d0 Mon Sep 17 00:00:00 2001 From: Szymon Lesisz Date: Mon, 7 May 2018 18:04:04 +0200 Subject: [PATCH] fixed token balance + decimal regexp --- src/js/actions/DiscoveryActions.js | 9 ++---- src/js/actions/SendFormActions.js | 6 ++-- src/js/actions/SummaryActions.js | 1 - src/js/actions/TokenActions.js | 28 +++++++++--------- src/js/actions/Web3Actions.js | 46 ++++++++++++++++++++++++++---- 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/js/actions/DiscoveryActions.js b/src/js/actions/DiscoveryActions.js index e614fc73..13bf3be9 100644 --- a/src/js/actions/DiscoveryActions.js +++ b/src/js/actions/DiscoveryActions.js @@ -192,11 +192,6 @@ const begin = (device: TrezorDevice, network: string): AsyncAction => { const discoverAddress = (device: TrezorDevice, discoveryProcess: Discovery): AsyncAction => { return async (dispatch: Dispatch, getState: GetState): Promise => { - //const hdKey = discoveryProcess.hdKey - console.log("TYPEOF", typeof discoveryProcess.hdKey.derive, discoveryProcess.hdKey) - console.log("TYPEOF", typeof discoveryProcess.hdKey.derive === typeof HDKey); - - const derivedKey = discoveryProcess.hdKey.derive(`m/${discoveryProcess.accountIndex}`); const path = discoveryProcess.basePath.concat(discoveryProcess.accountIndex); const publicAddress: string = EthereumjsUtil.publicToAddress(derivedKey.publicKey, true).toString('hex'); @@ -300,9 +295,9 @@ const discoverAddress = (device: TrezorDevice, discoveryProcess: Discovery): Asy // ]; for (let i = 0; i < userTokens.length; i++) { - const tokenBalance = await getTokenBalanceAsync(web3instance.erc20, userTokens[i].address, ethAddress); + const tokenBalance: string = await getTokenBalanceAsync(web3instance.erc20, userTokens[i]); if (discoveryProcess.interrupted) return; - dispatch( setTokenBalance(userTokens[i].address, ethAddress, tokenBalance.toString()) ) + dispatch( setTokenBalance(userTokens[i].address, ethAddress, tokenBalance) ) } const nonce: number = await getNonceAsync(web3instance.web3, ethAddress); diff --git a/src/js/actions/SendFormActions.js b/src/js/actions/SendFormActions.js index 55830c8c..3b40d627 100644 --- a/src/js/actions/SendFormActions.js +++ b/src/js/actions/SendFormActions.js @@ -86,7 +86,7 @@ export type SendFormAction = { }; //const numberRegExp = new RegExp('^([0-9]{0,10}\\.)?[0-9]{1,18}$'); -const numberRegExp: RegExp = new RegExp('^(0|0\\.([0-9]+)?|[1-9]+\\.?([0-9]+)?|\\.[0-9]+)$'); +const numberRegExp: RegExp = new RegExp('^(0|0\\.([0-9]+)?|[1-9][0-9]*\\.?([0-9]+)?|\\.[0-9]+)$'); const calculateFee = (gasPrice: string, gasLimit: string): string => { return EthereumjsUnits.convert( new BigNumber(gasPrice).times(gasLimit), 'gwei', 'ether'); @@ -289,7 +289,7 @@ export const validation = (): ThunkAction => { if (token) { if (parseInt(token.decimals) > 0) { //decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,' + token.decimals + '})?|[1-9]+\\.?([0-9]{0,' + token.decimals + '})?|\\.[0-9]{1,' + token.decimals + '})$'); - decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,' + token.decimals + '})?|[1-9]+\\.?([0-9]{0,' + token.decimals + '})?|\\.[0-9]{1,' + token.decimals + '})$'); + decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,' + token.decimals + '})?|[1-9][0-9]*\\.?([0-9]{0,' + token.decimals + '})?|\\.[0-9]{1,' + token.decimals + '})$'); } else { // decimalRegExp = new RegExp('^(0|0\\.?|[1-9]+\\.?)$'); decimalRegExp = new RegExp('^[0-9]+$'); @@ -307,7 +307,7 @@ export const validation = (): ThunkAction => { } } else { - decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9]+\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$'); + decimalRegExp = new RegExp('^(0|0\\.([0-9]{0,18})?|[1-9][0-9]*\\.?([0-9]{0,18})?|\\.[0-9]{0,18})$'); if (!state.amount.match(decimalRegExp)) { errors.amount = `Maximum 18 decimals allowed`; } else if (new BigNumber(state.total).greaterThan(account.balance)) { diff --git a/src/js/actions/SummaryActions.js b/src/js/actions/SummaryActions.js index 149593ba..776bfeed 100644 --- a/src/js/actions/SummaryActions.js +++ b/src/js/actions/SummaryActions.js @@ -6,7 +6,6 @@ import * as SUMMARY from './constants/summary'; import * as TOKEN from './constants/token'; import * as ADDRESS from './constants/address'; import { resolveAfter } from '../utils/promiseUtils'; -import { getTokenInfoAsync, getTokenBalanceAsync } from './Web3Actions'; import { initialState } from '../reducers/SummaryReducer'; import { findSelectedDevice } from '../reducers/TrezorConnectReducer'; diff --git a/src/js/actions/TokenActions.js b/src/js/actions/TokenActions.js index 27b14996..ed6fbc4e 100644 --- a/src/js/actions/TokenActions.js +++ b/src/js/actions/TokenActions.js @@ -70,23 +70,25 @@ export const add = (token: NetworkToken, account: Account): AsyncAction => { const web3instance = getState().web3.find(w3 => w3.network === account.network); if (!web3instance) return; + const tkn: Token = { + loaded: false, + deviceState: account.deviceState, + network: account.network, + name: token.name, + symbol: token.symbol, + address: token.address, + ethAddress: account.address, + decimals: token.decimals, + balance: '0' + } + dispatch({ type: TOKEN.ADD, - payload: { - loaded: false, - deviceState: account.deviceState, - network: account.network, - name: token.name, - symbol: token.symbol, - address: token.address, - ethAddress: account.address, - decimals: token.decimals, - balance: '0' - } + payload: tkn }); - const tokenBalance = await getTokenBalanceAsync(web3instance.erc20, token.address, account.address); - dispatch( setBalance(token.address, account.address, tokenBalance.toString()) ) + const tokenBalance = await getTokenBalanceAsync(web3instance.erc20, tkn); + dispatch( setBalance(token.address, account.address, tokenBalance) ) } } diff --git a/src/js/actions/Web3Actions.js b/src/js/actions/Web3Actions.js index 1a889937..e36387e7 100644 --- a/src/js/actions/Web3Actions.js +++ b/src/js/actions/Web3Actions.js @@ -11,6 +11,7 @@ import * as ADDRESS from './constants/address'; import * as WEB3 from './constants/web3'; import * as PENDING from './constants/pendingTx'; import * as AddressActions from '../actions/AddressActions'; +import * as TokenActions from '../actions/TokenActions'; import type { Dispatch, @@ -23,6 +24,7 @@ import type { ContractFactory } from 'web3'; import type { Account } from '../reducers/AccountsReducer'; import type { PendingTx } from '../reducers/PendingTxReducer'; import type { Web3Instance } from '../reducers/Web3Reducer'; +import type { Token } from '../reducers/TokensReducer'; export type Web3Action = { type: typeof WEB3.READY, @@ -171,6 +173,11 @@ export function init(web3: ?Web3, coinIndex: number = 0): AsyncAction { dispatch( getNonce(addr) ); } + const tokens = getState().tokens.filter(t => t.network === network); + for (const token of tokens) { + dispatch( getTokenBalance(token) ); + } + dispatch( getGasPrice(network) ); const pending = getState().pending.filter(p => p.network === network); @@ -281,6 +288,32 @@ export function getBalance(account: Account): AsyncAction { } } +export function getTokenBalance(token: Token): AsyncAction { + return async (dispatch: Dispatch, getState: GetState): Promise => { + + const web3instance = getState().web3.filter(w3 => w3.network === token.network)[0]; + const web3 = web3instance.web3; + const contract = web3instance.erc20.at(token.address); + + console.warn("Get bal", token) + + contract.balanceOf(token.ethAddress, (error: ?Error, balance: ?BigNumber) => { + if (balance) { + const newBalance: string = balance.dividedBy( Math.pow(10, token.decimals) ).toString(); + if (newBalance !== token.balance) { + dispatch(TokenActions.setBalance( + token.address, + token.ethAddress, + newBalance + )); + } + console.log("BALANCE!", balance, newBalance); + + } + }); + } +} + export function getNonce(account: Account): AsyncAction { return async (dispatch: Dispatch, getState: GetState): Promise => { @@ -359,15 +392,18 @@ export const getBalanceAsync = (web3: Web3, address: string): Promise => { }); } -export const getTokenBalanceAsync = (erc20: any, token: string, address: string): Promise => { + + +export const getTokenBalanceAsync = (erc20: ContractFactory, token: Token): Promise => { return new Promise((resolve, reject) => { - const contr = erc20.at(token); - contr.balanceOf(address, (error: Error, result) => { + const contract = erc20.at(token.address); + contract.balanceOf(token.ethAddress, (error: ?Error, balance: ?BigNumber) => { if (error) { reject(error); - } else { - resolve(result); + } else if (balance) { + const newBalance: string = balance.dividedBy( Math.pow(10, token.decimals) ).toString(); + resolve(newBalance); } }); });