diff --git a/package.json b/package.json index fd6d23134..4d7738179 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,14 @@ "@buidlhub/buidlhub-ens-notifications": "^1.0.3", "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", + "@ensdomains/address-encoder": "^0.2.6", + "@ensdomains/mock": "^2.0.34", + "@ensdomains/react-ens-address": "^0.0.27", + "@ensdomains/ui": "https://github.com/buffrr/ui.git#dns-contract", "@myetherwallet/mewconnect-web-client": "^2.1.11", "@portis/web3": "^2.0.0-beta.59", "@toruslabs/torus-embed": "^1.8.6", "@walletconnect/web3-provider": "^1.3.1", - "@ensdomains/address-encoder": "^0.2.6", - "@ensdomains/mock": "^2.0.34", - "@ensdomains/react-ens-address": "^0.0.27", - "@ensdomains/ui": "https://github.com/imperviousinc/ui.git", "apollo-cache-inmemory": "^1.2.9", "apollo-client": "^2.4.5", "apollo-link": "^1.2.2", @@ -23,6 +23,7 @@ "apollo-link-state": "^0.4.1", "authereum": "^0.1.0", "big-integer": "^1.6.44", + "bns": "^0.14.0", "chart.js": "^2.9.3", "core-js": "^3.1.4", "cross-fetch": "^2.2.3", @@ -57,8 +58,8 @@ "react-transition-group-plus": "^0.5.3", "slugify": "^1.4.6", "stackdriver-errors-js": "^0.8.0", - "web3modal": "^1.9.1", - "web3": "^1.3.0" + "web3": "^1.3.0", + "web3modal": "^1.9.1" }, "scripts": { "start": "react-scripts start", diff --git a/public/locales/en.json b/public/locales/en.json index 2f722dbda..948da73a5 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -64,6 +64,7 @@ "set": "Set", "sync": "Sync", "textrecord": "Text Record", + "dnsrecord": "DNS Record", "transfer": "Transfer", "warning": "Warning", "year": "year", diff --git a/src/api/manager/resolvers.js b/src/api/manager/resolvers.js index 7e88765f4..fb909fbb8 100644 --- a/src/api/manager/resolvers.js +++ b/src/api/manager/resolvers.js @@ -12,11 +12,15 @@ import { labelhash, utils } from '@ensdomains/ui' + +import bns from 'bns' import { formatsByName } from '@ensdomains/address-encoder' import isEqual from 'lodash/isEqual' import modeNames from '../modes' import { sendHelper, sendHelperArray } from '../resolverUtils' import { emptyAddress, DNSREGISTRAR_ADDRESS } from '../../utils/utils' +import { strRecord } from '../../utils/dns' + import TEXT_RECORD_KEYS from 'constants/textRecords' import COIN_LIST_KEYS from 'constants/coinList' import { @@ -367,6 +371,7 @@ const resolvers = { ) DEPRECATED_RESOLVERS = [...DEPRECATED_RESOLVERS, ...localResolvers] } + /* Deprecated resolvers are using the new registry and can be continued to be used*/ function calculateIsDeprecatedResolver(address) { @@ -482,6 +487,33 @@ const resolvers = { ) return Promise.all(addresses) }, + getDNSRecords: async (_, { name, types }) => { + const ens = getENS() + const dnsRecords = types.map(key => + ens.getDNSRecordsZoneFormat(name, name, key).then(records => { + let value = '' + if (records.length === 0) { + return { key, value: value } + } + + const record = records[0] + const rr = bns.wire.Record.fromString(record) + + if (rr.type === bns.wire.types.TXT && rr.data.txt.length === 1) { + value = rr.data.txt[0] + } else { + value = record + .trim() + .split(/[\s]+/) + .slice(4) + .join(' ') + } + + return { key, value: value } + }) + ) + return Promise.all(dnsRecords) + }, getTextRecords: async (_, { name, keys }) => { const ens = getENS() const textRecords = keys.map(key => @@ -604,6 +636,33 @@ const resolvers = { addMultiRecords: async (_, { name, records }, { cache }) => { const ens = getENS() + // Handling DNS Records + try { + if (records.dnsRecords.length > 0) { + if (records.textRecords.length > 0 || records.coins.length > 0) { + console.warn( + 'dns records cannot be modified with other types of records' + ) + return + } + + const defaultTTL = '43200' + let owner = name + '.' + const strRecords = [] + + for (const record of records.dnsRecords) { + const rr = strRecord(owner, defaultTTL, record.key, record.value) + strRecords.push(rr) + } + + const tx = await ens.setDNSRecordsFromZone(name, strRecords) + return sendHelper(tx) + } + } catch (e) { + console.log('unable to perform dns transaction', e) + return + } + function setupTransactions({ name, records, resolverInstance }) { try { const resolver = resolverInstance.interface.functions diff --git a/src/components/SingleName/ResolverAndRecords/AddRecord.js b/src/components/SingleName/ResolverAndRecords/AddRecord.js index bdb12aac5..5361c64e8 100644 --- a/src/components/SingleName/ResolverAndRecords/AddRecord.js +++ b/src/components/SingleName/ResolverAndRecords/AddRecord.js @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next' import { validateRecord } from '../../../utils/records' import { useEditable } from '../../hooks' import { getOldContentWarning } from './warnings' +import DNS_RECORD_KEYS from 'constants/dnsRecords' import TEXT_RECORD_KEYS from 'constants/textRecords' import COIN_LIST from 'constants/coinList' import { getEnsAddress } from '../../../api/ens' @@ -131,6 +132,12 @@ const textRecordOptions = TEXT_RECORD_KEYS.slice() label: key, value: key })) +const dnsRecordOptions = DNS_RECORD_KEYS.slice() + .sort() + .map(key => ({ + label: key, + value: key + })) const coinOptions = COIN_LIST.slice() .sort() .map(key => ({ @@ -168,6 +175,36 @@ function TextRecordInput({ ) } +function DNSRecordInput({ + selectedRecord, + updateValue, + newValue, + selectedKey, + setSelectedKey, + isValid, + isInvalid +}) { + return ( + <> +