From da1290cc30240b52f2df2000f2fe2ab471710aa7 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 22 Apr 2020 13:19:23 +0300 Subject: [PATCH 01/20] Fix token decimals --- old-ui/app/components/dropdown.js | 9 +- old-ui/app/components/pending-tx.js | 1411 +++++++++-------- old-ui/app/components/token-balance.js | 272 ++-- old-ui/app/components/token-cell.js | 274 ++-- .../unit/ui/app/components/token-cell.spec.js | 69 - ui/app/components/token-cell.js | 160 -- 6 files changed, 1011 insertions(+), 1184 deletions(-) delete mode 100644 test/unit/ui/app/components/token-cell.spec.js delete mode 100644 ui/app/components/token-cell.js diff --git a/old-ui/app/components/dropdown.js b/old-ui/app/components/dropdown.js index 99710ba31..bc9771307 100644 --- a/old-ui/app/components/dropdown.js +++ b/old-ui/app/components/dropdown.js @@ -60,8 +60,8 @@ class Dropdown extends Component { > {children} @@ -94,16 +94,17 @@ class DropdownMenuItem extends Component { }, this.props.style) return ( -
  • { onClick() closeMenu() }} + key={`dropdown-menu-item_${Math.random()}`} style={style} > {children} -
  • + ) } diff --git a/old-ui/app/components/pending-tx.js b/old-ui/app/components/pending-tx.js index e2477cf4a..78516880b 100644 --- a/old-ui/app/components/pending-tx.js +++ b/old-ui/app/components/pending-tx.js @@ -1,9 +1,9 @@ const Component = require('react').Component const h = require('react-hyperscript') -const inherits = require('util').inherits const actions = require('../../../ui/app/actions') -const clone = require('clone') -const log = require('loglevel') +import PropTypes from 'prop-types' +import clone from 'clone' +import log from 'loglevel' const ethUtil = require('ethereumjs-util') const BN = ethUtil.BN @@ -19,31 +19,730 @@ const BNInput = require('./bn-as-decimal-input') const { getEnvironmentType } = require('../../../app/scripts/lib/util') const NetworkIndicator = require('../components/network') const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../../app/scripts/lib/enums') -const connect = require('react-redux').connect -const abiDecoder = require('abi-decoder') +import { connect } from 'react-redux' +import abiDecoder from 'abi-decoder' const { tokenInfoGetter, calcTokenAmount } = require('../../../ui/app/token-util') -const BigNumber = require('bignumber.js') -const ethNetProps = require('eth-net-props') +import BigNumber from 'bignumber.js' +import ethNetProps from 'eth-net-props' import { getMetaMaskAccounts } from '../../../ui/app/selectors' import ToastComponent from './toast' const MIN_GAS_PRICE_BN = new BN('0') const MIN_GAS_LIMIT_BN = new BN('21000') +const emptyAddress = '0x0000000000000000000000000000000000000000' -module.exports = connect(mapStateToProps)(PendingTx) -inherits(PendingTx, Component) -function PendingTx (props) { - Component.call(this) - this.state = { - valid: true, - txData: null, - submitting: false, - tokenSymbol: '', - tokenDecimals: 0, - tokenDataRetrieved: false, - coinName: ethNetProps.props.getNetworkCoinName(props.network), +class PendingTx extends Component { + static propTypes = { + network: PropTypes.string, + buyEth: PropTypes.func, + cancelTransaction: PropTypes.func, + cancelAllTransactions: PropTypes.func, + sendTransaction: PropTypes.func, + actions: PropTypes.object, + txData: PropTypes.object, + selectedAddress: PropTypes.string, + identities: PropTypes.object, + accounts: PropTypes.object, + isToken: PropTypes.bool, + isUnlocked: PropTypes.bool, + currentCurrency: PropTypes.string, + conversionRate: PropTypes.number, + unconfTxListLength: PropTypes.number, + provider: PropTypes.object, + index: PropTypes.number, + blockGasLimit: PropTypes.string, + tokensToSend: PropTypes.objectOf(BigNumber), + tokensTransferTo: PropTypes.string, } - this.tokenInfoGetter = tokenInfoGetter() + + constructor (opts = {}) { + super() + this.state = { + valid: true, + txData: null, + submitting: false, + token: { + address: emptyAddress, + symbol: '', + decimals: 0, + dataRetrieved: false, + }, + isToken: false, + coinName: ethNetProps.props.getNetworkCoinName(opts.network), + } + this.tokenInfoGetter = tokenInfoGetter() + } + + render () { + const props = this.props + if (props.isToken || this.state.isToken) { + if (!this.state.token.dataRetrieved) return null + } + const { currentCurrency, blockGasLimit, network, provider, isUnlocked } = props + + const conversionRate = props.conversionRate + const txMeta = this.gatherTxMeta() + const txParams = txMeta.txParams || {} + let { isToken, tokensToSend, tokensTransferTo } = props + + const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data) + if (decodedData && decodedData.name === 'transfer') { + isToken = true + const tokenValBN = new BigNumber(calcTokenAmount(decodedData.params[1].value, this.state.token.decimals)) + const multiplier = Math.pow(10, 18) + tokensToSend = tokenValBN.mul(multiplier).toString(16) + tokensTransferTo = decodedData.params[0].value + } + + // Allow retry txs + const { lastGasPrice } = txMeta + let forceGasMin + if (lastGasPrice) { + const stripped = ethUtil.stripHexPrefix(lastGasPrice) + const lastGas = new BN(stripped, 16) + const priceBump = lastGas.divn('10') + forceGasMin = lastGas.add(priceBump) + } + + // Account Details + const address = txParams.from || props.selectedAddress + const identity = props.identities[address] || { address: address } + const account = props.accounts[address] + const balance = account ? account.balance : '0x0' + + // recipient check + const isValidAddress = !txParams.to || util.isValidAddress(txParams.to, network) + + // Gas + const gas = txParams.gas + const gasBn = hexToBn(gas) + // default to 8MM gas limit + const gasLimit = new BN(parseInt(blockGasLimit) || '8000000') + const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 99, 100) + const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 98, 100) + const safeGasLimit = safeGasLimitBN.toString(10) + + // Gas Price + const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_BN.toString(16) + const gasPriceBn = hexToBn(gasPrice) + + const txFeeBn = gasBn.mul(gasPriceBn) + const valueBn = hexToBn(txParams.value) + const maxCost = txFeeBn.add(valueBn) + + const dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0 + + const balanceBn = hexToBn(balance) + const insufficientBalance = balanceBn.lt(maxCost) + const dangerousGasLimit = gasBn.gte(saferGasLimitBN) + const gasLimitSpecified = txMeta.gasLimitSpecified + const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting + const showRejectAll = props.unconfTxListLength > 1 + + const isNotification = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION + + this.inputs = [] + + const valueStyle = { + fontFamily: 'Nunito Bold', + width: '100%', + textAlign: 'right', + fontSize: '14px', + color: '#333333', + } + + const dimStyle = { + color: '#333333', + marginLeft: '5px', + fontSize: '14px', + } + + const isError = txMeta.simulationFails || !isValidAddress || insufficientBalance || (dangerousGasLimit && !gasLimitSpecified) + + return ( + + h('div', { + key: txMeta.id, + }, [ + h(ToastComponent, { + isSuccess: false, + }), + + h('form#pending-tx-form', { + onSubmit: this.onSubmit.bind(this), + + }, [ + + // tx info + h('div', [ + + h('.flex-row.flex-center', { + style: { + maxWidth: '100%', + padding: showRejectAll ? '20px 20px 50px 20px' : '20px 20px 20px 20px', + background: 'linear-gradient(rgb(84, 36, 147), rgb(104, 45, 182))', + position: 'relative', + }, + }, [ + + h('div', { + style: { + position: 'absolute', + bottom: '20px', + width: '100%', + textAlign: 'center', + color: '#ffffff', + }, + }, [ + h('h3', { + style: { + alignSelf: 'center', + display: props.unconfTxListLength > 1 ? 'block' : 'none', + fontSize: '14px', + }, + }, [ + h('i.fa.white-arrow-left.fa-lg.cursor-pointer', { + style: { + display: props.index === 0 ? 'none' : 'inline-block', + }, + onClick: () => props.actions.previousTx(), + }), + ` ${props.index + 1} of ${props.unconfTxListLength} `, + h('i.fa.white-arrow-right.fa-lg.cursor-pointer', { + style: { + display: props.index + 1 === props.unconfTxListLength ? 'none' : 'inline-block', + }, + onClick: () => props.actions.nextTx(), + }), + ])], + ), + + h(MiniAccountPanel, { + imageSeed: address, + picOrder: 'left', + }, [ + h('div', { + style: { + marginLeft: '10px', + }, + }, [ + h('div.font-pre-medium', { + style: { + fontFamily: 'Nunito SemiBold', + color: '#ffffff', + whiteSpace: 'nowrap', + }, + }, accountSummary(identity.name, 6, 4)), + + h(Copyable, { + value: toChecksumAddress(network, address), + }, [ + h('span.font-small', { + style: { + fontFamily: 'Nunito Regular', + color: 'rgba(255, 255, 255, 0.7)', + }, + }, addressSummary(network, address, 6, 4, false)), + ]), + + h('span.font-small', { + style: { + fontFamily: 'Nunito Regular', + }, + }, [ + isToken ? h(TokenBalance, { + token: this.state.token, + fontSize: '12px', + }) : h(EthBalance, { + fontSize: '12px', + value: balance, + conversionRate, + currentCurrency, + network, + inline: true, + }), + ]), + ]), + ]), + + forwardCarrat(), + + this.miniAccountPanelForRecipient(isToken, tokensTransferTo), + ]), + + h('style', ` + .table-box { + margin: 7px 0px 0px 0px; + width: 100%; + position: relative; + } + .table-box .row { + margin: 0px; + background: #ffffff; + display: flex; + justify-content: space-between; + font-family: Nunito Regular; + font-size: 14px; + padding: 5px 30px; + } + .table-box .row .value { + font-family: Nunito Regular; + } + `), + + h('.table-box', [ + + h('.flex-row.flex-center', { + style: { + marginTop: '20px', + marginBottom: '30px', + }, + }, [ + !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { + onClick: this.goHome.bind(this), + style: { + position: 'absolute', + left: '30px', + }, + }) : null, + 'Confirm Transaction', + isNotification ? h(NetworkIndicator, { + network: network, + provider: provider, + isUnlocked: isUnlocked, + }) : null, + ]), + + isError ? h('div', { + style: { + textAlign: 'center', + position: 'absolute', + top: '25px', + background: 'rgba(255, 255, 255, 0.85)', + width: '100%', + paddingLeft: '30px', + paddingRight: '30px', + }, + }, [ + txMeta.simulationFails ? + h('.error', { + style: { + fontSize: '12px', + }, + }, 'Transaction Error. Exception thrown in contract code.') + : null, + + !isValidAddress ? + h('.error', { + style: { + fontSize: '12px', + }, + }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH. ') + : null, + + insufficientBalance ? + h('.error', { + style: { + fontSize: '12px', + }, + }, 'Insufficient balance for transaction. ') + : null, + + (dangerousGasLimit && !gasLimitSpecified) ? + h('.error', { + style: { + fontSize: '12px', + }, + }, 'Gas limit set dangerously high. Approving this transaction is liable to fail. ') + : null, + ]) : null, + + // Ether Value + // Currently not customizable, but easily modified + // in the way that gas and gasLimit currently are. + h('.row', [ + h('.cell.label', 'Amount'), + h(EthBalance, { + valueStyle, + dimStyle, + value: isToken ? tokensToSend/* (new BN(tokensToSend)).mul(1e18)*/ : txParams.value, + currentCurrency, + conversionRate, + network, + isToken, + tokenSymbol: this.state.token.symbol, + showFiat: !isToken, + }), + ]), + + // Gas Limit (customizable) + h('.cell.row', [ + h('.cell.label', 'Gas Limit'), + h('.cell.value', { + }, [ + h(BNInput, { + id: 'gas_limit', + name: 'Gas Limit', + value: gasBn, + precision: 0, + scale: 0, + // The hard lower limit for gas. + min: MIN_GAS_LIMIT_BN, + max: safeGasLimit, + suffix: 'UNITS', + style: { + position: 'relative', + width: '91px', + }, + onChange: this.gasLimitChanged.bind(this), + + ref: (hexInput) => { this.inputs.push(hexInput) }, + }), + ]), + ]), + + // Gas Price (customizable) + h('.cell.row', [ + h('.cell.label', 'Gas Price'), + h('.cell.value', { + }, [ + h(BNInput, { + id: 'gas_price', + name: 'Gas Price', + value: gasPriceBn, + precision: 9, + scale: 9, + suffix: 'GWEI', + min: forceGasMin || MIN_GAS_PRICE_BN, + style: { + position: 'relative', + width: '91px', + }, + onChange: this.gasPriceChanged.bind(this), + ref: (hexInput) => { this.inputs.push(hexInput) }, + }), + ]), + ]), + + // Max Transaction Fee (calculated) + h('.cell.row', [ + h('.cell.label', 'Max Transaction Fee'), + h(EthBalance, { + valueStyle, + dimStyle, + value: txFeeBn.toString(16), + currentCurrency, + conversionRate, + network, + }), + ]), + + h('.cell.row', { + style: { + fontFamily: 'Nunito Regular', + }, + }, [ + h('.cell.label', 'Max Total'), + h('.cell.value', { + style: { + display: 'flex', + alignItems: 'center', + }, + }, [ + h(EthBalance, { + valueStyle, + dimStyle, + value: maxCost.toString(16), + currentCurrency, + conversionRate, + inline: true, + network, + labelColor: 'black', + fontSize: '16px', + }), + ]), + ]), + + // Data size row: + h('.cell.row', { + style: { + background: '#ffffff', + paddingBottom: '0px', + }, + }, [ + h('.cell.label'), + h('.cell.value', { + style: { + fontFamily: 'Nunito Regular', + fontSize: '14px', + }, + }, `Data included: ${dataLength} bytes`), + ]), + ]), // End of Table + + ]), + + h('style', ` + .conf-buttons button { + margin-left: 10px; + } + `), + + // send + cancel + h('.flex-row.flex-space-around.conf-buttons', { + style: { + display: 'flex', + justifyContent: 'flex-end', + margin: '14px 30px', + }, + }, [ + h('button.btn-violet', { + onClick: (event) => { + this.resetGasFields() + event.preventDefault() + }, + style: { + marginRight: 0, + }, + }, 'Reset'), + + // Accept Button or Buy Button + insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, `Buy ${this.state.coinName}`) : + h('input.confirm', { + type: 'submit', + value: 'Submit', + style: { marginLeft: '10px' }, + disabled: buyDisabled, + }), + + h('button.cancel.btn-red', { + onClick: props.cancelTransaction, + }, 'Reject'), + ]), + showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', { + style: { + display: 'flex', + justifyContent: 'flex-end', + margin: '14px 30px', + }, + }, [ + h('button.cancel.btn-red', { + onClick: props.cancelAllTransactions, + }, 'Reject All'), + ]) : null, + ]), + ]) + ) + } + + miniAccountPanelForRecipient (isToken, tokensTransferTo) { + const props = this.props + const txData = props.txData + const txParams = txData.txParams || {} + const isContractDeploy = !('to' in txParams) + const to = isToken ? tokensTransferTo : txParams.to + + // If it's not a contract deploy, send to the account + if (!isContractDeploy) { + return h(MiniAccountPanel, { + imageSeed: txParams.to, + picOrder: 'right', + }, [ + h('div', { + style: { + marginRight: '10px', + }, + }, [ + h('span.font-pre-medium', { + style: { + fontFamily: 'Nunito SemiBold', + color: '#ffffff', + display: 'inline-block', + whiteSpace: 'nowrap', + }, + }, accountSummary(nameForAddress(to, props.identities, props.network)), 6, 4), + + h(Copyable, { + value: toChecksumAddress(props.network, to), + }, [ + h('span.font-small', { + style: { + fontFamily: 'Nunito Regular', + color: 'rgba(255, 255, 255, 0.7)', + }, + }, addressSummary(props.network, to, 6, 4, false)), + ]), + ]), + ]) + } else { + return h(MiniAccountPanel, { + picOrder: 'right', + }, [ + + h('span.font-small', { + style: { + fontFamily: 'Nunito Bold', + color: '#ffffff', + }, + }, 'New Contract'), + + ]) + } + } + + componentWillMount () { + const txMeta = this.gatherTxMeta() + const txParams = txMeta.txParams || {} + if (this.props.isToken || this.state.isToken) { + return this.updateTokenInfo(txParams) + } + const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data) + if (decodedData && decodedData.name === 'transfer') { + return this.updateTokenInfo(txParams) + } + } + + componentWillUnmount () { + this.setState({ + token: { + address: emptyAddress, + symbol: '', + decimals: 0, + dataRetrieved: false, + }, + isToken: false, + }) + } + + updateTokenInfo = async function (txParams) { + const tokenParams = await this.tokenInfoGetter(txParams.to) + this.setState({ + token: { + address: txParams.to, + symbol: tokenParams.symbol, + decimals: tokenParams.decimals, + dataRetrieved: true, + }, + isToken: true, + }) + } + + gasPriceChanged (newBN, valid) { + log.info(`Gas price changed to: ${newBN.toString(10)}`) + const txMeta = this.gatherTxMeta() + txMeta.txParams.gasPrice = '0x' + newBN.toString('hex') + this.setState({ + txData: clone(txMeta), + valid, + }) + } + + gasLimitChanged (newBN, valid) { + log.info(`Gas limit changed to ${newBN.toString(10)}`) + const txMeta = this.gatherTxMeta() + txMeta.txParams.gas = '0x' + newBN.toString('hex') + this.setState({ + txData: clone(txMeta), + valid, + }) + } + + resetGasFields () { + log.debug(`pending-tx resetGasFields`) + + this.inputs.forEach((hexInput) => { + if (hexInput) { + hexInput.setValid() + } + }) + + this.setState({ + txData: null, + valid: true, + }) + } + + onSubmit (event) { + event.preventDefault() + const txMeta = this.gatherTxMeta() + const valid = this.checkValidity() + this.setState({ valid, submitting: true }) + if (valid && this.verifyGasParams()) { + this.props.sendTransaction(txMeta, event) + } else { + this.props.actions.displayWarning('Invalid Gas Parameters') + this.setState({ submitting: false }) + } + } + + checkValidity () { + const form = this.getFormEl() + const valid = form.checkValidity() + return valid + } + + getFormEl () { + const form = document.querySelector('form#pending-tx-form') + // Stub out form for unit tests: + if (!form) { + return { checkValidity () { return true } } + } + return form + } + +// After a customizable state value has been updated, + gatherTxMeta () { + log.debug(`pending-tx gatherTxMeta`) + const props = this.props + const state = this.state + const txData = clone(state.txData) || clone(props.txData) + + log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`) + return txData + } + + verifyGasParams () { + // We call this in case the gas has not been modified at all + if (!this.state) { return true } + return ( + this._notZeroOrEmptyString(this.state.gas) && + this._notZeroOrEmptyString(this.state.gasPrice) + ) + } + + _notZeroOrEmptyString (obj) { + return obj !== '' && obj !== '0x0' + } + + bnMultiplyByFraction (targetBN, numerator, denominator) { + const numBN = new BN(numerator) + const denomBN = new BN(denominator) + return targetBN.mul(numBN).div(denomBN) + } + + goHome (event) { + this.stopPropagation(event) + this.props.actions.goHome() + } + + stopPropagation (event) { + if (event.stopPropagation) { + event.stopPropagation() + } + } + +} + +function forwardCarrat () { + return ( + h('img', { + src: 'images/forward-carrat-light.svg', + style: { + padding: '0px 20px 0px', + height: '62px', + }, + }) + ) } function mapStateToProps (state) { @@ -68,669 +767,15 @@ function mapStateToProps (state) { } } -PendingTx.prototype.render = function () { - const state = this.state - if (this.props.isToken) { - if (!state.tokenDataRetrieved) return null - } - const props = this.props - const { currentCurrency, blockGasLimit, network, provider, isUnlocked } = props - - const conversionRate = props.conversionRate - const txMeta = this.gatherTxMeta() - const txParams = txMeta.txParams || {} - let { isToken, tokensToSend, tokensTransferTo } = props - let token = { - address: txParams.to, - } - - const decodedData = txParams.data && abiDecoder.decodeMethod(txParams.data) - if (decodedData && decodedData.name === 'transfer') { - isToken = true - const tokenValBN = new BigNumber(calcTokenAmount(decodedData.params[1].value, state.tokenDecimals)) - const multiplier = Math.pow(10, 18) - tokensToSend = tokenValBN.mul(multiplier).toString(16) - tokensTransferTo = decodedData.params[0].value - token = { - address: txParams.to, - decimals: state.tokenDecimals, - symbol: state.tokenSymbol, - } - } - - // Allow retry txs - const { lastGasPrice } = txMeta - let forceGasMin - if (lastGasPrice) { - const stripped = ethUtil.stripHexPrefix(lastGasPrice) - const lastGas = new BN(stripped, 16) - const priceBump = lastGas.divn('10') - forceGasMin = lastGas.add(priceBump) - } - - // Account Details - const address = txParams.from || props.selectedAddress - const identity = props.identities[address] || { address: address } - const account = props.accounts[address] - const balance = account ? account.balance : '0x0' - - // recipient check - const isValidAddress = !txParams.to || util.isValidAddress(txParams.to, network) - - // Gas - const gas = txParams.gas - const gasBn = hexToBn(gas) - // default to 8MM gas limit - const gasLimit = new BN(parseInt(blockGasLimit) || '8000000') - const safeGasLimitBN = this.bnMultiplyByFraction(gasLimit, 99, 100) - const saferGasLimitBN = this.bnMultiplyByFraction(gasLimit, 98, 100) - const safeGasLimit = safeGasLimitBN.toString(10) - - // Gas Price - const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_BN.toString(16) - const gasPriceBn = hexToBn(gasPrice) - - const txFeeBn = gasBn.mul(gasPriceBn) - const valueBn = hexToBn(txParams.value) - const maxCost = txFeeBn.add(valueBn) - - const dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0 - - const balanceBn = hexToBn(balance) - const insufficientBalance = balanceBn.lt(maxCost) - const dangerousGasLimit = gasBn.gte(saferGasLimitBN) - const gasLimitSpecified = txMeta.gasLimitSpecified - const buyDisabled = insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting - const showRejectAll = props.unconfTxListLength > 1 - - const isNotification = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_NOTIFICATION - - this.inputs = [] - - const valueStyle = { - fontFamily: 'Nunito Bold', - width: '100%', - textAlign: 'right', - fontSize: '14px', - color: '#333333', - } - - const dimStyle = { - color: '#333333', - marginLeft: '5px', - fontSize: '14px', - } - - const isError = txMeta.simulationFails || !isValidAddress || insufficientBalance || (dangerousGasLimit && !gasLimitSpecified) - - return ( - - h('div', { - key: txMeta.id, - }, [ - h(ToastComponent, { - isSuccess: false, - }), - - h('form#pending-tx-form', { - onSubmit: this.onSubmit.bind(this), - - }, [ - - // tx info - h('div', [ - - h('.flex-row.flex-center', { - style: { - maxWidth: '100%', - padding: showRejectAll ? '20px 20px 50px 20px' : '20px 20px 20px 20px', - background: 'linear-gradient(rgb(84, 36, 147), rgb(104, 45, 182))', - position: 'relative', - }, - }, [ - - h('div', { - style: { - position: 'absolute', - bottom: '20px', - width: '100%', - textAlign: 'center', - color: '#ffffff', - }, - }, [ - h('h3', { - style: { - alignSelf: 'center', - display: props.unconfTxListLength > 1 ? 'block' : 'none', - fontSize: '14px', - }, - }, [ - h('i.fa.white-arrow-left.fa-lg.cursor-pointer', { - style: { - display: props.index === 0 ? 'none' : 'inline-block', - }, - onClick: () => props.dispatch(actions.previousTx()), - }), - ` ${props.index + 1} of ${props.unconfTxListLength} `, - h('i.fa.white-arrow-right.fa-lg.cursor-pointer', { - style: { - display: props.index + 1 === props.unconfTxListLength ? 'none' : 'inline-block', - }, - onClick: () => props.dispatch(actions.nextTx()), - }), - ])], - ), - - h(MiniAccountPanel, { - imageSeed: address, - picOrder: 'left', - }, [ - h('div', { - style: { - marginLeft: '10px', - }, - }, [ - h('div.font-pre-medium', { - style: { - fontFamily: 'Nunito SemiBold', - color: '#ffffff', - whiteSpace: 'nowrap', - }, - }, accountSummary(identity.name, 6, 4)), - - h(Copyable, { - value: toChecksumAddress(network, address), - }, [ - h('span.font-small', { - style: { - fontFamily: 'Nunito Regular', - color: 'rgba(255, 255, 255, 0.7)', - }, - }, addressSummary(network, address, 6, 4, false)), - ]), - - h('span.font-small', { - style: { - fontFamily: 'Nunito Regular', - }, - }, [ - isToken ? h(TokenBalance, { - token, - fontSize: '12px', - }) : h(EthBalance, { - fontSize: '12px', - value: balance, - conversionRate, - currentCurrency, - network, - inline: true, - }), - ]), - ]), - ]), - - forwardCarrat(), - - this.miniAccountPanelForRecipient(isToken, tokensTransferTo), - ]), - - h('style', ` - .table-box { - margin: 7px 0px 0px 0px; - width: 100%; - position: relative; - } - .table-box .row { - margin: 0px; - background: #ffffff; - display: flex; - justify-content: space-between; - font-family: Nunito Regular; - font-size: 14px; - padding: 5px 30px; - } - .table-box .row .value { - font-family: Nunito Regular; - } - `), - - h('.table-box', [ - - h('.flex-row.flex-center', { - style: { - marginTop: '20px', - marginBottom: '30px', - }, - }, [ - !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { - onClick: this.goHome.bind(this), - style: { - position: 'absolute', - left: '30px', - }, - }) : null, - 'Confirm Transaction', - isNotification ? h(NetworkIndicator, { - network: network, - provider: provider, - isUnlocked: isUnlocked, - }) : null, - ]), - - isError ? h('div', { - style: { - textAlign: 'center', - position: 'absolute', - top: '25px', - background: 'rgba(255, 255, 255, 0.85)', - width: '100%', - paddingLeft: '30px', - paddingRight: '30px', - }, - }, [ - txMeta.simulationFails ? - h('.error', { - style: { - fontSize: '12px', - }, - }, 'Transaction Error. Exception thrown in contract code.') - : null, - - !isValidAddress ? - h('.error', { - style: { - fontSize: '12px', - }, - }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH. ') - : null, - - insufficientBalance ? - h('.error', { - style: { - fontSize: '12px', - }, - }, 'Insufficient balance for transaction. ') - : null, - - (dangerousGasLimit && !gasLimitSpecified) ? - h('.error', { - style: { - fontSize: '12px', - }, - }, 'Gas limit set dangerously high. Approving this transaction is liable to fail. ') - : null, - ]) : null, - - // Ether Value - // Currently not customizable, but easily modified - // in the way that gas and gasLimit currently are. - h('.row', [ - h('.cell.label', 'Amount'), - h(EthBalance, { - valueStyle, - dimStyle, - value: isToken ? tokensToSend/* (new BN(tokensToSend)).mul(1e18)*/ : txParams.value, - currentCurrency, - conversionRate, - network, - isToken, - tokenSymbol: this.state.tokenSymbol, - showFiat: !isToken, - }), - ]), - - // Gas Limit (customizable) - h('.cell.row', [ - h('.cell.label', 'Gas Limit'), - h('.cell.value', { - }, [ - h(BNInput, { - id: 'gas_limit', - name: 'Gas Limit', - value: gasBn, - precision: 0, - scale: 0, - // The hard lower limit for gas. - min: MIN_GAS_LIMIT_BN, - max: safeGasLimit, - suffix: 'UNITS', - style: { - position: 'relative', - width: '91px', - }, - onChange: this.gasLimitChanged.bind(this), - - ref: (hexInput) => { this.inputs.push(hexInput) }, - }), - ]), - ]), - - // Gas Price (customizable) - h('.cell.row', [ - h('.cell.label', 'Gas Price'), - h('.cell.value', { - }, [ - h(BNInput, { - id: 'gas_price', - name: 'Gas Price', - value: gasPriceBn, - precision: 9, - scale: 9, - suffix: 'GWEI', - min: forceGasMin || MIN_GAS_PRICE_BN, - style: { - position: 'relative', - width: '91px', - }, - onChange: this.gasPriceChanged.bind(this), - ref: (hexInput) => { this.inputs.push(hexInput) }, - }), - ]), - ]), - - // Max Transaction Fee (calculated) - h('.cell.row', [ - h('.cell.label', 'Max Transaction Fee'), - h(EthBalance, { - valueStyle, - dimStyle, - value: txFeeBn.toString(16), - currentCurrency, - conversionRate, - network, - }), - ]), - - h('.cell.row', { - style: { - fontFamily: 'Nunito Regular', - }, - }, [ - h('.cell.label', 'Max Total'), - h('.cell.value', { - style: { - display: 'flex', - alignItems: 'center', - }, - }, [ - h(EthBalance, { - valueStyle, - dimStyle, - value: maxCost.toString(16), - currentCurrency, - conversionRate, - inline: true, - network, - labelColor: 'black', - fontSize: '16px', - }), - ]), - ]), - - // Data size row: - h('.cell.row', { - style: { - background: '#ffffff', - paddingBottom: '0px', - }, - }, [ - h('.cell.label'), - h('.cell.value', { - style: { - fontFamily: 'Nunito Regular', - fontSize: '14px', - }, - }, `Data included: ${dataLength} bytes`), - ]), - ]), // End of Table - - ]), - - h('style', ` - .conf-buttons button { - margin-left: 10px; - } - `), - - // send + cancel - h('.flex-row.flex-space-around.conf-buttons', { - style: { - display: 'flex', - justifyContent: 'flex-end', - margin: '14px 30px', - }, - }, [ - h('button.btn-violet', { - onClick: (event) => { - this.resetGasFields() - event.preventDefault() - }, - style: { - marginRight: 0, - }, - }, 'Reset'), - - // Accept Button or Buy Button - insufficientBalance ? h('button.btn-green', { onClick: props.buyEth }, `Buy ${this.state.coinName}`) : - h('input.confirm', { - type: 'submit', - value: 'Submit', - style: { marginLeft: '10px' }, - disabled: buyDisabled, - }), - - h('button.cancel.btn-red', { - onClick: props.cancelTransaction, - }, 'Reject'), - ]), - showRejectAll ? h('.flex-row.flex-space-around.conf-buttons', { - style: { - display: 'flex', - justifyContent: 'flex-end', - margin: '14px 30px', - }, - }, [ - h('button.cancel.btn-red', { - onClick: props.cancelAllTransactions, - }, 'Reject All'), - ]) : null, - ]), - ]) - ) -} - -PendingTx.prototype.miniAccountPanelForRecipient = function (isToken, tokensTransferTo) { - const props = this.props - const txData = props.txData - const txParams = txData.txParams || {} - const isContractDeploy = !('to' in txParams) - const to = isToken ? tokensTransferTo : txParams.to - - // If it's not a contract deploy, send to the account - if (!isContractDeploy) { - return h(MiniAccountPanel, { - imageSeed: txParams.to, - picOrder: 'right', - }, [ - h('div', { - style: { - marginRight: '10px', - }, - }, [ - h('span.font-pre-medium', { - style: { - fontFamily: 'Nunito SemiBold', - color: '#ffffff', - display: 'inline-block', - whiteSpace: 'nowrap', - }, - }, accountSummary(nameForAddress(to, props.identities, props.network)), 6, 4), - - h(Copyable, { - value: toChecksumAddress(props.network, to), - }, [ - h('span.font-small', { - style: { - fontFamily: 'Nunito Regular', - color: 'rgba(255, 255, 255, 0.7)', - }, - }, addressSummary(props.network, to, 6, 4, false)), - ]), - ]), - ]) - } else { - return h(MiniAccountPanel, { - picOrder: 'right', - }, [ - - h('span.font-small', { - style: { - fontFamily: 'Nunito Bold', - color: '#ffffff', - }, - }, 'New Contract'), - - ]) +const mapDispatchToProps = (dispatch) => { + return { + actions: { + previousTx: () => dispatch(actions.previousTx()), + nextTx: () => dispatch(actions.nextTx()), + displayWarning: (msg) => dispatch(actions.displayWarning(msg)), + goHome: () => dispatch(actions.goHome()), + }, } } -PendingTx.prototype.componentWillMount = function () { - const txMeta = this.gatherTxMeta() - const txParams = txMeta.txParams || {} - if (this.props.isToken) { - this.updateTokenInfo(txParams) - } -} - -PendingTx.prototype.componentWillUnmount = function () { - this.setState({ - tokenSymbol: '', - tokenDecimals: 0, - tokenDataRetrieved: false, - }) -} - -PendingTx.prototype.updateTokenInfo = async function (txParams) { - const tokenParams = await this.tokenInfoGetter(txParams.to) - this.setState({ - tokenSymbol: tokenParams.symbol, - tokenDecimals: tokenParams.decimals, - tokenDataRetrieved: true, - }) -} - -PendingTx.prototype.gasPriceChanged = function (newBN, valid) { - log.info(`Gas price changed to: ${newBN.toString(10)}`) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gasPrice = '0x' + newBN.toString('hex') - this.setState({ - txData: clone(txMeta), - valid, - }) -} - -PendingTx.prototype.gasLimitChanged = function (newBN, valid) { - log.info(`Gas limit changed to ${newBN.toString(10)}`) - const txMeta = this.gatherTxMeta() - txMeta.txParams.gas = '0x' + newBN.toString('hex') - this.setState({ - txData: clone(txMeta), - valid, - }) -} - -PendingTx.prototype.resetGasFields = function () { - log.debug(`pending-tx resetGasFields`) - - this.inputs.forEach((hexInput) => { - if (hexInput) { - hexInput.setValid() - } - }) - - this.setState({ - txData: null, - valid: true, - }) -} - -PendingTx.prototype.onSubmit = function (event) { - event.preventDefault() - const txMeta = this.gatherTxMeta() - const valid = this.checkValidity() - this.setState({ valid, submitting: true }) - if (valid && this.verifyGasParams()) { - this.props.sendTransaction(txMeta, event) - } else { - this.props.dispatch(actions.displayWarning('Invalid Gas Parameters')) - this.setState({ submitting: false }) - } -} - -PendingTx.prototype.checkValidity = function () { - const form = this.getFormEl() - const valid = form.checkValidity() - return valid -} - -PendingTx.prototype.getFormEl = function () { - const form = document.querySelector('form#pending-tx-form') - // Stub out form for unit tests: - if (!form) { - return { checkValidity () { return true } } - } - return form -} - -// After a customizable state value has been updated, -PendingTx.prototype.gatherTxMeta = function () { - log.debug(`pending-tx gatherTxMeta`) - const props = this.props - const state = this.state - const txData = clone(state.txData) || clone(props.txData) - - log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`) - return txData -} - -PendingTx.prototype.verifyGasParams = function () { - // We call this in case the gas has not been modified at all - if (!this.state) { return true } - return ( - this._notZeroOrEmptyString(this.state.gas) && - this._notZeroOrEmptyString(this.state.gasPrice) - ) -} - -PendingTx.prototype._notZeroOrEmptyString = function (obj) { - return obj !== '' && obj !== '0x0' -} - -PendingTx.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) { - const numBN = new BN(numerator) - const denomBN = new BN(denominator) - return targetBN.mul(numBN).div(denomBN) -} - -PendingTx.prototype.goHome = function (event) { - this.stopPropagation(event) - this.props.dispatch(actions.goHome()) -} - -PendingTx.prototype.stopPropagation = function (event) { - if (event.stopPropagation) { - event.stopPropagation() - } -} - -function forwardCarrat () { - return ( - h('img', { - src: 'images/forward-carrat-light.svg', - style: { - padding: '0px 20px 0px', - height: '62px', - }, - }) - ) -} +module.exports = connect(mapStateToProps, mapDispatchToProps)(PendingTx) diff --git a/old-ui/app/components/token-balance.js b/old-ui/app/components/token-balance.js index 2534110f7..54ec1a609 100644 --- a/old-ui/app/components/token-balance.js +++ b/old-ui/app/components/token-balance.js @@ -1,10 +1,146 @@ const Component = require('react').Component const h = require('react-hyperscript') -const inherits = require('util').inherits -const TokenTracker = require('eth-token-watcher') -const connect = require('react-redux').connect +import PropTypes from 'prop-types' +import TokenTracker from 'eth-token-watcher' +import { connect } from 'react-redux' const selectors = require('../../../ui/app/selectors') -const log = require('loglevel') +import log from 'loglevel' + +class TokenBalance extends Component { + static propTypes = { + dimStyle: PropTypes.object, + valueStyle: PropTypes.object, + fontSize: PropTypes.string, + token: PropTypes.object, + userAddress: PropTypes.string, + } + + constructor () { + super() + this.state = { + string: '', + symbol: '', + isLoading: true, + error: null, + } + Component.call(this) + } + + render () { + const state = this.state + const props = this.props + const { string, isLoading } = state + + const valueStyle = props.valueStyle ? props.valueStyle : { + color: '#ffffff', + width: '100%', + fontSize: props.fontSize || '14px', + textAlign: 'right', + } + const dimStyle = props.dimStyle ? props.dimStyle : { + color: ' #60db97', + fontSize: props.fontSize || '14px', + marginLeft: '5px', + } + + return isLoading + ? h('div', '') + : h('.flex-row', { + style: { + alignItems: 'flex-end', + lineHeight: '20px', + textRendering: 'geometricPrecision', + }, + }, [ + h('div.hide-text-overflow.token-balance__amount', { + style: valueStyle, + }, string), + h('span.token-balance__symbol', { + style: dimStyle, + }, this.state.symbol), + ]) + } + + componentDidMount () { + this.createFreshTokenTracker() + } + + createFreshTokenTracker () { + if (this.tracker) { + // Clean up old trackers when refreshing: + this.tracker.stop() + this.tracker.removeListener('update', this.balanceUpdater) + this.tracker.removeListener('error', this.showError) + } + + if (!global.ethereumProvider) return + const { userAddress, token } = this.props + + this.tracker = new TokenTracker({ + userAddress, + provider: global.ethereumProvider, + tokens: [token], + pollingInterval: 8000, + }) + + + // Set up listener instances for cleaning up + this.balanceUpdater = this.updateBalance.bind(this) + this.showError = error => { + this.setState({ error, isLoading: false }) + } + this.tracker.on('update', this.balanceUpdater) + this.tracker.on('error', this.showError) + + this.tracker.updateBalances() + .then(() => { + this.updateBalance(this.tracker.serialize()) + }) + .catch((reason) => { + log.error(`Problem updating balances`, reason) + this.setState({ isLoading: false }) + }) + } + + componentDidUpdate (nextProps) { + const { + userAddress: oldAddress, + token: { address: oldTokenAddress }, + } = this.props + const { + userAddress: newAddress, + token: { address: newTokenAddress }, + } = nextProps + + if ((!oldAddress || !newAddress) && (!oldTokenAddress || !newTokenAddress)) return + if ((oldAddress === newAddress) && (oldTokenAddress === newTokenAddress)) return + + this.setState({ isLoading: true }) + this.createFreshTokenTracker() + } + + updateBalance (tokens = []) { + if (!this.tracker.running) { + return + } + + const [{ string, symbol }] = tokens + + this.setState({ + string, + symbol, + isLoading: false, + }) + } + + componentWillUnmount () { + if (!this.tracker) return + this.tracker.stop() + this.tracker.removeListener('update', this.balanceUpdater) + this.tracker.removeListener('error', this.showError) + } + +} function mapStateToProps (state) { return { @@ -13,131 +149,3 @@ function mapStateToProps (state) { } module.exports = connect(mapStateToProps)(TokenBalance) - - -inherits(TokenBalance, Component) -function TokenBalance () { - this.state = { - string: '', - symbol: '', - isLoading: true, - error: null, - } - Component.call(this) -} - -TokenBalance.prototype.render = function () { - const state = this.state - const props = this.props - const { symbol, string, isLoading } = state - const { balanceOnly } = this.props - - const valueStyle = props.valueStyle ? props.valueStyle : { - color: '#ffffff', - width: '100%', - fontSize: props.fontSize || '14px', - textAlign: 'right', - } - const dimStyle = props.dimStyle ? props.dimStyle : { - color: ' #60db97', - fontSize: props.fontSize || '14px', - marginLeft: '5px', - } - - return isLoading - ? h('div', '') - : h('.flex-row', { - style: { - alignItems: 'flex-end', - lineHeight: '20px', - textRendering: 'geometricPrecision', - }, - }, [ - h('div.hide-text-overflow.token-balance__amount', { - style: valueStyle, - }, string), - !balanceOnly && h('span.token-balance__symbol', { - style: dimStyle, - }, symbol), - ]) -} - -TokenBalance.prototype.componentDidMount = function () { - this.createFreshTokenTracker() -} - -TokenBalance.prototype.createFreshTokenTracker = function () { - if (this.tracker) { - // Clean up old trackers when refreshing: - this.tracker.stop() - this.tracker.removeListener('update', this.balanceUpdater) - this.tracker.removeListener('error', this.showError) - } - - if (!global.ethereumProvider) return - const { userAddress, token } = this.props - - this.tracker = new TokenTracker({ - userAddress, - provider: global.ethereumProvider, - tokens: [token], - pollingInterval: 8000, - }) - - - // Set up listener instances for cleaning up - this.balanceUpdater = this.updateBalance.bind(this) - this.showError = error => { - this.setState({ error, isLoading: false }) - } - this.tracker.on('update', this.balanceUpdater) - this.tracker.on('error', this.showError) - - this.tracker.updateBalances() - .then(() => { - this.updateBalance(this.tracker.serialize()) - }) - .catch((reason) => { - log.error(`Problem updating balances`, reason) - this.setState({ isLoading: false }) - }) -} - -TokenBalance.prototype.componentDidUpdate = function (nextProps) { - const { - userAddress: oldAddress, - token: { address: oldTokenAddress }, - } = this.props - const { - userAddress: newAddress, - token: { address: newTokenAddress }, - } = nextProps - - if ((!oldAddress || !newAddress) && (!oldTokenAddress || !newTokenAddress)) return - if ((oldAddress === newAddress) && (oldTokenAddress === newTokenAddress)) return - - this.setState({ isLoading: true }) - this.createFreshTokenTracker() -} - -TokenBalance.prototype.updateBalance = function (tokens = []) { - if (!this.tracker.running) { - return - } - - const [{ string, symbol }] = tokens - - this.setState({ - string, - symbol, - isLoading: false, - }) -} - -TokenBalance.prototype.componentWillUnmount = function () { - if (!this.tracker) return - this.tracker.stop() - this.tracker.removeListener('update', this.balanceUpdater) - this.tracker.removeListener('error', this.showError) -} - diff --git a/old-ui/app/components/token-cell.js b/old-ui/app/components/token-cell.js index aea569b9d..896a1c951 100644 --- a/old-ui/app/components/token-cell.js +++ b/old-ui/app/components/token-cell.js @@ -1,168 +1,170 @@ -const Component = require('react').Component -const h = require('react-hyperscript') -const inherits = require('util').inherits -const Identicon = require('./identicon') -const ethNetProps = require('eth-net-props') -const Dropdown = require('./dropdown').Dropdown -const DropdownMenuItem = require('./dropdown').DropdownMenuItem -const copyToClipboard = require('copy-to-clipboard') -const actions = require('../../../ui/app/actions') -const connect = require('react-redux').connect -const { MAINNET_CODE } = require('../../../app/scripts/controllers/network/enums') +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import Identicon from './identicon' +import ethNetProps from 'eth-net-props' +import { Dropdown, DropdownMenuItem } from './dropdown' +import copyToClipboard from 'copy-to-clipboard' +import { connect } from 'react-redux' import { countSignificantDecimals, toChecksumAddress } from '../util' +import actions from '../../../ui/app/actions' +const { MAINNET_CODE } = require('../../../app/scripts/controllers/network/enums') const tokenCellDropDownPrefix = 'token-cell_dropdown_' -inherits(TokenCell, Component) -function TokenCell () { - Component.call(this) - - this.state = { - optionsMenuActive: false, +class TokenCell extends Component { + static propTypes = { + address: PropTypes.string, + symbol: PropTypes.string, + string: PropTypes.string, + network: PropTypes.string, + ind: PropTypes.number, + showSendTokenPage: PropTypes.func, + isLastTokenCell: PropTypes.bool, + userAddress: PropTypes.string, + menuToTop: PropTypes.bool, + removeToken: PropTypes.func, } - this.optionsMenuToggleClassName = 'token-dropdown' -} -TokenCell.prototype.render = function () { - const { address, symbol, string, network, userAddress, isLastTokenCell, menuToTop, ind } = this.props - const { optionsMenuActive } = this.state + constructor () { + super() - const tokenBalanceRaw = Number.parseFloat(string) - const tokenBalance = tokenBalanceRaw.toFixed(countSignificantDecimals(tokenBalanceRaw, 2)) + this.state = { + optionsMenuActive: false, + } + this.optionsMenuToggleClassName = 'token-dropdown' + } - return ( - h(`li#token-cell_${ind}.token-cell`, { - style: { - cursor: Number(network) === MAINNET_CODE ? 'pointer' : 'default', - borderBottom: isLastTokenCell ? 'none' : '1px solid #e2e2e2', - padding: '20px 0', - margin: '0 30px', - }, - onClick: this.view.bind(this, address, userAddress, network), - }, [ + render () { + const { address, symbol, string, network, userAddress, isLastTokenCell, menuToTop, ind } = this.props + const { optionsMenuActive } = this.state - h(Identicon, { - diameter: 50, - address, - network, - }), + const tokenBalanceRaw = Number.parseFloat(string) + const tokenBalance = tokenBalanceRaw.toFixed(countSignificantDecimals(tokenBalanceRaw, 2)) - h('h3', { - style: { - fontFamily: 'Nunito Bold', - fontSize: '14px', - }, - }, `${tokenBalance || 0} ${symbol}`), + return ( +
  • + - h('span', { style: { flex: '1 0 auto' } }), +

    + {`${tokenBalance || 0} ${symbol}`} +

    - h(`div#${tokenCellDropDownPrefix}${ind}.address-dropdown.token-dropdown`, - { - style: { cursor: 'pointer' }, - onClick: (event) => { - event.stopPropagation() - this.setState({ - optionsMenuActive: !optionsMenuActive, - }) - }, - }, - this.renderTokenOptions(menuToTop, ind), - ), + - /* - h('button', { - onClick: this.send.bind(this, address), - }, 'SEND'), - */ +
    { + event.stopPropagation() + this.setState({ + optionsMenuActive: !optionsMenuActive, + }) + }} + > + {this.renderTokenOptions(menuToTop, ind)} +
    +
  • + ) + } - ]) - ) -} + renderTokenOptions (menuToTop, ind) { + const { address, symbol, string, network, userAddress, showSendTokenPage } = this.props + const { optionsMenuActive } = this.state -TokenCell.prototype.renderTokenOptions = function (menuToTop, ind) { - const { address, symbol, string, network, userAddress, showSendTokenPage } = this.props - const { optionsMenuActive } = this.state - - return h( - Dropdown, - { - style: { + return ( + { + }} + isOpen={optionsMenuActive} + onClickOutside={(event) => { const { classList, id: targetID } = event.target const isNotToggleCell = !classList.contains(this.optionsMenuToggleClassName) const isAnotherCell = targetID !== `${tokenCellDropDownPrefix}${ind}` if (optionsMenuActive && (isNotToggleCell || (!isNotToggleCell && isAnotherCell))) { this.setState({ optionsMenuActive: false }) } - }, - }, - [ - h( - DropdownMenuItem, - { - closeMenu: () => {}, - onClick: () => { - showSendTokenPage(address) - }, - }, - `Send`, - ), - h( - DropdownMenuItem, - { - closeMenu: () => {}, - onClick: () => { - const { network } = this.props - const url = ethNetProps.explorerLinks.getExplorerTokenLinkFor(address, userAddress, network) - global.platform.openWindow({ url }) - }, - }, - `View token on block explorer`, - ), - h( - DropdownMenuItem, - { - closeMenu: () => {}, - onClick: () => { - const checkSumAddress = address && toChecksumAddress(network, address) - copyToClipboard(checkSumAddress) - }, - }, - 'Copy address to clipboard', - ), - h( - DropdownMenuItem, - { - closeMenu: () => {}, - onClick: () => { - this.props.removeToken({ address, symbol, string, network, userAddress }) - }, - }, - 'Remove', - ), - ], - ) -} + }} + > + {}} + onClick={() => { + showSendTokenPage(address) + }} + > + Send + + {}} + onClick={() => { + const { network } = this.props + const url = ethNetProps.explorerLinks.getExplorerTokenLinkFor(address, userAddress, network) + global.platform.openWindow({ url }) + }} + > + View token on block explorer + + {}} + onClick={() => { + const checkSumAddress = address && toChecksumAddress(network, address) + copyToClipboard(checkSumAddress) + }} + > + Copy address to clipboard + + {}} + onClick={() => { + this.props.removeToken({ address, symbol, string, network, userAddress }) + }} + > + Remove + + + ) + } -TokenCell.prototype.send = function (address, event) { - event.preventDefault() - event.stopPropagation() - const url = tokenFactoryFor(address) - navigateTo(url) -} - -TokenCell.prototype.view = function (address, userAddress, network, event) { - const url = ethNetProps.explorerLinks.getExplorerTokenLinkFor(address, userAddress, network) - if (url) { + send (address, event) { + event.preventDefault() + event.stopPropagation() + const url = tokenFactoryFor(address) navigateTo(url) } + + view (address, userAddress, network, _event) { + const url = ethNetProps.explorerLinks.getExplorerTokenLinkFor(address, userAddress, network) + if (url) { + navigateTo(url) + } + } } function navigateTo (url) { diff --git a/test/unit/ui/app/components/token-cell.spec.js b/test/unit/ui/app/components/token-cell.spec.js deleted file mode 100644 index de03258d7..000000000 --- a/test/unit/ui/app/components/token-cell.spec.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react' -import assert from 'assert' -import thunk from 'redux-thunk' -import { Provider } from 'react-redux' -import configureMockStore from 'redux-mock-store' -import { mount } from 'enzyme' - -import TokenCell from '../../../../../ui/app/components/token-cell' -import Identicon from '../../../../../ui/app/components/identicon' - -describe('Token Cell', () => { - let wrapper - - const state = { - metamask: { - network: 'test', - currentCurrency: 'usd', - selectedTokenAddress: '0xToken', - selectedAddress: '0xAddress', - contractExchangeRates: { - '0xAnotherToken': 0.015, - }, - conversionRate: 7.00, - }, - appState: { - sidebar: { - isOpen: true, - }, - }, - } - - const middlewares = [thunk] - const mockStore = configureMockStore(middlewares) - const store = mockStore(state) - - beforeEach(() => { - wrapper = mount( - - - , - ) - }) - - it('renders Identicon with props from token cell', () => { - assert.equal(wrapper.find(Identicon).prop('address'), '0xAnotherToken') - assert.equal(wrapper.find(Identicon).prop('network'), 'test') - assert.equal(wrapper.find(Identicon).prop('image'), './test-image') - }) - - it('renders token balance', () => { - assert.equal(wrapper.find('.token-list-item__token-balance').text(), '5.000') - }) - - it('renders token symbol', () => { - assert.equal(wrapper.find('.token-list-item__token-symbol').text(), 'TEST') - }) - - it('renders converted fiat amount', () => { - assert.equal(wrapper.find('.token-list-item__fiat-amount').text(), '0.52 USD') - }) - -}) diff --git a/ui/app/components/token-cell.js b/ui/app/components/token-cell.js deleted file mode 100644 index 70a24b59e..000000000 --- a/ui/app/components/token-cell.js +++ /dev/null @@ -1,160 +0,0 @@ -const Component = require('react').Component -const h = require('react-hyperscript') -const inherits = require('util').inherits -const connect = require('react-redux').connect -const Identicon = require('./identicon') -const ethNetProps = require('eth-net-props') -const selectors = require('../selectors') -const actions = require('../actions') -const { conversionUtil, multiplyCurrencies } = require('../conversion-util') - -const TokenMenuDropdown = require('./dropdowns/token-menu-dropdown.js') - -function mapStateToProps (state) { - return { - network: state.metamask.network, - currentCurrency: state.metamask.currentCurrency, - selectedTokenAddress: state.metamask.selectedTokenAddress, - userAddress: selectors.getSelectedAddress(state), - contractExchangeRates: state.metamask.contractExchangeRates, - conversionRate: state.metamask.conversionRate, - sidebarOpen: state.appState.sidebar.isOpen, - } -} - -function mapDispatchToProps (dispatch) { - return { - setSelectedToken: address => dispatch(actions.setSelectedToken(address)), - hideSidebar: () => dispatch(actions.hideSidebar()), - } -} - -module.exports = connect(mapStateToProps, mapDispatchToProps)(TokenCell) - -inherits(TokenCell, Component) -function TokenCell () { - Component.call(this) - - this.state = { - tokenMenuOpen: false, - } -} - -TokenCell.prototype.render = function () { - const { tokenMenuOpen } = this.state - const props = this.props - const { - address, - symbol, - string, - network, - setSelectedToken, - selectedTokenAddress, - contractExchangeRates, - conversionRate, - hideSidebar, - sidebarOpen, - currentCurrency, - // userAddress, - image, - } = props - let currentTokenToFiatRate - let currentTokenInFiat - let formattedFiat = '' - - if (contractExchangeRates[address]) { - currentTokenToFiatRate = multiplyCurrencies( - contractExchangeRates[address], - conversionRate, - ) - currentTokenInFiat = conversionUtil(string, { - fromNumericBase: 'dec', - fromCurrency: symbol, - toCurrency: currentCurrency.toUpperCase(), - numberOfDecimals: 2, - conversionRate: currentTokenToFiatRate, - }) - formattedFiat = currentTokenInFiat.toString() === '0' - ? '' - : `${currentTokenInFiat} ${currentCurrency.toUpperCase()}` - } - - const showFiat = Boolean(currentTokenInFiat) && currentCurrency.toUpperCase() !== symbol - - return ( - h('div.token-list-item', { - className: `token-list-item ${selectedTokenAddress === address ? 'token-list-item--active' : ''}`, - // style: { cursor: network === '1' ? 'pointer' : 'default' }, - // onClick: this.view.bind(this, address, userAddress, network), - onClick: () => { - setSelectedToken(address) - selectedTokenAddress !== address && sidebarOpen && hideSidebar() - }, - }, [ - - h(Identicon, { - className: 'token-list-item__identicon', - diameter: 50, - address, - network, - image, - }), - - h('div.token-list-item__balance-ellipsis', null, [ - h('div.token-list-item__balance-wrapper', null, [ - h('div.token-list-item__token-balance', `${string || 0}`), - h('div.token-list-item__token-symbol', symbol), - showFiat && h('div.token-list-item__fiat-amount', { - style: {}, - }, formattedFiat), - ]), - - h('i.fa.fa-ellipsis-h.fa-lg.token-list-item__ellipsis.cursor-pointer', { - onClick: (e) => { - e.stopPropagation() - this.setState({ tokenMenuOpen: true }) - }, - }), - - ]), - - - tokenMenuOpen && h(TokenMenuDropdown, { - onClose: () => this.setState({ tokenMenuOpen: false }), - token: { symbol, address }, - }), - - /* - h('button', { - onClick: this.send.bind(this, address), - }, 'SEND'), - */ - - ]) - ) -} - -TokenCell.prototype.send = function (address, event) { - event.preventDefault() - event.stopPropagation() - const url = tokenFactoryFor(address) - if (url) { - navigateTo(url) - } -} - -TokenCell.prototype.view = function (address, userAddress, network, event) { - const url = ethNetProps.explorerLinks.getExplorerTokenLinkFor(address, userAddress, network) - if (url) { - navigateTo(url) - } -} - -function navigateTo (url) { - global.platform.openWindow({ url }) -} - -function tokenFactoryFor (tokenAddress) { - return `https://tokenfactory.surge.sh/#/token/${tokenAddress}` -} - From 1561400fd9e863f644c9f633f511f4f1defbf0cd Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 22 Apr 2020 15:43:02 +0300 Subject: [PATCH 02/20] Return back import contract tests --- CHANGELOG.md | 3 + old-ui/app/components/dropdown.js | 9 +- old-ui/app/components/token-cell.js | 4 +- old-ui/app/components/token-list.js | 6 +- test/e2e/elements.js | 2 + test/e2e/nw.spec.js | 10 +- .../delete-imported-account.spec.js | 2 +- .../import-contract-account.spec.js | 178 +++++++++--------- 8 files changed, 109 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4683c81f4..dc93d1189 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Current Master +- [#361](https://github.com/poanetwork/nifty-wallet/pull/361) - (Fix) token decimals display in pending tx screen +- [#356](https://github.com/poanetwork/nifty-wallet/pull/356) - (Backwards-compatibility feature) Custom derivation paths and access to funds in accounts derived from ETH dPath + ## 5.0.2 Thu Apr 16 2020 - [#359](https://github.com/poanetwork/nifty-wallet/pull/359) - (Fix) Fix exposed accounts in wallet locked state diff --git a/old-ui/app/components/dropdown.js b/old-ui/app/components/dropdown.js index bc9771307..99710ba31 100644 --- a/old-ui/app/components/dropdown.js +++ b/old-ui/app/components/dropdown.js @@ -60,8 +60,8 @@ class Dropdown extends Component { > {children} @@ -94,17 +94,16 @@ class DropdownMenuItem extends Component { }, this.props.style) return ( -
    { onClick() closeMenu() }} - key={`dropdown-menu-item_${Math.random()}`} style={style} > {children} -
    + ) } diff --git a/old-ui/app/components/token-cell.js b/old-ui/app/components/token-cell.js index 896a1c951..251c12246 100644 --- a/old-ui/app/components/token-cell.js +++ b/old-ui/app/components/token-cell.js @@ -42,7 +42,7 @@ class TokenCell extends Component { const tokenBalance = tokenBalanceRaw.toFixed(countSignificantDecimals(tokenBalanceRaw, 2)) return ( -
  • {this.renderTokenOptions(menuToTop, ind)} -
  • + ) } diff --git a/old-ui/app/components/token-list.js b/old-ui/app/components/token-list.js index eebd5c132..95550b545 100644 --- a/old-ui/app/components/token-list.js +++ b/old-ui/app/components/token-list.js @@ -120,7 +120,7 @@ TokenList.prototype.render = function () { }, [ h('style', ` - li.token-cell { + span.token-cell { display: flex; flex-direction: row; align-items: center; @@ -128,11 +128,11 @@ TokenList.prototype.render = function () { min-height: 50px; } - li.token-cell > h3 { + span.token-cell > h3 { margin-left: 12px; } - li.token-cell:hover { + span.token-cell:hover { background: white; cursor: pointer; } diff --git a/test/e2e/elements.js b/test/e2e/elements.js index 8f0e97f8b..cd27c895a 100644 --- a/test/e2e/elements.js +++ b/test/e2e/elements.js @@ -244,6 +244,7 @@ module.exports = { titleText: 'Delete Imported Account', buttons: { no: By.css('#app-content > div > div.app-primary.from-left > div > div.flex-row.flex-right > button.btn-violet'), + no2: By.css('#app-content > div > div.app-primary.from-right > div > div.flex-row.flex-right > button.btn-violet'), yes: By.css('#app-content > div > div.app-primary.from-right > div > div.flex-row.flex-right > button:nth-child(2)'), arrow: By.className('fa fa-arrow-left fa-lg cursor-pointer'), }, @@ -255,6 +256,7 @@ module.exports = { selectArrow: By.className('Select-arrow-zone'), selectType: By.name('import-type-select'), itemContract: By.id('react-select-4--option-2'), + itemContract1: By.id('react-select-3--option-2'), // itemContract2: By.id('react-select-3--option-2'), itemProxyContract: By.id('react-select-3--option-3'), // itemProxyContract2: By.id('react-select-2--option-3'), diff --git a/test/e2e/nw.spec.js b/test/e2e/nw.spec.js index 09f024064..71f1c15ee 100644 --- a/test/e2e/nw.spec.js +++ b/test/e2e/nw.spec.js @@ -8,10 +8,10 @@ const account2 = '0xd7b7AFeCa35e32594e29504771aC847E2a803742' const testsFolder = './test-cases' const setup = require(`${testsFolder}/setup.spec`) const login = require(`${testsFolder}/login.spec`) -const { accountCreation } = require(`${testsFolder}/account-creation.spec`) +const { accountCreation, getCreatedAccounts } = require(`${testsFolder}/account-creation.spec`) const connectHDWallet = require(`${testsFolder}/connect-hd-wallet.spec`) const importAccount = require(`${testsFolder}/import-account.spec`) -// const importContractAccount = require(`${testsFolder}/import-contract-account.spec`) +const importContractAccount = require(`${testsFolder}/import-contract-account.spec`) const deleteImportedAccount = require(`${testsFolder}/delete-imported-account.spec`) const signData = require(`${testsFolder}/sign-data.spec`) const exportPrivateKey = require(`${testsFolder}/export-private-key.spec`) @@ -100,9 +100,9 @@ describe('Metamask popup page', async function () { await importAccount(f) }) - // describe('Import Contract account', async () => { - // await importContractAccount(f, account1, getCreatedAccounts) - // }) + describe('Import Contract account', async () => { + await importContractAccount(f, account1, getCreatedAccounts) + }) describe('Delete Imported Account', async () => { await deleteImportedAccount(f) diff --git a/test/e2e/test-cases/delete-imported-account.spec.js b/test/e2e/test-cases/delete-imported-account.spec.js index bf32aa997..389a1e4ef 100644 --- a/test/e2e/test-cases/delete-imported-account.spec.js +++ b/test/e2e/test-cases/delete-imported-account.spec.js @@ -15,7 +15,7 @@ const deleteImportedAccount = async (f) => { }) it("Can't remove imported account with 'No' button", async function () { - const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.no) + const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.no2) assert.equal(await button.getText(), 'No', 'button has incorrect name') await f.click(button) await f.driver.findElements(main.container) diff --git a/test/e2e/test-cases/import-contract-account.spec.js b/test/e2e/test-cases/import-contract-account.spec.js index 5f909cb5d..83e854cf9 100644 --- a/test/e2e/test-cases/import-contract-account.spec.js +++ b/test/e2e/test-cases/import-contract-account.spec.js @@ -5,105 +5,105 @@ const { main } = screens let abiClipboard const importContractAccount = async (f, account1, getCreatedAccounts) => { - describe('Proxy contract', async () => { - const proxyContract = '0x0518ac3db78eb326f42dbcfb4b2978e8059989a5' - const proxyABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}] // eslint-disable-line no-unused-vars - const joinedABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}, {'constant': true, 'inputs': [], 'name': 'desc', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'methodFromImplementation', 'outputs': [{'name': 'yep', 'type': 'bool'}], 'payable': false, 'stateMutability': 'pure', 'type': 'function'}] + // describe('Proxy contract', async () => { + // const proxyContract = '0x0518ac3db78eb326f42dbcfb4b2978e8059989a5' + // const proxyABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}] // eslint-disable-line no-unused-vars + // const joinedABI = [{'constant': true, 'inputs': [], 'name': 'proxyOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'version', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}], 'name': 'upgradeTo', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'implementation', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'upgradeabilityOwner', 'outputs': [{'name': '', 'type': 'address'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'version', 'type': 'string'}, {'name': 'implementation', 'type': 'address'}, {'name': 'data', 'type': 'bytes'}], 'name': 'upgradeToAndCall', 'outputs': [], 'payable': true, 'stateMutability': 'payable', 'type': 'function'}, {'constant': false, 'inputs': [{'name': 'newOwner', 'type': 'address'}], 'name': 'transferProxyOwnership', 'outputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'function'}, {'inputs': [], 'payable': false, 'stateMutability': 'nonpayable', 'type': 'constructor'}, {'payable': true, 'stateMutability': 'payable', 'type': 'fallback'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'previousOwner', 'type': 'address'}, {'indexed': false, 'name': 'newOwner', 'type': 'address'}], 'name': 'ProxyOwnershipTransferred', 'type': 'event'}, {'anonymous': false, 'inputs': [{'indexed': false, 'name': 'version', 'type': 'string'}, {'indexed': true, 'name': 'implementation', 'type': 'address'}], 'name': 'Upgraded', 'type': 'event'}, {'constant': true, 'inputs': [], 'name': 'desc', 'outputs': [{'name': '', 'type': 'string'}], 'payable': false, 'stateMutability': 'view', 'type': 'function'}, {'constant': true, 'inputs': [], 'name': 'methodFromImplementation', 'outputs': [{'name': 'yep', 'type': 'bool'}], 'payable': false, 'stateMutability': 'pure', 'type': 'function'}] - describe('imports ABI of proxy and implementation together', async () => { - it('opens import account menu', async () => { - await f.setProvider(NETWORKS.SOKOL) - const menu = await f.waitUntilShowUp(menus.account.menu) - await menu.click() - const item = await f.waitUntilShowUp(menus.account.import2) - await item.click() - const importAccountTitle = await f.waitUntilShowUp(screens.importAccounts.title) - assert.equal(await importAccountTitle.getText(), screens.importAccounts.textTitle) - }) + // describe('imports ABI of proxy and implementation together', async () => { + // it('opens import account menu', async () => { + // await f.setProvider(NETWORKS.SOKOL) + // const menu = await f.waitUntilShowUp(menus.account.menu) + // await menu.click() + // const item = await f.waitUntilShowUp(menus.account.import2) + // await item.click() + // const importAccountTitle = await f.waitUntilShowUp(screens.importAccounts.title) + // assert.equal(await importAccountTitle.getText(), screens.importAccounts.textTitle) + // }) - it("Select type 'Proxy'", async () => { - await f.delay(1000) - const field = await f.waitUntilShowUp(screens.importAccounts.selectArrow) - await field.click() - await f.delay(1000) - const item = await f.waitUntilShowUp(screens.importAccounts.itemProxyContract) - await item.click() - }) + // it("Select type 'Proxy'", async () => { + // await f.delay(1000) + // const field = await f.waitUntilShowUp(screens.importAccounts.selectArrow) + // await field.click() + // await f.delay(1000) + // const item = await f.waitUntilShowUp(screens.importAccounts.itemProxyContract) + // await item.click() + // }) - it("Fill 'Address' with valid proxy contract , SOKOL", async () => { - const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress) - await f.clearField(field, 100) - await field.sendKeys(proxyContract) - }) + // it("Fill 'Address' with valid proxy contract , SOKOL", async () => { + // const field = await f.waitUntilShowUp(screens.importAccounts.contractAddress) + // await f.clearField(field, 100) + // await field.sendKeys(proxyContract) + // }) - it('ABI of Proxy + Implementation is fetched and matches the pattern', async () => { - await f.delay(10000) - const field = await f.waitUntilShowUp(screens.importAccounts.contractABI) - abiClipboard = await field.getText() - assert.deepEqual(JSON.parse(abiClipboard), joinedABI, "ABI isn't fetched") - }) + // it('ABI of Proxy + Implementation is fetched and matches the pattern', async () => { + // await f.delay(10000) + // const field = await f.waitUntilShowUp(screens.importAccounts.contractABI) + // abiClipboard = await field.getText() + // assert.deepEqual(JSON.parse(abiClipboard), joinedABI, "ABI isn't fetched") + // }) - it("Click button 'Import', main screen opens", async () => { - const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport) - await f.click(button) - await f.delay(7000) - const ident = await f.waitUntilShowUp(screens.main.identicon, 20) - assert.notEqual(ident, false, "main screen isn't opened") - }) - }) + // it("Click button 'Import', main screen opens", async () => { + // const button = await f.waitUntilShowUp(screens.importAccounts.buttonImport) + // await f.click(button) + // await f.delay(7000) + // const ident = await f.waitUntilShowUp(screens.main.identicon, 20) + // assert.notEqual(ident, false, "main screen isn't opened") + // }) + // }) - describe("Check 3dots menu for 'Proxy' account", () => { + // describe("Check 3dots menu for 'Proxy' account", () => { - it('open 3dots menu', async () => { - const menu = await f.waitUntilShowUp(menus.dot.menu) - await menu.click() - await f.waitUntilShowUp(menus.dot.item) - const items = await f.driver.findElements(menus.dot.item) - assert.equal(items.length, 5, '3dot menu has incorrect number of items') - }) + // it('open 3dots menu', async () => { + // const menu = await f.waitUntilShowUp(menus.dot.menu) + // await menu.click() + // await f.waitUntilShowUp(menus.dot.item) + // const items = await f.driver.findElements(menus.dot.item) + // assert.equal(items.length, 5, '3dot menu has incorrect number of items') + // }) - it('Check text of items', async () => { - const items = await f.driver.findElements(menus.dot.item) - assert.equal(await items[0].getText(), 'View on block explorer', '1st item has incorrect text') - assert.equal(await items[1].getText(), 'Show QR Code', '2nd item has incorrect text') - assert.equal(await items[2].getText(), 'Copy address to clipboard', '3d item has incorrect text') - assert.equal(await items[3].getText(), 'Copy ABI to clipboard', '4th item has incorrect text') - assert.equal(await items[4].getText(), 'Update implementation ABI', '5th item has incorrect text') - }) + // it('Check text of items', async () => { + // const items = await f.driver.findElements(menus.dot.item) + // assert.equal(await items[0].getText(), 'View on block explorer', '1st item has incorrect text') + // assert.equal(await items[1].getText(), 'Show QR Code', '2nd item has incorrect text') + // assert.equal(await items[2].getText(), 'Copy address to clipboard', '3d item has incorrect text') + // assert.equal(await items[3].getText(), 'Copy ABI to clipboard', '4th item has incorrect text') + // assert.equal(await items[4].getText(), 'Update implementation ABI', '5th item has incorrect text') + // }) - it("Click 'Update implementation ABI'", async () => { - const items = await f.driver.findElements(menus.dot.item) - await items[4].click() - const menu = await f.waitUntilShowUp(menus.dot.item, 20) - assert.equal(menu, false, "3dot menu wasn't closed") - }) - }) + // it("Click 'Update implementation ABI'", async () => { + // const items = await f.driver.findElements(menus.dot.item) + // await items[4].click() + // const menu = await f.waitUntilShowUp(menus.dot.item, 20) + // assert.equal(menu, false, "3dot menu wasn't closed") + // }) + // }) - const accountPosition = 1 + // const accountPosition = 1 - describe("Remove imported 'Proxy' account", async () => { - it("Label 'PROXY' present", async () => { - const menu = await f.waitUntilShowUp(menus.account.menu) - await menu.click() - await f.delay(2000) - await f.waitUntilShowUp(menus.account.label) - const labels = await f.driver.findElements(menus.account.label) - const label = labels[accountPosition] - const text1 = await label.getText() - console.log(text1) - assert.equal(text1, 'PROXY', 'label incorrect') - }) - it('Delete imported account', async () => { - const deleteButton = await f.waitUntilShowUp(menus.account.delete) - await deleteButton.click() - const yesButton = await f.waitUntilShowUp(screens.deleteImportedAccount.buttons.yes) - await yesButton.click() - await f.driver.findElements(main.container) - const identicon = await f.waitUntilShowUp(screens.main.identicon) - assert.notEqual(identicon, false, 'main screen didn\'t opened') - }) - }) - }) + // describe("Remove imported 'Proxy' account", async () => { + // it("Label 'PROXY' present", async () => { + // const menu = await f.waitUntilShowUp(menus.account.menu) + // await menu.click() + // await f.delay(2000) + // await f.waitUntilShowUp(menus.account.label) + // const labels = await f.driver.findElements(menus.account.label) + // const label = labels[accountPosition] + // const text1 = await label.getText() + // console.log(text1) + // assert.equal(text1, 'PROXY', 'label incorrect') + // }) + // it('Delete imported account', async () => { + // const deleteButton = await f.waitUntilShowUp(menus.account.delete) + // await deleteButton.click() + // const yesButton = await f.waitUntilShowUp(screens.deleteImportedAccount.buttons.yes) + // await yesButton.click() + // await f.driver.findElements(main.container) + // const identicon = await f.waitUntilShowUp(screens.main.identicon) + // assert.notEqual(identicon, false, 'main screen didn\'t opened') + // }) + // }) + // }) describe('Simple contract', async () => { const contractSokol = '0x215b2ab35749e5a9f3efe890de602fb9844e842f' @@ -127,7 +127,7 @@ const importContractAccount = async (f, account1, getCreatedAccounts) => { const field = await f.waitUntilShowUp(screens.importAccounts.selectArrow) await field.click() await f.delay(2000) - const item = await f.waitUntilShowUp(screens.importAccounts.itemContract) + const item = await f.waitUntilShowUp(screens.importAccounts.itemContract1) await item.click() }) From 3d12d82644d9bf75b8a3165afcab8d702490f050 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 22 Apr 2020 15:58:47 +0300 Subject: [PATCH 03/20] Return back search tokens tests --- test/e2e/nw.spec.js | 8 ++++---- test/e2e/test-cases/add-token-search.spec.js | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/test/e2e/nw.spec.js b/test/e2e/nw.spec.js index 71f1c15ee..b776415c9 100644 --- a/test/e2e/nw.spec.js +++ b/test/e2e/nw.spec.js @@ -20,7 +20,7 @@ const RSKNetworkTests = require(`${testsFolder}/RSK-network-tests.js`) const checkEmittedEvents = require(`${testsFolder}/check-emitted-events.spec`) // const addCustomToken = require(`${testsFolder}/add-token-custom.spec`) const changePassword = require(`${testsFolder}/change-password.spec`) -// const addTokenFromSearch = require(`${testsFolder}/add-token-search.spec`) +const addTokenFromSearch = require(`${testsFolder}/add-token-search.spec`) const customRPC = require(`${testsFolder}/custom-rpc.spec`) const { buildWebDriver } = require(`./webdriver`) @@ -138,9 +138,9 @@ describe('Metamask popup page', async function () { }) // todo - // describe('Add Token:Search', async () => { - // await addTokenFromSearch(f) - // }) + describe('Add Token:Search', async () => { + await addTokenFromSearch(f) + }) describe('Custom RPC', async () => { await customRPC(f) diff --git a/test/e2e/test-cases/add-token-search.spec.js b/test/e2e/test-cases/add-token-search.spec.js index fc0c31c45..cb12dadcb 100644 --- a/test/e2e/test-cases/add-token-search.spec.js +++ b/test/e2e/test-cases/add-token-search.spec.js @@ -254,15 +254,15 @@ const addTokeFromSearch = async (f) => { assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed') }) - it('token should not be displayed in RSK', async () => { - await f.setProvider(NETWORKS.RSK) - assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed') - }) + // it('token should not be displayed in RSK', async () => { + // await f.setProvider(NETWORKS.RSK) + // assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed') + // }) - it('token should not be displayed in RSK testnet', async () => { - await f.setProvider(NETWORKS.RSK_TESTNET) - assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed') - }) + // it('token should not be displayed in RSK testnet', async () => { + // await f.setProvider(NETWORKS.RSK_TESTNET) + // assert.equal(await f.assertTokensNotDisplayed(), true, 'tokens are displayed') + // }) }) describe('remove Mainnet\'s tokens', function () { From e0f9a490a968fd70186113a4c13d602b69614a95 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 23 Apr 2020 15:55:22 +0300 Subject: [PATCH 04/20] Disable temp import contract tests --- test/e2e/nw.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/e2e/nw.spec.js b/test/e2e/nw.spec.js index b776415c9..6fe5afa9b 100644 --- a/test/e2e/nw.spec.js +++ b/test/e2e/nw.spec.js @@ -8,10 +8,10 @@ const account2 = '0xd7b7AFeCa35e32594e29504771aC847E2a803742' const testsFolder = './test-cases' const setup = require(`${testsFolder}/setup.spec`) const login = require(`${testsFolder}/login.spec`) -const { accountCreation, getCreatedAccounts } = require(`${testsFolder}/account-creation.spec`) +const { accountCreation } = require(`${testsFolder}/account-creation.spec`) const connectHDWallet = require(`${testsFolder}/connect-hd-wallet.spec`) const importAccount = require(`${testsFolder}/import-account.spec`) -const importContractAccount = require(`${testsFolder}/import-contract-account.spec`) +// const importContractAccount = require(`${testsFolder}/import-contract-account.spec`) const deleteImportedAccount = require(`${testsFolder}/delete-imported-account.spec`) const signData = require(`${testsFolder}/sign-data.spec`) const exportPrivateKey = require(`${testsFolder}/export-private-key.spec`) @@ -100,9 +100,9 @@ describe('Metamask popup page', async function () { await importAccount(f) }) - describe('Import Contract account', async () => { - await importContractAccount(f, account1, getCreatedAccounts) - }) + // describe('Import Contract account', async () => { + // await importContractAccount(f, account1, getCreatedAccounts) + // }) describe('Delete Imported Account', async () => { await deleteImportedAccount(f) From ef65a72d9664861dede7744dab87a01fed6d7498 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 23 Apr 2020 16:23:24 +0300 Subject: [PATCH 05/20] Fix test --- test/e2e/test-cases/delete-imported-account.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/test-cases/delete-imported-account.spec.js b/test/e2e/test-cases/delete-imported-account.spec.js index 389a1e4ef..bf32aa997 100644 --- a/test/e2e/test-cases/delete-imported-account.spec.js +++ b/test/e2e/test-cases/delete-imported-account.spec.js @@ -15,7 +15,7 @@ const deleteImportedAccount = async (f) => { }) it("Can't remove imported account with 'No' button", async function () { - const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.no2) + const button = await f.waitUntilShowUp(deleteImportedAccountScr.buttons.no) assert.equal(await button.getText(), 'No', 'button has incorrect name') await f.click(button) await f.driver.findElements(main.container) From f31f0f5e40237628fcc2101540d3ec0e04ec899f Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 23 Apr 2020 16:25:13 +0300 Subject: [PATCH 06/20] CHANGEGLOG entry --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc93d1189..f6c68aae7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,7 @@ ## Current Master -- [#361](https://github.com/poanetwork/nifty-wallet/pull/361) - (Fix) token decimals display in pending tx screen -- [#356](https://github.com/poanetwork/nifty-wallet/pull/356) - (Backwards-compatibility feature) Custom derivation paths and access to funds in accounts derived from ETH dPath +- [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen ## 5.0.2 Thu Apr 16 2020 From ed841f71965771b07f85db11436ed05d7adbbcc1 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 11:09:38 +0300 Subject: [PATCH 07/20] Increase max token symbol length up to 12 --- CHANGELOG.md | 1 + old-ui/app/components/add-token/add-token.component.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c68aae7..a34d48bc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- [#366](https://github.com/poanetwork/nifty-wallet/pull/366) - (Fix) Increase max token symbol length up to 12 - [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen ## 5.0.2 Thu Apr 16 2020 diff --git a/old-ui/app/components/add-token/add-token.component.js b/old-ui/app/components/add-token/add-token.component.js index 546fca16a..9845960ee 100644 --- a/old-ui/app/components/add-token/add-token.component.js +++ b/old-ui/app/components/add-token/add-token.component.js @@ -368,9 +368,9 @@ export default class AddTokenScreen extends Component { } const symbolLen = symbol.trim().length - const validSymbol = symbolLen > 0 && symbolLen < 10 + const validSymbol = symbolLen > 0 && symbolLen < 12 if (!validSymbol) { - msg += 'Symbol must be between 0 and 10 characters.' + msg += 'Symbol must be between 0 and 12 characters.' } let ownAddress = identitiesList.includes(standardAddress) @@ -527,8 +527,8 @@ export default class AddTokenScreen extends Component { const symbolLength = customSymbol.length let customSymbolError = null - if (symbolLength <= 0 || symbolLength >= 10) { - customSymbolError = 'Symbol must be between 0 and 10 characters.' /* this.context.t('symbolBetweenZeroTen')*/ + if (symbolLength <= 0 || symbolLength >= 12) { + customSymbolError = 'Symbol must be between 0 and 12 characters.' /* this.context.t('symbolBetweenZeroTen')*/ } this.setState({ customSymbol, customSymbolError }) From 7a0a0696815f0e58f3a5ca0ab003d2b643e3414c Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 12:17:33 +0300 Subject: [PATCH 08/20] Refactoring: var -> let, const --- app/scripts/chromereload.js | 94 ++++++++++++++-------------- app/scripts/contentscript.js | 12 ++-- app/scripts/edge-encryptor.js | 28 ++++----- app/scripts/popup-core.js | 8 +-- old-ui/app/util.js | 76 +++++++++++----------- old-ui/example.js | 22 +++---- test/helper.js | 4 +- test/lib/mock-encryptor.js | 4 +- test/lib/mock-simple-keychain.js | 4 +- ui/app/actions.js | 20 +++--- ui/app/components/identicon.js | 16 ++--- ui/app/reducers/app.js | 8 +-- ui/app/util.js | 78 +++++++++++------------ ui/lib/blockies.js | 104 +++++++++++++++---------------- ui/lib/icon-factory.js | 16 ++--- 15 files changed, 247 insertions(+), 247 deletions(-) diff --git a/app/scripts/chromereload.js b/app/scripts/chromereload.js index f0bae403c..a8bf61f50 100644 --- a/app/scripts/chromereload.js +++ b/app/scripts/chromereload.js @@ -4,12 +4,12 @@ // // The reload client has a compatibility with livereload. // // WARNING: only supports reload command. -// var LIVERELOAD_HOST = 'localhost:'; -// var LIVERELOAD_PORT = 35729; -// var connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload'); +// const LIVERELOAD_HOST = 'localhost:'; +// const LIVERELOAD_PORT = 35729; +// const connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload'); // connection.onopen = function(event) { -// var hello = { +// const hello = { // command: 'hello', // protocols: ['http://livereload.com/protocols/official-7'] // }; @@ -23,7 +23,7 @@ // connection.onmessage = function (e) { // if (e.data) { -// var data = JSON.parse(e.data); +// const data = JSON.parse(e.data); // if (data && data.command === 'reload') { // extension.runtime.reload(); // } @@ -32,9 +32,9 @@ window.LiveReloadOptions = { host: 'localhost' }; -(function e (t, n, r) { function s (o, u) { if (!n[o]) { if (!t[o]) { var a = typeof require === 'function' && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); var f = new Error("Cannot find module '" + o + "'"); throw f.code = 'MODULE_NOT_FOUND', f } var l = n[o] = {exports: {}}; t[o][0].call(l.exports, function (e) { var n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } var i = typeof require === 'function' && require; for (var o = 0; o < r.length; o++)s(r[o]); return s })({1: [function (require, module, exports) { +(function e (t, n, r) { function s (o, u) { if (!n[o]) { if (!t[o]) { let a = typeof require === 'function' && require; if (!u && a) return a(o, !0); if (i) return i(o, !0); let f = new Error("Cannot find module '" + o + "'"); throw f.code = 'MODULE_NOT_FOUND', f } let l = n[o] = {exports: {}}; t[o][0].call(l.exports, function (e) { let n = t[o][1][e]; return s(n ? n : e) }, l, l.exports, e, t, n, r) } return n[o].exports } let i = typeof require === 'function' && require; for (let o = 0; o < r.length; o++)s(r[o]); return s })({1: [function (require, module, exports) { (function () { - var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref + let Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref _ref = require('./protocol'), Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7 @@ -166,7 +166,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Connector.prototype._onopen = function (e) { - var hello + let hello this.handlers.socketConnected() this._disconnectionReason = 'handshake-failed' hello = { @@ -204,7 +204,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {'./protocol': 6}], 2: [function (require, module, exports) { (function () { - var CustomEvents + let CustomEvents CustomEvents = { bind: function (element, eventName, handler) { @@ -222,7 +222,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } }, fire: function (element, eventName) { - var event + let event if (element.addEventListener) { event = document.createEvent('HTMLEvents') event.initEvent(eventName, true, true) @@ -243,7 +243,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {}], 3: [function (require, module, exports) { (function () { - var LessPlugin + let LessPlugin module.exports = LessPlugin = (function () { LessPlugin.identifier = 'less' @@ -268,9 +268,9 @@ window.LiveReloadOptions = { host: 'localhost' }; } LessPlugin.prototype.reloadLess = function (path) { - var link, links, _i, _len + let link, links, _i, _len links = (function () { - var _i, _len, _ref, _results + let _i, _len, _ref, _results _ref = document.getElementsByTagName('link') _results = [] for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -304,7 +304,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {}], 4: [function (require, module, exports) { (function () { - var Connector, LiveReload, Options, Reloader, Timer, + let Connector, LiveReload, Options, Reloader, Timer, __hasProp = {}.hasOwnProperty Connector = require('./connector').Connector @@ -317,7 +317,7 @@ window.LiveReloadOptions = { host: 'localhost' }; exports.LiveReload = LiveReload = (function () { function LiveReload (window) { - var k, v, _ref + let k, v, _ref this.window = window this.listeners = {} this.plugins = [] @@ -358,7 +358,7 @@ window.LiveReloadOptions = { host: 'localhost' }; })(this), connected: (function (_this) { return function (protocol) { - var _base + let _base if (typeof (_base = _this.listeners).connect === 'function') { _base.connect() } @@ -381,7 +381,7 @@ window.LiveReloadOptions = { host: 'localhost' }; })(this), disconnected: (function (_this) { return function (reason, nextDelay) { - var _base + let _base if (typeof (_base = _this.listeners).disconnect === 'function') { _base.disconnect() } @@ -426,7 +426,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } LiveReload.prototype.performReload = function (message) { - var _ref, _ref1 + let _ref, _ref1 this.log('LiveReload received reload request: ' + (JSON.stringify(message, null, 2))) return this.reloader.reload(message.path, { liveCSS: (_ref = message.liveCSS) != null ? _ref : true, @@ -442,7 +442,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } LiveReload.prototype.shutDown = function () { - var _base + let _base if (!this.initialized) { return } @@ -456,7 +456,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } LiveReload.prototype.addPlugin = function (pluginClass) { - var plugin + let plugin if (!this.initialized) { return } @@ -481,7 +481,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } LiveReload.prototype.analyze = function () { - var plugin, pluginData, pluginsData, _i, _len, _ref + let plugin, pluginData, pluginsData, _i, _len, _ref if (!this.initialized) { return } @@ -507,7 +507,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {'./connector': 1, './options': 5, './reloader': 7, './timer': 9}], 5: [function (require, module, exports) { (function () { - var Options + let Options exports.Options = Options = (function () { function Options () { @@ -536,7 +536,7 @@ window.LiveReloadOptions = { host: 'localhost' }; })() Options.extract = function (document) { - var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len1, _ref, _ref1 + let element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len1, _ref, _ref1 _ref = document.getElementsByTagName('script') for (_i = 0, _len = _ref.length; _i < _len; _i++) { element = _ref[_i] @@ -566,8 +566,8 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {}], 6: [function (require, module, exports) { (function () { - var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError, - __indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i } return -1 } + let PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError, + __indexOf = [].indexOf || function (item) { for (let i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i } return -1 } exports.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6' @@ -592,7 +592,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Parser.prototype.process = function (data) { - var command, e, message, options, _ref + let command, e, message, options, _ref try { if (this.protocol == null) { if (data.match(/^!!ver:([\d.]+)$/)) { @@ -638,7 +638,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Parser.prototype._parseMessage = function (data, validCommands) { - var e, message, _ref + let e, message, _ref try { message = JSON.parse(data) } catch (_error) { @@ -659,10 +659,10 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {}], 7: [function (require, module, exports) { (function () { - var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl + let IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl splitUrl = function (url) { - var hash, index, params + let hash, index, params if ((index = url.indexOf('#')) >= 0) { hash = url.slice(index) url = url.slice(0, index) @@ -683,7 +683,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } pathFromUrl = function (url) { - var path + let path url = splitUrl(url).url if (url.indexOf('file://') === 0) { path = url.replace(/^file:\/\/(localhost)?/, '') @@ -694,7 +694,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } pickBestMatch = function (path, objects, pathFunc) { - var bestMatch, object, score, _i, _len + let bestMatch, object, score, _i, _len bestMatch = { score: 0, } @@ -716,7 +716,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } numberOfMatchingSegments = function (path1, path2) { - var comps1, comps2, eqCount, len + let comps1, comps2, eqCount, len path1 = path1.replace(/^\/+/, '').toLowerCase() path2 = path2.replace(/^\/+/, '').toLowerCase() if (path1 === path2) { @@ -765,7 +765,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reload = function (path, options) { - var plugin, _base, _i, _len, _ref + let plugin, _base, _i, _len, _ref this.options = options if ((_base = this.options).stylesheetReloadTimeout == null) { _base.stylesheetReloadTimeout = 15000 @@ -798,7 +798,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reloadImages = function (path) { - var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results + let expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results expando = this.generateUniqueString() _ref = this.document.images for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -829,7 +829,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reloadStylesheetImages = function (styleSheet, path, expando) { - var e, rule, rules, styleNames, _i, _j, _len, _len1 + let e, rule, rules, styleNames, _i, _j, _len, _len1 try { rules = styleSheet != null ? styleSheet.cssRules : void 0 } catch (_error) { @@ -857,7 +857,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reloadStyleImages = function (style, styleNames, path, expando) { - var newValue, styleName, value, _i, _len + let newValue, styleName, value, _i, _len for (_i = 0, _len = styleNames.length; _i < _len; _i++) { styleName = styleNames[_i] value = style[styleName] @@ -879,9 +879,9 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reloadStylesheet = function (path) { - var imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1 + let imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1 links = (function () { - var _i, _len, _ref, _results + let _i, _len, _ref, _results _ref = this.document.getElementsByTagName('link') _results = [] for (_i = 0, _len = _ref.length; _i < _len; _i++) { @@ -936,7 +936,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.collectImportedStylesheets = function (link, styleSheet, result) { - var e, index, rule, rules, _i, _len + let e, index, rule, rules, _i, _len try { rules = styleSheet != null ? styleSheet.cssRules : void 0 } catch (_error) { @@ -965,7 +965,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.waitUntilCssLoads = function (clone, func) { - var callbackExecuted, executeCallback, poll + let callbackExecuted, executeCallback, poll callbackExecuted = false executeCallback = (function (_this) { return function () { @@ -1003,7 +1003,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reattachStylesheetLink = function (link) { - var clone, parent + let clone, parent if (link.__LiveReload_pendingRemoval) { return } @@ -1025,14 +1025,14 @@ window.LiveReloadOptions = { host: 'localhost' }; } return this.waitUntilCssLoads(clone, (function (_this) { return function () { - var additionalWaitingTime + let additionalWaitingTime if (/AppleWebKit/.test(navigator.userAgent)) { additionalWaitingTime = 5 } else { additionalWaitingTime = 200 } return _this.Timer.start(additionalWaitingTime, function () { - var _ref + let _ref if (!link.parentNode) { return } @@ -1045,7 +1045,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.reattachImportedRule = function (_arg) { - var href, index, link, media, newRule, parent, rule, tempLink + let href, index, link, media, newRule, parent, rule, tempLink rule = _arg.rule, index = _arg.index, link = _arg.link parent = rule.parentStyleSheet href = this.generateCacheBustUrl(rule.href) @@ -1087,7 +1087,7 @@ window.LiveReloadOptions = { host: 'localhost' }; } Reloader.prototype.generateCacheBustUrl = function (url, expando) { - var hash, oldParams, originalUrl, params, _ref + let hash, oldParams, originalUrl, params, _ref if (expando == null) { expando = this.generateUniqueString() } @@ -1117,7 +1117,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {}], 8: [function (require, module, exports) { (function () { - var CustomEvents, LiveReload, k + let CustomEvents, LiveReload, k CustomEvents = require('./customevents') @@ -1149,7 +1149,7 @@ window.LiveReloadOptions = { host: 'localhost' }; }).call(this) }, {'./customevents': 2, './less': 3, './livereload': 4}], 9: [function (require, module, exports) { (function () { - var Timer + let Timer exports.Timer = Timer = (function () { function Timer (func) { diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 4faceed9d..be3e6aae1 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -30,10 +30,10 @@ if (shouldInjectWeb3()) { function setupInjection () { try { // inject in-page script - var scriptTag = document.createElement('script') + const scriptTag = document.createElement('script') scriptTag.textContent = inpageBundle scriptTag.onload = function () { this.parentNode.removeChild(this) } - var container = document.head || document.documentElement + const container = document.head || document.documentElement // append as first child container.insertBefore(scriptTag, container.children[0]) } catch (e) { @@ -163,7 +163,7 @@ function suffixCheck () { * @returns {boolean} {@code true} if the documentElement is an html node or if none exists */ function documentElementCheck () { - var documentElement = document.documentElement.nodeName + const documentElement = document.documentElement.nodeName if (documentElement) { return documentElement.toLowerCase() === 'html' } @@ -176,7 +176,7 @@ function documentElementCheck () { * @returns {boolean} {@code true} if the current domain is blacklisted */ function blacklistedDomainCheck () { - var blacklistedDomains = [ + const blacklistedDomains = [ 'uscourts.gov', 'dropbox.com', 'webbyawards.com', @@ -187,8 +187,8 @@ function blacklistedDomainCheck () { 'ani.gamer.com.tw', 'blueskybooking.com', ] - var currentUrl = window.location.href - var currentRegex + const currentUrl = window.location.href + let currentRegex for (let i = 0; i < blacklistedDomains.length; i++) { const blacklistedDomain = blacklistedDomains[i].replace('.', '\\.') currentRegex = new RegExp(`(?:https?:\\/\\/)(?:(?!${blacklistedDomain}).)*$`) diff --git a/app/scripts/edge-encryptor.js b/app/scripts/edge-encryptor.js index dcb06873b..c5fd0685a 100644 --- a/app/scripts/edge-encryptor.js +++ b/app/scripts/edge-encryptor.js @@ -14,17 +14,17 @@ class EdgeEncryptor { * @returns {Promise} Promise resolving to an object with ciphertext */ encrypt (password, dataObject) { - var salt = this._generateSalt() + const salt = this._generateSalt() return this._keyFromPassword(password, salt) .then(function (key) { - var data = JSON.stringify(dataObject) - var dataBuffer = Unibabel.utf8ToBuffer(data) - var vector = global.crypto.getRandomValues(new Uint8Array(16)) - var resultbuffer = asmcrypto.AES_GCM.encrypt(dataBuffer, key, vector) + const data = JSON.stringify(dataObject) + const dataBuffer = Unibabel.utf8ToBuffer(data) + const vector = global.crypto.getRandomValues(new Uint8Array(16)) + const resultbuffer = asmcrypto.AES_GCM.encrypt(dataBuffer, key, vector) - var buffer = new Uint8Array(resultbuffer) - var vectorStr = Unibabel.bufferToBase64(vector) - var vaultStr = Unibabel.bufferToBase64(buffer) + const buffer = new Uint8Array(resultbuffer) + const vectorStr = Unibabel.bufferToBase64(vector) + const vaultStr = Unibabel.bufferToBase64(buffer) return JSON.stringify({ data: vaultStr, iv: vectorStr, @@ -48,7 +48,7 @@ class EdgeEncryptor { const encryptedData = Unibabel.base64ToBuffer(payload.data) const vector = Unibabel.base64ToBuffer(payload.iv) return new Promise((resolve, reject) => { - var result + let result try { result = asmcrypto.AES_GCM.decrypt(encryptedData, key, vector) } catch (err) { @@ -72,10 +72,10 @@ class EdgeEncryptor { */ _keyFromPassword (password, salt) { - var passBuffer = Unibabel.utf8ToBuffer(password) - var saltBuffer = Unibabel.base64ToBuffer(salt) + const passBuffer = Unibabel.utf8ToBuffer(password) + const saltBuffer = Unibabel.base64ToBuffer(salt) return new Promise((resolve) => { - var key = asmcrypto.PBKDF2_HMAC_SHA256.bytes(passBuffer, saltBuffer, 10000) + const key = asmcrypto.PBKDF2_HMAC_SHA256.bytes(passBuffer, saltBuffer, 10000) resolve(key) }) } @@ -87,9 +87,9 @@ class EdgeEncryptor { * @returns {string} Randomized base64 encoded data */ _generateSalt (byteCount = 32) { - var view = new Uint8Array(byteCount) + const view = new Uint8Array(byteCount) global.crypto.getRandomValues(view) - var b64encoded = btoa(String.fromCharCode.apply(null, view)) + const b64encoded = btoa(String.fromCharCode.apply(null, view)) return b64encoded } } diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js index db885ec93..50ec2b5c9 100644 --- a/app/scripts/popup-core.js +++ b/app/scripts/popup-core.js @@ -32,7 +32,7 @@ function initializePopup ({ container, connectionStream }, cb) { function connectToAccountManager (connectionStream, cb) { // setup communication with background // setup multiplexing - var mx = setupMultiplex(connectionStream) + const mx = setupMultiplex(connectionStream) // connect features setupControllerConnection(mx.createStream('controller'), cb) setupWeb3Connection(mx.createStream('provider')) @@ -44,7 +44,7 @@ function connectToAccountManager (connectionStream, cb) { * @param {PortDuplexStream} connectionStream PortStream instance establishing a background connection */ function setupWeb3Connection (connectionStream) { - var providerStream = new StreamProvider() + const providerStream = new StreamProvider() providerStream.pipe(connectionStream).pipe(providerStream) connectionStream.on('error', console.error.bind(console)) providerStream.on('error', console.error.bind(console)) @@ -62,8 +62,8 @@ function setupWeb3Connection (connectionStream) { function setupControllerConnection (connectionStream, cb) { // this is a really sneaky way of adding EventEmitter api // to a bi-directional dnode instance - var eventEmitter = new EventEmitter() - var accountManagerDnode = Dnode({ + const eventEmitter = new EventEmitter() + const accountManagerDnode = Dnode({ sendUpdate: function (state) { eventEmitter.emit('update', state) }, diff --git a/old-ui/app/util.js b/old-ui/app/util.js index 2cce90c4b..7642e63f4 100644 --- a/old-ui/app/util.js +++ b/old-ui/app/util.js @@ -42,7 +42,7 @@ const { // customDPaths, } = require('../../app/scripts/controllers/network/enums') -var valueTable = { +const valueTable = { wei: '1000000000000000000', kwei: '1000000000000000', mwei: '1000000000000', @@ -55,8 +55,8 @@ var valueTable = { gether: '0.000000001', tether: '0.000000000001', } -var bnTable = {} -for (var currency in valueTable) { +const bnTable = {} +for (const currency in valueTable) { bnTable[currency] = new ethUtil.BN(valueTable[currency], 10) } @@ -124,7 +124,7 @@ function accountSummary (acc, firstSegLength = 6, lastSegLength = 4) { } function isValidAddress (address, network) { - var prefixed = ethUtil.addHexPrefix(address) + const prefixed = ethUtil.addHexPrefix(address) if (ifRSK(network)) { if (address === '0x0000000000000000000000000000000000000000') return false return (ethUtil.isValidAddress(prefixed)) @@ -139,33 +139,33 @@ function isValidENSAddress (address) { } function isInvalidChecksumAddress (address, network) { - var prefixed = ethUtil.addHexPrefix(address) + const prefixed = ethUtil.addHexPrefix(address) if (address === '0x0000000000000000000000000000000000000000') return false return !isAllOneCase(prefixed) && !isValidChecksumAddress(network, prefixed) } function isAllOneCase (address) { if (!address) return true - var lower = address.toLowerCase() - var upper = address.toUpperCase() + const lower = address.toLowerCase() + const upper = address.toUpperCase() return address === lower || address === upper } // Takes wei Hex, returns wei BN, even if input is null function numericBalance (balance) { if (!balance) return new ethUtil.BN(0, 16) - var stripped = ethUtil.stripHexPrefix(balance) + const stripped = ethUtil.stripHexPrefix(balance) return new ethUtil.BN(stripped, 16) } // Takes hex, returns [beforeDecimal, afterDecimal] function parseBalance (balance) { - var beforeDecimal, afterDecimal + let afterDecimal const wei = numericBalance(balance) - var weiString = wei.toString() + const weiString = wei.toString() const trailingZeros = /0+$/ - beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0' + const beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0' afterDecimal = ('000000000000000000' + wei).slice(-18).replace(trailingZeros, '') if (afterDecimal === '') { afterDecimal = '0' } return [beforeDecimal, afterDecimal] @@ -176,14 +176,14 @@ function parseBalance (balance) { function formatBalance (balance, decimalsToKeep, needsParse = true, network, isToken, tokenSymbol) { const coinName = ethNetProps.props.getNetworkCoinName(network) const assetName = isToken ? tokenSymbol : coinName - var parsed = needsParse ? parseBalance(balance) : balance.split('.') - var beforeDecimal = parsed[0] - var afterDecimal = parsed[1] - var formatted = '0' + const parsed = needsParse ? parseBalance(balance) : balance.split('.') + const beforeDecimal = parsed[0] + let afterDecimal = parsed[1] + let formatted = '0' if (decimalsToKeep === undefined) { if (beforeDecimal === '0') { if (afterDecimal !== '0') { - var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits + const sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits if (sigFigs) { afterDecimal = sigFigs[0] } formatted = '0.' + afterDecimal + ` ${assetName}` } @@ -199,11 +199,11 @@ function formatBalance (balance, decimalsToKeep, needsParse = true, network, isT function generateBalanceObject (formattedBalance, decimalsToKeep = 1) { - var balance = formattedBalance.split(' ')[0] - var label = formattedBalance.split(' ')[1] - var beforeDecimal = balance.split('.')[0] - var afterDecimal = balance.split('.')[1] - var shortBalance = shortenBalance(balance, decimalsToKeep) + let balance = formattedBalance.split(' ')[0] + const label = formattedBalance.split(' ')[1] + const beforeDecimal = balance.split('.')[0] + const afterDecimal = balance.split('.')[1] + const shortBalance = shortenBalance(balance, decimalsToKeep) if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') { // eslint-disable-next-line eqeqeq @@ -220,8 +220,8 @@ function generateBalanceObject (formattedBalance, decimalsToKeep = 1) { } function shortenBalance (balance, decimalsToKeep = 1) { - var truncatedValue - var convertedBalance = parseFloat(balance) + let truncatedValue + const convertedBalance = parseFloat(balance) if (convertedBalance > 1000000) { truncatedValue = (balance / 1000000).toFixed(decimalsToKeep) return `${truncatedValue}m` @@ -233,7 +233,7 @@ function shortenBalance (balance, decimalsToKeep = 1) { } else if (convertedBalance < 0.001) { return '<0.001' } else if (convertedBalance < 1) { - var stringBalance = convertedBalance.toString() + const stringBalance = convertedBalance.toString() if (stringBalance.split('.')[1].length > 3) { return convertedBalance.toFixed(3) } else { @@ -245,7 +245,7 @@ function shortenBalance (balance, decimalsToKeep = 1) { } function dataSize (data) { - var size = data ? ethUtil.stripHexPrefix(data).length : 0 + const size = data ? ethUtil.stripHexPrefix(data).length : 0 return size + ' bytes' } @@ -262,7 +262,7 @@ function normalizeEthStringToWei (str) { const parts = str.split('.') let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei) if (parts[1]) { - var decimal = parts[1] + let decimal = parts[1] while (decimal.length < 18) { decimal += '0' } @@ -275,24 +275,24 @@ function normalizeEthStringToWei (str) { return eth } -var multiple = new ethUtil.BN('10000', 10) +const multiple = new ethUtil.BN('10000', 10) function normalizeNumberToWei (n, currency) { - var enlarged = n * 10000 - var amount = new ethUtil.BN(String(enlarged), 10) + const enlarged = n * 10000 + const amount = new ethUtil.BN(String(enlarged), 10) return normalizeToWei(amount, currency).div(multiple) } function readableDate (ms) { - var date = new Date(ms) - var month = date.getMonth() - var day = date.getDate() - var year = date.getFullYear() - var hours = date.getHours() - var minutes = '0' + date.getMinutes() - var seconds = '0' + date.getSeconds() + const date = new Date(ms) + const month = date.getMonth() + const day = date.getDate() + const year = date.getFullYear() + const hours = date.getHours() + const minutes = '0' + date.getMinutes() + const seconds = '0' + date.getSeconds() - var dateStr = `${month}/${day}/${year}` - var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` + const dateStr = `${month}/${day}/${year}` + const time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` return `${dateStr} ${time}` } diff --git a/old-ui/example.js b/old-ui/example.js index 4627c0e9c..1e6f619d3 100644 --- a/old-ui/example.js +++ b/old-ui/example.js @@ -5,7 +5,7 @@ const EventEmitter = require('events').EventEmitter // account management -var identities = { +const identities = { '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111': { name: 'Walrus', img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd', @@ -29,7 +29,7 @@ var identities = { }, } -var unapprovedTxs = {} +const unapprovedTxs = {} addUnconfTx({ from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222', to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111', @@ -43,8 +43,8 @@ addUnconfTx({ }) function addUnconfTx (txParams) { - var time = (new Date()).getTime() - var id = createRandomId() + const time = (new Date()).getTime() + const id = createRandomId() unapprovedTxs[id] = { id: id, txParams: txParams, @@ -52,8 +52,8 @@ function addUnconfTx (txParams) { } } -var isUnlocked = false -var selectedAccount = null +let isUnlocked = false +let selectedAccount = null function getState () { return { @@ -64,7 +64,7 @@ function getState () { } } -var accountManager = new EventEmitter() +const accountManager = new EventEmitter() accountManager.getState = function (cb) { cb(null, getState()) @@ -101,9 +101,9 @@ accountManager._didUpdate = function () { // start app -var container = document.getElementById('app-content') +const container = document.getElementById('app-content') -var css = MetaMaskUiCss() +const css = MetaMaskUiCss() injectCss(css) MetaMaskUi({ @@ -115,9 +115,9 @@ MetaMaskUi({ function createRandomId () { // 13 time digits - var datePart = new Date().getTime() * Math.pow(10, 3) + const datePart = new Date().getTime() * Math.pow(10, 3) // 3 random digits - var extraPart = Math.floor(Math.random() * Math.pow(10, 3)) + const extraPart = Math.floor(Math.random() * Math.pow(10, 3)) // 16 digits return datePart + extraPart } diff --git a/test/helper.js b/test/helper.js index 80f27fe8a..2061dafa7 100644 --- a/test/helper.js +++ b/test/helper.js @@ -17,7 +17,7 @@ server.listen(8545, () => { }) // logging util -var log = require('loglevel') +const log = require('loglevel') log.setDefaultLevel(5) global.log = log @@ -57,7 +57,7 @@ function enableFailureOnUnhandledPromiseRejection () { throw evt.detail.reason }) } else { - var oldOHR = window.onunhandledrejection + const oldOHR = window.onunhandledrejection window.onunhandledrejection = function (evt) { if (typeof oldOHR === 'function') oldOHR.apply(this, arguments) throw evt.detail.reason diff --git a/test/lib/mock-encryptor.js b/test/lib/mock-encryptor.js index 852c536c2..a76ace194 100644 --- a/test/lib/mock-encryptor.js +++ b/test/lib/mock-encryptor.js @@ -1,5 +1,5 @@ -var mockHex = '0xabcdef0123456789' -var mockKey = Buffer.alloc(32) +const mockHex = '0xabcdef0123456789' +const mockKey = Buffer.alloc(32) let cacheVal module.exports = { diff --git a/test/lib/mock-simple-keychain.js b/test/lib/mock-simple-keychain.js index d3addc3e8..ef1d540ac 100644 --- a/test/lib/mock-simple-keychain.js +++ b/test/lib/mock-simple-keychain.js @@ -1,4 +1,4 @@ -var fakeWallet = { +const fakeWallet = { privKey: '0x123456788890abcdef', address: '0xfedcba0987654321', } @@ -26,7 +26,7 @@ module.exports = class MockSimpleKeychain { } addAccounts (n = 1) { - for (var i = 0; i < n; i++) { + for (let i = 0; i < n; i++) { this.wallets.push(fakeWallet) } } diff --git a/ui/app/actions.js b/ui/app/actions.js index 2dd696087..be1fd3970 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -20,7 +20,7 @@ const { POA, const { hasUnconfirmedTransactions } = require('./helpers/confirm-transaction/util') const WebcamUtils = require('../lib/webcam-utils') -var actions = { +const actions = { _setBackgroundConnection: _setBackgroundConnection, GO_HOME: 'GO_HOME', @@ -374,7 +374,7 @@ var actions = { module.exports = actions -var background = null +let background = null function _setBackgroundConnection (backgroundConnection) { background = backgroundConnection } @@ -2237,7 +2237,7 @@ function requestExportAccount () { } function exportAccount (password, address, dPath) { - var self = this + const self = this return function (dispatch) { dispatch(self.showLoadingIndication()) @@ -2383,7 +2383,7 @@ function pairUpdate (coin) { } function shapeShiftSubview (network) { - var pair = 'btc_eth' + const pair = 'btc_eth' return (dispatch) => { dispatch(actions.showSubLoadingIndication()) shapeShiftRequest('marketinfo', {pair}, (mktResponse) => { @@ -2408,7 +2408,7 @@ function coinShiftRquest (data, marketData) { shapeShiftRequest('shift', { method: 'POST', data}, (response) => { dispatch(actions.hideLoadingIndication()) if (response.error) return dispatch(actions.displayWarning(response.error)) - var message = ` + const message = ` Deposit your ${response.depositType} to the address below:` log.debug(`background.createShapeShiftTx`) background.createShapeShiftTx(response.deposit, response.depositType) @@ -2444,7 +2444,7 @@ function reshowQrCode (data, coin) { shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => { if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error)) - var message = [ + const message = [ `Deposit your ${coin} to the address below:`, `Deposit Limit: ${mktResponse.limit}`, `Deposit Minimum:${mktResponse.minimum}`, @@ -2461,11 +2461,11 @@ function reshowQrCode (data, coin) { } function shapeShiftRequest (query, options, cb) { - var queryResponse, method + let queryResponse, method !options ? options = {} : null options.method ? method = options.method : method = 'GET' - var requestListner = function (request) { + const requestListner = function (request) { try { queryResponse = JSON.parse(this.responseText) cb ? cb(queryResponse) : null @@ -2476,12 +2476,12 @@ function shapeShiftRequest (query, options, cb) { } } - var shapShiftReq = new XMLHttpRequest() + const shapShiftReq = new XMLHttpRequest() shapShiftReq.addEventListener('load', requestListner) shapShiftReq.open(method, `https://shapeshift.io/${query}/${options.pair ? options.pair : ''}`, true) if (options.method === 'POST') { - var jsonObj = JSON.stringify(options.data) + const jsonObj = JSON.stringify(options.data) shapShiftReq.setRequestHeader('Content-Type', 'application/json') return shapShiftReq.send(jsonObj) } else { diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js index e76068aa4..9fb8dbe54 100644 --- a/ui/app/components/identicon.js +++ b/ui/app/components/identicon.js @@ -25,9 +25,9 @@ function mapStateToProps (state) { } IdenticonComponent.prototype.render = function () { - var props = this.props + const props = this.props const { className = '', address, image } = props - var diameter = props.diameter || this.defaultDiameter + const diameter = props.diameter || this.defaultDiameter const style = { height: diameter, width: diameter, @@ -66,14 +66,14 @@ IdenticonComponent.prototype.render = function () { } IdenticonComponent.prototype.componentDidMount = function () { - var props = this.props + const props = this.props const { address, useBlockie } = props if (!address) return if (!isNode) { // eslint-disable-next-line react/no-find-dom-node - var container = findDOMNode(this) + const container = findDOMNode(this) const diameter = props.diameter || this.defaultDiameter @@ -86,17 +86,17 @@ IdenticonComponent.prototype.componentDidMount = function () { } IdenticonComponent.prototype.componentDidUpdate = function () { - var props = this.props + const props = this.props const { address, useBlockie } = props if (!address) return if (!isNode) { // eslint-disable-next-line react/no-find-dom-node - var container = findDOMNode(this) + const container = findDOMNode(this) - var children = container.children - for (var i = 0; i < children.length; i++) { + const children = container.children + for (let i = 0; i < children.length; i++) { container.removeChild(children[i]) } diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 92449e6c6..b86adde20 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -22,21 +22,21 @@ function reduceApp (state, action) { name = 'confTx' } - var defaultView = { + const defaultView = { name, detailView: null, context: selectedAddress, } // confirm seed words - var seedWords = state.metamask.seedWords - var seedConfView = { + const seedWords = state.metamask.seedWords + const seedConfView = { name: 'createVaultComplete', seedWords, } // default state - var appState = extend({ + const appState = extend({ shouldClose: false, menuOpen: false, modal: { diff --git a/ui/app/util.js b/ui/app/util.js index 37c0fb698..870acb9f0 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -12,7 +12,7 @@ function formatDate (date) { return vreme.format(new Date(date), '3/16/2014 at 14:30') } -var valueTable = { +const valueTable = { wei: '1000000000000000000', kwei: '1000000000000000', mwei: '1000000000000', @@ -25,8 +25,8 @@ var valueTable = { gether: '0.000000001', tether: '0.000000000001', } -var bnTable = {} -for (var currency in valueTable) { +const bnTable = {} +for (const currency in valueTable) { bnTable[currency] = new ethUtil.BN(valueTable[currency], 10) } @@ -79,12 +79,12 @@ function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includ function miniAddressSummary (address) { if (!address) return '' - var checked = checksumAddress(address) + const checked = checksumAddress(address) return checked ? checked.slice(0, 4) + '...' + checked.slice(-4) : '...' } function isValidAddress (address) { - var prefixed = ethUtil.addHexPrefix(address) + const prefixed = ethUtil.addHexPrefix(address) if (address === '0x0000000000000000000000000000000000000000') return false return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed) } @@ -94,33 +94,33 @@ function isValidENSAddress (address) { } function isInvalidChecksumAddress (address) { - var prefixed = ethUtil.addHexPrefix(address) + const prefixed = ethUtil.addHexPrefix(address) if (address === '0x0000000000000000000000000000000000000000') return false return !isAllOneCase(prefixed) && !ethUtil.isValidChecksumAddress(prefixed) && ethUtil.isValidAddress(prefixed) } function isAllOneCase (address) { if (!address) return true - var lower = address.toLowerCase() - var upper = address.toUpperCase() + const lower = address.toLowerCase() + const upper = address.toUpperCase() return address === lower || address === upper } // Takes wei Hex, returns wei BN, even if input is null function numericBalance (balance) { if (!balance) return new ethUtil.BN(0, 16) - var stripped = ethUtil.stripHexPrefix(balance) + const stripped = ethUtil.stripHexPrefix(balance) return new ethUtil.BN(stripped, 16) } // Takes hex, returns [beforeDecimal, afterDecimal] function parseBalance (balance) { - var beforeDecimal, afterDecimal + let afterDecimal const wei = numericBalance(balance) - var weiString = wei.toString() + const weiString = wei.toString() const trailingZeros = /0+$/ - beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0' + const beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0' afterDecimal = ('000000000000000000' + wei).slice(-18).replace(trailingZeros, '') if (afterDecimal === '') { afterDecimal = '0' } return [beforeDecimal, afterDecimal] @@ -129,14 +129,14 @@ function parseBalance (balance) { // Takes wei hex, returns an object with three properties. // Its "formatted" property is what we generally use to render values. function formatBalance (balance, decimalsToKeep, needsParse = true) { - var parsed = needsParse ? parseBalance(balance) : balance.split('.') - var beforeDecimal = parsed[0] - var afterDecimal = parsed[1] - var formatted = 'None' + const parsed = needsParse ? parseBalance(balance) : balance.split('.') + const beforeDecimal = parsed[0] + let afterDecimal = parsed[1] + let formatted = 'None' if (decimalsToKeep === undefined) { if (beforeDecimal === '0') { if (afterDecimal !== '0') { - var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits + const sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits if (sigFigs) { afterDecimal = sigFigs[0] } formatted = '0.' + afterDecimal + ' ETH' } @@ -152,11 +152,11 @@ function formatBalance (balance, decimalsToKeep, needsParse = true) { function generateBalanceObject (formattedBalance, decimalsToKeep = 1) { - var balance = formattedBalance.split(' ')[0] - var label = formattedBalance.split(' ')[1] - var beforeDecimal = balance.split('.')[0] - var afterDecimal = balance.split('.')[1] - var shortBalance = shortenBalance(balance, decimalsToKeep) + let balance = formattedBalance.split(' ')[0] + const label = formattedBalance.split(' ')[1] + const beforeDecimal = balance.split('.')[0] + const afterDecimal = balance.split('.')[1] + const shortBalance = shortenBalance(balance, decimalsToKeep) if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') { // eslint-disable-next-line eqeqeq @@ -173,8 +173,8 @@ function generateBalanceObject (formattedBalance, decimalsToKeep = 1) { } function shortenBalance (balance, decimalsToKeep = 1) { - var truncatedValue - var convertedBalance = parseFloat(balance) + let truncatedValue + const convertedBalance = parseFloat(balance) if (convertedBalance > 1000000) { truncatedValue = (balance / 1000000).toFixed(decimalsToKeep) return `${truncatedValue}m` @@ -186,7 +186,7 @@ function shortenBalance (balance, decimalsToKeep = 1) { } else if (convertedBalance < 0.001) { return '<0.001' } else if (convertedBalance < 1) { - var stringBalance = convertedBalance.toString() + const stringBalance = convertedBalance.toString() if (stringBalance.split('.')[1].length > 3) { return convertedBalance.toFixed(3) } else { @@ -198,7 +198,7 @@ function shortenBalance (balance, decimalsToKeep = 1) { } function dataSize (data) { - var size = data ? ethUtil.stripHexPrefix(data).length : 0 + const size = data ? ethUtil.stripHexPrefix(data).length : 0 return size + ' bytes' } @@ -215,7 +215,7 @@ function normalizeEthStringToWei (str) { const parts = str.split('.') let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei) if (parts[1]) { - var decimal = parts[1] + let decimal = parts[1] while (decimal.length < 18) { decimal += '0' } @@ -228,24 +228,24 @@ function normalizeEthStringToWei (str) { return eth } -var multiple = new ethUtil.BN('10000', 10) +const multiple = new ethUtil.BN('10000', 10) function normalizeNumberToWei (n, currency) { - var enlarged = n * 10000 - var amount = new ethUtil.BN(String(enlarged), 10) + const enlarged = n * 10000 + const amount = new ethUtil.BN(String(enlarged), 10) return normalizeToWei(amount, currency).div(multiple) } function readableDate (ms) { - var date = new Date(ms) - var month = date.getMonth() - var day = date.getDate() - var year = date.getFullYear() - var hours = date.getHours() - var minutes = '0' + date.getMinutes() - var seconds = '0' + date.getSeconds() + const date = new Date(ms) + const month = date.getMonth() + const day = date.getDate() + const year = date.getFullYear() + const hours = date.getHours() + const minutes = '0' + date.getMinutes() + const seconds = '0' + date.getSeconds() - var dateStr = `${month}/${day}/${year}` - var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` + const dateStr = `${month}/${day}/${year}` + const time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` return `${dateStr} ${time}` } diff --git a/ui/lib/blockies.js b/ui/lib/blockies.js index ee5a2a5ca..f0488f150 100644 --- a/ui/lib/blockies.js +++ b/ui/lib/blockies.js @@ -18,8 +18,8 @@ // helper functions for that ctx function write(buffer, offs) { - for (var i = 2; i < arguments.length; i++) { - for (var j = 0; j < arguments[i].length; j++) { + for (let i = 2; i < arguments.length; i++) { + for (let j = 0; j < arguments[i].length; j++) { buffer[offs++] = arguments[i].charAt(j); } } @@ -37,7 +37,7 @@ return String.fromCharCode(w & 255, (w >> 8) & 255); } - var PNG = function(width,height,depth) { + const PNG = function(width,height,depth) { this.width = width; this.height = height; @@ -66,10 +66,10 @@ this.palette = new Object(); this.pindex = 0; - var _crc32 = new Array(); + const _crc32 = new Array(); // initialize buffer with zero bytes - for (var i = 0; i < this.buffer_size; i++) { + for (let i = 0; i < this.buffer_size; i++) { this.buffer[i] = "\x00"; } @@ -81,14 +81,14 @@ write(this.buffer, this.iend_offs, byte4(this.iend_size - 12), 'IEND'); // initialize deflate header - var header = ((8 + (7 << 4)) << 8) | (3 << 6); + const header = ((8 + (7 << 4)) << 8) | (3 << 6); header+= 31 - (header % 31); write(this.buffer, this.idat_offs + 8, byte2(header)); // initialize deflate block headers - for (var i = 0; (i << 16) - 1 < this.pix_size; i++) { - var size, bits; + for (let i = 0; (i << 16) - 1 < this.pix_size; i++) { + const size, bits; if (i + 0xffff < this.pix_size) { size = 0xffff; bits = "\x00"; @@ -100,9 +100,9 @@ } /* Create crc32 lookup table */ - for (var i = 0; i < 256; i++) { - var c = i; - for (var j = 0; j < 8; j++) { + for (let i = 0; i < 256; i++) { + const c = i; + for (let j = 0; j < 8; j++) { if (c & 1) { c = -306674912 ^ ((c >> 1) & 0x7fffffff); } else { @@ -114,8 +114,8 @@ // compute the index into a png for a given pixel this.index = function(x,y) { - var i = y * (this.width + 1) + x + 1; - var j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i; + const i = y * (this.width + 1) + x + 1; + const j = this.idat_offs + 8 + 2 + 5 * Math.floor((i / 0xffff) + 1) + i; return j; }; @@ -123,12 +123,12 @@ this.color = function(red, green, blue, alpha) { alpha = alpha >= 0 ? alpha : 255; - var color = (((((alpha << 8) | red) << 8) | green) << 8) | blue; + const color = (((((alpha << 8) | red) << 8) | green) << 8) | blue; if (typeof this.palette[color] == "undefined") { if (this.pindex == this.depth) return "\x00"; - var ndx = this.plte_offs + 8 + 3 * this.pindex; + const ndx = this.plte_offs + 8 + 3 * this.pindex; this.buffer[ndx + 0] = String.fromCharCode(red); this.buffer[ndx + 1] = String.fromCharCode(green); @@ -143,13 +143,13 @@ // output a PNG string, Base64 encoded this.getBase64 = function() { - var s = this.getDump(); + const s = this.getDump(); - var ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - var c1, c2, c3, e1, e2, e3, e4; - var l = s.length; - var i = 0; - var r = ""; + const ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + const c1, c2, c3, e1, e2, e3, e4; + const l = s.length; + const i = 0; + const r = ""; do { c1 = s.charCodeAt(i); @@ -168,14 +168,14 @@ this.getDump = function() { // compute adler32 of output pixels + row filter bytes - var BASE = 65521; /* largest prime smaller than 65536 */ - var NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - var s1 = 1; - var s2 = 0; - var n = NMAX; + const BASE = 65521; /* largest prime smaller than 65536 */ + const NMAX = 5552; /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + const s1 = 1; + const s2 = 0; + const n = NMAX; - for (var y = 0; y < this.height; y++) { - for (var x = -1; x < this.width; x++) { + for (let y = 0; y < this.height; y++) { + for (let x = -1; x < this.width; x++) { s1+= this.buffer[this.index(x, y)].charCodeAt(0); s2+= s1; if ((n-= 1) == 0) { @@ -191,8 +191,8 @@ // compute crc32 of the PNG chunks function crc32(png, offs, size) { - var crc = -1; - for (var i = 4; i < size-4; i += 1) { + const crc = -1; + for (let i = 4; i < size-4; i += 1) { crc = _crc32[(crc ^ png[offs+i].charCodeAt(0)) & 0xff] ^ ((crc >> 8) & 0x00ffffff); } write(png, offs+size-4, byte4(crc ^ -1)); @@ -209,8 +209,8 @@ }; this.fillRect = function (x, y, w, h, color) { - for(var i = 0; i < w; i++) { - for (var j = 0; j < h; j++) { + for(let i = 0; i < w; i++) { + for (let j = 0; j < h; j++) { this.buffer[this.index(x+i, y+j)] = color; } } @@ -240,13 +240,13 @@ } function hsl2rgb(h, s, l){ - var r, g, b; + let r, g, b; if(s == 0){ r = g = b = l; // achromatic }else{ - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; r = hue2rgb(p, q, h + 1/3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3); @@ -256,20 +256,20 @@ } // The random number is a js implementation of the Xorshift PRNG - var randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values +const randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values function seedrand(seed) { - for (var i = 0; i < randseed.length; i++) { + for (let i = 0; i < randseed.length; i++) { randseed[i] = 0; } - for (var i = 0; i < seed.length; i++) { + for (let i = 0; i < seed.length; i++) { randseed[i % 4] = (randseed[i % 4] << 5) - randseed[i % 4] + seed.charCodeAt(i); } } function rand() { // based on Java's String.hashCode(), expanded to 4 32bit values - var t = randseed[0] ^ (randseed[0] << 11); + const t = randseed[0] ^ (randseed[0] << 11); randseed[0] = randseed[1]; randseed[1] = randseed[2]; @@ -281,35 +281,35 @@ function createColor() { //saturation is the whole color spectrum - var h = Math.floor(rand() * 360); + const h = Math.floor(rand() * 360); //saturation goes from 40 to 100, it avoids greyish colors - var s = rand() * 60 + 40; + const s = rand() * 60 + 40; //lightness can be anything from 0 to 100, but probabilities are a bell curve around 50% - var l = (rand() + rand() + rand() + rand()) * 25; + const l = (rand() + rand() + rand() + rand()) * 25; return [h / 360,s / 100,l / 100]; } function createImageData(size) { - var width = size; // Only support square icons for now - var height = size; + const width = size; // Only support square icons for now + const height = size; - var dataWidth = Math.ceil(width / 2); - var mirrorWidth = width - dataWidth; + const dataWidth = Math.ceil(width / 2); + const mirrorWidth = width - dataWidth; - var data = []; - for (var y = 0; y < height; y++) { - var row = []; - for (var x = 0; x < dataWidth; x++) { + const data = []; + for (let y = 0; y < height; y++) { + const row = []; + for (let x = 0; x < dataWidth; x++) { // this makes foreground and background color to have a 43% (1/2.3) probability // spot color has 13% chance row[x] = Math.floor(rand() * 2.3); } - var r = row.slice(0, mirrorWidth); + const r = row.slice(0, mirrorWidth); r.reverse(); row = row.concat(r); - for (var i = 0; i < row.length; i++) { + for (let i = 0; i < row.length; i++) { data.push(row[i]); } } diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js index 3b015eb32..393c5786d 100644 --- a/ui/lib/icon-factory.js +++ b/ui/lib/icon-factory.js @@ -1,4 +1,4 @@ -var iconFactory +let iconFactory const isValidAddress = require('ethereumjs-util').isValidAddress const { checksumAddress } = require('../app/util') const contractMap = require('eth-contract-metadata') @@ -28,18 +28,18 @@ IconFactory.prototype.iconForAddress = function (address, diameter) { // returns svg dom element IconFactory.prototype.generateIdenticonSvg = function (address, diameter) { - var cacheId = `${address}:${diameter}` + const cacheId = `${address}:${diameter}` // check cache, lazily generate and populate cache - var identicon = this.cache[cacheId] || (this.cache[cacheId] = this.generateNewIdenticon(address, diameter)) + const identicon = this.cache[cacheId] || (this.cache[cacheId] = this.generateNewIdenticon(address, diameter)) // create a clean copy so you can modify it - var cleanCopy = identicon.cloneNode(true) + const cleanCopy = identicon.cloneNode(true) return cleanCopy } // creates a new identicon IconFactory.prototype.generateNewIdenticon = function (address, diameter) { - var numericRepresentation = jsNumberForAddress(address) - var identicon = this.jazzicon.generateIdenticon(diameter, numericRepresentation) + const numericRepresentation = jsNumberForAddress(address) + const identicon = this.jazzicon.generateIdenticon(diameter, numericRepresentation) return identicon } @@ -60,7 +60,7 @@ function imageElFor (address) { } function jsNumberForAddress (address) { - var addr = address.slice(2, 10) - var seed = parseInt(addr, 16) + const addr = address.slice(2, 10) + const seed = parseInt(addr, 16) return seed } From 6dd83a340de84c7c22114a45443481c67d143b83 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 12:29:20 +0300 Subject: [PATCH 09/20] var -> let, const. Fix tests --- ui/lib/blockies.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/lib/blockies.js b/ui/lib/blockies.js index f0488f150..e7de38eab 100644 --- a/ui/lib/blockies.js +++ b/ui/lib/blockies.js @@ -88,7 +88,7 @@ // initialize deflate block headers for (let i = 0; (i << 16) - 1 < this.pix_size; i++) { - const size, bits; + let size, bits; if (i + 0xffff < this.pix_size) { size = 0xffff; bits = "\x00"; @@ -146,7 +146,7 @@ const s = this.getDump(); const ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - const c1, c2, c3, e1, e2, e3, e4; + let c1, c2, c3, e1, e2, e3, e4; const l = s.length; const i = 0; const r = ""; @@ -344,9 +344,9 @@ const randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values const color = p.color(...hsl2rgb(...opts.color)); const spotcolor = p.color(...hsl2rgb(...opts.spotcolor)); - for (var i = 0; i < imageData.length; i++) { - var row = Math.floor(i / width); - var col = i % width; + for (let i = 0; i < imageData.length; i++) { + const row = Math.floor(i / width); + const col = i % width; // if data is 0, leave the background if (imageData[i]) { // if data is 2, choose spot color, if 1 choose foreground From 051813f1f3b6ccaa24788d829a9ceed400c4c0f0 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 13:10:04 +0300 Subject: [PATCH 10/20] Extend available Symbol length to 22 to support yDAI+yUSDC+yUSDT+yTUSD --- old-ui/app/components/add-token/add-token.component.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/old-ui/app/components/add-token/add-token.component.js b/old-ui/app/components/add-token/add-token.component.js index 9845960ee..4bbb92583 100644 --- a/old-ui/app/components/add-token/add-token.component.js +++ b/old-ui/app/components/add-token/add-token.component.js @@ -368,9 +368,9 @@ export default class AddTokenScreen extends Component { } const symbolLen = symbol.trim().length - const validSymbol = symbolLen > 0 && symbolLen < 12 + const validSymbol = symbolLen > 0 && symbolLen < 23 if (!validSymbol) { - msg += 'Symbol must be between 0 and 12 characters.' + msg += 'Symbol must be between 0 and 23 characters.' } let ownAddress = identitiesList.includes(standardAddress) @@ -527,8 +527,8 @@ export default class AddTokenScreen extends Component { const symbolLength = customSymbol.length let customSymbolError = null - if (symbolLength <= 0 || symbolLength >= 12) { - customSymbolError = 'Symbol must be between 0 and 12 characters.' /* this.context.t('symbolBetweenZeroTen')*/ + if (symbolLength <= 0 || symbolLength >= 23) { + customSymbolError = 'Symbol must be between 0 and 23 characters.' /* this.context.t('symbolBetweenZeroTen')*/ } this.setState({ customSymbol, customSymbolError }) From 1fa277ba8d368148610b63c9e3911b00aec50f19 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 13:28:29 +0300 Subject: [PATCH 11/20] Keystore file import without password --- old-ui/app/accounts/import/json.js | 21 ++++++++------------- package-lock.json | 13 ++++++------- package.json | 2 +- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/old-ui/app/accounts/import/json.js b/old-ui/app/accounts/import/json.js index 60dd2bfd5..6d0b83bf7 100644 --- a/old-ui/app/accounts/import/json.js +++ b/old-ui/app/accounts/import/json.js @@ -1,9 +1,9 @@ const Component = require('react').Component const h = require('react-hyperscript') -const connect = require('react-redux').connect +import { connect } from 'react-redux' const actions = require('../../../../ui/app/actions') const FileInput = require('react-simple-file-input').default -const PropTypes = require('prop-types') +import PropTypes from 'prop-types' class JsonImportSubview extends Component { constructor (props) { @@ -75,31 +75,26 @@ class JsonImportSubview extends Component { } createNewKeychain () { + const { displayWarning, importNewJsonAccount } = this.props const { fileContents } = this.state if (!fileContents) { const message = 'You must select a file to import.' - return this.props.displayWarning(message) + return displayWarning(message) } const passwordInput = document.getElementById('json-password-box') const password = passwordInput.value - if (!password) { - const message = 'You must enter a password for the selected file.' - return this.props.displayWarning(message) - } - - this.props.importNewAccount([ fileContents, password ]) - // JS runtime requires caught rejections but failures are handled by Redux - .catch() + importNewJsonAccount([ fileContents, password ]) + .catch((err) => err && displayWarning(err.message || err)) } } JsonImportSubview.propTypes = { error: PropTypes.string, displayWarning: PropTypes.func, - importNewAccount: PropTypes.func, + importNewJsonAccount: PropTypes.func, } const mapStateToProps = state => { @@ -112,7 +107,7 @@ const mapDispatchToProps = dispatch => { return { goHome: () => dispatch(actions.goHome()), displayWarning: warning => dispatch(actions.displayWarning(warning)), - importNewAccount: options => dispatch(actions.importNewAccount('JSON File', options)), + importNewJsonAccount: options => dispatch(actions.importNewAccount('JSON File', options)), } } diff --git a/package-lock.json b/package-lock.json index 5f20689de..cece4756e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11369,8 +11369,8 @@ } }, "eth-hd-keyring": { - "version": "github:vbaranov/eth-hd-keyring#2c761c59e7cc978da6a612bf6d9833d8ea95efb5", - "from": "github:vbaranov/eth-hd-keyring#2.1.0", + "version": "github:vbaranov/eth-hd-keyring#487eec0e853cee95723f2efede99a0c722826b34", + "from": "github:vbaranov/eth-hd-keyring#2.1.1", "requires": { "bip39": "^2.2.0", "eth-sig-util": "^2.4.4", @@ -11632,19 +11632,18 @@ } }, "eth-keychain-controller": { - "version": "github:vbaranov/KeyringController#a39087f825b1cbffc663ef002d7d66ade3c5944b", - "from": "github:vbaranov/KeyringController#5.2.0", + "version": "github:vbaranov/KeyringController#7c32b3d0d7a35d09d2a85f8f339f499e3df44811", + "from": "github:vbaranov/KeyringController#5.3.1", "requires": { "bip39": "^2.4.0", "bluebird": "^3.5.0", "browser-passworder": "^2.0.3", - "eth-hd-keyring": "github:vbaranov/eth-hd-keyring#2.1.0", + "eth-hd-keyring": "github:vbaranov/eth-hd-keyring#2.1.1", "eth-sig-util": "^1.4.0", "eth-simple-keyring": "^3.5.0", "ethereumjs-util": "^5.1.2", "loglevel": "^1.5.0", - "obs-store": "^4.0.3", - "promise-filter": "^1.1.0" + "obs-store": "^4.0.3" }, "dependencies": { "eth-sig-util": { diff --git a/package.json b/package.json index b6e4e0089..d29ed6c0b 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "eth-json-rpc-filters": "github:poanetwork/eth-json-rpc-filters#3.0.2", "eth-json-rpc-infura": "^4.0.2", "eth-json-rpc-middleware": "^4.4.1", - "eth-keychain-controller": "github:vbaranov/KeyringController#5.2.0", + "eth-keychain-controller": "github:vbaranov/KeyringController#5.3.1", "eth-ledger-bridge-keyring": "github:vbaranov/eth-ledger-bridge-keyring#0.1.0-clear-accounts-flag", "eth-method-registry": "^1.0.0", "eth-net-props": "^1.0.33", From 2b0e11338f7f9d187c46b8ee196db49fade1e85e Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 13:37:26 +0300 Subject: [PATCH 12/20] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6c68aae7..218fefeb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password - [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen ## 5.0.2 Thu Apr 16 2020 From b20644da1e1c5160232e3f906aa6b708b82ba122 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 16:09:40 +0300 Subject: [PATCH 13/20] RSK: fix GasPrice calculation (changed output of minimumGasPrice) --- app/scripts/metamask-controller.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 6f4d4c941..e9db53a8d 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1886,7 +1886,7 @@ module.exports = class MetamaskController extends EventEmitter { resolve(gasPrice) } } else if (isRSK) { - gasPrice = this.getGasPriceFromLastBlockRSK(networkId) + gasPrice = this.getGasPriceFromLastBlockRSK() resolve(gasPrice) } else { gasPrice = this.getGasPriceFromBlocks(networkId) @@ -1937,7 +1937,7 @@ module.exports = class MetamaskController extends EventEmitter { * Related issue: https://github.com/poanetwork/nifty-wallet/issues/301 * @returns {string} A hex representation of the suggested wei gas price. */ - getGasPriceFromLastBlockRSK (networkId) { + getGasPriceFromLastBlockRSK () { const { recentBlocksController } = this const { recentBlocks } = recentBlocksController.store.getState() @@ -1946,10 +1946,8 @@ module.exports = class MetamaskController extends EventEmitter { const gasPrice = recentBlock && recentBlock.minimumGasPrice - const gasPriceInt = parseInt(gasPrice, 10) - - if (gasPriceInt !== 0) { - return '0x' + gasPriceInt.toString(16) + if (gasPrice !== 0) { + return gasPrice } else { return '0x' + GWEI_BN.toString(16) } From 1799d54fd61c6cfaffabc277119cad89d83b67ee Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 16:16:09 +0300 Subject: [PATCH 14/20] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffddd2cb7..248a2feef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- [#369](https://github.com/poanetwork/nifty-wallet/pull/369) - (Fix) RSK: fix GasPrice calculation (changed interface of minimumGasPrice - hex instead of integer) - [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password - [#366](https://github.com/poanetwork/nifty-wallet/pull/366) - (Fix) Increase max token symbol length up to 12 - [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen From 18d64749ae4e5c76dff0c5b227a9b5398d9e7960 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Wed, 29 Apr 2020 16:42:06 +0300 Subject: [PATCH 15/20] Fix unit tests --- app/scripts/metamask-controller.js | 6 +++--- test/unit/app/controllers/metamask-controller-test.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e9db53a8d..3421e07de 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1944,9 +1944,9 @@ module.exports = class MetamaskController extends EventEmitter { const recentBlock = recentBlocks .sort((block1, block2) => block1.number - block2.number)[recentBlocks.length - 1] - const gasPrice = recentBlock && recentBlock.minimumGasPrice - - if (gasPrice !== 0) { + const gasPrice = recentBlock && recentBlock.minimumGasPrice && recentBlock.minimumGasPrice.toString() + + if (gasPrice !== '0x' && gasPrice !== '0x0' && gasPrice !== '') { return gasPrice } else { return '0x' + GWEI_BN.toString(16) diff --git a/test/unit/app/controllers/metamask-controller-test.js b/test/unit/app/controllers/metamask-controller-test.js index 0bfbb5a75..6ceb5da81 100644 --- a/test/unit/app/controllers/metamask-controller-test.js +++ b/test/unit/app/controllers/metamask-controller-test.js @@ -161,9 +161,9 @@ describe('MetaMaskController', function () { getState: () => { return { recentBlocks: [ - { number: '0x1', minimumGasPrice: '59240010' }, - { number: '0x2', minimumGasPrice: '59240005' }, - { number: '0x3', minimumGasPrice: '59240000' }, + { number: '0x1', minimumGasPrice: '0x387ee48' }, + { number: '0x2', minimumGasPrice: '0x387ee42' }, + { number: '0x3', minimumGasPrice: '0x387ee40' }, ], } }, @@ -175,7 +175,7 @@ describe('MetaMaskController', function () { getState: () => { return { recentBlocks: [ - { number: '0x4', minimumGasPrice: '0' }, + { number: '0x4', minimumGasPrice: '0x' }, ], } }, From 5b11748cf37c3e02f5865ba15164266b3341915b Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 30 Apr 2020 12:45:54 +0300 Subject: [PATCH 16/20] Update RSK contracts metadata repo --- app/scripts/controllers/detect-tokens.js | 4 ++-- gulpfile.js | 4 ++-- .../add-token/token-search/token-search.component.js | 4 ++-- old-ui/app/components/token-list.js | 4 ++-- old-ui/lib/icon-factory.js | 4 ++-- package-lock.json | 12 ++++++++---- package.json | 4 ++-- ui/app/token-util.js | 4 ++-- 8 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/scripts/controllers/detect-tokens.js b/app/scripts/controllers/detect-tokens.js index 80381f402..f468213fb 100644 --- a/app/scripts/controllers/detect-tokens.js +++ b/app/scripts/controllers/detect-tokens.js @@ -1,8 +1,8 @@ import Web3 from 'web3' import contractsETH from 'eth-contract-metadata' import contractsPOA from 'poa-contract-metadata' -import contractsRSK from 'rsk-contract-metadata' -import contractsRSKTest from 'rsk-test-contract-metadata' +import contractsRSK from '@rsksmart/rsk-contract-metadata' +import contractsRSKTest from '@rsksmart/rsk-testnet-contract-metadata' import { warn } from 'loglevel' const { MAINNET, POA, RSK, RSK_TESTNET } = require('./network/enums') // By default, poll every 3 minutes diff --git a/gulpfile.js b/gulpfile.js index d4508336b..9e5326c2a 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -73,11 +73,11 @@ createCopyTasks('contractImagesPOA', { destinations: commonPlatforms.map(platform => `./dist/${platform}/images/contractPOA`), }) createCopyTasks('contractImagesRSK', { - source: './node_modules/rsk-contract-metadata/images/', + source: './node_modules/@rsksmart/rsk-contract-metadata/images/', destinations: commonPlatforms.map(platform => `./dist/${platform}/images/contractRSK`), }) createCopyTasks('contractImagesRSKTest', { - source: './node_modules/rsk-test-contract-metadata/images/', + source: './node_modules/@rsksmart/rsk-testnet-contract-metadata/images/', destinations: commonPlatforms.map(platform => `./dist/${platform}/images/contractRSKTest`), }) createCopyTasks('fonts', { diff --git a/old-ui/app/components/add-token/token-search/token-search.component.js b/old-ui/app/components/add-token/token-search/token-search.component.js index e3a36b8b9..c17828655 100644 --- a/old-ui/app/components/add-token/token-search/token-search.component.js +++ b/old-ui/app/components/add-token/token-search/token-search.component.js @@ -2,8 +2,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import contractMapETH from 'eth-contract-metadata' import contractMapPOA from 'poa-contract-metadata' -import contractMapRSK from 'rsk-contract-metadata' -import contractMapRSKTest from 'rsk-test-contract-metadata' +import contractMapRSK from '@rsksmart/rsk-contract-metadata' +import contractMapRSKTest from '@rsksmart/rsk-testnet-contract-metadata' import Fuse from 'fuse.js' import InputAdornment from '@material-ui/core/InputAdornment' import TextField from '../../../../../ui/app/components/text-field' diff --git a/old-ui/app/components/token-list.js b/old-ui/app/components/token-list.js index 95550b545..eee577044 100644 --- a/old-ui/app/components/token-list.js +++ b/old-ui/app/components/token-list.js @@ -19,8 +19,8 @@ const defaultTokens = [] const contractsETH = require('eth-contract-metadata') const contractsPOA = require('poa-contract-metadata') -const contractsRSK = require('rsk-contract-metadata') -const contractsRSKTest = require('rsk-test-contract-metadata') +const contractsRSK = require('@rsksmart/rsk-contract-metadata') +const contractsRSKTest = require('@rsksmart/rsk-testnet-contract-metadata') for (const address in contractsETH) { const contract = contractsETH[address] if (contract.erc20) { diff --git a/old-ui/lib/icon-factory.js b/old-ui/lib/icon-factory.js index 74ef65e56..9db318f6f 100644 --- a/old-ui/lib/icon-factory.js +++ b/old-ui/lib/icon-factory.js @@ -1,8 +1,8 @@ import { isValidAddress } from 'ethereumjs-util' import contractMapETH from 'eth-contract-metadata' import contractMapPOA from 'poa-contract-metadata' -import contractMapRSK from 'rsk-contract-metadata' -import contractMapRSKTest from 'rsk-test-contract-metadata' +import contractMapRSK from '@rsksmart/rsk-contract-metadata' +import contractMapRSKTest from '@rsksmart/rsk-testnet-contract-metadata' import { MAINNET_CODE, POA_CODE, RSK_CODE, RSK_TESTNET_CODE } from '../../app/scripts/controllers/network/enums' const colors = require('../../colors') const { toChecksumAddress, getTokenImageFolder } = require('../app/util') diff --git a/package-lock.json b/package-lock.json index cece4756e..e3f52d9e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1966,6 +1966,14 @@ "react-lifecycles-compat": "^3.0.4" } }, + "@rsksmart/rsk-contract-metadata": { + "version": "github:rsksmart/rsk-contract-metadata#d7913739e5ee93dac8667043e2c17b0ef339c206", + "from": "github:rsksmart/rsk-contract-metadata#master" + }, + "@rsksmart/rsk-testnet-contract-metadata": { + "version": "github:rsksmart/rsk-testnet-contract-metadata#2b89e70d36d2aa58cae68ac817debbf3c451690a", + "from": "github:rsksmart/rsk-testnet-contract-metadata#master" + }, "@sentry/cli": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.52.0.tgz", @@ -49791,10 +49799,6 @@ "uuid": "^3.3.2" } }, - "rsk-contract-metadata": { - "version": "github:rsksmart/rsk-contract-metadata#262495abfa6ff83fb9cd46c7fb9f85690e4e5d4b", - "from": "github:rsksmart/rsk-contract-metadata#master" - }, "rsk-test-contract-metadata": { "version": "github:rsksmart/rsk-testnet-contract-metadata#69ff2d652b286648e9264e2689009e940ec7ccad", "from": "github:rsksmart/rsk-testnet-contract-metadata#master" diff --git a/package.json b/package.json index d29ed6c0b..e7d4a39c4 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,8 @@ "dependencies": { "@babel/runtime": "^7.5.5", "@material-ui/core": "^4.1.1", + "@rsksmart/rsk-contract-metadata": "github:rsksmart/rsk-contract-metadata#master", + "@rsksmart/rsk-testnet-contract-metadata": "github:rsksmart/rsk-testnet-contract-metadata#master", "@zxing/library": "^0.8.0", "abi-decoder": "^1.2.0", "asmcrypto.js": "0.22.0", @@ -198,8 +200,6 @@ "reselect": "^3.0.1", "rockicon": "^1.0.0", "rpc-cap": "^2.0.0", - "rsk-contract-metadata": "github:rsksmart/rsk-contract-metadata#master", - "rsk-test-contract-metadata": "github:rsksmart/rsk-testnet-contract-metadata#master", "sandwich-expando": "^1.1.3", "semaphore": "^1.0.5", "semver": "^5.4.1", diff --git a/ui/app/token-util.js b/ui/app/token-util.js index 2e516bf4d..d72f042e8 100644 --- a/ui/app/token-util.js +++ b/ui/app/token-util.js @@ -2,8 +2,8 @@ import log from 'loglevel' import BigNumber from 'bignumber.js' import contractMapETH from 'eth-contract-metadata' import contractMapPOA from 'poa-contract-metadata' -import contractMapRSK from 'rsk-contract-metadata' -import contractMapRSKTest from 'rsk-test-contract-metadata' +import contractMapRSK from '@rsksmart/rsk-contract-metadata' +import contractMapRSKTest from '@rsksmart/rsk-testnet-contract-metadata' const util = require('./util') const casedContractMapETH = Object.keys(contractMapETH).reduce((acc, base) => { From dcc03caad12112137f1f5aacbe2947cb48e21f0c Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Thu, 30 Apr 2020 12:53:43 +0300 Subject: [PATCH 17/20] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 248a2feef..0c494e51d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- [#372](https://github.com/poanetwork/nifty-wallet/pull/372) - (Chore) Update RSK contracts metadata repo - [#369](https://github.com/poanetwork/nifty-wallet/pull/369) - (Fix) RSK: fix GasPrice calculation (changed interface of minimumGasPrice - hex instead of integer) - [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password - [#366](https://github.com/poanetwork/nifty-wallet/pull/366) - (Fix) Increase max token symbol length up to 12 From c9def98cf77f53a3790a3170d036a9b3555c0b78 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Fri, 1 May 2020 17:06:22 +0300 Subject: [PATCH 18/20] Add Stake token --- package-lock.json | 10 +++------- package.json | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3f52d9e7..90407ee7c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11363,9 +11363,9 @@ } }, "eth-contract-metadata": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/eth-contract-metadata/-/eth-contract-metadata-1.12.1.tgz", - "integrity": "sha512-9u2jUcdxaKIv4RvA9RtjyD4+M2yWt4yCulR5bpdQTiG3HUFnN9lHtNL5NIRDpvQVJKerFhexrgEM2WdGP3a6VA==" + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/eth-contract-metadata/-/eth-contract-metadata-1.13.0.tgz", + "integrity": "sha512-9CjXHX8IdXysUEvOHdbCsjdAwM1E98jaeK2HeOqm/9S/vOZ8YryaBBt/YSiBq3MkpCwf+d1pEQ53p96rsdy52w==" }, "eth-ens-namehash": { "version": "2.0.8", @@ -49799,10 +49799,6 @@ "uuid": "^3.3.2" } }, - "rsk-test-contract-metadata": { - "version": "github:rsksmart/rsk-testnet-contract-metadata#69ff2d652b286648e9264e2689009e940ec7ccad", - "from": "github:rsksmart/rsk-testnet-contract-metadata#master" - }, "rst-selector-parser": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz", diff --git a/package.json b/package.json index e7d4a39c4..463f61538 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "dnode": "^1.2.2", "end-of-stream": "^1.4.4", "eth-block-tracker": "^4.4.2", - "eth-contract-metadata": "^1.12.1", + "eth-contract-metadata": "^1.13.0", "eth-ens-namehash": "^2.0.8", "eth-json-rpc-errors": "^2.0.2", "eth-json-rpc-filters": "github:poanetwork/eth-json-rpc-filters#3.0.2", From 975799589745381e64b9c09ee1bb945548942b9a Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Fri, 1 May 2020 17:07:57 +0300 Subject: [PATCH 19/20] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c494e51d..c799d3805 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Current Master +- [#373](https://github.com/poanetwork/nifty-wallet/pull/373) - (Feature) Add STAKE token - [#372](https://github.com/poanetwork/nifty-wallet/pull/372) - (Chore) Update RSK contracts metadata repo - [#369](https://github.com/poanetwork/nifty-wallet/pull/369) - (Fix) RSK: fix GasPrice calculation (changed interface of minimumGasPrice - hex instead of integer) - [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password From 5e49fa72b46080689a4dc1d2c3c8c91cf352c865 Mon Sep 17 00:00:00 2001 From: Victor Baranov Date: Fri, 1 May 2020 17:24:26 +0300 Subject: [PATCH 20/20] Bump version: 5.0.3 --- CHANGELOG.md | 2 ++ app/manifest.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c799d3805..a8b6d258e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Current Master +## 5.0.3 Fri May 01 2020 + - [#373](https://github.com/poanetwork/nifty-wallet/pull/373) - (Feature) Add STAKE token - [#372](https://github.com/poanetwork/nifty-wallet/pull/372) - (Chore) Update RSK contracts metadata repo - [#369](https://github.com/poanetwork/nifty-wallet/pull/369) - (Fix) RSK: fix GasPrice calculation (changed interface of minimumGasPrice - hex instead of integer) diff --git a/app/manifest.json b/app/manifest.json index c4c49818c..8350e7259 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "__MSG_appName__", - "version": "5.0.2", + "version": "5.0.3", "manifest_version": 2, "author": "POA Network", "description": "__MSG_appDescription__",