mirror of
https://github.com/embarklabs/embark.git
synced 2025-02-22 10:28:34 +00:00
Instead of relying on the name of network. Fetch the real network id and configure ENS based on that value
333 lines
11 KiB
JavaScript
333 lines
11 KiB
JavaScript
const fs = require('../../core/fs.js');
|
|
const utils = require('../../utils/utils.js');
|
|
const namehash = require('eth-ens-namehash');
|
|
const async = require('async');
|
|
const embarkJsUtils = require('embarkjs').Utils;
|
|
const reverseAddrSuffix = '.addr.reverse';
|
|
|
|
const DEFAULT_ENS_CONTRACTS_CONFIG = {
|
|
"default": {
|
|
"contracts": {
|
|
"ENS": {
|
|
"deploy": false,
|
|
"silent": true
|
|
},
|
|
"ENSRegistry": {
|
|
"deploy": true,
|
|
"silent": true,
|
|
"args": []
|
|
},
|
|
"Resolver": {
|
|
"deploy": true,
|
|
"silent": true,
|
|
"args": ["$ENSRegistry"]
|
|
},
|
|
"FIFSRegistrar": {
|
|
"deploy": false
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const ENS_CONTRACTS_CONFIG = {
|
|
"1": {
|
|
"contracts": {
|
|
"ENSRegistry": {
|
|
"address": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
|
"silent": true
|
|
},
|
|
"Resolver": {
|
|
"deploy": false
|
|
},
|
|
"FIFSRegistrar": {
|
|
"deploy": false
|
|
}
|
|
}
|
|
},
|
|
"3": {
|
|
"contracts": {
|
|
"ENSRegistry": {
|
|
"address": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
|
"silent": true
|
|
},
|
|
"Resolver": {
|
|
"deploy": false
|
|
},
|
|
"FIFSRegistrar": {
|
|
"deploy": false
|
|
}
|
|
}
|
|
},
|
|
"4": {
|
|
"contracts": {
|
|
"ENSRegistry": {
|
|
"address": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A",
|
|
"silent": true
|
|
},
|
|
"Resolver": {
|
|
"deploy": false
|
|
},
|
|
"FIFSRegistrar": {
|
|
"deploy": false
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class ENS {
|
|
constructor(embark, _options) {
|
|
this.env = embark.env;
|
|
this.logger = embark.logger;
|
|
this.events = embark.events;
|
|
this.namesConfig = embark.config.namesystemConfig;
|
|
this.registration = this.namesConfig.register || {};
|
|
this.embark = embark;
|
|
|
|
if (this.namesConfig === {} ||
|
|
this.namesConfig.enabled !== true ||
|
|
this.namesConfig.available_providers.indexOf('ens') < 0) {
|
|
return;
|
|
}
|
|
this.doSetENSProvider = this.namesConfig.provider === 'ens';
|
|
|
|
this.addENSToEmbarkJS();
|
|
this.registerEvents();
|
|
}
|
|
|
|
registerEvents() {
|
|
this.events.once("contracts:deploy:afterAll", this.setProviderAndRegisterDomains.bind(this));
|
|
this.events.once("web3Ready", this.configureContracts.bind(this));
|
|
|
|
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));
|
|
}
|
|
|
|
setProviderAndRegisterDomains(cb = (() => {})) {
|
|
const self = this;
|
|
async.parallel([
|
|
function getENSRegistry(paraCb) {
|
|
self.events.request('contracts:contract', "ENSRegistry", (contract) => {
|
|
paraCb(null, contract);
|
|
});
|
|
},
|
|
function getRegistrar(paraCb) {
|
|
self.events.request('contracts:contract', "FIFSRegistrar", (contract) => {
|
|
paraCb(null, contract);
|
|
});
|
|
},
|
|
function getResolver(paraCb) {
|
|
self.events.request('contracts:contract', "Resolver", (contract) => {
|
|
paraCb(null, contract);
|
|
});
|
|
}
|
|
], (err, results) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
if (!results[0] || !results[1] || !results[2]) {
|
|
return cb(__('Aborting ENS setup as some of the contracts did not deploy properly'));
|
|
}
|
|
// result[0] => ENSRegistry; result[1] => FIFSRegistrar; result[2] => FIFSRegistrar
|
|
let config = {
|
|
env: self.env,
|
|
registration: self.registration,
|
|
registryAbi: results[0].abiDefinition,
|
|
registryAddress: results[0].deployedAddress,
|
|
registrarAbi: results[1].abiDefinition,
|
|
registrarAddress: results[1].deployedAddress,
|
|
resolverAbi: results[2].abiDefinition,
|
|
resolverAddress: results[2].deployedAddress
|
|
};
|
|
|
|
if (self.doSetENSProvider) {
|
|
self.addSetProvider(config);
|
|
}
|
|
|
|
self.events.request('blockchain:networkId', (networkId) => {
|
|
const isKnownNetworks = Object.keys(ENS_CONTRACTS_CONFIG).includes(networkId);
|
|
const shouldRegisterSubdomain = self.registration && self.registration.subdomains && Object.keys(self.registration.subdomains).length;
|
|
if (isKnownNetworks || !shouldRegisterSubdomain) {
|
|
return cb();
|
|
}
|
|
self.registerConfigDomains(config, cb);
|
|
});
|
|
});
|
|
}
|
|
|
|
associateStorageToEns(options, cb) {
|
|
const self = this;
|
|
// Code inspired by https://github.com/monkybrain/ipfs-to-ens
|
|
const {name, storageHash} = options;
|
|
|
|
if (!utils.isValidEthDomain(name)) {
|
|
return cb('Invalid domain name ' + name);
|
|
}
|
|
|
|
let hashedName = namehash.hash(name);
|
|
let contentHash;
|
|
try {
|
|
contentHash = utils.hashTo32ByteHexString(storageHash);
|
|
} catch (e) {
|
|
return cb('Invalid IPFS hash');
|
|
}
|
|
|
|
// Set content
|
|
async.waterfall([
|
|
function getRegistryABI(next) {
|
|
self.events.request('contracts:contract', "ENSRegistry", (contract) => {
|
|
next(null, contract);
|
|
});
|
|
},
|
|
function createRegistryContract(contract, next) {
|
|
self.events.request("blockchain:contract:create",
|
|
{abi: contract.abiDefinition, address: contract.deployedAddress},
|
|
(resolver) => {
|
|
next(null, resolver);
|
|
});
|
|
},
|
|
function getResolverForName(registry, next) {
|
|
registry.methods.resolver(hashedName).call((err, resolverAddress) => {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
if (resolverAddress === '0x0000000000000000000000000000000000000000') {
|
|
return cb('Name not yet registered');
|
|
}
|
|
next(null, resolverAddress);
|
|
});
|
|
},
|
|
function getResolverABI(resolverAddress, next) {
|
|
self.events.request('contracts:contract', "Resolver", (contract) => {
|
|
next(null, resolverAddress, contract);
|
|
});
|
|
},
|
|
function createResolverContract(resolverAddress, contract, next) {
|
|
self.events.request("blockchain:contract:create",
|
|
{abi: contract.abiDefinition, address: resolverAddress},
|
|
(resolver) => {
|
|
next(null, resolver);
|
|
});
|
|
},
|
|
function getDefaultAccount(resolver, next) {
|
|
self.events.request("blockchain:defaultAccount:get", (defaultAccount) => {
|
|
next(null, resolver, defaultAccount);
|
|
});
|
|
},
|
|
function setContent(resolver, defaultAccount, next) {
|
|
resolver.methods.setContent(hashedName, contentHash).send({from: defaultAccount}).then((transaction) => {
|
|
if (transaction.status !== "0x1" && transaction.status !== "0x01" && transaction.status !== true) {
|
|
return next('Association failed. Status: ' + transaction.status);
|
|
}
|
|
next();
|
|
}).catch(next);
|
|
}
|
|
], cb);
|
|
}
|
|
|
|
registerConfigDomains(config, cb) {
|
|
const self = this;
|
|
const register = require('./register');
|
|
const secureSend = embarkJsUtils.secureSend;
|
|
self.events.request("blockchain:defaultAccount:get", (defaultAccount) => {
|
|
async.parallel([
|
|
function createRegistryContract(paraCb) {
|
|
self.events.request("blockchain:contract:create",
|
|
{abi: config.registryAbi, address: config.registryAddress},
|
|
(registry) => {
|
|
paraCb(null, registry);
|
|
});
|
|
},
|
|
function createRegistrarContract(paraCb) {
|
|
self.events.request("blockchain:contract:create",
|
|
{abi: config.registrarAbi, address: config.registrarAddress},
|
|
(registrar) => {
|
|
paraCb(null, registrar);
|
|
});
|
|
},
|
|
function createResolverContract(paraCb) {
|
|
self.events.request("blockchain:contract:create",
|
|
{abi: config.resolverAbi, address: config.resolverAddress},
|
|
(resolver) => {
|
|
paraCb(null, resolver);
|
|
});
|
|
}
|
|
], function(err, contracts) {
|
|
if (err) {
|
|
return cb(err);
|
|
}
|
|
const [ens, registrar, resolver] = contracts;
|
|
|
|
async.each(Object.keys(self.registration.subdomains), (subDomainName, eachCb) => {
|
|
const address = self.registration.subdomains[subDomainName];
|
|
const reverseNode = utils.soliditySha3(address.toLowerCase().substr(2) + reverseAddrSuffix);
|
|
register(ens, registrar, resolver, defaultAccount, subDomainName, self.registration.rootDomain,
|
|
reverseNode, address, self.logger, secureSend, eachCb);
|
|
}, cb);
|
|
|
|
});
|
|
});
|
|
}
|
|
|
|
addENSToEmbarkJS() {
|
|
const self = this;
|
|
|
|
// get namehash, import it into file
|
|
self.events.request("version:get:eth-ens-namehash", function(EnsNamehashVersion) {
|
|
let currentEnsNamehashVersion = require('../../../package.json').dependencies["eth-ens-namehash"];
|
|
if (EnsNamehashVersion !== currentEnsNamehashVersion) {
|
|
self.events.request("version:getPackageLocation", "eth-ens-namehash", EnsNamehashVersion, function(err, location) {
|
|
self.embark.registerImportFile("eth-ens-namehash", fs.dappPath(location));
|
|
});
|
|
}
|
|
});
|
|
|
|
let code = fs.readFileSync(utils.joinPath(__dirname, 'register.js')).toString();
|
|
code += "\n" + fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
|
|
code += "\nEmbarkJS.Names.registerProvider('ens', __embarkENS);";
|
|
|
|
this.embark.addCodeToEmbarkJS(code);
|
|
}
|
|
|
|
configureContracts() {
|
|
this.events.request('blockchain:networkId', (networkId) => {
|
|
const config = Object.assign({}, DEFAULT_ENS_CONTRACTS_CONFIG, {[this.env]: ENS_CONTRACTS_CONFIG[networkId]});
|
|
|
|
if (this.registration && this.registration.rootDomain) {
|
|
// Register root domain if it is defined
|
|
const rootNode = namehash.hash(this.registration.rootDomain);
|
|
config.default.contracts['FIFSRegistrar'] = {
|
|
"deploy": true,
|
|
"silent": true,
|
|
"args": ["$ENSRegistry", rootNode],
|
|
"onDeploy": [
|
|
`ENSRegistry.methods.setOwner('${rootNode}', web3.eth.defaultAccount).send({from: web3.eth.defaultAccount}).then(() => {
|
|
ENSRegistry.methods.setResolver('${rootNode}', "$Resolver").send({from: web3.eth.defaultAccount});
|
|
var reverseNode = web3.utils.soliditySha3(web3.eth.defaultAccount.toLowerCase().substr(2) + '${reverseAddrSuffix}');
|
|
ENSRegistry.methods.setResolver(reverseNode, "$Resolver").send({from: web3.eth.defaultAccount});
|
|
Resolver.methods.setAddr('${rootNode}', web3.eth.defaultAccount).send({from: web3.eth.defaultAccount});
|
|
Resolver.methods.setName(reverseNode, '${this.registration.rootDomain}').send({from: web3.eth.defaultAccount});
|
|
})`
|
|
]
|
|
};
|
|
}
|
|
this.embark.registerContractConfiguration(config);
|
|
|
|
this.embark.events.request("config:contractsFiles:add", this.embark.pathToFile('./contracts/ENSRegistry.sol'));
|
|
this.embark.events.request("config:contractsFiles:add", this.embark.pathToFile('./contracts/FIFSRegistrar.sol'));
|
|
this.embark.events.request("config:contractsFiles:add", this.embark.pathToFile('./contracts/Resolver.sol'));
|
|
});
|
|
}
|
|
|
|
addSetProvider(config) {
|
|
let code = "\nEmbarkJS.Names.setProvider('ens'," + JSON.stringify(config) + ");";
|
|
|
|
let shouldInit = (namesConfig) => {
|
|
return (namesConfig.provider === 'ens' && namesConfig.enabled === true);
|
|
};
|
|
|
|
this.embark.addProviderInit('names', code, shouldInit);
|
|
this.embark.addConsoleProviderInit('names', code, shouldInit);
|
|
}
|
|
}
|
|
|
|
module.exports = ENS;
|