Skip to content

Commit

Permalink
Bugfix: android tx list crashes (#973)
Browse files Browse the repository at this point in the history
* check for tx to before lowercase

* small refactor

* cleaner code

* cleaner code

* text transfoirm

* snaps
  • Loading branch information
estebanmino authored and Bruno Barbieri committed Aug 5, 2019
1 parent 0aaccb3 commit 0d3a476
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 56 deletions.
13 changes: 8 additions & 5 deletions app/components/UI/EthereumAddress/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import networkMap from 'ethjs-ens/lib/network-map.json';
import Engine from '../../../core/Engine';
import { renderShortAddress, renderFullAddress } from '../../../util/address';
import Logger from '../../../util/Logger';
import { isValidAddress } from 'ethereumjs-util';

/**
* View that renders an ethereum address
Expand Down Expand Up @@ -45,12 +46,14 @@ class EthereumAddress extends PureComponent {
}

formatAddress(rawAddress, type) {
let formattedAddress;
let formattedAddress = rawAddress;

if (type && type === 'short') {
formattedAddress = renderShortAddress(rawAddress);
} else {
formattedAddress = renderFullAddress(rawAddress);
if (isValidAddress(rawAddress)) {
if (type && type === 'short') {
formattedAddress = renderShortAddress(rawAddress);
} else {
formattedAddress = renderFullAddress(rawAddress);
}
}
return formattedAddress;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ export default class TransferElement extends PureComponent {
let [transactionElement, transactionDetails] = this.state.isCollectible
? this.getCollectibleTransfer(totalGas)
: this.getTokenTransfer(totalGas);
transactionElement = { ...transactionElement, ...{ addressTo } };
transactionElement = { ...transactionElement, renderTo: addressTo };
transactionDetails = {
...transactionDetails,
...{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ exports[`TransactionElement should render correctly 1`] = `
"paddingHorizontal": 5,
"paddingVertical": 3,
"textAlign": "center",
"textTransform": "uppercase",
"width": 75,
},
null,
Expand Down
101 changes: 56 additions & 45 deletions app/components/UI/TransactionElement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const styles = StyleSheet.create({
fontSize: 9,
letterSpacing: 0.5,
width: 75,
textTransform: 'uppercase',
...fontStyles.bold
},
amount: {
Expand Down Expand Up @@ -254,16 +255,15 @@ class TransactionElement extends PureComponent {

renderTxElementImage = transactionElement => {
const {
addressTo,
addressFrom,
renderTo,
renderFrom,
actionKey,
contractDeployment = false,
paymentChannelTransaction
} = transactionElement;
const {
tx: { networkID }
} = this.props;
const checksumAddress = toChecksumAddress(addressTo);
let logo;

if (contractDeployment) {
Expand All @@ -273,20 +273,20 @@ class TransactionElement extends PureComponent {
</FadeIn>
);
} else if (actionKey === strings('transactions.smart_contract_interaction')) {
if (checksumAddress in contractMap) {
logo = contractMap[checksumAddress].logo;
if (renderTo in contractMap) {
logo = contractMap[renderTo].logo;
}
return (
<TokenImage
asset={{ address: addressTo, logo }}
asset={{ address: renderTo, logo }}
containerStyle={styles.tokenImageStyle}
iconStyle={styles.tokenImageStyle}
logoDefined
/>
);
} else if (paymentChannelTransaction) {
const contract = CONTRACTS[networkID];
const isDeposit = contract && addressTo.toLowerCase() === contract.toLowerCase();
const isDeposit = contract && renderTo.toLowerCase() === contract.toLowerCase();
if (isDeposit) {
return (
<FadeIn style={styles.paymentChannelTransactionIconWrapper}>
Expand All @@ -299,7 +299,7 @@ class TransactionElement extends PureComponent {
</FadeIn>
);
}
const isWithdraw = addressFrom === CONTRACTS[networkID];
const isWithdraw = renderFrom === CONTRACTS[networkID];
if (isWithdraw) {
return (
<FadeIn style={styles.paymentChannelTransactionIconWrapper}>
Expand All @@ -313,7 +313,7 @@ class TransactionElement extends PureComponent {
);
}
}
return <Identicon address={addressTo} diameter={24} />;
return <Identicon address={renderTo} diameter={24} />;
};

/**
Expand All @@ -325,11 +325,10 @@ class TransactionElement extends PureComponent {
const {
tx: { status }
} = this.props;
const { addressTo, actionKey, value, fiatValue = false } = transactionElement;
const checksumAddress = toChecksumAddress(addressTo);
const { renderTo, actionKey, value, fiatValue = false } = transactionElement;
let symbol;
if (checksumAddress in contractMap) {
symbol = contractMap[checksumAddress].symbol;
if (renderTo in contractMap) {
symbol = contractMap[renderTo].symbol;
}
return (
<View style={styles.rowOnly}>
Expand All @@ -340,7 +339,7 @@ class TransactionElement extends PureComponent {
<Text numberOfLines={1} style={styles.address}>
{symbol ? symbol + ' ' + actionKey : actionKey}
</Text>
<Text style={[styles.status, this.getStatusStyle(status)]}>{status.toUpperCase()}</Text>
<Text style={[styles.status, this.getStatusStyle(status)]}>{status}</Text>
</View>
<View style={styles.amounts}>
<Text style={styles.amount}>{value}</Text>
Expand All @@ -351,7 +350,7 @@ class TransactionElement extends PureComponent {
);
};

renderTransferFromElement = () => {
decodeTransferFromTx = () => {
const {
tx: {
transaction: { gas, gasPrice, data, to },
Expand All @@ -375,9 +374,12 @@ class TransactionElement extends PureComponent {
? strings('unit.token_id') + tokenId + ' ' + collectible.symbol
: strings('unit.token_id') + tokenId;

const renderFrom = renderFullAddress(addressFrom);
const renderTo = renderFullAddress(addressTo);

const transactionDetails = {
renderFrom: renderFullAddress(addressFrom),
renderTo: renderFullAddress(addressTo),
renderFrom,
renderTo,
transactionHash,
renderValue: renderCollectible,
renderGas: parseInt(gas, 16).toString(),
Expand All @@ -394,8 +396,8 @@ class TransactionElement extends PureComponent {
};

const transactionElement = {
addressTo,
addressFrom,
renderTo,
renderFrom,
actionKey,
value: `${strings('unit.token_id')}${tokenId}`,
fiatValue: collectible ? collectible.symbol : undefined
Expand All @@ -404,7 +406,7 @@ class TransactionElement extends PureComponent {
return [transactionElement, transactionDetails];
};

renderConfirmElement = () => {
decodeConfirmTx = () => {
const {
tx: {
transaction: { value, gas, gasPrice, from, to },
Expand All @@ -417,27 +419,30 @@ class TransactionElement extends PureComponent {
const { actionKey } = this.state;
const totalEth = hexToBN(value);
const renderTotalEth = renderFromWei(totalEth) + ' ' + ticker;
const renderTotalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency.toUpperCase());
const renderTotalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency);

const gasBN = hexToBN(gas);
const gasPriceBN = hexToBN(gasPrice);
const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0');
const totalValue = isBN(totalEth) ? totalEth.add(totalGas) : totalGas;

const renderFrom = renderFullAddress(from);
const renderTo = renderFullAddress(to);

const transactionDetails = {
renderFrom: from ? renderFullAddress(from) : strings('transactions.tx_details_not_available'),
renderTo: to ? renderFullAddress(to) : strings('transactions.tx_details_not_available'),
renderFrom,
renderTo,
transactionHash,
renderValue: renderFromWei(value) + ' ' + ticker,
renderGas: parseInt(gas, 16).toString(),
renderGasPrice: renderToGwei(gasPrice),
renderTotalValue: renderFromWei(totalValue) + ' ' + ticker,
renderTotalValueFiat: weiToFiat(totalValue, conversionRate, currentCurrency.toUpperCase())
renderTotalValueFiat: weiToFiat(totalValue, conversionRate, currentCurrency)
};

const transactionElement = {
addressTo: to,
addressFrom: from,
renderTo,
renderFrom,
actionKey,
value: renderTotalEth,
fiatValue: renderTotalEthFiat
Expand All @@ -446,10 +451,10 @@ class TransactionElement extends PureComponent {
return [transactionElement, transactionDetails];
};

renderDeploymentElement = () => {
decodeDeploymentTx = () => {
const {
tx: {
transaction: { value, gas, gasPrice, to, from },
transaction: { value, gas, gasPrice, from },
transactionHash
},
conversionRate,
Expand All @@ -462,32 +467,35 @@ class TransactionElement extends PureComponent {
const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0');

const renderTotalEth = renderFromWei(totalGas) + ' ' + ticker;
const renderTotalEthFiat = weiToFiat(totalGas, conversionRate, currentCurrency.toUpperCase());
const renderTotalEthFiat = weiToFiat(totalGas, conversionRate, currentCurrency);
const totalEth = isBN(value) ? value.add(totalGas) : totalGas;

const renderFrom = renderFullAddress(from);
const renderTo = strings('transactions.to_contract');

const transactionElement = {
addressTo: to,
addressFrom: from,
renderTo,
renderFrom,
actionKey,
value: renderTotalEth,
fiatValue: renderTotalEthFiat,
contractDeployment: true
};
const transactionDetails = {
renderFrom: renderFullAddress(from),
renderTo: strings('transactions.to_contract'),
renderFrom,
renderTo,
transactionHash,
renderValue: renderFromWei(value) + ' ' + ticker,
renderGas: parseInt(gas, 16).toString(),
renderGasPrice: renderToGwei(gasPrice),
renderTotalValue: renderFromWei(totalEth) + ' ' + ticker,
renderTotalValueFiat: weiToFiat(totalEth, conversionRate, currentCurrency.toUpperCase())
renderTotalValueFiat: weiToFiat(totalEth, conversionRate, currentCurrency)
};

return [transactionElement, transactionDetails];
};

renderPaymentChannelTx = () => {
decodePaymentChannelTx = () => {
const {
tx: {
networkID,
Expand All @@ -502,16 +510,19 @@ class TransactionElement extends PureComponent {
const contract = CONTRACTS[networkID];
const isDeposit = contract && to.toLowerCase() === contract.toLowerCase();
const totalEth = hexToBN(value);
const totalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency.toUpperCase());
const totalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency);
const readableTotalEth = renderFromWei(totalEth);
const renderTotalEth = readableTotalEth + ' ' + (isDeposit ? strings('unit.eth') : strings('unit.dai'));
const renderTotalEthFiat = isDeposit
? totalEthFiat
: balanceToFiat(parseFloat(readableTotalEth), conversionRate, exchangeRate, currentCurrency);

const renderFrom = renderFullAddress(from);
const renderTo = renderFullAddress(to);

const transactionDetails = {
renderFrom: renderFullAddress(from),
renderTo: renderFullAddress(to),
renderFrom,
renderTo,
transactionHash,
renderGas: gas ? parseInt(gas, 16).toString() : strings('transactions.tx_details_not_available'),
renderGasPrice: gasPrice ? renderToGwei(gasPrice) : strings('transactions.tx_details_not_available'),
Expand All @@ -521,8 +532,8 @@ class TransactionElement extends PureComponent {
};

const transactionElement = {
addressTo: to,
addressFrom: from,
renderFrom,
renderTo,
actionKey,
value: renderTotalEth,
fiatValue: renderTotalEthFiat,
Expand Down Expand Up @@ -565,23 +576,23 @@ class TransactionElement extends PureComponent {
);
}
if (paymentChannelTransaction) {
[transactionElement, transactionDetails] = this.renderPaymentChannelTx();
[transactionElement, transactionDetails] = this.decodePaymentChannelTx();
} else {
switch (actionKey) {
case strings('transactions.sent_collectible'):
[transactionElement, transactionDetails] = this.renderTransferFromElement(totalGas);
[transactionElement, transactionDetails] = this.decodeTransferFromTx(totalGas);
break;
case strings('transactions.contract_deploy'):
[transactionElement, transactionDetails] = this.renderDeploymentElement(totalGas);
[transactionElement, transactionDetails] = this.decodeDeploymentTx(totalGas);
break;
default:
[transactionElement, transactionDetails] = this.renderConfirmElement(totalGas);
[transactionElement, transactionDetails] = this.decodeConfirmTx(totalGas);
}
}
return (
<TouchableHighlight
style={styles.row}
onPress={this.onPressItem} // eslint-disable-line react/jsx-no-bind
onPress={this.onPressItem}
underlayColor={colors.grey000}
activeOpacity={1}
>
Expand Down
2 changes: 1 addition & 1 deletion app/components/UI/Transactions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class Transactions extends PureComponent {
contractExchangeRates={this.props.contractExchangeRates}
exchangeRate={this.props.exchangeRate}
conversionRate={this.props.conversionRate}
currentCurrency={this.props.currentCurrency}
currentCurrency={this.props.currentCurrency.toUpperCase()}
showAlert={this.props.showAlert}
navigation={this.props.navigation}
/>
Expand Down
4 changes: 2 additions & 2 deletions app/components/Views/Asset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ class Asset extends PureComponent {
if (symbol.toUpperCase() !== 'ETH' && tokenAddress !== '') {
txs = txs.filter(
tx =>
tx.transaction.from.toLowerCase() === tokenAddress.toLowerCase() ||
tx.transaction.to.toLowerCase() === tokenAddress.toLowerCase()
(tx.transaction.from && tx.transaction.from.toLowerCase()) === tokenAddress.toLowerCase() ||
(tx.transaction.to && tx.transaction.to.toLowerCase()) === tokenAddress.toLowerCase()
);
}

Expand Down
2 changes: 1 addition & 1 deletion app/components/Views/PaymentChannel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ class PaymentChannel extends PureComponent {
internalTransactions.forEach(tx => {
if (
Networks[provider.type].networkId.toString() === tx.networkID &&
tx.transaction.to.toLowerCase() === selectedAddress.toLowerCase()
(tx.transaction.to && tx.transaction.to.toLowerCase()) === selectedAddress.toLowerCase()
) {
parsedTransactions.push({
...tx,
Expand Down
4 changes: 3 additions & 1 deletion app/util/address.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { toChecksumAddress } from 'ethereumjs-util';
import Engine from '../core/Engine';
import AppConstants from '../core/AppConstants';
import { strings } from '../../locales/i18n';

/**
* Returns full checksummed address
*
* @param {String} address - String corresponding to an address
* @returns {String} - String corresponding to full checksummed address
*/
export function renderFullAddress(address) {
return toChecksumAddress(address);
return address ? toChecksumAddress(address) : strings('transactions.tx_details_not_available');
}

/**
Expand Down

0 comments on commit 0d3a476

Please sign in to comment.