diff --git a/app/components/TransactionElement/TransactionDetails/index.js b/app/components/TransactionElement/TransactionDetails/index.js index 3a93cb07eb3..745301e1dc2 100644 --- a/app/components/TransactionElement/TransactionDetails/index.js +++ b/app/components/TransactionElement/TransactionDetails/index.js @@ -3,9 +3,7 @@ import PropTypes from 'prop-types'; import { Clipboard, TouchableOpacity, StyleSheet, Text, View } from 'react-native'; import { colors, fontStyles } from '../../../styles/common'; import { strings } from '../../../../locales/i18n'; -import { renderFromWei, weiToFiat, hexToBN, isBN, toBN, toGwei, weiToFiatNumber } from '../../../util/number'; import Icon from 'react-native-vector-icons/FontAwesome'; -import { renderFullAddress } from '../../../util/address'; const styles = StyleSheet.create({ detailRowWrapper: { @@ -81,14 +79,6 @@ const styles = StyleSheet.create({ */ export default class TransactionDetails extends PureComponent { static propTypes = { - /** - * ETH to current currency conversion rate - */ - conversionRate: PropTypes.number, - /** - * Currency code of the currently-active currency - */ - currentCurrency: PropTypes.string, /** * Object corresponding to a transaction, containing transaction object, networkId and transaction hash string */ @@ -104,7 +94,11 @@ export default class TransactionDetails extends PureComponent { /** * Action that shows the global alert */ - viewOnEtherscan: PropTypes.func.isRequired + viewOnEtherscan: PropTypes.func.isRequired, + /** + * Object with information to render + */ + transactionDetails: PropTypes.object }; renderTxHash = transactionHash => { @@ -124,10 +118,7 @@ export default class TransactionDetails extends PureComponent { }; copy = async () => { - const { - transactionObject: { transactionHash } - } = this.props; - await Clipboard.setString(transactionHash); + await Clipboard.setString(this.props.transactionDetails.transactionHash); this.props.showAlert({ isVisible: true, autodismiss: 2000, @@ -144,87 +135,66 @@ export default class TransactionDetails extends PureComponent { viewOnEtherscan = () => { const { - transactionObject: { transactionHash, networkID } + transactionObject: { networkID } } = this.props; - this.props.viewOnEtherscan(networkID, transactionHash); + this.props.viewOnEtherscan(networkID, this.props.transactionDetails.transactionHash); }; render = () => { - const { - transactionObject: { - transaction: { gas, gasPrice, value, to, from }, - transactionHash, - transfer - }, - blockExplorer - } = this.props; - const gasBN = hexToBN(gas); - const gasPriceBN = hexToBN(gasPrice); - const amount = hexToBN(value); - const { conversionRate, currentCurrency } = this.props; - const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0'); - const totalEth = isBN(amount) ? amount.add(totalGas) : totalGas; - const renderAmount = transfer - ? !transfer.amount - ? strings('transaction.value_not_available') - : transfer.amount - : renderFromWei(value) + ' ' + strings('unit.eth'); - const renderTotalEth = renderFromWei(totalEth) + ' ' + strings('unit.eth'); - const renderTotal = transfer - ? transfer.amount - ? transfer.amount + ' ' + strings('unit.divisor') + ' ' + renderTotalEth - : strings('transaction.value_not_available') - : renderTotalEth; - - const renderTotalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency).toUpperCase(); - const totalEthFiatAmount = weiToFiatNumber(totalEth, conversionRate); - const renderTotalFiat = transfer - ? transfer.amountFiat - ? totalEthFiatAmount + transfer.amountFiat + ' ' + currentCurrency.toUpperCase() - : undefined - : renderTotalEthFiat; - const renderTo = transfer ? transfer.to : !to ? strings('transactions.to_contract') : renderFullAddress(to); + const { blockExplorer } = this.props; return ( - {this.renderTxHash(transactionHash)} + {this.renderTxHash(this.props.transactionDetails.transactionHash)} {strings('transactions.from')} - {renderFullAddress(from)} + {this.props.transactionDetails.renderFrom} {strings('transactions.to')} - {renderTo} + {this.props.transactionDetails.renderTo} {strings('transactions.details')} - {strings('transactions.amount')} - {renderAmount} + + {this.props.transactionDetails.valueLabel || strings('transactions.amount')} + + + {this.props.transactionDetails.renderValue} + {strings('transactions.gas_limit')} - {hexToBN(gas).toNumber()} + + {this.props.transactionDetails.renderGas} + {strings('transactions.gas_price')} - {toGwei(gasPrice)} + + {this.props.transactionDetails.renderGasPrice} + {strings('transactions.total')} - {renderTotal} + + {this.props.transactionDetails.renderTotalValue} + - {renderTotalFiat && ( + {this.props.transactionDetails.renderTotalValueFiat && ( - {renderTotalFiat} + + {this.props.transactionDetails.renderTotalValueFiat} + )} - {transactionHash && + {this.props.transactionDetails.transactionHash && blockExplorer && ( { const wrapper = shallow( , { context: { store: mockStore(initialState) } diff --git a/app/components/TransactionElement/index.js b/app/components/TransactionElement/index.js index 99c4b44dd59..bbd254ccf46 100644 --- a/app/components/TransactionElement/index.js +++ b/app/components/TransactionElement/index.js @@ -13,12 +13,16 @@ import { balanceToFiat, toBN, isBN, - balanceToFiatNumber + balanceToFiatNumber, + renderToGwei, + weiToFiatNumber } from '../../util/number'; import { toChecksumAddress } from 'ethereumjs-util'; import Identicon from '../Identicon'; import { getActionKey, decodeTransferData } from '../../util/transactions'; import TransactionDetails from './TransactionDetails'; +import { renderFullAddress } from '../../util/address'; +import FadeIn from 'react-native-fade-in-image'; const styles = StyleSheet.create({ row: { @@ -139,6 +143,10 @@ export default class TransactionElement extends PureComponent { * An array that represents the user tokens */ tokens: PropTypes.object, + /** + * An array that represents the user collectible contracts + */ + collectibleContracts: PropTypes.array, /** * Boolean to determine if this network supports a block explorer */ @@ -198,33 +206,68 @@ export default class TransactionElement extends PureComponent { ); }; - renderTxDetails = (selected, tx, blockExplorer, showAlert, currentCurrency, conversionRate) => - selected ? ( + renderTxDetails = (selected, tx, transactionDetails) => { + const { showAlert, blockExplorer } = this.props; + return selected ? ( ) : null; + }; + + /** + * Renders an horizontal bar with basic tx information + * + * @param {object} transactionElement - Transaction information to render, containing addressTo, actionKey, value, fiatValue, contractDeployment + */ + renderTxElement = transactionElement => { + const { + tx: { status } + } = this.props; + const { addressTo, actionKey, value, fiatValue, contractDeployment = false } = transactionElement; + return ( + + {this.renderTxTime()} + + {contractDeployment ? ( + + + + ) : ( + + )} + + {actionKey} + {status.toUpperCase()} + + + {value} + {fiatValue} + + + + ); + }; renderTransferElement = () => { const { - tx, + tx: { + transaction: { gas, gasPrice, to, data, from }, + transactionHash + }, conversionRate, currentCurrency, tokens, - contractExchangeRates, - selected, - blockExplorer, - showAlert + contractExchangeRates } = this.props; const { actionKey } = this.state; - const [addressTo, amount] = decodeTransferData('ERC20', tx.transaction.data); - const userHasToken = toChecksumAddress(tx.transaction.to) in tokens; - const token = userHasToken ? tokens[toChecksumAddress(tx.transaction.to)] : null; + const [addressTo, amount] = decodeTransferData('ERC20', data); + const userHasToken = toChecksumAddress(to) in tokens; + const token = userHasToken ? tokens[toChecksumAddress(to)] : null; const renderActionKey = token ? strings('transactions.sent') + ' ' + token.symbol : actionKey; const renderTokenAmount = token ? renderFromTokenMinimalUnit(amount, token.decimals) + ' ' + token.symbol @@ -246,139 +289,204 @@ export default class TransactionElement extends PureComponent { exchangeRate ); } - const transfer = { - to: addressTo, - amount: renderTokenAmount, - amountFiat: renderTokenFiatNumber + const gasBN = hexToBN(gas); + const gasPriceBN = hexToBN(gasPrice); + const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0'); + const renderToken = token + ? renderFromTokenMinimalUnit(amount, token.decimals) + ' ' + token.symbol + : strings('transaction.value_not_available'); + const totalFiatNumber = renderTokenFiatNumber + ? weiToFiatNumber(totalGas, conversionRate) + renderTokenFiatNumber + : undefined; + + const transactionDetails = { + renderFrom: renderFullAddress(from), + renderTo: renderFullAddress(addressTo), + transactionHash, + renderValue: renderToken, + renderGas: parseInt(gas, 16).toString(), + renderGasPrice: renderToGwei(gasPrice), + renderTotalValue: + renderToken + ' ' + strings('unit.divisor') + ' ' + renderFromWei(totalGas) + ' ' + strings('unit.eth'), + renderTotalValueFiat: totalFiatNumber ? totalFiatNumber + ' ' + currentCurrency.toUpperCase() : undefined }; - return ( - - - {this.renderTxTime()} - - - - {renderActionKey} - - {tx.status.toUpperCase()} - - - - - {!renderTokenAmount ? strings('transaction.value_not_available') : renderTokenAmount} - - {renderTokenFiatAmount} - - - - {this.renderTxDetails( - selected, - { ...tx, ...{ transfer } }, - blockExplorer, - showAlert, - currentCurrency, - conversionRate - )} - + + const transactionElement = { + addressTo, + actionKey: renderActionKey, + value: !renderTokenAmount ? strings('transaction.value_not_available') : renderTokenAmount, + fiatValue: renderTokenFiatAmount + }; + + return [transactionElement, transactionDetails]; + }; + + renderTransferFromElement = () => { + const { + tx: { + transaction: { gas, gasPrice, data, to }, + transactionHash + }, + collectibleContracts + } = this.props; + let { actionKey } = this.state; + const [addressFrom, addressTo, tokenId] = decodeTransferData('ERC721', data); + const collectible = collectibleContracts.find( + collectible => collectible.address.toLowerCase() === to.toLowerCase() ); + if (collectible) { + actionKey = strings('transactions.sent') + ' ' + collectible.name; + } + + const gasBN = hexToBN(gas); + const gasPriceBN = hexToBN(gasPrice); + const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0'); + const renderCollectible = collectible + ? strings('unit.token_id') + tokenId + ' ' + collectible.symbol + : strings('unit.token_id') + tokenId; + + const transactionDetails = { + renderFrom: renderFullAddress(addressFrom), + renderTo: renderFullAddress(addressTo), + transactionHash, + renderValue: renderCollectible, + renderGas: parseInt(gas, 16).toString(), + renderGasPrice: renderToGwei(gasPrice), + renderTotalValue: + renderCollectible + + ' ' + + strings('unit.divisor') + + ' ' + + renderFromWei(totalGas) + + ' ' + + strings('unit.eth'), + renderTotalValueFiat: undefined + }; + + const transactionElement = { + addressTo, + actionKey, + value: `${strings('unit.token_id')}${tokenId}`, + fiatValue: collectible ? collectible.symbol : undefined + }; + + return [transactionElement, transactionDetails]; }; renderConfirmElement = () => { const { - tx, tx: { - transaction: { value } + transaction: { value, gas, gasPrice, from, to }, + transactionHash }, conversionRate, - currentCurrency, - selected, - blockExplorer, - showAlert + currentCurrency } = this.props; const { actionKey } = this.state; - const totalETh = hexToBN(value); - const renderTotalEth = renderFromWei(totalETh) + ' ' + strings('unit.eth'); - const renderTotalEthFiat = weiToFiat(totalETh, conversionRate, currentCurrency).toUpperCase(); - return ( - - - {this.renderTxTime()} - - - - {actionKey} - - {tx.status.toUpperCase()} - - - - {renderTotalEth} - {renderTotalEthFiat} - - - - {this.renderTxDetails(selected, tx, blockExplorer, showAlert, currentCurrency, conversionRate)} - - ); + const totalEth = hexToBN(value); + const renderTotalEth = renderFromWei(totalEth) + ' ' + strings('unit.eth'); + const renderTotalEthFiat = weiToFiat(totalEth, conversionRate, currentCurrency).toUpperCase(); + + 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 transactionDetails = { + renderFrom: renderFullAddress(from), + renderTo: renderFullAddress(to), + transactionHash, + renderValue: renderFromWei(value) + ' ' + strings('unit.eth'), + renderGas: parseInt(gas, 16).toString(), + renderGasPrice: renderToGwei(gasPrice), + renderTotalValue: renderFromWei(totalValue) + ' ' + strings('unit.eth'), + renderTotalValueFiat: weiToFiat(totalValue, conversionRate, currentCurrency).toUpperCase() + }; + + const transactionElement = { + addressTo: to, + actionKey, + value: renderTotalEth, + fiatValue: renderTotalEthFiat + }; + + return [transactionElement, transactionDetails]; }; - renderDeploymentElement = totalGas => { - const { tx, selected, blockExplorer, conversionRate, currentCurrency, showAlert } = this.props; + renderDeploymentElement = () => { + const { + tx: { + transaction: { value, gas, gasPrice, to, from }, + transactionHash + }, + conversionRate, + currentCurrency + } = this.props; const { actionKey } = this.state; + const gasBN = hexToBN(gas); + const gasPriceBN = hexToBN(gasPrice); + const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0'); + const renderTotalEth = renderFromWei(totalGas) + ' ' + strings('unit.eth'); const renderTotalEthFiat = weiToFiat(totalGas, conversionRate, currentCurrency).toUpperCase(); - return ( - - - {this.renderTxTime()} - - - - {actionKey} - - {tx.status.toUpperCase()} - - - - {renderTotalEth} - {renderTotalEthFiat} - - - - {this.renderTxDetails(selected, tx, blockExplorer, showAlert, currentCurrency, conversionRate)} - - ); + const totalEth = isBN(value) ? value.add(totalGas) : totalGas; + + const transactionElement = { + addressTo: to, + actionKey, + value: renderTotalEth, + fiatValue: renderTotalEthFiat, + contractDeployment: true + }; + const transactionDetails = { + renderFrom: renderFullAddress(from), + renderTo: strings('transactions.to_contract'), + transactionHash, + renderValue: renderFromWei(value) + ' ' + strings('unit.eth'), + renderGas: parseInt(gas, 16).toString(), + renderGasPrice: renderToGwei(gasPrice), + renderTotalValue: renderFromWei(totalEth) + ' ' + strings('unit.eth'), + renderTotalValueFiat: weiToFiat(totalEth, conversionRate, currentCurrency).toUpperCase() + }; + + return [transactionElement, transactionDetails]; }; render = () => { const { tx: { transaction: { gas, gasPrice } - } + }, + selected, + tx } = this.props; const { actionKey } = this.state; - let transactionElement; const gasBN = hexToBN(gas); const gasPriceBN = hexToBN(gasPrice); const totalGas = isBN(gasBN) && isBN(gasPriceBN) ? gasBN.mul(gasPriceBN) : toBN('0x0'); - + let transactionElement, transactionDetails; switch (actionKey) { case strings('transactions.sent_tokens'): - transactionElement = this.renderTransferElement(totalGas); + [transactionElement, transactionDetails] = this.renderTransferElement(totalGas); + break; + case strings('transactions.sent_collectible'): + [transactionElement, transactionDetails] = this.renderTransferFromElement(totalGas); break; case strings('transactions.contract_deploy'): - transactionElement = this.renderDeploymentElement(totalGas); + [transactionElement, transactionDetails] = this.renderDeploymentElement(totalGas); break; default: - transactionElement = this.renderConfirmElement(totalGas); + [transactionElement, transactionDetails] = this.renderConfirmElement(totalGas); } - return ( - {transactionElement} + + {this.renderTxElement(transactionElement)} + {this.renderTxDetails(selected, tx, transactionDetails)} + ); }; diff --git a/app/components/Transactions/index.js b/app/components/Transactions/index.js index d878cf879e0..e653fa98bcc 100644 --- a/app/components/Transactions/index.js +++ b/app/components/Transactions/index.js @@ -54,6 +54,10 @@ class Transactions extends PureComponent { /* navigation object required to push new views */ navigation: PropTypes.object, + /** + * An array that represents the user collectible contracts + */ + collectibleContracts: PropTypes.array, /** * An array that represents the user tokens */ @@ -186,6 +190,7 @@ class Transactions extends PureComponent { onPressItem={this.toggleDetailsView} blockExplorer tokens={this.props.tokens} + collectibleContracts={this.props.collectibleContracts} contractExchangeRates={this.props.contractExchangeRates} conversionRate={this.props.conversionRate} currentCurrency={this.props.currentCurrency} @@ -230,6 +235,7 @@ const mapStateToProps = state => ({ tokens[token.address] = token; return tokens; }, {}), + collectibleContracts: state.engine.backgroundState.AssetsController.collectibleContracts, contractExchangeRates: state.engine.backgroundState.TokenRatesController.contractExchangeRates, conversionRate: state.engine.backgroundState.CurrencyRateController.conversionRate, currentCurrency: state.engine.backgroundState.CurrencyRateController.currentCurrency diff --git a/app/util/number.js b/app/util/number.js index ab6dd2feb01..30d57372794 100644 --- a/app/util/number.js +++ b/app/util/number.js @@ -205,6 +205,20 @@ export function toGwei(value, unit = 'ether') { return fromWei(value, unit) * 1000000000; } +/** + * Converts some unit to Gwei and return it in render format + * + * @param {number|string|BN} value - Value to convert + * @param {string} unit - Unit to convert from, ether by default + * @returns {string} - String instance containing the renderable number + */ +export function renderToGwei(value, unit = 'ether') { + const gwei = fromWei(value, unit) * 1000000000; + let gweiFixed = parseFloat(Math.round(gwei)); + gweiFixed = isNaN(gweiFixed) ? 0 : gweiFixed; + return gweiFixed; +} + /** * Converts wei expressed as a BN instance into a human-readable fiat string * diff --git a/app/util/transactions.js b/app/util/transactions.js index e197bfa43e4..b37a53c6939 100644 --- a/app/util/transactions.js +++ b/app/util/transactions.js @@ -85,13 +85,25 @@ export function generateTransferData(assetType, opts) { * @returns {Object} - Object containing the decoded transfer data */ export function decodeTransferData(assetType, data) { - let encodedAddress, encodedAmount, bufferEncodedAddress; switch (assetType) { - case 'ERC20': - encodedAddress = data.substr(10, 64); - encodedAmount = data.substr(74, 138); - bufferEncodedAddress = rawEncode(['address'], [addHexPrefix(encodedAddress)]); + case 'ERC20': { + const encodedAddress = data.substr(10, 64); + const encodedAmount = data.substr(74, 138); + const bufferEncodedAddress = rawEncode(['address'], [addHexPrefix(encodedAddress)]); return [addHexPrefix(rawDecode(['address'], bufferEncodedAddress)[0]), hexToBN(encodedAmount)]; + } + case 'ERC721': { + const encodedFromAddress = data.substr(10, 64); + const encodedToAddress = data.substr(74, 64); + const encodedTokenId = data.substr(138, 64); + const bufferEncodedFromAddress = rawEncode(['address'], [addHexPrefix(encodedFromAddress)]); + const bufferEncodedToAddress = rawEncode(['address'], [addHexPrefix(encodedToAddress)]); + return [ + addHexPrefix(rawDecode(['address'], bufferEncodedFromAddress)[0]), + addHexPrefix(rawDecode(['address'], bufferEncodedToAddress)[0]), + parseInt(encodedTokenId, 16).toString() + ]; + } } } @@ -198,6 +210,8 @@ export async function getActionKey(tx, selectedAddress) { switch (actionKey) { case SEND_TOKEN_ACTION_KEY: return strings('transactions.sent_tokens'); + case TRANSFER_FROM_ACTION_KEY: + return strings('transactions.sent_collectible'); case SEND_ETHER_ACTION_KEY: return incoming ? selfSent diff --git a/app/util/transactions.test.js b/app/util/transactions.test.js index 7470269aecd..f0cc0ba1f7e 100644 --- a/app/util/transactions.test.js +++ b/app/util/transactions.test.js @@ -48,7 +48,7 @@ describe('Transactions utils :: generateTransferData', () => { }); describe('Transactions utils :: decodeTransferData', () => { - it('decodeTransferData', () => { + it('decodeTransferData ERC20', () => { const [address, amount] = decodeTransferData( 'ERC20', '0xa9059cbb00000000000000000000000056ced0d816c668d7c0bcc3fbf0ab2c6896f589a00000000000000000000000000000000000000000000000000000000000000001' @@ -56,6 +56,16 @@ describe('Transactions utils :: decodeTransferData', () => { expect(address).toEqual('0x56ced0d816c668d7c0bcc3fbf0ab2c6896f589a0'); expect(amount.toNumber()).toEqual(1); }); + + it('decodeTransferData ERC721', () => { + const [fromAddress, toAddress, tokenId] = decodeTransferData( + 'ERC721', + '0x23b872dd00000000000000000000000056ced0d816c668d7c0bcc3fbf0ab2c6896f589c900000000000000000000000056ced0d816c668d7c0bcc3fbf0ab2c6896f589b400000000000000000000000000000000000000000000000000000000000004f1' + ); + expect(fromAddress).toEqual('0x56ced0d816c668d7c0bcc3fbf0ab2c6896f589c9'); + expect(toAddress).toEqual('0x56ced0d816c668d7c0bcc3fbf0ab2c6896f589b4'); + expect(tokenId).toEqual('1265'); + }); }); describe('Transactions utils :: getMethodData', () => { diff --git a/locales/en.json b/locales/en.json index fe619743924..b6a525acabf 100644 --- a/locales/en.json +++ b/locales/en.json @@ -358,6 +358,7 @@ "self_sent_ether": "Sent Yourself Ether", "received_ether": "Received Ether", "sent_tokens": "Sent Tokens", + "sent_collectible": "Sent Collectible", "sent": "Sent", "contract_deploy": "Contract Deployment", "to_contract": "New Contract", diff --git a/package-lock.json b/package-lock.json index 9817189131d..2196f2dccb1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2408,14 +2408,6 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, - "backoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "requires": { - "precond": "0.2" - } - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -5108,8 +5100,17 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereumjs-abi": { @@ -5237,8 +5238,17 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereumjs-abi": { @@ -6074,7 +6084,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6092,11 +6103,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6109,15 +6122,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6220,7 +6236,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6230,6 +6247,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6242,17 +6260,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6269,6 +6290,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -6341,7 +6363,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6351,6 +6374,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -6426,7 +6450,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -6456,6 +6481,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6473,6 +6499,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -6511,11 +6538,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.3", - "bundled": true + "bundled": true, + "optional": true } } }, @@ -6561,7 +6590,6 @@ "requires": { "await-semaphore": "^0.1.3", "eth-block-tracker": "^4.1.0", - "eth-contract-metadata": "github:estebanmino/eth-contract-metadata#e307359ca9ea6be4ded6ac58ac7e16f192ae4e2a", "eth-json-rpc-infura": "^3.1.2", "eth-keyring-controller": "^4.0.0", "eth-phishing-detect": "^1.1.13", @@ -6577,8 +6605,86 @@ "percentile": "^1.2.1", "single-call-balance-checker-abi": "^1.0.0", "uuid": "^3.3.2", - "web3": "^0.20.7", - "web3-provider-engine": "github:metamask/provider-engine#e91367bc2c2535fbf7add06244d9d4ec98620042" + "web3": "^0.20.7" + }, + "dependencies": { + "eth-contract-metadata": { + "version": "github:estebanmino/eth-contract-metadata#e307359ca9ea6be4ded6ac58ac7e16f192ae4e2a", + "from": "github:estebanmino/eth-contract-metadata#e307359ca9ea6be4ded6ac58ac7e16f192ae4e2a" + }, + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "web3-provider-engine": { + "version": "github:metamask/provider-engine#e91367bc2c2535fbf7add06244d9d4ec98620042", + "from": "github:metamask/provider-engine#e91367bc2c2535fbf7add06244d9d4ec98620042", + "requires": { + "async": "^2.5.0", + "backoff": "^2.5.0", + "clone": "^2.0.0", + "cross-fetch": "^2.1.0", + "eth-block-tracker": "^3.0.0", + "eth-json-rpc-infura": "^3.1.0", + "eth-sig-util": "^1.4.2", + "ethereumjs-block": "^1.2.2", + "ethereumjs-tx": "^1.2.0", + "ethereumjs-util": "^5.1.5", + "ethereumjs-vm": "^2.3.4", + "json-rpc-error": "^2.0.0", + "json-stable-stringify": "^1.0.1", + "promise-to-callback": "^1.0.0", + "readable-stream": "^2.2.9", + "request": "^2.85.0", + "semaphore": "^1.0.3", + "ws": "^5.1.1", + "xhr": "^2.2.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "eth-block-tracker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz", + "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==", + "requires": { + "eth-query": "^2.1.0", + "ethereumjs-tx": "^1.3.3", + "ethereumjs-util": "^5.1.3", + "ethjs-util": "^0.1.3", + "json-rpc-engine": "^3.6.0", + "pify": "^2.3.0", + "tape": "^4.6.3" + } + }, + "eth-sig-util": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", + "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", + "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "ethereumjs-util": "^5.1.1" + } + } + } + } } }, "gauge": { @@ -11869,11 +11975,6 @@ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, - "precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" - }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -15581,7 +15682,6 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.7.tgz", "integrity": "sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==", "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2-cookies": "^1.1.0", @@ -15590,80 +15690,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" - } - } - }, - "web3-provider-engine": { - "version": "github:metamask/provider-engine#e91367bc2c2535fbf7add06244d9d4ec98620042", - "from": "github:metamask/provider-engine#feature/getaccounts-payload", - "requires": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "eth-block-tracker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz", - "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==", - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#d84a96796079c8595a0c78accd1e7709f2277215", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" } } },