2018-10-23 18:20:42 +00:00
|
|
|
/*global web3*/
|
2018-08-14 15:12:03 +00:00
|
|
|
const namehash = require('eth-ens-namehash');
|
2018-10-23 18:20:42 +00:00
|
|
|
// Price of ENS registration contract functions
|
|
|
|
const ENS_GAS_PRICE = 700000;
|
2018-08-14 15:12:03 +00:00
|
|
|
|
2018-10-23 18:20:42 +00:00
|
|
|
const reverseAddressSuffix = '.addr.reverse';
|
|
|
|
const voidAddr = '0x0000000000000000000000000000000000000000';
|
|
|
|
const NoDecodeAddrErr = 'Error: Couldn\'t decode address from ABI: 0x';
|
|
|
|
const NoDecodeStringErr = 'ERROR: The returned value is not a convertible string: 0x0';
|
2018-08-14 15:12:03 +00:00
|
|
|
|
2018-10-23 18:20:42 +00:00
|
|
|
function registerSubDomain(ens, registrar, resolver, defaultAccount, subdomain, rootDomain, reverseNode, address, logger, secureSend, callback) {
|
2018-08-14 15:12:03 +00:00
|
|
|
const subnode = namehash.hash(subdomain);
|
2018-10-23 18:20:42 +00:00
|
|
|
const rootNode = namehash.hash(rootDomain);
|
2018-08-14 15:12:03 +00:00
|
|
|
const node = namehash.hash(`${subdomain}.${rootDomain}`);
|
2018-10-23 18:20:42 +00:00
|
|
|
// FIXME Registrar calls a function in ENS and in privatenet it doesn't work for soem reason
|
|
|
|
// const toSend = registrar.methods.register(subnode, defaultAccount);
|
|
|
|
const toSend = ens.methods.setSubnodeOwner(rootNode, subnode, defaultAccount);
|
2018-08-14 15:12:03 +00:00
|
|
|
let transaction;
|
|
|
|
|
2018-10-23 18:20:42 +00:00
|
|
|
secureSend(web3, toSend, {from: defaultAccount, gas: ENS_GAS_PRICE}, false)
|
|
|
|
// Set resolver for the node
|
2018-08-14 15:12:03 +00:00
|
|
|
.then(transac => {
|
|
|
|
if (transac.status !== "0x1" && transac.status !== "0x01" && transac.status !== true) {
|
|
|
|
logger.warn('Failed transaction', transac);
|
|
|
|
return callback('Failed to register. Check gas cost.');
|
|
|
|
}
|
|
|
|
transaction = transac;
|
2018-10-23 18:20:42 +00:00
|
|
|
return secureSend(web3, ens.methods.setResolver(node, resolver.options.address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false);
|
2018-08-14 15:12:03 +00:00
|
|
|
})
|
|
|
|
// Set address for node
|
|
|
|
.then(_result => {
|
2018-10-23 18:20:42 +00:00
|
|
|
return secureSend(web3, resolver.methods.setAddr(node, address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false);
|
2018-08-14 15:12:03 +00:00
|
|
|
})
|
|
|
|
// Set resolver for the reverse node
|
|
|
|
.then(_result => {
|
2018-10-23 18:20:42 +00:00
|
|
|
return secureSend(web3, ens.methods.setResolver(reverseNode, resolver.options.address), {from: defaultAccount, gas: ENS_GAS_PRICE}, false);
|
2018-08-14 15:12:03 +00:00
|
|
|
})
|
|
|
|
// Set name for reverse node
|
|
|
|
.then(_result => {
|
2018-10-23 18:20:42 +00:00
|
|
|
return secureSend(web3, resolver.methods.setName(reverseNode, `${subdomain}.${rootDomain}`), {from: defaultAccount, gas: ENS_GAS_PRICE}, false);
|
2018-08-14 15:12:03 +00:00
|
|
|
})
|
|
|
|
.then(_result => {
|
|
|
|
callback(null, transaction);
|
|
|
|
})
|
|
|
|
.catch(err => {
|
2018-10-23 18:20:42 +00:00
|
|
|
logger.error(err.message || err);
|
2018-08-14 15:12:03 +00:00
|
|
|
callback('Failed to register with error: ' + (err.message || err));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function lookupAddress(address, ens, utils, createResolverContract, callback) {
|
|
|
|
if (address.startsWith("0x")) {
|
|
|
|
address = address.slice(2);
|
|
|
|
}
|
|
|
|
|
2018-10-23 18:20:42 +00:00
|
|
|
let node = utils.soliditySha3(address.toLowerCase() + reverseAddressSuffix);
|
2018-08-14 15:12:03 +00:00
|
|
|
|
|
|
|
function cb(err, name) {
|
2018-10-23 18:20:42 +00:00
|
|
|
if (err === NoDecodeStringErr || err === NoDecodeAddrErr) {
|
2018-08-14 15:12:03 +00:00
|
|
|
return callback('Address does not resolve to name. Try syncing chain.');
|
|
|
|
}
|
|
|
|
return callback(err, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ens.methods.resolver(node).call((err, resolverAddress) => {
|
|
|
|
if (err) {
|
|
|
|
return cb(err);
|
|
|
|
}
|
2018-10-23 18:20:42 +00:00
|
|
|
if (resolverAddress === voidAddr) {
|
2018-08-14 15:12:03 +00:00
|
|
|
return cb('Address not associated to a resolver');
|
|
|
|
}
|
|
|
|
createResolverContract(resolverAddress, (_, resolverContract) => {
|
|
|
|
resolverContract.methods.name(node).call(cb);
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function resolveName(name, ens, createResolverContract, callback) {
|
|
|
|
let node = namehash.hash(name);
|
|
|
|
|
|
|
|
function cb(err, addr) {
|
2018-10-23 18:20:42 +00:00
|
|
|
if (err === NoDecodeAddrErr) {
|
2018-08-14 15:12:03 +00:00
|
|
|
return callback(name + " is not registered", "0x");
|
|
|
|
}
|
|
|
|
callback(err, addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ens.methods.resolver(node).call((err, resolverAddress) => {
|
|
|
|
if (err) {
|
|
|
|
return cb(err);
|
|
|
|
}
|
2018-10-23 18:20:42 +00:00
|
|
|
if (resolverAddress === voidAddr) {
|
2018-08-14 15:12:03 +00:00
|
|
|
return cb('Name not yet registered');
|
|
|
|
}
|
|
|
|
createResolverContract(resolverAddress, (_, resolverContract) => {
|
|
|
|
resolverContract.methods.addr(node).call(cb);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
|
|
module.exports = {
|
|
|
|
registerSubDomain,
|
|
|
|
resolveName,
|
|
|
|
lookupAddress
|
|
|
|
};
|
|
|
|
}
|