aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/_locales/en/messages.json3
-rw-r--r--ui/app/components/send/send-content/send-to-row/send-to-row.component.js6
-rw-r--r--ui/app/components/send/send-content/send-to-row/send-to-row.container.js4
-rw-r--r--ui/app/components/send/send-content/send-to-row/send-to-row.selectors.js5
-rw-r--r--ui/app/components/send/send-content/send-to-row/send-to-row.utils.js9
-rw-r--r--ui/app/components/send/send-content/send-to-row/tests/send-to-row-container.test.js4
-rw-r--r--ui/app/components/send/send-content/send-to-row/tests/send-to-row-selectors.test.js12
-rw-r--r--ui/app/components/send/send-content/send-to-row/tests/send-to-row-utils.test.js24
-rw-r--r--ui/app/components/send/send.constants.js2
9 files changed, 66 insertions, 3 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 9024481d8..e849517a8 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -648,6 +648,9 @@
"invalidAddressRecipient": {
"message": "Recipient address is invalid"
},
+ "knownAddressRecipient": {
+ "message": "Known contract address."
+ },
"invalidGasParams": {
"message": "Invalid Gas Parameters"
},
diff --git a/ui/app/components/send/send-content/send-to-row/send-to-row.component.js b/ui/app/components/send/send-content/send-to-row/send-to-row.component.js
index ce5325314..dbcc4ecd6 100644
--- a/ui/app/components/send/send-content/send-to-row/send-to-row.component.js
+++ b/ui/app/components/send/send-content/send-to-row/send-to-row.component.js
@@ -12,9 +12,11 @@ export default class SendToRow extends Component {
inError: PropTypes.bool,
network: PropTypes.string,
openToDropdown: PropTypes.func,
+ selectedToken: PropTypes.object,
to: PropTypes.string,
toAccounts: PropTypes.array,
toDropdownOpen: PropTypes.bool,
+ tokens: PropTypes.array,
updateGas: PropTypes.func,
updateSendTo: PropTypes.func,
updateSendToError: PropTypes.func,
@@ -26,8 +28,8 @@ export default class SendToRow extends Component {
}
handleToChange (to, nickname = '', toError) {
- const { hasHexData, updateSendTo, updateSendToError, updateGas } = this.props
- const toErrorObject = getToErrorObject(to, toError, hasHexData)
+ const { hasHexData, updateSendTo, updateSendToError, updateGas, tokens, selectedToken } = this.props
+ const toErrorObject = getToErrorObject(to, toError, hasHexData, tokens, selectedToken)
updateSendTo(to, nickname)
updateSendToError(toErrorObject)
if (toErrorObject.to === null) {
diff --git a/ui/app/components/send/send-content/send-to-row/send-to-row.container.js b/ui/app/components/send/send-content/send-to-row/send-to-row.container.js
index 3ee188bad..945cdbaeb 100644
--- a/ui/app/components/send/send-content/send-to-row/send-to-row.container.js
+++ b/ui/app/components/send/send-content/send-to-row/send-to-row.container.js
@@ -1,12 +1,14 @@
import { connect } from 'react-redux'
import {
getCurrentNetwork,
+ getSelectedToken,
getSendTo,
getSendToAccounts,
getSendHexData,
} from '../../send.selectors.js'
import {
getToDropdownOpen,
+ getTokens,
sendToIsInError,
} from './send-to-row.selectors.js'
import {
@@ -26,9 +28,11 @@ function mapStateToProps (state) {
hasHexData: Boolean(getSendHexData(state)),
inError: sendToIsInError(state),
network: getCurrentNetwork(state),
+ selectedToken: getSelectedToken(state),
to: getSendTo(state),
toAccounts: getSendToAccounts(state),
toDropdownOpen: getToDropdownOpen(state),
+ tokens: getTokens(state),
}
}
diff --git a/ui/app/components/send/send-content/send-to-row/send-to-row.selectors.js b/ui/app/components/send/send-content/send-to-row/send-to-row.selectors.js
index 8919014be..982fd2e46 100644
--- a/ui/app/components/send/send-content/send-to-row/send-to-row.selectors.js
+++ b/ui/app/components/send/send-content/send-to-row/send-to-row.selectors.js
@@ -1,5 +1,6 @@
const selectors = {
getToDropdownOpen,
+ getTokens,
sendToIsInError,
}
@@ -12,3 +13,7 @@ function getToDropdownOpen (state) {
function sendToIsInError (state) {
return Boolean(state.send.errors.to)
}
+
+function getTokens (state) {
+ return state.metamask.tokens
+}
diff --git a/ui/app/components/send/send-content/send-to-row/send-to-row.utils.js b/ui/app/components/send/send-content/send-to-row/send-to-row.utils.js
index 0eeaa3a11..7efd2a772 100644
--- a/ui/app/components/send/send-content/send-to-row/send-to-row.utils.js
+++ b/ui/app/components/send/send-content/send-to-row/send-to-row.utils.js
@@ -1,16 +1,23 @@
const {
REQUIRED_ERROR,
INVALID_RECIPIENT_ADDRESS_ERROR,
+ KNOWN_RECIPIENT_ADDRESS_ERROR,
} = require('../../send.constants')
const { isValidAddress } = require('../../../../util')
+import { checkExistingAddresses } from '../../../pages/add-token/util'
-function getToErrorObject (to, toError = null, hasHexData = false) {
+const ethUtil = require('ethereumjs-util')
+const contractMap = require('eth-contract-metadata')
+
+function getToErrorObject (to, toError = null, hasHexData = false, tokens = [], selectedToken = null) {
if (!to) {
if (!hasHexData) {
toError = REQUIRED_ERROR
}
} else if (!isValidAddress(to) && !toError) {
toError = INVALID_RECIPIENT_ADDRESS_ERROR
+ } else if (selectedToken && (ethUtil.toChecksumAddress(to) in contractMap || checkExistingAddresses(to, tokens))) {
+ toError = KNOWN_RECIPIENT_ADDRESS_ERROR
}
return { to: toError }
diff --git a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-container.test.js b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-container.test.js
index dfce7652f..95efdd7cc 100644
--- a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-container.test.js
+++ b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-container.test.js
@@ -24,6 +24,7 @@ proxyquire('../send-to-row.container.js', {
},
'../../send.selectors.js': {
getCurrentNetwork: (s) => `mockNetwork:${s}`,
+ getSelectedToken: (s) => `mockSelectedToken:${s}`,
getSendHexData: (s) => s,
getSendTo: (s) => `mockTo:${s}`,
getSendToAccounts: (s) => `mockToAccounts:${s}`,
@@ -31,6 +32,7 @@ proxyquire('../send-to-row.container.js', {
'./send-to-row.selectors.js': {
getToDropdownOpen: (s) => `mockToDropdownOpen:${s}`,
sendToIsInError: (s) => `mockInError:${s}`,
+ getTokens: (s) => `mockTokens:${s}`,
},
'../../../../actions': actionSpies,
'../../../../ducks/send.duck': duckActionSpies,
@@ -45,9 +47,11 @@ describe('send-to-row container', () => {
hasHexData: true,
inError: 'mockInError:mockState',
network: 'mockNetwork:mockState',
+ selectedToken: 'mockSelectedToken:mockState',
to: 'mockTo:mockState',
toAccounts: 'mockToAccounts:mockState',
toDropdownOpen: 'mockToDropdownOpen:mockState',
+ tokens: 'mockTokens:mockState',
})
})
diff --git a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-selectors.test.js b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-selectors.test.js
index 122ad3265..0fa342d1e 100644
--- a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-selectors.test.js
+++ b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-selectors.test.js
@@ -1,6 +1,7 @@
import assert from 'assert'
import {
getToDropdownOpen,
+ getTokens,
sendToIsInError,
} from '../send-to-row.selectors.js'
@@ -44,4 +45,15 @@ describe('send-to-row selectors', () => {
})
})
+ describe('getTokens()', () => {
+ it('should return empty array if no tokens in state', () => {
+ const state = {
+ metamask: {
+ tokens: [],
+ },
+ }
+
+ assert.deepStrictEqual(getTokens(state), [])
+ })
+ })
})
diff --git a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-utils.test.js b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-utils.test.js
index c779aeb76..8d4f26e15 100644
--- a/ui/app/components/send/send-content/send-to-row/tests/send-to-row-utils.test.js
+++ b/ui/app/components/send/send-content/send-to-row/tests/send-to-row-utils.test.js
@@ -5,6 +5,7 @@ import sinon from 'sinon'
import {
REQUIRED_ERROR,
INVALID_RECIPIENT_ADDRESS_ERROR,
+ KNOWN_RECIPIENT_ADDRESS_ERROR,
} from '../../../send.constants'
const stubs = {
@@ -52,6 +53,29 @@ describe('send-to-row utils', () => {
to: 'someExplicitError',
})
})
+
+ it('should return a known address recipient if to is truthy but part of state tokens', () => {
+ assert.deepEqual(getToErrorObject('0xabc123', undefined, false, [{'address': '0xabc123'}], {'address': '0xabc123'}), {
+ to: KNOWN_RECIPIENT_ADDRESS_ERROR,
+ })
+ })
+
+ it('should null if to is truthy part of tokens but selectedToken falsy', () => {
+ assert.deepEqual(getToErrorObject('0xabc123', undefined, false, [{'address': '0xabc123'}]), {
+ to: null,
+ })
+ })
+
+ it('should return a known address recipient if to is truthy but part of contract metadata', () => {
+ assert.deepEqual(getToErrorObject('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', undefined, false, [{'address': '0xabc123'}], {'address': '0xabc123'}), {
+ to: KNOWN_RECIPIENT_ADDRESS_ERROR,
+ })
+ })
+ it('should null if to is truthy part of contract metadata but selectedToken falsy', () => {
+ assert.deepEqual(getToErrorObject('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359', undefined, false, [{'address': '0xabc123'}], {'address': '0xabc123'}), {
+ to: KNOWN_RECIPIENT_ADDRESS_ERROR,
+ })
+ })
})
})
diff --git a/ui/app/components/send/send.constants.js b/ui/app/components/send/send.constants.js
index 8acdf0641..e79734a54 100644
--- a/ui/app/components/send/send.constants.js
+++ b/ui/app/components/send/send.constants.js
@@ -27,6 +27,7 @@ const INSUFFICIENT_TOKENS_ERROR = 'insufficientTokens'
const NEGATIVE_ETH_ERROR = 'negativeETH'
const INVALID_RECIPIENT_ADDRESS_ERROR = 'invalidAddressRecipient'
const REQUIRED_ERROR = 'required'
+const KNOWN_RECIPIENT_ADDRESS_ERROR = 'knownAddressRecipient'
const ONE_GWEI_IN_WEI_HEX = ethUtil.addHexPrefix(conversionUtil('0x1', {
fromDenomination: 'GWEI',
@@ -42,6 +43,7 @@ module.exports = {
INSUFFICIENT_FUNDS_ERROR,
INSUFFICIENT_TOKENS_ERROR,
INVALID_RECIPIENT_ADDRESS_ERROR,
+ KNOWN_RECIPIENT_ADDRESS_ERROR,
MIN_GAS_LIMIT_DEC,
MIN_GAS_LIMIT_HEX,
MIN_GAS_PRICE_DEC,