diff --git a/js/embark.js b/js/embark.js index 2a9416cad..74ff3ec9d 100644 --- a/js/embark.js +++ b/js/embark.js @@ -408,6 +408,10 @@ EmbarkJS.Names.lookup = function (identifier, callback) { return this.currentNameSystems.lookup(identifier, callback); }; +EmbarkJS.Names.isAvailable = function () { + return this.currentNameSystems.isAvailable(); +}; + // To Implement diff --git a/lib/modules/ens/embarkjs.js b/lib/modules/ens/embarkjs.js index 063b525d0..cac082295 100644 --- a/lib/modules/ens/embarkjs.js +++ b/lib/modules/ens/embarkjs.js @@ -1,6 +1,5 @@ -import namehash from 'eth-ens-namehash'; +/*global EmbarkJS, web3, registerSubDomain, namehash*/ -/*global web3, EmbarkJS*/ let __embarkENS = {}; // resolver interface @@ -56,27 +55,6 @@ __embarkENS.resolverInterface = [ ], "type": "function" }, - { - "constant": true, - "inputs": [ - { - "name": "node", - "type": "bytes32" - }, - { - "name": "kind", - "type": "bytes32" - } - ], - "name": "has", - "outputs": [ - { - "name": "", - "type": "bool" - } - ], - "type": "function" - }, { "constant": false, "inputs": [ @@ -153,6 +131,12 @@ __embarkENS.resolverInterface = [ } ]; +const providerNotSetError = 'ENS provider not set'; +const NoDecodeAddrError = 'Error: Couldn\'t decode address from ABI: 0x'; +const NoDecodeStringError = 'ERROR: The returned value is not a convertible string: 0x0'; +const reverseAddrSuffix = '.addr.reverse'; +const voidAddress = '0x0000000000000000000000000000000000000000'; + __embarkENS.registryAddresses = { // Mainnet "1": "0x314159265dd8dbb310642f98f50c066173c1259b", @@ -162,90 +146,108 @@ __embarkENS.registryAddresses = { "4": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A" }; -const providerNotSetError = 'ENS provider not set'; -const NoDecodeAddrError = 'Error: Couldn\'t decode address from ABI: 0x'; -const NoDecodeStringError = 'ERROR: The returned value is not a convertible string: 0x0'; - -__embarkENS.setProvider = function () { +__embarkENS.setProvider = function (config) { const self = this; - // get network id and then assign ENS contract based on that - let registryAddresses = this.registryAddresses; - this.ens = null; - web3.eth.net.getId().then(id => { - if (registryAddresses[id] !== undefined) { - EmbarkJS.onReady(() => { - self.ens = new EmbarkJS.Contract({abi: self.registryInterface, address: registryAddresses[id]}); + const ERROR_MESSAGE = 'ENS is not available in this chain'; + self.registration = config.registration; + self.env = config.env; + + EmbarkJS.onReady(() => { + web3.eth.net.getId() + .then((id) => { + const registryAddress = self.registryAddresses[id] || config.registryAddress; + self.isAvailable = true; + self.ens = new EmbarkJS.Contract({abi: config.registryAbi, address: registryAddress}); + self.registrar = new EmbarkJS.Contract({abi: config.registrarAbi, address: config.registrarAddress}); + self.resolver = new EmbarkJS.Contract({abi: config.resolverAbi, address: config.resolverAddress}); + }) + .catch(err => { + if (err.message.indexOf('Provider not set or invalid') > -1) { + console.warn(ERROR_MESSAGE); + return; + } + console.error(err); }); - } - // todo: deploy at this point - }).catch(e => { - if (e.message.indexOf('Provider not set or invalid') > -1) { - console.warn('ENS is not available in this chain'); - return; - } - console.error(e); }); }; __embarkENS.resolve = function (name, callback) { + callback = callback || function () {}; if (!this.ens) { return callback(providerNotSetError); } - let node = namehash.hash(name); - console.log('Name to check', name); - console.log('Node', node); - console.log(this.ens); - return this.ens.methods.resolver(node).call().then((resolverAddress) => { - console.log('address', resolverAddress); - let resolverContract = new EmbarkJS.Contract({abi: this.resolverInterface, address: resolverAddress}); - return resolverContract.methods.addr(node).call() - .then((addr) => { - console.log('ADRESSS', addr); - callback(null, addr); - }) - .catch(err => { - if (err === NoDecodeAddrError) { - return callback(name + " is not registered", "0x"); - } - callback(err); - }); - }).catch((err) => { + function cb(err, addr) { if (err === NoDecodeAddrError) { return callback(name + " is not registered", "0x"); } - console.log('oldekwe^pfke'); - callback(err); + callback(err, addr); + } + + return this.ens.methods.resolver(node).call((err, resolverAddress) => { + if (err) { + return cb(err); + } + if (resolverAddress === voidAddress) { + return cb('Name not yet registered'); + } + let resolverContract = new EmbarkJS.Contract({abi: this.resolverInterface, address: resolverAddress}); + resolverContract.methods.addr(node).call(cb); }); }; __embarkENS.lookup = function (address, callback) { + callback = callback || function () {}; if (!this.ens) { return callback(providerNotSetError); } if (address.startsWith("0x")) { address = address.slice(2); } - console.log('Address', address); - let node = namehash.hash(address.toLowerCase() + ".addr.reverse"); - console.log('Node', node); + let node = web3.utils.soliditySha3(address.toLowerCase() + reverseAddrSuffix); - return this.ens.methods.resolver(node).call().then((resolverAddress) => { - console.log('Resolver address', resolverAddress); - let resolverContract = new EmbarkJS.Contract({abi: this.resolverInterface, address: resolverAddress}); - resolverContract.methods.name(node).call() - .then(name => { - console.log('Name'); - callback(null, name); - }) - .catch(callback); - }).catch((err) => { - console.log('Got error', err); + function cb(err, name) { if (err === NoDecodeStringError || err === NoDecodeAddrError) { - console.log('Address does not resolve to name. Try syncing chain.'); - return ""; + return callback('Address does not resolve to name. Try syncing chain.'); } - return err; + return callback(err, name); + } + + return this.ens.methods.resolver(node).call((err, resolverAddress) => { + if (err) { + return cb(err); + } + if (resolverAddress === voidAddress) { + return cb('Address not associated to a resolver'); + } + let resolverContract = new EmbarkJS.Contract({abi: this.resolverInterface, address: resolverAddress}); + resolverContract.methods.name(node).call(cb); }); }; + +__embarkENS.registerSubDomain = function (name, address, callback) { + callback = callback || function () {}; + + if (this.env !== 'development' && this.env !== 'privatenet') { + return callback('Sub-domain registration is only available in development or privatenet mode'); + } + if (!this.registration || !this.registration.rootDomain) { + return callback('No rootDomain is declared in config/namesystem.js (register.rootDomain). Unable to register a subdomain until then.'); + } + if (!address || !web3.utils.isAddress(address)) { + return callback('You need to specify a valid address for the subdomain'); + } + + // Register function generated by the index + registerSubDomain(this.ens, this.registrar, this.resolver, web3.eth.defaultAccount, name, this.registration.rootDomain, + web3.utils.soliditySha3(address.toLowerCase().substr(2) + reverseAddrSuffix), address, console, EmbarkJS.Utils.secureSend, callback); +}; + +__embarkENS.isAvailable = function () { + return Boolean(this.isAvailable); +}; + +__embarkENS.register = function () { + return new Error("Not available with ENS"); +};