1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00

ENS input in send form shows distinct errors for invalid addresses and non-existent addresses.

This commit is contained in:
Dan 2018-06-14 11:25:55 -02:30
parent 5995b6d68d
commit bb855707ef
7 changed files with 46 additions and 22 deletions

View File

@ -262,6 +262,9 @@
"encryptNewDen": {
"message": "Encrypt your new DEN"
},
"ensNameNotFound": {
"message": "ENS name not found"
},
"enterPassword": {
"message": "Enter password"
},

View File

@ -12,6 +12,7 @@ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
const connect = require('react-redux').connect
const ToAutoComplete = require('./send/to-autocomplete')
const log = require('loglevel')
const { isValidENSAddress } = require('../util')
EnsInput.contextTypes = {
t: PropTypes.func,
@ -29,7 +30,7 @@ EnsInput.prototype.onChange = function (recipient) {
const network = this.props.network
const networkHasEnsSupport = getNetworkEnsSupport(network)
this.props.onChange(recipient)
this.props.onChange({ toAddress: recipient })
if (!networkHasEnsSupport) return
@ -38,6 +39,7 @@ EnsInput.prototype.onChange = function (recipient) {
loadingEns: false,
ensResolution: null,
ensFailure: null,
toError: null,
})
}
@ -87,20 +89,28 @@ EnsInput.prototype.lookupEnsName = function (recipient) {
nickname: recipient.trim(),
hoverText: address + '\n' + this.context.t('clickCopy'),
ensFailure: false,
toError: null,
})
}
})
.catch((reason) => {
// log.error(reason)
if (reason.message !== 'ENS name not defined.') {
log.error(reason)
}
return this.setState({
const setStateObj = {
loadingEns: false,
ensResolution: recipient,
ensFailure: true,
hoverText: reason.message,
})
toError: null,
}
if (isValidENSAddress(recipient) && reason.message === 'ENS name not defined.') {
setStateObj.hoverText = this.context.t('ensNameNotFound')
setStateObj.toError = 'ensNameNotFound'
setStateObj.ensFailure = false
} else {
log.error(reason)
setStateObj.hoverText = reason.message
}
return this.setState(setStateObj)
})
}
@ -117,7 +127,7 @@ EnsInput.prototype.componentDidUpdate = function (prevProps, prevState) {
}
if (prevState && ensResolution && this.props.onChange &&
ensResolution !== prevState.ensResolution) {
this.props.onChange(ensResolution, nickname)
this.props.onChange({ toAddress: ensResolution, nickname, toError: state.toError })
}
}
@ -134,7 +144,9 @@ EnsInput.prototype.ensIcon = function (recipient) {
}
EnsInput.prototype.ensIconContents = function (recipient) {
const { loadingEns, ensFailure, ensResolution } = this.state || { ensResolution: ZERO_ADDRESS}
const { loadingEns, ensFailure, ensResolution, toError } = this.state || { ensResolution: ZERO_ADDRESS }
if (toError) return
if (loadingEns) {
return h('img', {

View File

@ -19,9 +19,9 @@ export default class SendToRow extends Component {
updateSendToError: PropTypes.func,
};
handleToChange (to, nickname = '') {
handleToChange (to, nickname = '', toError) {
const { updateSendTo, updateSendToError, updateGas } = this.props
const toErrorObject = getToErrorObject(to)
const toErrorObject = getToErrorObject(to, toError)
updateSendTo(to, nickname)
updateSendToError(toErrorObject)
if (toErrorObject.to === null) {
@ -53,7 +53,7 @@ export default class SendToRow extends Component {
inError={inError}
name={'address'}
network={network}
onChange={(newTo, newNickname) => this.handleToChange(newTo, newNickname)}
onChange={({ toAddress, nickname, toError }) => this.handleToChange(toAddress, nickname, toError)}
openDropdown={() => openToDropdown()}
placeholder={this.context.t('recipientAddress')}
to={to}

View File

@ -4,12 +4,10 @@ const {
} = require('../../send.constants')
const { isValidAddress } = require('../../../../util')
function getToErrorObject (to) {
let toError = null
function getToErrorObject (to, toError = null) {
if (!to) {
toError = REQUIRED_ERROR
} else if (!isValidAddress(to)) {
} else if (!isValidAddress(to) && !toError) {
toError = INVALID_RECIPIENT_ADDRESS_ERROR
}

View File

@ -6,8 +6,8 @@ import proxyquire from 'proxyquire'
const SendToRow = proxyquire('../send-to-row.component.js', {
'./send-to-row.utils.js': {
getToErrorObject: (to) => ({
to: to === false ? null : `mockToErrorObject:${to}`,
getToErrorObject: (to, toError) => ({
to: to === false ? null : `mockToErrorObject:${to}${toError}`,
}),
},
}).default
@ -67,11 +67,11 @@ describe('SendToRow Component', function () {
it('should call updateSendToError', () => {
assert.equal(propsMethodSpies.updateSendToError.callCount, 0)
instance.handleToChange('mockTo2')
instance.handleToChange('mockTo2', '', 'mockToError')
assert.equal(propsMethodSpies.updateSendToError.callCount, 1)
assert.deepEqual(
propsMethodSpies.updateSendToError.getCall(0).args,
[{ to: 'mockToErrorObject:mockTo2' }]
[{ to: 'mockToErrorObject:mockTo2mockToError' }]
)
})
@ -138,11 +138,11 @@ describe('SendToRow Component', function () {
openDropdown()
assert.equal(propsMethodSpies.openToDropdown.callCount, 1)
assert.equal(SendToRow.prototype.handleToChange.callCount, 0)
onChange('mockNewTo', 'mockNewNickname')
onChange({ toAddress: 'mockNewTo', nickname: 'mockNewNickname', toError: 'mockToError' })
assert.equal(SendToRow.prototype.handleToChange.callCount, 1)
assert.deepEqual(
SendToRow.prototype.handleToChange.getCall(0).args,
['mockNewTo', 'mockNewNickname']
['mockNewTo', 'mockNewNickname', 'mockToError']
)
})
})

View File

@ -40,6 +40,12 @@ describe('send-to-row utils', () => {
to: null,
})
})
it('should return the passed error if to is truthy but invalid if to is truthy and valid', () => {
assert.deepEqual(getToErrorObject('invalid #$ 345878', 'someExplicitError'), {
to: 'someExplicitError',
})
})
})
})

View File

@ -36,6 +36,7 @@ module.exports = {
miniAddressSummary: miniAddressSummary,
isAllOneCase: isAllOneCase,
isValidAddress: isValidAddress,
isValidENSAddress,
numericBalance: numericBalance,
parseBalance: parseBalance,
formatBalance: formatBalance,
@ -87,6 +88,10 @@ function isValidAddress (address) {
return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
}
function isValidENSAddress (address) {
return address.match(/^.{7,}\.(eth|test)$/)
}
function isInvalidChecksumAddress (address) {
var prefixed = ethUtil.addHexPrefix(address)
if (address === '0x0000000000000000000000000000000000000000') return false