mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Use send
state for send flow token (#8695)
The chosen token in the `send` flow was set from one of two places: `metamask.selectedTokenAddress` or `metamask.send.token`. The former is used most of the time, but the latter is used for the 'Edit' button shown in the upper-left of the confirmation UI. The send flow will now exclusively use `metamask.send.token` for the token state during the send flow. `metamask.selectedTokenAddress` is now only used for the selected token state on the Home screen. This simplifies the Redux state, as the send token is now in one place instead of two, and `metamask.selectedTokenAddress` has only one purpose.
This commit is contained in:
parent
e481166052
commit
ddaa492751
@ -28,7 +28,7 @@ import {
|
||||
getCurrentCurrency,
|
||||
getCurrentEthBalance,
|
||||
getIsMainnet,
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
isEthereumNetwork,
|
||||
getPreferences,
|
||||
getBasicGasEstimateLoadingStatus,
|
||||
@ -75,7 +75,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
|
||||
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state)
|
||||
const gasEstimatesLoading = getGasEstimatesLoadingStatus(state)
|
||||
const selectedToken = getSelectedToken(state)
|
||||
const sendToken = getSendToken(state)
|
||||
|
||||
// a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case
|
||||
const txParams = selectedTransaction?.txParams
|
||||
@ -83,7 +83,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
: {
|
||||
gas: send.gasLimit || '0x5208',
|
||||
gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true),
|
||||
value: selectedToken ? '0x0' : send.amount,
|
||||
value: sendToken ? '0x0' : send.amount,
|
||||
}
|
||||
|
||||
const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = txParams
|
||||
@ -112,11 +112,11 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const isMainnet = getIsMainnet(state)
|
||||
const showFiat = Boolean(isMainnet || showFiatInTestnets)
|
||||
|
||||
const isTokenSelected = Boolean(selectedToken)
|
||||
const isSendTokenSet = Boolean(sendToken)
|
||||
|
||||
const newTotalEth = maxModeOn && !isTokenSelected ? addHexWEIsToRenderableEth(balance, '0x0') : addHexWEIsToRenderableEth(value, customGasTotal)
|
||||
const newTotalEth = maxModeOn && !isSendTokenSet ? addHexWEIsToRenderableEth(balance, '0x0') : addHexWEIsToRenderableEth(value, customGasTotal)
|
||||
|
||||
const sendAmount = maxModeOn && !isTokenSelected ? subtractHexWEIsFromRenderableEth(balance, customGasTotal) : addHexWEIsToRenderableEth(value, '0x0')
|
||||
const sendAmount = maxModeOn && !isSendTokenSet ? subtractHexWEIsFromRenderableEth(balance, customGasTotal) : addHexWEIsToRenderableEth(value, '0x0')
|
||||
|
||||
const insufficientBalance = maxModeOn ? false : !isBalanceSufficient({
|
||||
amount: value,
|
||||
@ -167,7 +167,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
gasEstimatesLoading,
|
||||
isMainnet,
|
||||
isEthereumNetwork: isEthereumNetwork(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken,
|
||||
balance,
|
||||
tokenBalance: getTokenBalance(state),
|
||||
}
|
||||
@ -223,7 +223,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||
customGasPrice,
|
||||
customGasTotal,
|
||||
balance,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
customGasLimit,
|
||||
transaction,
|
||||
@ -274,7 +274,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
|
||||
dispatchSetAmountToMax({
|
||||
balance,
|
||||
gasTotal: customGasTotal,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ proxyquire('../gas-modal-page-container.container.js', {
|
||||
getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`,
|
||||
getDefaultActiveButtonIndex: (a, b) => a + b,
|
||||
getCurrentEthBalance: (state) => state.metamask.balance || '0x0',
|
||||
getSelectedToken: () => null,
|
||||
getSendToken: () => null,
|
||||
getTokenBalance: (state) => state.metamask.send.tokenBalance || '0x0',
|
||||
},
|
||||
'../../../../store/actions': actionSpies,
|
||||
@ -158,7 +158,7 @@ describe('gas-modal-page-container container', function () {
|
||||
isEthereumNetwork: true,
|
||||
isMainnet: true,
|
||||
maxModeOn: false,
|
||||
selectedToken: null,
|
||||
sendToken: null,
|
||||
tokenBalance: '0x0',
|
||||
transaction: {
|
||||
id: 34,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useContext } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
import Button from '../../ui/button'
|
||||
@ -11,8 +11,10 @@ import WalletOverview from './wallet-overview'
|
||||
import { SEND_ROUTE } from '../../../helpers/constants/routes'
|
||||
import { useMetricEvent } from '../../../hooks/useMetricEvent'
|
||||
import { getAssetImages } from '../../../selectors/selectors'
|
||||
import { updateSend } from '../../../store/actions'
|
||||
|
||||
const TokenOverview = ({ token }) => {
|
||||
const dispatch = useDispatch()
|
||||
const t = useContext(I18nContext)
|
||||
const sendTokenEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
@ -41,6 +43,7 @@ const TokenOverview = ({ token }) => {
|
||||
className="token-overview__button"
|
||||
onClick={() => {
|
||||
sendTokenEvent()
|
||||
dispatch(updateSend({ token }))
|
||||
history.push(SEND_ROUTE)
|
||||
}}
|
||||
>
|
||||
|
@ -1,16 +1,14 @@
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { useCallback } from 'react'
|
||||
import { setSelectedToken, showSidebar } from '../store/actions'
|
||||
import { showSidebar } from '../store/actions'
|
||||
import {
|
||||
fetchBasicGasAndTimeEstimates,
|
||||
fetchGasEstimates,
|
||||
setCustomGasPriceForRetry,
|
||||
setCustomGasLimit,
|
||||
} from '../ducks/gas/gas.duck'
|
||||
import { TOKEN_METHOD_TRANSFER } from '../helpers/constants/transactions'
|
||||
import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util'
|
||||
import { useMetricEvent } from './useMetricEvent'
|
||||
import { useMethodData } from './useMethodData'
|
||||
|
||||
|
||||
/**
|
||||
@ -22,7 +20,6 @@ import { useMethodData } from './useMethodData'
|
||||
export function useRetryTransaction (transactionGroup) {
|
||||
const { primaryTransaction, initialTransaction } = transactionGroup
|
||||
const gasPrice = primaryTransaction.txParams.gasPrice
|
||||
const methodData = useMethodData(primaryTransaction.txParams.data)
|
||||
const trackMetricsEvent = useMetricEvent(({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
@ -32,8 +29,6 @@ export function useRetryTransaction (transactionGroup) {
|
||||
}))
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const { name: methodName } = methodData || {}
|
||||
|
||||
const retryTransaction = useCallback(async (event) => {
|
||||
event.stopPropagation()
|
||||
|
||||
@ -49,14 +44,7 @@ export function useRetryTransaction (transactionGroup) {
|
||||
type: 'customize-gas',
|
||||
props: { transaction },
|
||||
}))
|
||||
|
||||
if (
|
||||
methodName === TOKEN_METHOD_TRANSFER &&
|
||||
initialTransaction.txParams.to
|
||||
) {
|
||||
dispatch(setSelectedToken(initialTransaction.txParams.to))
|
||||
}
|
||||
}, [dispatch, methodName, trackMetricsEvent, initialTransaction, gasPrice])
|
||||
}, [dispatch, trackMetricsEvent, initialTransaction, gasPrice])
|
||||
|
||||
return retryTransaction
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { compose } from 'redux'
|
||||
import { withRouter } from 'react-router-dom'
|
||||
import ConfirmSendToken from './confirm-send-token.component'
|
||||
import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'
|
||||
import { setSelectedToken, updateSend, showSendTokenPage } from '../../store/actions'
|
||||
import { updateSend, showSendTokenPage } from '../../store/actions'
|
||||
import { conversionUtil } from '../../helpers/utils/conversion-util'
|
||||
import { sendTokenTokenAmountAndToAddressSelector } from '../../selectors'
|
||||
|
||||
@ -38,7 +38,6 @@ const mapDispatchToProps = (dispatch) => {
|
||||
toNumericBase: 'hex',
|
||||
})
|
||||
|
||||
dispatch(setSelectedToken(tokenAddress))
|
||||
dispatch(updateSend({
|
||||
from,
|
||||
gasLimit,
|
||||
|
@ -24,9 +24,9 @@ export function getToErrorObject (to, hasHexData = false, _, __, network) {
|
||||
return { to: toError }
|
||||
}
|
||||
|
||||
export function getToWarningObject (to, tokens = [], selectedToken = null) {
|
||||
export function getToWarningObject (to, tokens = [], sendToken = null) {
|
||||
let toWarning = null
|
||||
if (selectedToken && (ethUtil.toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens))) {
|
||||
if (sendToken && (ethUtil.toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens))) {
|
||||
toWarning = KNOWN_RECIPIENT_ADDRESS_ERROR
|
||||
}
|
||||
return { to: toWarning }
|
||||
|
@ -55,7 +55,7 @@ describe('add-recipient utils', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should null if to is truthy part of tokens but selectedToken falsy', function () {
|
||||
it('should null if to is truthy part of tokens but sendToken falsy', function () {
|
||||
assert.deepEqual(getToErrorObject('0xabc123', false, [{ 'address': '0xabc123' }]), {
|
||||
to: null,
|
||||
})
|
||||
@ -66,7 +66,7 @@ describe('add-recipient utils', function () {
|
||||
to: null,
|
||||
})
|
||||
})
|
||||
it('should null if to is truthy part of contract metadata but selectedToken falsy', function () {
|
||||
it('should null if to is truthy part of contract metadata but sendToken falsy', function () {
|
||||
assert.deepEqual(getToErrorObject('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', false, [{ 'address': '0xabc123' }], { 'address': '0xabc123' }), {
|
||||
to: null,
|
||||
})
|
||||
@ -80,7 +80,7 @@ describe('add-recipient utils', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should null if to is truthy part of tokens but selectedToken falsy', function () {
|
||||
it('should null if to is truthy part of tokens but sendToken falsy', function () {
|
||||
assert.deepEqual(getToWarningObject('0xabc123', [{ 'address': '0xabc123' }]), {
|
||||
to: null,
|
||||
})
|
||||
@ -91,7 +91,7 @@ describe('add-recipient utils', function () {
|
||||
to: KNOWN_RECIPIENT_ADDRESS_ERROR,
|
||||
})
|
||||
})
|
||||
it('should null if to is truthy part of contract metadata but selectedToken falsy', function () {
|
||||
it('should null if to is truthy part of contract metadata but sendToken falsy', function () {
|
||||
assert.deepEqual(getToWarningObject('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', [{ 'address': '0xabc123' }], { 'address': '0xabc123' }), {
|
||||
to: KNOWN_RECIPIENT_ADDRESS_ERROR,
|
||||
})
|
||||
|
@ -11,7 +11,7 @@ export default class AmountMaxButton extends Component {
|
||||
inError: PropTypes.bool,
|
||||
gasTotal: PropTypes.string,
|
||||
maxModeOn: PropTypes.bool,
|
||||
selectedToken: PropTypes.object,
|
||||
sendToken: PropTypes.object,
|
||||
setAmountToMax: PropTypes.func,
|
||||
setMaxModeTo: PropTypes.func,
|
||||
tokenBalance: PropTypes.string,
|
||||
@ -27,7 +27,7 @@ export default class AmountMaxButton extends Component {
|
||||
const {
|
||||
balance,
|
||||
gasTotal,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
setAmountToMax,
|
||||
tokenBalance,
|
||||
} = this.props
|
||||
@ -35,7 +35,7 @@ export default class AmountMaxButton extends Component {
|
||||
setAmountToMax({
|
||||
balance,
|
||||
gasTotal,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { connect } from 'react-redux'
|
||||
import {
|
||||
getGasTotal,
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
getSendFromBalance,
|
||||
getTokenBalance,
|
||||
getSendMaxModeState,
|
||||
@ -26,7 +26,7 @@ function mapStateToProps (state) {
|
||||
buttonDataLoading: getBasicGasEstimateLoadingStatus(state),
|
||||
gasTotal: getGasTotal(state),
|
||||
maxModeOn: getSendMaxModeState(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken: getSendToken(state),
|
||||
tokenBalance: getTokenBalance(state),
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { multiplyCurrencies, subtractCurrencies } from '../../../../../helpers/utils/conversion-util'
|
||||
import ethUtil from 'ethereumjs-util'
|
||||
|
||||
export function calcMaxAmount ({ balance, gasTotal, selectedToken, tokenBalance }) {
|
||||
const { decimals } = selectedToken || {}
|
||||
export function calcMaxAmount ({ balance, gasTotal, sendToken, tokenBalance }) {
|
||||
const { decimals } = sendToken || {}
|
||||
const multiplier = Math.pow(10, Number(decimals || 0))
|
||||
|
||||
return selectedToken
|
||||
return sendToken
|
||||
? multiplyCurrencies(
|
||||
tokenBalance,
|
||||
multiplier,
|
||||
|
@ -25,7 +25,7 @@ describe('AmountMaxButton Component', function () {
|
||||
balance="mockBalance"
|
||||
gasTotal="mockGasTotal"
|
||||
maxModeOn={false}
|
||||
selectedToken={ { address: 'mockTokenAddress' } }
|
||||
sendToken={ { address: 'mockTokenAddress' } }
|
||||
setAmountToMax={propsMethodSpies.setAmountToMax}
|
||||
setMaxModeTo={propsMethodSpies.setMaxModeTo}
|
||||
tokenBalance="mockTokenBalance"
|
||||
@ -60,7 +60,7 @@ describe('AmountMaxButton Component', function () {
|
||||
[{
|
||||
balance: 'mockBalance',
|
||||
gasTotal: 'mockGasTotal',
|
||||
selectedToken: { address: 'mockTokenAddress' },
|
||||
sendToken: { address: 'mockTokenAddress' },
|
||||
tokenBalance: 'mockTokenBalance',
|
||||
}]
|
||||
)
|
||||
|
@ -23,7 +23,7 @@ proxyquire('../amount-max-button.container.js', {
|
||||
},
|
||||
'../../../../../selectors': {
|
||||
getGasTotal: (s) => `mockGasTotal:${s}`,
|
||||
getSelectedToken: (s) => `mockSelectedToken:${s}`,
|
||||
getSendToken: (s) => `mockSendToken:${s}`,
|
||||
getSendFromBalance: (s) => `mockBalance:${s}`,
|
||||
getTokenBalance: (s) => `mockTokenBalance:${s}`,
|
||||
getSendMaxModeState: (s) => `mockMaxModeOn:${s}`,
|
||||
@ -44,7 +44,7 @@ describe('amount-max-button container', function () {
|
||||
buttonDataLoading: 'mockButtonDataLoading:mockState',
|
||||
gasTotal: 'mockGasTotal:mockState',
|
||||
maxModeOn: 'mockMaxModeOn:mockState',
|
||||
selectedToken: 'mockSelectedToken:mockState',
|
||||
sendToken: 'mockSendToken:mockState',
|
||||
tokenBalance: 'mockTokenBalance:mockState',
|
||||
})
|
||||
})
|
||||
|
@ -6,17 +6,17 @@ import {
|
||||
describe('amount-max-button utils', function () {
|
||||
|
||||
describe('calcMaxAmount()', function () {
|
||||
it('should calculate the correct amount when no selectedToken defined', function () {
|
||||
it('should calculate the correct amount when no sendToken defined', function () {
|
||||
assert.deepEqual(calcMaxAmount({
|
||||
balance: 'ffffff',
|
||||
gasTotal: 'ff',
|
||||
selectedToken: false,
|
||||
sendToken: false,
|
||||
}), 'ffff00')
|
||||
})
|
||||
|
||||
it('should calculate the correct amount when a selectedToken is defined', function () {
|
||||
it('should calculate the correct amount when a sendToken is defined', function () {
|
||||
assert.deepEqual(calcMaxAmount({
|
||||
selectedToken: {
|
||||
sendToken: {
|
||||
decimals: 10,
|
||||
},
|
||||
tokenBalance: '64',
|
||||
|
@ -15,7 +15,7 @@ export default class SendAmountRow extends Component {
|
||||
gasTotal: PropTypes.string,
|
||||
inError: PropTypes.bool,
|
||||
primaryCurrency: PropTypes.string,
|
||||
selectedToken: PropTypes.object,
|
||||
sendToken: PropTypes.object,
|
||||
setMaxModeTo: PropTypes.func,
|
||||
tokenBalance: PropTypes.string,
|
||||
updateGasFeeError: PropTypes.func,
|
||||
@ -31,9 +31,9 @@ export default class SendAmountRow extends Component {
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
const { maxModeOn: prevMaxModeOn, gasTotal: prevGasTotal } = prevProps
|
||||
const { maxModeOn, amount, gasTotal, selectedToken } = this.props
|
||||
const { maxModeOn, amount, gasTotal, sendToken } = this.props
|
||||
|
||||
if (maxModeOn && selectedToken && !prevMaxModeOn) {
|
||||
if (maxModeOn && sendToken && !prevMaxModeOn) {
|
||||
this.updateGas(amount)
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ export default class SendAmountRow extends Component {
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
updateGasFeeError,
|
||||
updateSendAmountError,
|
||||
@ -62,17 +62,17 @@ export default class SendAmountRow extends Component {
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
|
||||
if (selectedToken) {
|
||||
if (sendToken) {
|
||||
updateGasFeeError({
|
||||
balance,
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
}
|
||||
@ -86,9 +86,9 @@ export default class SendAmountRow extends Component {
|
||||
}
|
||||
|
||||
updateGas (amount) {
|
||||
const { selectedToken, updateGas } = this.props
|
||||
const { sendToken, updateGas } = this.props
|
||||
|
||||
if (selectedToken) {
|
||||
if (sendToken) {
|
||||
updateGas({ amount })
|
||||
}
|
||||
}
|
||||
@ -100,14 +100,14 @@ export default class SendAmountRow extends Component {
|
||||
}
|
||||
|
||||
renderInput () {
|
||||
const { amount, inError, selectedToken } = this.props
|
||||
const { amount, inError, sendToken } = this.props
|
||||
|
||||
return selectedToken ?
|
||||
return sendToken ?
|
||||
(
|
||||
<UserPreferencedTokenInput
|
||||
error={inError}
|
||||
onChange={this.handleChange}
|
||||
token={selectedToken}
|
||||
token={sendToken}
|
||||
value={amount}
|
||||
/>
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
getConversionRate,
|
||||
getGasTotal,
|
||||
getPrimaryCurrency,
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
getSendAmount,
|
||||
getSendFromBalance,
|
||||
getTokenBalance,
|
||||
@ -30,7 +30,7 @@ function mapStateToProps (state) {
|
||||
gasTotal: getGasTotal(state),
|
||||
inError: sendAmountIsInError(state),
|
||||
primaryCurrency: getPrimaryCurrency(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken: getSendToken(state),
|
||||
tokenBalance: getTokenBalance(state),
|
||||
maxModeOn: getSendMaxModeState(state),
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ describe('SendAmountRow Component', function () {
|
||||
conversionRate: 7,
|
||||
gasTotal: 'mockGasTotal',
|
||||
primaryCurrency: 'mockPrimaryCurrency',
|
||||
selectedToken: { address: 'mockTokenAddress' },
|
||||
sendToken: { address: 'mockTokenAddress' },
|
||||
tokenBalance: 'mockTokenBalance',
|
||||
}))
|
||||
})
|
||||
|
||||
it('should call updateGasFeeError if selectedToken is truthy', function () {
|
||||
it('should call updateGasFeeError if sendToken is truthy', function () {
|
||||
const { instance, propsMethodSpies: { updateGasFeeError } } = shallowRenderSendAmountRow()
|
||||
|
||||
assert.equal(updateGasFeeError.callCount, 0)
|
||||
@ -40,15 +40,15 @@ describe('SendAmountRow Component', function () {
|
||||
conversionRate: 7,
|
||||
gasTotal: 'mockGasTotal',
|
||||
primaryCurrency: 'mockPrimaryCurrency',
|
||||
selectedToken: { address: 'mockTokenAddress' },
|
||||
sendToken: { address: 'mockTokenAddress' },
|
||||
tokenBalance: 'mockTokenBalance',
|
||||
}))
|
||||
})
|
||||
|
||||
it('should call not updateGasFeeError if selectedToken is falsey', function () {
|
||||
it('should call not updateGasFeeError if sendToken is falsey', function () {
|
||||
const { wrapper, instance, propsMethodSpies: { updateGasFeeError } } = shallowRenderSendAmountRow()
|
||||
|
||||
wrapper.setProps({ selectedToken: null })
|
||||
wrapper.setProps({ sendToken: null })
|
||||
|
||||
assert.equal(updateGasFeeError.callCount, 0)
|
||||
|
||||
@ -152,7 +152,7 @@ function shallowRenderSendAmountRow () {
|
||||
gasTotal="mockGasTotal"
|
||||
inError={false}
|
||||
primaryCurrency="mockPrimaryCurrency"
|
||||
selectedToken={ { address: 'mockTokenAddress' } }
|
||||
sendToken={ { address: 'mockTokenAddress' } }
|
||||
setMaxModeTo={setMaxModeTo}
|
||||
tokenBalance="mockTokenBalance"
|
||||
updateGasFeeError={updateGasFeeError}
|
||||
|
@ -17,8 +17,8 @@ export default class SendAssetRow extends Component {
|
||||
).isRequired,
|
||||
accounts: PropTypes.object.isRequired,
|
||||
selectedAddress: PropTypes.string.isRequired,
|
||||
selectedTokenAddress: PropTypes.string,
|
||||
setSelectedToken: PropTypes.func.isRequired,
|
||||
sendTokenAddress: PropTypes.string,
|
||||
setSendToken: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
@ -34,7 +34,7 @@ export default class SendAssetRow extends Component {
|
||||
|
||||
closeDropdown = () => this.setState({ isShowingDropdown: false })
|
||||
|
||||
selectToken = (address) => {
|
||||
selectToken = (token) => {
|
||||
this.setState({
|
||||
isShowingDropdown: false,
|
||||
}, () => {
|
||||
@ -45,10 +45,10 @@ export default class SendAssetRow extends Component {
|
||||
name: 'User clicks "Assets" dropdown',
|
||||
},
|
||||
customVariables: {
|
||||
assetSelected: address ? 'ERC20' : 'ETH',
|
||||
assetSelected: token ? 'ERC20' : 'ETH',
|
||||
},
|
||||
})
|
||||
this.props.setSelectedToken(address)
|
||||
this.props.setSendToken(token)
|
||||
})
|
||||
}
|
||||
|
||||
@ -58,16 +58,16 @@ export default class SendAssetRow extends Component {
|
||||
return (
|
||||
<SendRowWrapper label={`${t('asset')}:`}>
|
||||
<div className="send-v2__asset-dropdown">
|
||||
{ this.renderSelectedToken() }
|
||||
{ this.renderSendToken() }
|
||||
{ this.props.tokens.length > 0 ? this.renderAssetDropdown() : null }
|
||||
</div>
|
||||
</SendRowWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
renderSelectedToken () {
|
||||
const { selectedTokenAddress } = this.props
|
||||
const token = this.props.tokens.find(({ address }) => address === selectedTokenAddress)
|
||||
renderSendToken () {
|
||||
const { sendTokenAddress } = this.props
|
||||
const token = this.props.tokens.find(({ address }) => address === sendTokenAddress)
|
||||
return (
|
||||
<div
|
||||
className="send-v2__asset-dropdown__input-wrapper"
|
||||
@ -133,7 +133,7 @@ export default class SendAssetRow extends Component {
|
||||
<div
|
||||
key={address}
|
||||
className="send-v2__asset-dropdown__asset"
|
||||
onClick={() => this.selectToken(address)}
|
||||
onClick={() => this.selectToken(token)}
|
||||
>
|
||||
<div className="send-v2__asset-dropdown__asset-icon">
|
||||
<Identicon address={address} diameter={36} />
|
||||
|
@ -1,20 +1,20 @@
|
||||
import { connect } from 'react-redux'
|
||||
import SendAssetRow from './send-asset-row.component'
|
||||
import { getMetaMaskAccounts } from '../../../../selectors'
|
||||
import { setSelectedToken } from '../../../../store/actions'
|
||||
import { getMetaMaskAccounts, getSendTokenAddress } from '../../../../selectors'
|
||||
import { updateSend } from '../../../../store/actions'
|
||||
|
||||
function mapStateToProps (state) {
|
||||
return {
|
||||
tokens: state.metamask.tokens,
|
||||
selectedAddress: state.metamask.selectedAddress,
|
||||
selectedTokenAddress: state.metamask.selectedTokenAddress,
|
||||
sendTokenAddress: getSendTokenAddress(state),
|
||||
accounts: getMetaMaskAccounts(state),
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
setSelectedToken: (address) => dispatch(setSelectedToken(address)),
|
||||
setSendToken: (token) => dispatch(updateSend({ token })),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ export default class SendGasRow extends Component {
|
||||
gasTotal: PropTypes.string,
|
||||
maxModeOn: PropTypes.bool,
|
||||
showCustomizeGasModal: PropTypes.func,
|
||||
selectedToken: PropTypes.object,
|
||||
sendToken: PropTypes.object,
|
||||
setAmountToMax: PropTypes.func,
|
||||
setGasPrice: PropTypes.func,
|
||||
setGasLimit: PropTypes.func,
|
||||
@ -59,7 +59,7 @@ export default class SendGasRow extends Component {
|
||||
const {
|
||||
balance,
|
||||
gasTotal,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
setAmountToMax,
|
||||
tokenBalance,
|
||||
} = this.props
|
||||
@ -67,7 +67,7 @@ export default class SendGasRow extends Component {
|
||||
setAmountToMax({
|
||||
balance,
|
||||
gasTotal,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
getGasButtonGroupShown,
|
||||
getAdvancedInlineGasShown,
|
||||
getCurrentEthBalance,
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
getBasicGasEstimateLoadingStatus,
|
||||
getRenderableEstimateDataForSmallButtonsFromGWEI,
|
||||
getDefaultActiveButtonIndex,
|
||||
@ -49,7 +49,7 @@ function mapStateToProps (state) {
|
||||
const balance = getCurrentEthBalance(state)
|
||||
|
||||
const insufficientBalance = !isBalanceSufficient({
|
||||
amount: getSelectedToken(state) ? '0x0' : getSendAmount(state),
|
||||
amount: getSendToken(state) ? '0x0' : getSendAmount(state),
|
||||
gasTotal,
|
||||
balance,
|
||||
conversionRate,
|
||||
@ -72,7 +72,7 @@ function mapStateToProps (state) {
|
||||
gasLimit,
|
||||
insufficientBalance,
|
||||
maxModeOn: getSendMaxModeState(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken: getSendToken(state),
|
||||
tokenBalance: getTokenBalance(state),
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export default class SendFooter extends Component {
|
||||
gasTotal: PropTypes.string,
|
||||
history: PropTypes.object,
|
||||
inError: PropTypes.bool,
|
||||
selectedToken: PropTypes.object,
|
||||
sendToken: PropTypes.object,
|
||||
sign: PropTypes.func,
|
||||
to: PropTypes.string,
|
||||
toAccounts: PropTypes.array,
|
||||
@ -49,7 +49,7 @@ export default class SendFooter extends Component {
|
||||
from: { address: from },
|
||||
gasLimit: gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
sign,
|
||||
to,
|
||||
unapprovedTxs,
|
||||
@ -78,11 +78,11 @@ export default class SendFooter extends Component {
|
||||
from,
|
||||
gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
unapprovedTxs,
|
||||
})
|
||||
: sign({ data, selectedToken, to, amount, from, gas, gasPrice })
|
||||
: sign({ data, sendToken, to, amount, from, gas, gasPrice })
|
||||
|
||||
Promise.resolve(promise)
|
||||
.then(() => {
|
||||
@ -101,8 +101,8 @@ export default class SendFooter extends Component {
|
||||
}
|
||||
|
||||
formShouldBeDisabled () {
|
||||
const { data, inError, selectedToken, tokenBalance, gasTotal, to, gasLimit, gasIsLoading } = this.props
|
||||
const missingTokenBalance = selectedToken && !tokenBalance
|
||||
const { data, inError, sendToken, tokenBalance, gasTotal, to, gasLimit, gasIsLoading } = this.props
|
||||
const missingTokenBalance = sendToken && !tokenBalance
|
||||
const gasLimitTooLow = gasLimit < 5208 // 5208 is hex value of 21000, minimum gas limit
|
||||
const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) || gasLimitTooLow || gasIsLoading
|
||||
return shouldBeDisabled
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
getGasLimit,
|
||||
getGasPrice,
|
||||
getGasTotal,
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
getSendAmount,
|
||||
getSendEditingTransactionId,
|
||||
getSendFromObject,
|
||||
@ -54,7 +54,7 @@ function mapStateToProps (state) {
|
||||
gasPrice: getGasPrice(state),
|
||||
gasTotal: getGasTotal(state),
|
||||
inError: isSendFormInError(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken: getSendToken(state),
|
||||
to: getSendTo(state),
|
||||
toAccounts: getSendToAccounts(state),
|
||||
tokenBalance: getTokenBalance(state),
|
||||
@ -68,19 +68,19 @@ function mapStateToProps (state) {
|
||||
function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
clearSend: () => dispatch(clearSend()),
|
||||
sign: ({ selectedToken, to, amount, from, gas, gasPrice, data }) => {
|
||||
sign: ({ sendToken, to, amount, from, gas, gasPrice, data }) => {
|
||||
const txParams = constructTxParams({
|
||||
amount,
|
||||
data,
|
||||
from,
|
||||
gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
})
|
||||
|
||||
selectedToken
|
||||
? dispatch(signTokenTx(selectedToken.address, to, amount, txParams))
|
||||
sendToken
|
||||
? dispatch(signTokenTx(sendToken.address, to, amount, txParams))
|
||||
: dispatch(signTx(txParams))
|
||||
},
|
||||
update: ({
|
||||
@ -90,7 +90,7 @@ function mapDispatchToProps (dispatch) {
|
||||
from,
|
||||
gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
unapprovedTxs,
|
||||
}) => {
|
||||
@ -101,7 +101,7 @@ function mapDispatchToProps (dispatch) {
|
||||
from,
|
||||
gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
unapprovedTxs,
|
||||
})
|
||||
|
@ -8,7 +8,7 @@ export function addHexPrefixToObjectValues (obj) {
|
||||
}, {})
|
||||
}
|
||||
|
||||
export function constructTxParams ({ selectedToken, data, to, amount, from, gas, gasPrice }) {
|
||||
export function constructTxParams ({ sendToken, data, to, amount, from, gas, gasPrice }) {
|
||||
const txParams = {
|
||||
data,
|
||||
from,
|
||||
@ -17,7 +17,7 @@ export function constructTxParams ({ selectedToken, data, to, amount, from, gas,
|
||||
gasPrice,
|
||||
}
|
||||
|
||||
if (!selectedToken) {
|
||||
if (!sendToken) {
|
||||
txParams.value = amount
|
||||
txParams.to = to
|
||||
}
|
||||
@ -32,7 +32,7 @@ export function constructUpdatedTx ({
|
||||
from,
|
||||
gas,
|
||||
gasPrice,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
unapprovedTxs,
|
||||
}) {
|
||||
@ -54,7 +54,7 @@ export function constructUpdatedTx ({
|
||||
),
|
||||
}
|
||||
|
||||
if (selectedToken) {
|
||||
if (sendToken) {
|
||||
const data = TOKEN_TRANSFER_FUNCTION_SIGNATURE + Array.prototype.map.call(
|
||||
ethAbi.rawEncode(['address', 'uint256'], [to, ethUtil.addHexPrefix(amount)]),
|
||||
(x) => ('00' + x.toString(16)).slice(-2)
|
||||
@ -62,7 +62,7 @@ export function constructUpdatedTx ({
|
||||
|
||||
Object.assign(editingTx.txParams, addHexPrefixToObjectValues({
|
||||
value: '0',
|
||||
to: selectedToken.address,
|
||||
to: sendToken.address,
|
||||
data,
|
||||
}))
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ describe('SendFooter Component', function () {
|
||||
gasTotal="mockGasTotal"
|
||||
history={historySpies}
|
||||
inError={false}
|
||||
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
|
||||
sendToken={{ mockProp: 'mockSendTokenProp' }}
|
||||
sign={propsMethodSpies.sign}
|
||||
to="mockTo"
|
||||
toAccounts={['mockAccount']}
|
||||
@ -103,8 +103,8 @@ describe('SendFooter Component', function () {
|
||||
expectedResult: true,
|
||||
gasIsLoading: false,
|
||||
},
|
||||
'should return true if selectedToken is truthy and tokenBalance is falsy': {
|
||||
selectedToken: { mockProp: 'mockSelectedTokenProp' },
|
||||
'should return true if sendToken is truthy and tokenBalance is falsy': {
|
||||
sendToken: { mockProp: 'mockSendTokenProp' },
|
||||
tokenBalance: '',
|
||||
expectedResult: true,
|
||||
gasIsLoading: false,
|
||||
@ -112,7 +112,7 @@ describe('SendFooter Component', function () {
|
||||
'should return true if gasIsLoading is truthy but all other params are falsy': {
|
||||
inError: false,
|
||||
gasTotal: '',
|
||||
selectedToken: null,
|
||||
sendToken: null,
|
||||
tokenBalance: '',
|
||||
expectedResult: true,
|
||||
gasIsLoading: true,
|
||||
@ -120,7 +120,7 @@ describe('SendFooter Component', function () {
|
||||
'should return false if inError is false and all other params are truthy': {
|
||||
inError: false,
|
||||
gasTotal: '0x123',
|
||||
selectedToken: { mockProp: 'mockSelectedTokenProp' },
|
||||
sendToken: { mockProp: 'mockSendTokenProp' },
|
||||
tokenBalance: '123',
|
||||
expectedResult: false,
|
||||
gasIsLoading: false,
|
||||
@ -157,7 +157,7 @@ describe('SendFooter Component', function () {
|
||||
from: 'mockAddress',
|
||||
gas: 'mockGasLimit',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedToken: { mockProp: 'mockSelectedTokenProp' },
|
||||
sendToken: { mockProp: 'mockSendTokenProp' },
|
||||
to: 'mockTo',
|
||||
unapprovedTxs: {},
|
||||
}
|
||||
@ -180,7 +180,7 @@ describe('SendFooter Component', function () {
|
||||
from: 'mockAddress',
|
||||
gas: 'mockGasLimit',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedToken: { mockProp: 'mockSelectedTokenProp' },
|
||||
sendToken: { mockProp: 'mockSendTokenProp' },
|
||||
to: 'mockTo',
|
||||
}
|
||||
)
|
||||
@ -214,7 +214,7 @@ describe('SendFooter Component', function () {
|
||||
gasTotal="mockGasTotal"
|
||||
history={historySpies}
|
||||
inError={false}
|
||||
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
|
||||
sendToken={{ mockProp: 'mockSendTokenProp' }}
|
||||
sign={propsMethodSpies.sign}
|
||||
to="mockTo"
|
||||
toAccounts={['mockAccount']}
|
||||
|
@ -31,7 +31,7 @@ proxyquire('../send-footer.container.js', {
|
||||
getGasLimit: (s) => `mockGasLimit:${s}`,
|
||||
getGasPrice: (s) => `mockGasPrice:${s}`,
|
||||
getGasTotal: (s) => `mockGasTotal:${s}`,
|
||||
getSelectedToken: (s) => `mockSelectedToken:${s}`,
|
||||
getSendToken: (s) => `mockSendToken:${s}`,
|
||||
getSendAmount: (s) => `mockAmount:${s}`,
|
||||
getSendEditingTransactionId: (s) => `mockEditingTransactionId:${s}`,
|
||||
getSendFromObject: (s) => `mockFromObject:${s}`,
|
||||
@ -69,9 +69,9 @@ describe('send-footer container', function () {
|
||||
})
|
||||
|
||||
describe('sign()', function () {
|
||||
it('should dispatch a signTokenTx action if selectedToken is defined', function () {
|
||||
it('should dispatch a signTokenTx action if sendToken is defined', function () {
|
||||
mapDispatchToPropsObject.sign({
|
||||
selectedToken: {
|
||||
sendToken: {
|
||||
address: '0xabc',
|
||||
},
|
||||
to: 'mockTo',
|
||||
@ -85,7 +85,7 @@ describe('send-footer container', function () {
|
||||
utilsStubs.constructTxParams.getCall(0).args[0],
|
||||
{
|
||||
data: undefined,
|
||||
selectedToken: {
|
||||
sendToken: {
|
||||
address: '0xabc',
|
||||
},
|
||||
to: 'mockTo',
|
||||
@ -101,7 +101,7 @@ describe('send-footer container', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should dispatch a sign action if selectedToken is not defined', function () {
|
||||
it('should dispatch a sign action if sendToken is not defined', function () {
|
||||
utilsStubs.constructTxParams.resetHistory()
|
||||
mapDispatchToPropsObject.sign({
|
||||
to: 'mockTo',
|
||||
@ -115,7 +115,7 @@ describe('send-footer container', function () {
|
||||
utilsStubs.constructTxParams.getCall(0).args[0],
|
||||
{
|
||||
data: undefined,
|
||||
selectedToken: undefined,
|
||||
sendToken: undefined,
|
||||
to: 'mockTo',
|
||||
amount: 'mockAmount',
|
||||
from: 'mockFrom',
|
||||
@ -139,7 +139,7 @@ describe('send-footer container', function () {
|
||||
gas: 'mockGas',
|
||||
gasPrice: 'mockGasPrice',
|
||||
editingTransactionId: 'mockEditingTransactionId',
|
||||
selectedToken: 'mockSelectedToken',
|
||||
sendToken: { address: 'mockAddress' },
|
||||
unapprovedTxs: 'mockUnapprovedTxs',
|
||||
})
|
||||
assert(dispatchSpy.calledOnce)
|
||||
@ -153,7 +153,7 @@ describe('send-footer container', function () {
|
||||
gas: 'mockGas',
|
||||
gasPrice: 'mockGasPrice',
|
||||
editingTransactionId: 'mockEditingTransactionId',
|
||||
selectedToken: 'mockSelectedToken',
|
||||
sendToken: { address: 'mockAddress' },
|
||||
unapprovedTxs: 'mockUnapprovedTxs',
|
||||
}
|
||||
)
|
||||
|
@ -69,7 +69,7 @@ describe('send-footer utils', function () {
|
||||
assert.deepEqual(
|
||||
constructTxParams({
|
||||
data: 'someData',
|
||||
selectedToken: false,
|
||||
sendToken: undefined,
|
||||
to: 'mockTo',
|
||||
amount: 'mockAmount',
|
||||
from: 'mockFrom',
|
||||
@ -87,10 +87,10 @@ describe('send-footer utils', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should return a new txParams object with value and to properties if there is no selectedToken', function () {
|
||||
it('should return a new txParams object with value and to properties if there is no sendToken', function () {
|
||||
assert.deepEqual(
|
||||
constructTxParams({
|
||||
selectedToken: false,
|
||||
sendToken: undefined,
|
||||
to: 'mockTo',
|
||||
amount: 'mockAmount',
|
||||
from: 'mockFrom',
|
||||
@ -108,10 +108,10 @@ describe('send-footer utils', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should return a new txParams object without a to property and a 0 value if there is a selectedToken', function () {
|
||||
it('should return a new txParams object without a to property and a 0 value if there is a sendToken', function () {
|
||||
assert.deepEqual(
|
||||
constructTxParams({
|
||||
selectedToken: true,
|
||||
sendToken: { address: '0x0' },
|
||||
to: 'mockTo',
|
||||
amount: 'mockAmount',
|
||||
from: 'mockFrom',
|
||||
@ -137,7 +137,7 @@ describe('send-footer utils', function () {
|
||||
from: 'mockFrom',
|
||||
gas: 'mockGas',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedToken: false,
|
||||
sendToken: false,
|
||||
to: 'mockTo',
|
||||
unapprovedTxs: {
|
||||
'0x123': {},
|
||||
@ -169,7 +169,7 @@ describe('send-footer utils', function () {
|
||||
from: 'mockFrom',
|
||||
gas: 'mockGas',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedToken: false,
|
||||
sendToken: false,
|
||||
to: 'mockTo',
|
||||
unapprovedTxs: {
|
||||
'0x123': {},
|
||||
@ -196,14 +196,14 @@ describe('send-footer utils', function () {
|
||||
})
|
||||
})
|
||||
|
||||
it('should have token property values if selectedToken is truthy', function () {
|
||||
it('should have token property values if sendToken is truthy', function () {
|
||||
const result = constructUpdatedTx({
|
||||
amount: 'mockAmount',
|
||||
editingTransactionId: '0x456',
|
||||
from: 'mockFrom',
|
||||
gas: 'mockGas',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedToken: {
|
||||
sendToken: {
|
||||
address: 'mockTokenAddress',
|
||||
},
|
||||
to: 'mockTo',
|
||||
|
@ -34,7 +34,7 @@ export default class SendTransactionScreen extends Component {
|
||||
primaryCurrency: PropTypes.string,
|
||||
resetSendState: PropTypes.func.isRequired,
|
||||
selectedAddress: PropTypes.string,
|
||||
selectedToken: PropTypes.object,
|
||||
sendToken: PropTypes.object,
|
||||
showHexData: PropTypes.bool,
|
||||
to: PropTypes.string,
|
||||
toNickname: PropTypes.string,
|
||||
@ -77,7 +77,7 @@ export default class SendTransactionScreen extends Component {
|
||||
gasTotal,
|
||||
network,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
updateSendErrors,
|
||||
updateSendTo,
|
||||
@ -97,7 +97,7 @@ export default class SendTransactionScreen extends Component {
|
||||
gasTotal: prevGasTotal,
|
||||
tokenBalance: prevTokenBalance,
|
||||
network: prevNetwork,
|
||||
selectedToken: prevSelectedToken,
|
||||
sendToken: prevSendToken,
|
||||
to: prevTo,
|
||||
} = prevProps
|
||||
|
||||
@ -109,7 +109,7 @@ export default class SendTransactionScreen extends Component {
|
||||
prevBalance,
|
||||
prevGasTotal,
|
||||
prevTokenBalance,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
|
||||
@ -120,16 +120,16 @@ export default class SendTransactionScreen extends Component {
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
})
|
||||
const gasFeeErrorObject = selectedToken
|
||||
const gasFeeErrorObject = sendToken
|
||||
? getGasFeeErrorObject({
|
||||
balance,
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
})
|
||||
: { gasFee: null }
|
||||
updateSendErrors(Object.assign(amountErrorObject, gasFeeErrorObject))
|
||||
@ -139,7 +139,7 @@ export default class SendTransactionScreen extends Component {
|
||||
|
||||
if (network !== prevNetwork && network !== 'loading') {
|
||||
updateSendTokenBalance({
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenContract,
|
||||
address,
|
||||
})
|
||||
@ -148,10 +148,10 @@ export default class SendTransactionScreen extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
const prevTokenAddress = prevSelectedToken && prevSelectedToken.address
|
||||
const selectedTokenAddress = selectedToken && selectedToken.address
|
||||
const prevTokenAddress = prevSendToken && prevSendToken.address
|
||||
const sendTokenAddress = sendToken && sendToken.address
|
||||
|
||||
if (selectedTokenAddress && prevTokenAddress !== selectedTokenAddress) {
|
||||
if (sendTokenAddress && prevTokenAddress !== sendTokenAddress) {
|
||||
this.updateSendToken()
|
||||
updateGas = true
|
||||
}
|
||||
@ -220,7 +220,7 @@ export default class SendTransactionScreen extends Component {
|
||||
const {
|
||||
hasHexData,
|
||||
tokens,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
network,
|
||||
} = this.props
|
||||
|
||||
@ -228,8 +228,8 @@ export default class SendTransactionScreen extends Component {
|
||||
return this.setState({ toError: '', toWarning: '' })
|
||||
}
|
||||
|
||||
const toErrorObject = getToErrorObject(query, hasHexData, tokens, selectedToken, network)
|
||||
const toWarningObject = getToWarningObject(query, tokens, selectedToken)
|
||||
const toErrorObject = getToErrorObject(query, hasHexData, tokens, sendToken, network)
|
||||
const toWarningObject = getToWarningObject(query, tokens, sendToken)
|
||||
|
||||
this.setState({
|
||||
toError: toErrorObject.to,
|
||||
@ -240,13 +240,13 @@ export default class SendTransactionScreen extends Component {
|
||||
updateSendToken () {
|
||||
const {
|
||||
from: { address },
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenContract,
|
||||
updateSendTokenBalance,
|
||||
} = this.props
|
||||
|
||||
updateSendTokenBalance({
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenContract,
|
||||
address,
|
||||
})
|
||||
@ -260,7 +260,7 @@ export default class SendTransactionScreen extends Component {
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
selectedAddress,
|
||||
selectedToken = {},
|
||||
sendToken = {},
|
||||
to: currentToAddress,
|
||||
updateAndSetGasLimit,
|
||||
} = this.props
|
||||
@ -271,7 +271,7 @@ export default class SendTransactionScreen extends Component {
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
selectedAddress,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to: getToAddressForGasUpdate(updatedToAddress, currentToAddress),
|
||||
value: value || amount,
|
||||
data,
|
||||
|
@ -11,8 +11,8 @@ import {
|
||||
getGasPrice,
|
||||
getGasTotal,
|
||||
getPrimaryCurrency,
|
||||
getSelectedToken,
|
||||
getSelectedTokenContract,
|
||||
getSendToken,
|
||||
getSendTokenContract,
|
||||
getSendAmount,
|
||||
getSendEditingTransactionId,
|
||||
getSendHexDataFeatureFlagState,
|
||||
@ -67,13 +67,13 @@ function mapStateToProps (state) {
|
||||
primaryCurrency: getPrimaryCurrency(state),
|
||||
qrCodeData: getQrCodeData(state),
|
||||
selectedAddress: getSelectedAddress(state),
|
||||
selectedToken: getSelectedToken(state),
|
||||
sendToken: getSendToken(state),
|
||||
showHexData: getSendHexDataFeatureFlagState(state),
|
||||
to: getSendTo(state),
|
||||
toNickname: getSendToNickname(state),
|
||||
tokens: getTokens(state),
|
||||
tokenBalance: getTokenBalance(state),
|
||||
tokenContract: getSelectedTokenContract(state),
|
||||
tokenContract: getSendTokenContract(state),
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,18 +85,18 @@ function mapDispatchToProps (dispatch) {
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
selectedAddress,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
value,
|
||||
data,
|
||||
}) => {
|
||||
!editingTransactionId
|
||||
? dispatch(updateGasData({ gasPrice, selectedAddress, selectedToken, blockGasLimit, to, value, data }))
|
||||
? dispatch(updateGasData({ gasPrice, selectedAddress, sendToken, blockGasLimit, to, value, data }))
|
||||
: dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice)))
|
||||
},
|
||||
updateSendTokenBalance: ({ selectedToken, tokenContract, address }) => {
|
||||
updateSendTokenBalance: ({ sendToken, tokenContract, address }) => {
|
||||
dispatch(updateSendTokenBalance({
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenContract,
|
||||
address,
|
||||
}))
|
||||
|
@ -105,11 +105,11 @@ function getAmountErrorObject ({
|
||||
conversionRate,
|
||||
gasTotal,
|
||||
primaryCurrency,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
}) {
|
||||
let insufficientFunds = false
|
||||
if (gasTotal && conversionRate && !selectedToken) {
|
||||
if (gasTotal && conversionRate && !sendToken) {
|
||||
insufficientFunds = !isBalanceSufficient({
|
||||
amount,
|
||||
balance,
|
||||
@ -120,8 +120,8 @@ function getAmountErrorObject ({
|
||||
}
|
||||
|
||||
let inSufficientTokens = false
|
||||
if (selectedToken && tokenBalance !== null) {
|
||||
const { decimals } = selectedToken
|
||||
if (sendToken && tokenBalance !== null) {
|
||||
const { decimals } = sendToken
|
||||
inSufficientTokens = !isTokenBalanceSufficient({
|
||||
tokenBalance,
|
||||
amount,
|
||||
@ -172,8 +172,8 @@ function getGasFeeErrorObject ({
|
||||
return { gasFee: gasFeeError }
|
||||
}
|
||||
|
||||
function calcTokenBalance ({ selectedToken, usersToken }) {
|
||||
const { decimals } = selectedToken || {}
|
||||
function calcTokenBalance ({ sendToken, usersToken }) {
|
||||
const { decimals } = sendToken || {}
|
||||
return calcTokenAmount(usersToken.balance.toString(), decimals).toString(16)
|
||||
}
|
||||
|
||||
@ -183,12 +183,12 @@ function doesAmountErrorRequireUpdate ({
|
||||
prevBalance,
|
||||
prevGasTotal,
|
||||
prevTokenBalance,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenBalance,
|
||||
}) {
|
||||
const balanceHasChanged = balance !== prevBalance
|
||||
const gasTotalHasChange = gasTotal !== prevGasTotal
|
||||
const tokenBalanceHasChanged = selectedToken && tokenBalance !== prevTokenBalance
|
||||
const tokenBalanceHasChanged = sendToken && tokenBalance !== prevTokenBalance
|
||||
const amountErrorRequiresUpdate = balanceHasChanged || gasTotalHasChange || tokenBalanceHasChanged
|
||||
|
||||
return amountErrorRequiresUpdate
|
||||
@ -196,7 +196,7 @@ function doesAmountErrorRequireUpdate ({
|
||||
|
||||
async function estimateGas ({
|
||||
selectedAddress,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
blockGasLimit = MIN_GAS_LIMIT_HEX,
|
||||
to,
|
||||
value,
|
||||
@ -207,21 +207,21 @@ async function estimateGas ({
|
||||
const paramsForGasEstimate = { from: selectedAddress, value, gasPrice }
|
||||
|
||||
// if recipient has no code, gas is 21k max:
|
||||
if (!selectedToken && !data) {
|
||||
if (!sendToken && !data) {
|
||||
const code = Boolean(to) && await global.eth.getCode(to)
|
||||
// Geth will return '0x', and ganache-core v2.2.1 will return '0x0'
|
||||
const codeIsEmpty = !code || code === '0x' || code === '0x0'
|
||||
if (codeIsEmpty) {
|
||||
return SIMPLE_GAS_COST
|
||||
}
|
||||
} else if (selectedToken && !to) {
|
||||
} else if (sendToken && !to) {
|
||||
return BASE_TOKEN_GAS_COST
|
||||
}
|
||||
|
||||
if (selectedToken) {
|
||||
if (sendToken) {
|
||||
paramsForGasEstimate.value = '0x0'
|
||||
paramsForGasEstimate.data = generateTokenTransferData({ toAddress: to, amount: value, selectedToken })
|
||||
paramsForGasEstimate.to = selectedToken.address
|
||||
paramsForGasEstimate.data = generateTokenTransferData({ toAddress: to, amount: value, sendToken })
|
||||
paramsForGasEstimate.to = sendToken.address
|
||||
} else {
|
||||
if (data) {
|
||||
paramsForGasEstimate.data = data
|
||||
@ -299,8 +299,8 @@ function addGasBuffer (initialGasLimitHex, blockGasLimitHex, bufferMultiplier =
|
||||
return upperGasLimit
|
||||
}
|
||||
|
||||
function generateTokenTransferData ({ toAddress = '0x0', amount = '0x0', selectedToken }) {
|
||||
if (!selectedToken) {
|
||||
function generateTokenTransferData ({ toAddress = '0x0', amount = '0x0', sendToken }) {
|
||||
if (!sendToken) {
|
||||
return
|
||||
}
|
||||
return TOKEN_TRANSFER_FUNCTION_SIGNATURE + Array.prototype.map.call(
|
||||
|
@ -58,7 +58,7 @@ describe('Send Component', function () {
|
||||
network="3"
|
||||
primaryCurrency="mockPrimaryCurrency"
|
||||
selectedAddress="mockSelectedAddress"
|
||||
selectedToken={{ address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }}
|
||||
sendToken={{ address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }}
|
||||
showHexData
|
||||
tokenBalance="mockTokenBalance"
|
||||
tokenContract={{ method: 'mockTokenMethod' }}
|
||||
@ -141,7 +141,7 @@ describe('Send Component', function () {
|
||||
prevBalance: '',
|
||||
prevGasTotal: undefined,
|
||||
prevTokenBalance: undefined,
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
tokenBalance: 'mockTokenBalance',
|
||||
}
|
||||
)
|
||||
@ -173,13 +173,13 @@ describe('Send Component', function () {
|
||||
conversionRate: 10,
|
||||
gasTotal: 'mockGasTotal',
|
||||
primaryCurrency: 'mockPrimaryCurrency',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
tokenBalance: 'mockTokenBalance',
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true and selectedToken is truthy', function () {
|
||||
it('should call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true and sendToken is truthy', function () {
|
||||
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
||||
wrapper.instance().componentDidUpdate({
|
||||
from: {
|
||||
@ -194,7 +194,7 @@ describe('Send Component', function () {
|
||||
conversionRate: 10,
|
||||
gasTotal: 'mockGasTotal',
|
||||
primaryCurrency: 'mockPrimaryCurrency',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
}
|
||||
)
|
||||
})
|
||||
@ -207,9 +207,9 @@ describe('Send Component', function () {
|
||||
assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0)
|
||||
})
|
||||
|
||||
it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true but selectedToken is falsy', function () {
|
||||
it('should not call getGasFeeErrorObject if doesAmountErrorRequireUpdate returns true but sendToken is falsy', function () {
|
||||
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
||||
wrapper.setProps({ selectedToken: null })
|
||||
wrapper.setProps({ sendToken: null })
|
||||
wrapper.instance().componentDidUpdate({
|
||||
from: {
|
||||
balance: 'balanceChanged',
|
||||
@ -218,9 +218,9 @@ describe('Send Component', function () {
|
||||
assert.equal(utilsMethodStubs.getGasFeeErrorObject.callCount, 0)
|
||||
})
|
||||
|
||||
it('should call updateSendErrors with the expected params if selectedToken is falsy', function () {
|
||||
it('should call updateSendErrors with the expected params if sendToken is falsy', function () {
|
||||
propsMethodSpies.updateSendErrors.resetHistory()
|
||||
wrapper.setProps({ selectedToken: null })
|
||||
wrapper.setProps({ sendToken: null })
|
||||
wrapper.instance().componentDidUpdate({
|
||||
from: {
|
||||
balance: 'balanceChanged',
|
||||
@ -233,9 +233,9 @@ describe('Send Component', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should call updateSendErrors with the expected params if selectedToken is truthy', function () {
|
||||
it('should call updateSendErrors with the expected params if sendToken is truthy', function () {
|
||||
propsMethodSpies.updateSendErrors.resetHistory()
|
||||
wrapper.setProps({ selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' } })
|
||||
wrapper.setProps({ sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' } })
|
||||
wrapper.instance().componentDidUpdate({
|
||||
from: {
|
||||
balance: 'balanceChanged',
|
||||
@ -256,7 +256,7 @@ describe('Send Component', function () {
|
||||
balance: 'balanceChanged',
|
||||
},
|
||||
network: '3',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
})
|
||||
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0)
|
||||
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
|
||||
@ -271,7 +271,7 @@ describe('Send Component', function () {
|
||||
balance: 'balanceChanged',
|
||||
},
|
||||
network: '3',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
})
|
||||
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0)
|
||||
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
|
||||
@ -285,13 +285,13 @@ describe('Send Component', function () {
|
||||
balance: 'balanceChanged',
|
||||
},
|
||||
network: '2',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
})
|
||||
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 1)
|
||||
assert.deepEqual(
|
||||
propsMethodSpies.updateSendTokenBalance.getCall(0).args[0],
|
||||
{
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' }, // Make sure not to hit updateGas when changing asset
|
||||
tokenContract: { method: 'mockTokenMethod' },
|
||||
address: 'mockAddress',
|
||||
}
|
||||
@ -303,7 +303,7 @@ describe('Send Component', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should call updateGas when selectedToken.address is changed', function () {
|
||||
it('should call updateGas when sendToken.address is changed', function () {
|
||||
SendTransactionScreen.prototype.updateGas.resetHistory()
|
||||
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||
wrapper.instance().componentDidUpdate({
|
||||
@ -311,7 +311,7 @@ describe('Send Component', function () {
|
||||
balance: 'balancedChanged',
|
||||
},
|
||||
network: '3', // Make sure not to hit updateGas when changing network
|
||||
selectedToken: { address: 'newSelectedToken' },
|
||||
sendToken: { address: 'newSelectedToken' },
|
||||
})
|
||||
assert.equal(propsMethodSpies.updateToNicknameIfNecessary.callCount, 0) // Network did not change
|
||||
assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1)
|
||||
@ -331,7 +331,7 @@ describe('Send Component', function () {
|
||||
gasLimit: 'mockGasLimit',
|
||||
gasPrice: 'mockGasPrice',
|
||||
selectedAddress: 'mockSelectedAddress',
|
||||
selectedToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
sendToken: { address: 'mockTokenAddress', decimals: 18, symbol: 'TST' },
|
||||
to: '',
|
||||
value: 'mockAmount',
|
||||
data: undefined,
|
||||
|
@ -49,7 +49,7 @@ describe('send container', function () {
|
||||
gasLimit: '0x3',
|
||||
gasPrice: '0x4',
|
||||
selectedAddress: '0x4',
|
||||
selectedToken: { address: '0x1' },
|
||||
sendToken: { address: '0x1' },
|
||||
to: 'mockTo',
|
||||
value: 'mockValue',
|
||||
data: undefined,
|
||||
@ -65,14 +65,14 @@ describe('send container', function () {
|
||||
})
|
||||
|
||||
it('should dispatch an updateGasData action when editingTransactionId is falsy', function () {
|
||||
const { gasPrice, selectedAddress, selectedToken, blockGasLimit, to, value, data } = mockProps
|
||||
const { gasPrice, selectedAddress, sendToken, blockGasLimit, to, value, data } = mockProps
|
||||
mapDispatchToPropsObject.updateAndSetGasLimit(
|
||||
Object.assign({}, mockProps, { editingTransactionId: false })
|
||||
)
|
||||
assert(dispatchSpy.calledOnce)
|
||||
assert.deepEqual(
|
||||
actionSpies.updateGasData.getCall(0).args[0],
|
||||
{ gasPrice, selectedAddress, selectedToken, blockGasLimit, to, value, data }
|
||||
{ gasPrice, selectedAddress, sendToken, blockGasLimit, to, value, data }
|
||||
)
|
||||
})
|
||||
})
|
||||
@ -81,7 +81,7 @@ describe('send container', function () {
|
||||
const mockProps = {
|
||||
address: '0x10',
|
||||
tokenContract: '0x00a',
|
||||
selectedToken: { address: '0x1' },
|
||||
sendToken: { address: '0x1' },
|
||||
}
|
||||
|
||||
it('should dispatch an action', function () {
|
||||
|
@ -89,7 +89,7 @@ describe('send utils', function () {
|
||||
'should return true if token balances are different': {
|
||||
tokenBalance: 0,
|
||||
prevTokenBalance: 1,
|
||||
selectedToken: 'someToken',
|
||||
sendToken: { address: '0x0' },
|
||||
expectedResult: true,
|
||||
},
|
||||
'should return false if they are all the same': {
|
||||
@ -99,7 +99,7 @@ describe('send utils', function () {
|
||||
prevGasTotal: 1,
|
||||
tokenBalance: 1,
|
||||
prevTokenBalance: 1,
|
||||
selectedToken: 'someToken',
|
||||
sendToken: { address: '0x0' },
|
||||
expectedResult: false,
|
||||
},
|
||||
}
|
||||
@ -112,13 +112,13 @@ describe('send utils', function () {
|
||||
})
|
||||
|
||||
describe('generateTokenTransferData()', function () {
|
||||
it('should return undefined if not passed a selected token', function () {
|
||||
assert.equal(generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', selectedToken: false }), undefined)
|
||||
it('should return undefined if not passed a send token', function () {
|
||||
assert.equal(generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', sendToken: undefined }), undefined)
|
||||
})
|
||||
|
||||
it('should call abi.rawEncode with the correct params', function () {
|
||||
stubs.rawEncode.resetHistory()
|
||||
generateTokenTransferData({ toAddress: 'mockAddress', amount: 'ab', selectedToken: true })
|
||||
generateTokenTransferData({ toAddress: 'mockAddress', amount: 'ab', sendToken: { address: '0x0' } })
|
||||
assert.deepEqual(
|
||||
stubs.rawEncode.getCall(0).args,
|
||||
[['address', 'uint256'], ['mockAddress', '0xab']]
|
||||
@ -127,7 +127,7 @@ describe('send utils', function () {
|
||||
|
||||
it('should return encoded token transfer data', function () {
|
||||
assert.equal(
|
||||
generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', selectedToken: true }),
|
||||
generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', sendToken: { address: '0x0' } }),
|
||||
'0xa9059cbb104c'
|
||||
)
|
||||
})
|
||||
@ -143,13 +143,13 @@ describe('send utils', function () {
|
||||
primaryCurrency: 'ABC',
|
||||
expectedResult: { amount: INSUFFICIENT_FUNDS_ERROR },
|
||||
},
|
||||
'should not return insufficientFunds error if selectedToken is truthy': {
|
||||
'should not return insufficientFunds error if sendToken is truthy': {
|
||||
amount: '0x0',
|
||||
balance: 1,
|
||||
conversionRate: 3,
|
||||
gasTotal: 17,
|
||||
primaryCurrency: 'ABC',
|
||||
selectedToken: { symbole: 'DEF', decimals: 0 },
|
||||
sendToken: { address: '0x0', symbol: 'DEF', decimals: 0 },
|
||||
decimals: 0,
|
||||
tokenBalance: 'sometokenbalance',
|
||||
expectedResult: { amount: null },
|
||||
@ -161,7 +161,7 @@ describe('send utils', function () {
|
||||
decimals: 10,
|
||||
gasTotal: 17,
|
||||
primaryCurrency: 'ABC',
|
||||
selectedToken: 'someToken',
|
||||
sendToken: { address: '0x0' },
|
||||
tokenBalance: 123,
|
||||
expectedResult: { amount: INSUFFICIENT_TOKENS_ERROR },
|
||||
},
|
||||
@ -200,7 +200,8 @@ describe('send utils', function () {
|
||||
describe('calcTokenBalance()', function () {
|
||||
it('should return the calculated token blance', function () {
|
||||
assert.equal(calcTokenBalance({
|
||||
selectedToken: {
|
||||
sendToken: {
|
||||
address: '0x0',
|
||||
decimals: 11,
|
||||
},
|
||||
usersToken: {
|
||||
@ -340,8 +341,8 @@ describe('send utils', function () {
|
||||
assert.equal(result, '0xabc16x1.5')
|
||||
})
|
||||
|
||||
it('should call ethQuery.estimateGas with a value of 0x0 and the expected data and to if passed a selectedToken', async function () {
|
||||
const result = await estimateGas(Object.assign({ data: 'mockData', selectedToken: { address: 'mockAddress' } }, baseMockParams))
|
||||
it('should call ethQuery.estimateGas with a value of 0x0 and the expected data and to if passed a sendToken', async function () {
|
||||
const result = await estimateGas(Object.assign({ data: 'mockData', sendToken: { address: 'mockAddress' } }, baseMockParams))
|
||||
assert.equal(baseMockParams.estimateGasMethod.callCount, 1)
|
||||
assert.deepEqual(
|
||||
baseMockParams.estimateGasMethod.getCall(0).args[0],
|
||||
@ -373,20 +374,20 @@ describe('send utils', function () {
|
||||
assert.equal(result, SIMPLE_GAS_COST)
|
||||
})
|
||||
|
||||
it(`should return ${SIMPLE_GAS_COST} if not passed a selectedToken or truthy to address`, async function () {
|
||||
it(`should return ${SIMPLE_GAS_COST} if not passed a sendToken or truthy to address`, async function () {
|
||||
assert.equal(baseMockParams.estimateGasMethod.callCount, 0)
|
||||
const result = await estimateGas(Object.assign({}, baseMockParams, { to: null }))
|
||||
assert.equal(result, SIMPLE_GAS_COST)
|
||||
})
|
||||
|
||||
it(`should not return ${SIMPLE_GAS_COST} if passed a selectedToken`, async function () {
|
||||
it(`should not return ${SIMPLE_GAS_COST} if passed a sendToken`, async function () {
|
||||
assert.equal(baseMockParams.estimateGasMethod.callCount, 0)
|
||||
const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123', selectedToken: { address: '' } }))
|
||||
const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123', sendToken: { address: '0x0' } }))
|
||||
assert.notEqual(result, SIMPLE_GAS_COST)
|
||||
})
|
||||
|
||||
it(`should return ${BASE_TOKEN_GAS_COST} if passed a selectedToken but no to address`, async function () {
|
||||
const result = await estimateGas(Object.assign({}, baseMockParams, { to: null, selectedToken: { address: '' } }))
|
||||
it(`should return ${BASE_TOKEN_GAS_COST} if passed a sendToken but no to address`, async function () {
|
||||
const result = await estimateGas(Object.assign({}, baseMockParams, { to: null, sendToken: { address: '0x0' } }))
|
||||
assert.equal(result, BASE_TOKEN_GAS_COST)
|
||||
})
|
||||
|
||||
|
@ -6,9 +6,18 @@ import {
|
||||
checksumAddress,
|
||||
getAccountByAddress,
|
||||
} from '../helpers/utils/util'
|
||||
import {
|
||||
getSelectedToken,
|
||||
} from '.'
|
||||
import { getSendToken } from './send'
|
||||
import { getTokens } from '../ducks/metamask/metamask'
|
||||
|
||||
export const getSelectedTokenAddress = (state) => state.metamask.selectedTokenAddress
|
||||
|
||||
export const getSelectedToken = createSelector(
|
||||
getTokens,
|
||||
getSelectedTokenAddress,
|
||||
(tokens, selectedTokenAddress) => {
|
||||
return tokens.find(({ address }) => address === selectedTokenAddress)
|
||||
}
|
||||
)
|
||||
|
||||
export function getNetworkIdentifier (state) {
|
||||
const { metamask: { provider: { type, nickname, rpcTarget } } } = state
|
||||
@ -48,10 +57,14 @@ export function getAccountType (state) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getSelectedAsset (state) {
|
||||
const selectedToken = getSelectedToken(state)
|
||||
return (selectedToken && selectedToken.symbol) || 'ETH'
|
||||
}
|
||||
export const getSelectedAsset = createSelector(
|
||||
getSelectedToken,
|
||||
getSendToken,
|
||||
(selectedToken, sendToken) => {
|
||||
const token = selectedToken || sendToken
|
||||
return token?.symbol || 'ETH'
|
||||
}
|
||||
)
|
||||
|
||||
export function getCurrentNetworkId (state) {
|
||||
return state.metamask.network
|
||||
@ -314,7 +327,7 @@ export function getTargetDomainMetadata (state, request, defaultOrigin) {
|
||||
return targetDomainMetadata
|
||||
}
|
||||
|
||||
export function getMetaMetricState (state) {
|
||||
export const getMetaMetricState = (state) => {
|
||||
return {
|
||||
network: getCurrentNetworkId(state),
|
||||
activeCurrency: getSelectedAsset(state),
|
||||
|
@ -37,23 +37,22 @@ export function getGasTotal (state) {
|
||||
}
|
||||
|
||||
export function getPrimaryCurrency (state) {
|
||||
const selectedToken = getSelectedToken(state)
|
||||
return selectedToken && selectedToken.symbol
|
||||
const sendToken = getSendToken(state)
|
||||
return sendToken?.symbol
|
||||
}
|
||||
|
||||
export function getSelectedToken (state) {
|
||||
const tokens = state.metamask.tokens || []
|
||||
const selectedTokenAddress = state.metamask.selectedTokenAddress
|
||||
const selectedToken = tokens.filter(({ address }) => address === selectedTokenAddress)[0]
|
||||
const sendToken = state.metamask?.send.token
|
||||
|
||||
return selectedToken || sendToken || null
|
||||
export function getSendToken (state) {
|
||||
return state.metamask.send.token
|
||||
}
|
||||
|
||||
export function getSelectedTokenContract (state) {
|
||||
const selectedToken = getSelectedToken(state)
|
||||
return selectedToken
|
||||
? global.eth.contract(abi).at(selectedToken.address)
|
||||
export function getSendTokenAddress (state) {
|
||||
return getSendToken(state)?.address
|
||||
}
|
||||
|
||||
export function getSendTokenContract (state) {
|
||||
const sendTokenAddress = getSendTokenAddress(state)
|
||||
return sendTokenAddress
|
||||
? global.eth.contract(abi).at(sendTokenAddress)
|
||||
: null
|
||||
}
|
||||
|
||||
@ -148,7 +147,7 @@ export function getGasButtonGroupShown (state) {
|
||||
|
||||
export function getTitleKey (state) {
|
||||
const isEditing = Boolean(getSendEditingTransactionId(state))
|
||||
const isToken = Boolean(getSelectedToken(state))
|
||||
const isToken = Boolean(getSendToken(state))
|
||||
|
||||
if (!getSendTo(state)) {
|
||||
return 'addRecipient'
|
||||
|
@ -13,8 +13,8 @@ import {
|
||||
getGasPrice,
|
||||
getGasTotal,
|
||||
getPrimaryCurrency,
|
||||
getSelectedToken,
|
||||
getSelectedTokenContract,
|
||||
getSendToken,
|
||||
getSendTokenContract,
|
||||
getSendAmount,
|
||||
sendAmountIsInError,
|
||||
getSendEditingTransactionId,
|
||||
@ -167,18 +167,28 @@ describe('send selectors', function () {
|
||||
})
|
||||
|
||||
describe('getPrimaryCurrency()', function () {
|
||||
it('should return the symbol of the selected token', function () {
|
||||
it('should return the symbol of the send token', function () {
|
||||
assert.equal(
|
||||
getPrimaryCurrency(mockState),
|
||||
getPrimaryCurrency({ metamask: { send: { token: { symbol: 'DEF' } } } }),
|
||||
'DEF'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getSelectedToken()', function () {
|
||||
it('should return the currently selected token if selected', function () {
|
||||
describe('getSendToken()', function () {
|
||||
it('should return the current send token if set', function () {
|
||||
assert.deepEqual(
|
||||
getSelectedToken(mockState),
|
||||
getSendToken({
|
||||
metamask: {
|
||||
send: {
|
||||
token: {
|
||||
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
|
||||
decimals: 4,
|
||||
symbol: 'DEF',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
{
|
||||
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
|
||||
decimals: 4,
|
||||
@ -186,40 +196,30 @@ describe('send selectors', function () {
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
it('should return the send token if none is currently selected, but a send token exists', function () {
|
||||
const mockSendToken = {
|
||||
address: '0x123456708414189a58339873ab429b6c47ab92d3',
|
||||
decimals: 4,
|
||||
symbol: 'JKL',
|
||||
}
|
||||
const editedMockState = {
|
||||
metamask: Object.assign({}, mockState.metamask, {
|
||||
selectedTokenAddress: null,
|
||||
send: {
|
||||
token: mockSendToken,
|
||||
},
|
||||
}),
|
||||
}
|
||||
assert.deepEqual(
|
||||
getSelectedToken(editedMockState),
|
||||
Object.assign({}, mockSendToken)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getSelectedTokenContract()', function () {
|
||||
it('should return the contract at the selected token address', function () {
|
||||
describe('getSendTokenContract()', function () {
|
||||
it('should return the contract at the send token address', function () {
|
||||
assert.equal(
|
||||
getSelectedTokenContract(mockState),
|
||||
getSendTokenContract({
|
||||
metamask: {
|
||||
send: {
|
||||
token: {
|
||||
address: '0x8d6b81208414189a58339873ab429b6c47ab92d3',
|
||||
decimals: 4,
|
||||
symbol: 'DEF',
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
'mockAt:0x8d6b81208414189a58339873ab429b6c47ab92d3'
|
||||
)
|
||||
})
|
||||
|
||||
it('should return null if no token is selected', function () {
|
||||
const modifiedMetamaskState = Object.assign({}, mockState.metamask, { selectedTokenAddress: false })
|
||||
it('should return null if send token is not set', function () {
|
||||
const modifiedMetamaskState = Object.assign({}, mockState.metamask, { send: {} })
|
||||
assert.equal(
|
||||
getSelectedTokenContract(Object.assign({}, mockState, { metamask: modifiedMetamaskState })),
|
||||
getSendTokenContract(Object.assign({}, mockState, { metamask: modifiedMetamaskState })),
|
||||
null
|
||||
)
|
||||
})
|
||||
@ -530,29 +530,29 @@ describe('send selectors', function () {
|
||||
getMetamaskSendMockState({
|
||||
to: true,
|
||||
editingTransactionId: true,
|
||||
token: true, // this can be whatever
|
||||
token: {},
|
||||
})
|
||||
), 'edit')
|
||||
})
|
||||
|
||||
it('should return the correct key when getSendEditingTransactionId is falsy and getSelectedToken is truthy', function () {
|
||||
it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is truthy', function () {
|
||||
assert.equal(
|
||||
getTitleKey(
|
||||
getMetamaskSendMockState({
|
||||
to: true,
|
||||
editingTransactionId: false,
|
||||
token: true,
|
||||
token: {},
|
||||
})
|
||||
), 'sendTokens')
|
||||
})
|
||||
|
||||
it('should return the correct key when getSendEditingTransactionId is falsy and getSelectedToken is falsy', function () {
|
||||
it('should return the correct key when getSendEditingTransactionId is falsy and getSendToken is falsy', function () {
|
||||
assert.equal(
|
||||
getTitleKey(
|
||||
getMetamaskSendMockState({
|
||||
to: true,
|
||||
editingTransactionId: false,
|
||||
token: false,
|
||||
token: null,
|
||||
})
|
||||
), 'sendETH')
|
||||
})
|
||||
|
@ -607,7 +607,7 @@ export function updateGasData ({
|
||||
gasPrice,
|
||||
blockGasLimit,
|
||||
selectedAddress,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
value,
|
||||
data,
|
||||
@ -618,7 +618,7 @@ export function updateGasData ({
|
||||
estimateGasMethod: promisifiedBackground.estimateGas,
|
||||
blockGasLimit,
|
||||
selectedAddress,
|
||||
selectedToken,
|
||||
sendToken,
|
||||
to,
|
||||
value,
|
||||
estimateGasPrice: gasPrice,
|
||||
@ -651,7 +651,7 @@ export function gasLoadingFinished () {
|
||||
}
|
||||
|
||||
export function updateSendTokenBalance ({
|
||||
selectedToken,
|
||||
sendToken,
|
||||
tokenContract,
|
||||
address,
|
||||
}) {
|
||||
@ -662,7 +662,7 @@ export function updateSendTokenBalance ({
|
||||
return tokenBalancePromise
|
||||
.then((usersToken) => {
|
||||
if (usersToken) {
|
||||
const newTokenBalance = calcTokenBalance({ selectedToken, usersToken })
|
||||
const newTokenBalance = calcTokenBalance({ sendToken, usersToken })
|
||||
dispatch(setSendTokenBalance(newTokenBalance))
|
||||
}
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user