ENSFunctions.js
1 /*global web3*/ 2 const namehash = require('eth-ens-namehash'); 3 // Price of ENS registration contract functions 4 const ENS_GAS_PRICE = 700000; 5 6 const reverseAddressSuffix = '.addr.reverse'; 7 const voidAddr = '0x0000000000000000000000000000000000000000'; 8 const NoDecodeAddrErr = 'Error: Couldn\'t decode address from ABI: 0x'; 9 const NoDecodeStringErr = 'ERROR: The returned value is not a convertible string: 0x0'; 10 11 function registerSubDomain(ens, registrar, resolver, defaultAccount, subdomain, rootDomain, reverseNode, address, logger, secureSend, callback) { 12 const subnode = namehash.hash(subdomain); 13 const rootNode = namehash.hash(rootDomain); 14 const node = namehash.hash(`${subdomain}.${rootDomain}`); 15 // FIXME Registrar calls a function in ENS and in privatenet it doesn't work for soem reason 16 // const toSend = registrar.methods.register(subnode, defaultAccount); 17 const toSend = ens.methods.setSubnodeOwner(rootNode, subnode, defaultAccount); 18 let transaction; 19 20 secureSend(web3, toSend, {from: defaultAccount, gas: ENS_GAS_PRICE}, false) 21 // Set resolver for the node 22 .then(transac => { 23 if (transac.status !== "0x1" && transac.status !== "0x01" && transac.status !== true) { 24 logger.warn('Failed transaction', transac); 25 return callback('Failed to register. Check gas cost.'); 26 } 27 transaction = transac; 28 return secureSend(web3, ens.methods.setResolver(node, resolver.options.address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false); 29 }) 30 // Set address for node 31 .then(_result => { 32 return secureSend(web3, resolver.methods.setAddr(node, address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false); 33 }) 34 // Set resolver for the reverse node 35 .then(_result => { 36 return secureSend(web3, ens.methods.setResolver(reverseNode, resolver.options.address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false); 37 }) 38 // Set name for reverse node 39 .then(_result => { 40 return secureSend(web3, resolver.methods.setName(reverseNode, `${subdomain}.${rootDomain}`), {from: defaultAccount, gas: ENS_GAS_PRICE}, false); 41 }) 42 .then(_result => { 43 callback(null, transaction); 44 }) 45 .catch(err => { 46 logger.error(err.message || err); 47 callback('Failed to register with error: ' + (err.message || err)); 48 }); 49 } 50 51 function lookupAddress(address, ens, utils, createResolverContract, callback) { 52 if (address.startsWith("0x")) { 53 address = address.slice(2); 54 } 55 56 let node = utils.soliditySha3(address.toLowerCase() + reverseAddressSuffix); 57 58 function cb(err, name) { 59 if (err === NoDecodeStringErr || err === NoDecodeAddrErr) { 60 return callback('Address does not resolve to name. Try syncing chain.'); 61 } 62 return callback(err, name); 63 } 64 65 return ens.methods.resolver(node).call((err, resolverAddress) => { 66 if (err) { 67 return cb(err); 68 } 69 if (resolverAddress === voidAddr) { 70 return cb('Address not associated to a resolver'); 71 } 72 createResolverContract(resolverAddress, (_, resolverContract) => { 73 resolverContract.methods.name(node).call(cb); 74 }); 75 76 }); 77 } 78 79 function resolveName(name, ens, createResolverContract, callback) { 80 let node = namehash.hash(name); 81 82 function cb(err, addr) { 83 if (err === NoDecodeAddrErr) { 84 return callback(name + " is not registered", "0x"); 85 } 86 callback(err, addr); 87 } 88 89 return ens.methods.resolver(node).call((err, resolverAddress) => { 90 if (err) { 91 return cb(err); 92 } 93 if (resolverAddress === voidAddr) { 94 return cb('Name not yet registered'); 95 } 96 createResolverContract(resolverAddress, (_, resolverContract) => { 97 resolverContract.methods.addr(node).call(cb); 98 }); 99 }); 100 } 101 102 if (typeof module !== 'undefined' && module.exports) { 103 module.exports = { 104 registerSubDomain, 105 resolveName, 106 lookupAddress 107 }; 108 }