diff --git a/js/src/modals/Transfer/Details/details.js b/js/src/modals/Transfer/Details/details.js index 55896f0c7..c00a1ee43 100644 --- a/js/src/modals/Transfer/Details/details.js +++ b/js/src/modals/Transfer/Details/details.js @@ -119,17 +119,19 @@ export default class Details extends Component { const { balance, images, tag } = this.props; const items = balance.tokens - .filter((token) => token.value.gt(0)) - .map((balance, idx) => { + .filter((token, index) => !index || token.value.gt(0)) + .map((balance, index) => { const token = balance.token; - const isEth = idx === 0; + const isEth = index === 0; const imagesrc = token.image || images[token.address] || imageUnknown; let value = 0; if (isEth) { value = api.util.fromWei(balance.value).toFormat(3); } else { - value = new BigNumber(balance.value).div(balance.token.format || 1).toFormat(3); + const format = balance.token.format || 1; + const decimals = format === 1 ? 0 : Math.min(3, Math.floor(format / 10)); + value = new BigNumber(balance.value).div(format).toFormat(decimals); } const label = ( @@ -165,7 +167,7 @@ export default class Details extends Component { ); } - onChangeToken = (event, idx, tag) => { + onChangeToken = (event, index, tag) => { this.props.onChange('tag', tag); } diff --git a/js/src/modals/Transfer/errors.js b/js/src/modals/Transfer/errors.js index cc6f9b365..a6456c785 100644 --- a/js/src/modals/Transfer/errors.js +++ b/js/src/modals/Transfer/errors.js @@ -18,6 +18,7 @@ const ERRORS = { requireRecipient: 'a recipient network address is required for the transaction', invalidAddress: 'the supplied address is an invalid network address', invalidAmount: 'the supplied amount should be a valid positive number', + invalidDecimals: 'the supplied amount exceeds the allowed decimals', largeAmount: 'the transaction total is higher than the available balance' }; diff --git a/js/src/modals/Transfer/transfer.js b/js/src/modals/Transfer/transfer.js index f14048203..2217d0e9c 100644 --- a/js/src/modals/Transfer/transfer.js +++ b/js/src/modals/Transfer/transfer.js @@ -297,6 +297,24 @@ export default class Transfer extends Component { return null; } + validateDecimals (num) { + const { balance } = this.props; + const { tag } = this.state; + + if (tag === 'ETH') { + return null; + } + + const token = balance.tokens.find((balance) => balance.token.tag === tag).token; + const s = new BigNumber(num).mul(token.format || 1).toString(); + + if (s.indexOf('.') !== -1) { + return ERRORS.invalidDecimals; + } + + return null; + } + _onUpdateGas (gas) { const gasError = this.validatePositiveNumber(gas); @@ -341,7 +359,11 @@ export default class Transfer extends Component { } _onUpdateValue (value) { - const valueError = this.validatePositiveNumber(value); + let valueError = this.validatePositiveNumber(value); + + if (!valueError) { + valueError = this.validateDecimals(value); + } this.setState({ value, @@ -407,7 +429,7 @@ export default class Transfer extends Component { to: token.address }, [ recipient, - new BigNumber(value).mul(token.format).toString() + new BigNumber(value).mul(token.format).toFixed(0) ]); } @@ -500,6 +522,7 @@ export default class Transfer extends Component { }) .catch((error) => { console.error('etimateGas', error); + this.recalculate(); }); } @@ -565,7 +588,7 @@ export default class Transfer extends Component { }, this.recalculate); }) .catch((error) => { - console.error('getDefaults', error); + console.warn('getDefaults', error); }); } diff --git a/js/src/redux/providers/balances.js b/js/src/redux/providers/balances.js index b88883fb7..38321e640 100644 --- a/js/src/redux/providers/balances.js +++ b/js/src/redux/providers/balances.js @@ -100,21 +100,31 @@ export default class Balances { }) .then(([_tokens, images]) => { const tokens = {}; - this._tokens = _tokens.map((_token, index) => { - const [address, tag, format, name] = _token; + this._tokens = _tokens + .map((_token, index) => { + const [address, tag, format, name] = _token; - const token = { - address, - name, - tag, - format: format.toString(), - contract: this._api.newContract(abis.eip20, address) - }; - tokens[address] = token; - this._store.dispatch(setAddressImage(address, images[index])); + const token = { + address, + name, + tag, + format: format.toString(), + contract: this._api.newContract(abis.eip20, address) + }; + tokens[address] = token; + this._store.dispatch(setAddressImage(address, images[index])); - return token; - }); + return token; + }) + .sort((a, b) => { + if (a.tag < b.tag) { + return -1; + } else if (a.tag > b.tag) { + return 1; + } + + return 0; + }); this._store.dispatch(getTokens(tokens)); this._retrieveBalances();