Token sorting, zero-ETH transfer & token decimals (#2805)

* Error trapping for decimals (Fixes #2799)

* Sort tokens by tag (Closes #2789)

* PR comments

* Always display ETH

* Recalculate in all cases (traps >available)
This commit is contained in:
Jaco Greeff 2016-10-25 13:22:27 +02:00 committed by Gav Wood
parent a6fd922ffb
commit b6f2628018
4 changed files with 57 additions and 21 deletions

View File

@ -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);
}

View File

@ -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'
};

View File

@ -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);
});
}

View File

@ -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();