Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V7.7.5 Upstream Changes #124

Merged
merged 12 commits into from Feb 25, 2020

Attempt ENS resolution on any valid domain name (#8059)

ENS currently supports a variety of tlds in addition to `.eth`, and
more will be supported in the future. Rather than hard-code a list of
supported ENS tlds, all valid domain names will now be interpreted as
potential ENS addresses in our address input component.

Closes #7978
  • Loading branch information
Gudahtt authored and ryanml committed Feb 18, 2020
commit 617faa4ae74406ca733dffa3e650f962c4a290d8
@@ -103,6 +103,64 @@ describe('util', function () {
})
})

describe('isValidDomainName', function () {
it('should return true when given a valid domain name', function () {
assert.strictEqual(util.isValidDomainName('foo.bar'), true)
})

it('should return true when given a valid subdomain', function () {
assert.strictEqual(util.isValidDomainName('foo.foo.bar'), true)
})

it('should return true when given a single-character domain', function () {
assert.strictEqual(util.isValidDomainName('f.bar'), true)
})

it('should return true when given a unicode TLD', function () {
assert.strictEqual(util.isValidDomainName('台灣.中国'), true)
})

it('should return false when given a domain with unacceptable ASCII characters', function () {
assert.strictEqual(util.isValidDomainName('$.bar'), false)
})

it('should return false when given a TLD that starts with a dash', function () {
assert.strictEqual(util.isValidDomainName('foo.-bar'), false)
})

it('should return false when given a TLD that ends with a dash', function () {
assert.strictEqual(util.isValidDomainName('foo.bar-'), false)
})

it('should return false when given a domain name with a chunk that starts with a dash', function () {
assert.strictEqual(util.isValidDomainName('-foo.bar'), false)
})

it('should return false when given a domain name with a chunk that ends with a dash', function () {
assert.strictEqual(util.isValidDomainName('foo-.bar'), false)
})

it('should return false when given a bare TLD', function () {
assert.strictEqual(util.isValidDomainName('bar'), false)
})

it('should return false when given a domain that starts with a period', function () {
assert.strictEqual(util.isValidDomainName('.bar'), false)
})

it('should return false when given a subdomain that starts with a period', function () {
assert.strictEqual(util.isValidDomainName('.foo.bar'), false)
})

it('should return false when given a domain that ends with a period', function () {
assert.strictEqual(util.isValidDomainName('bar.'), false)
})

it('should return false when given a 1-character TLD', function () {
assert.strictEqual(util.isValidDomainName('foo.b'), false)
})
})

describe('#numericBalance', function () {
it('should return a BN 0 if given nothing', function () {
var result = util.numericBalance()
@@ -2,6 +2,7 @@ const abi = require('human-standard-token-abi')
const ethUtil = require('ethereumjs-util')
const hexToBn = require('../../../../app/scripts/lib/hex-to-bn')
import { DateTime } from 'luxon'
import punycode from 'punycode'

const MIN_GAS_PRICE_GWEI_BN = new ethUtil.BN(1)
const GWEI_FACTOR = new ethUtil.BN(1e9)
@@ -36,7 +37,7 @@ module.exports = {
miniAddressSummary: miniAddressSummary,
isAllOneCase: isAllOneCase,
isValidAddress: isValidAddress,
isValidENSAddress,
isValidDomainName,
numericBalance: numericBalance,
parseBalance: parseBalance,
formatBalance: formatBalance,
@@ -99,8 +100,14 @@ function isValidAddress (address) {
return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
}

function isValidENSAddress (address) {
return address.match(/^.{3,}\.(eth|test|xyz)$/)
function isValidDomainName (address) {
const match = punycode.toASCII(address)
.toLowerCase()
// Checks that the domain consists of at least one valid domain pieces separated by periods, followed by a tld
// Each piece of domain name has only the characters a-z, 0-9, and a hyphen (but not at the start or end of chunk)
// A chunk has minimum length of 1, but minimum tld is set to 2 for now (no 1-character tlds exist yet)
.match(/^(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+[a-z0-9][-a-z0-9]*[a-z0-9]$/)
return match !== null
}

function isInvalidChecksumAddress (address) {
@@ -1,8 +1,8 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import c from 'classnames'
import { isValidENSAddress, isValidAddress, isValidAddressHead } from '../../../../helpers/utils/util'
import {ellipsify} from '../../send.utils'
import { isValidDomainName, isValidAddress, isValidAddressHead } from '../../../../helpers/utils/util'
import { ellipsify } from '../../send.utils'

import debounce from 'debounce'
import copyToClipboard from 'copy-to-clipboard/index'
@@ -91,7 +91,7 @@ export default class EnsInput extends Component {
this.props.updateEnsResolution(address)
})
.catch((reason) => {
if (isValidENSAddress(recipient) && reason.message === 'ENS name not defined.') {
if (isValidDomainName(recipient) && reason.message === 'ENS name not defined.') {
this.props.updateEnsResolutionError(this.context.t('ensNotFoundOnCurrentNetwork'))
} else {
log.error(reason)
@@ -124,7 +124,7 @@ export default class EnsInput extends Component {
return
}

if (isValidENSAddress(input)) {
if (isValidDomainName(input)) {
this.lookupEnsName(input)
} else if (onValidAddressTyped && isValidAddress(input)) {
onValidAddressTyped(input)
@@ -55,7 +55,7 @@ import {
calcGasTotal,
} from './send.utils.js'
import {
isValidENSAddress,
isValidDomainName,
} from '../../helpers/utils/util'

import {
@@ -126,8 +126,8 @@ function mapDispatchToProps (dispatch) {
updateSendEnsResolution: (ensResolution) => dispatch(updateSendEnsResolution(ensResolution)),
updateSendEnsResolutionError: (message) => dispatch(updateSendEnsResolutionError(message)),
updateToNicknameIfNecessary: (to, toNickname, addressBook) => {
if (isValidENSAddress(toNickname)) {
const addressBookEntry = addressBook.find(({ address}) => to === address) || {}
if (isValidDomainName(toNickname)) {
const addressBookEntry = addressBook.find(({ address }) => to === address) || {}
if (!addressBookEntry.name !== toNickname) {
dispatch(updateSendTo(to, addressBookEntry.name || ''))
}
@@ -3,8 +3,8 @@ import PropTypes from 'prop-types'
import Identicon from '../../../../components/ui/identicon'
import TextField from '../../../../components/ui/text-field'
import { CONTACT_LIST_ROUTE } from '../../../../helpers/constants/routes'
import { isValidAddress, isValidENSAddress } from '../../../../helpers/utils/util'
import EnsInput from '../../../../pages/send/send-content/add-recipient/ens-input'
import { isValidAddress, isValidDomainName } from '../../../../helpers/utils/util'
import EnsInput from '../../../send/send-content/add-recipient/ens-input'
import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer'
import debounce from 'lodash.debounce'

@@ -51,7 +51,7 @@ export default class AddContact extends PureComponent {

validate = address => {
const valid = isValidAddress(address)
const validEnsAddress = isValidENSAddress(address)
const validEnsAddress = isValidDomainName(address)
if (valid || validEnsAddress || address === '') {
this.setState({ error: '', ethAddress: address })
} else {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.