mirror of https://github.com/embarklabs/embark.git
refactor(@embark/ens): refactor and clean up embark-ens (#1900)
This commit is contained in:
parent
e282ae4974
commit
107e730fc3
|
@ -76,7 +76,7 @@ export default class BlockchainAPI {
|
|||
|
||||
this.events.setCommandHandler("blockchain:defaultAccount:get", (cb) => {
|
||||
const getDefaultAccount = this.getRequestForBlockchain(blockchainName, "getDefaultAccount");
|
||||
cb(getDefaultAccount);
|
||||
cb(null, getDefaultAccount());
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("blockchain:defaultAccount:set", (account, cb) => {
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
import {__} from 'embark-i18n';
|
||||
import ensJS from 'embarkjs-ens';
|
||||
|
||||
const ENSFunctions = ensJS.ENSFunctions;
|
||||
const namehash = require('eth-ens-namehash');
|
||||
|
||||
class ensAPI {
|
||||
constructor(embark, options) {
|
||||
this.embark = embark;
|
||||
this.ens = options.ens;
|
||||
}
|
||||
|
||||
registerAPIs() {
|
||||
this.embark.registerAPICall(
|
||||
'get',
|
||||
'/embark-api/ens/resolve',
|
||||
(req, res) => {
|
||||
ENSFunctions.resolveName(req.query.name, this.ens.ensContract, this.ens.createResolverContract.bind(this.ens), (error, address) => {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({address});
|
||||
}, namehash);
|
||||
});
|
||||
|
||||
this.embark.registerAPICall(
|
||||
'get',
|
||||
'/embark-api/ens/lookup',
|
||||
(req, res) => {
|
||||
ENSFunctions.lookupAddress(req.query.address, this.ens.ensContract, namehash, this.ens.createResolverContract.bind(this.ens), (error, name) => {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({name});
|
||||
});
|
||||
});
|
||||
|
||||
this.embark.registerAPICall(
|
||||
'post',
|
||||
'/embark-api/ens/register',
|
||||
(req, res) => {
|
||||
const {subdomain, address} = req.body;
|
||||
this.ens.ensRegisterSubdomain(subdomain, address, (error) => {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({
|
||||
name: `${req.body.subdomain}.${this.embark.config.namesystemConfig.register.rootDomain}`,
|
||||
address: req.body.address
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
registerConsoleCommands() {
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'resolve [name]',
|
||||
description: __('Resolves an ENS name'),
|
||||
matches: (cmd) => cmd.split(' ')[0] === 'resolve',
|
||||
process: (cmd, cb) => {
|
||||
const [_cmdName, name] = cmd.split(' ');
|
||||
ENSFunctions.resolveName(name, this.ens.ensContract, this.ens.createResolverContract.bind(this.ens), cb, namehash);
|
||||
}
|
||||
});
|
||||
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'lookup [address]',
|
||||
description: __('Lookup an ENS address'),
|
||||
matches: (cmd) => cmd.split(' ')[0] === 'lookup',
|
||||
process: (cmd, cb) => {
|
||||
const [_cmdName, address] = cmd.split(' ');
|
||||
ENSFunctions.lookupAddress(address, this.ens.ensContract, namehash, this.ens.createResolverContract.bind(this.ens), cb);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'registerSubDomain [subDomain] [address]',
|
||||
description: __('Register an ENS sub-domain'),
|
||||
matches: (cmd) => cmd.split(' ')[0] === 'registerSubDomain',
|
||||
process: (cmd, cb) => {
|
||||
const [_cmdName, name, address] = cmd.split(' ');
|
||||
this.embark.events.request("blockchain:defaultAccount:get", (_err, defaultAccount) => {
|
||||
this.ens.safeRegisterSubDomain(name, address, defaultAccount, cb);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ensAPI;
|
|
@ -0,0 +1,42 @@
|
|||
const MAINNET_ID = '1';
|
||||
const ROPSTEN_ID = '3';
|
||||
const RINKEBY_ID = '4';
|
||||
|
||||
export default {
|
||||
[MAINNET_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
},
|
||||
[ROPSTEN_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
},
|
||||
[RINKEBY_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,10 +1,12 @@
|
|||
import {__} from 'embark-i18n';
|
||||
import {AddressUtils, dappPath, hashTo32ByteHexString, recursiveMerge} from 'embark-utils';
|
||||
import {recursiveMerge} from 'embark-utils';
|
||||
const namehash = require('eth-ens-namehash');
|
||||
const async = require('async');
|
||||
import {dappArtifacts, ens} from 'embark-core/constants.json';
|
||||
import EmbarkJS, {Utils as embarkJsUtils} from 'embarkjs';
|
||||
import {ens} from 'embark-core/constants.json';
|
||||
import {Utils as embarkJsUtils} from 'embarkjs';
|
||||
import ensJS from 'embarkjs-ens';
|
||||
import ensContractAddresses from './ensContractAddresses';
|
||||
import EnsAPI from './api';
|
||||
const ENSFunctions = ensJS.ENSFunctions;
|
||||
const Web3 = require('web3');
|
||||
|
||||
|
@ -12,55 +14,12 @@ const ensConfig = require('./ensContractConfigs');
|
|||
const secureSend = embarkJsUtils.secureSend;
|
||||
|
||||
const reverseAddrSuffix = '.addr.reverse';
|
||||
const {ZERO_ADDRESS} = AddressUtils;
|
||||
const ENS_WHITELIST = ens.whitelist;
|
||||
const NOT_REGISTERED_ERROR = 'Name not yet registered';
|
||||
|
||||
const MAINNET_ID = '1';
|
||||
const ROPSTEN_ID = '3';
|
||||
const RINKEBY_ID = '4';
|
||||
// Price of ENS registration contract functions
|
||||
const ENS_GAS_PRICE = 700000;
|
||||
|
||||
const ENS_CONTRACTS_CONFIG = {
|
||||
[MAINNET_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
},
|
||||
[ROPSTEN_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
},
|
||||
[RINKEBY_ID]: {
|
||||
"ENSRegistry": {
|
||||
"address": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A",
|
||||
"silent": true
|
||||
},
|
||||
"Resolver": {
|
||||
"deploy": false
|
||||
},
|
||||
"FIFSRegistrar": {
|
||||
"deploy": false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ENS {
|
||||
constructor(embark, _options) {
|
||||
this.env = embark.env;
|
||||
|
@ -72,23 +31,13 @@ class ENS {
|
|||
this.embark = embark;
|
||||
this.ensConfig = ensConfig;
|
||||
this.configured = false;
|
||||
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, dappArtifacts.symlinkDir);
|
||||
this.initated = false;
|
||||
|
||||
this.ensAPI = new EnsAPI(embark, {ens: this});
|
||||
|
||||
this.events.request("namesystem:node:register", "ens", (readyCb) => {
|
||||
readyCb();
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("ens:resolve", this.ensResolve.bind(this));
|
||||
this.events.setCommandHandler("ens:isENSName", (name, cb) => {
|
||||
setImmediate(cb, this.isENSName(name));
|
||||
});
|
||||
|
||||
this.events.on("blockchain:started", () => {
|
||||
this._web3 = null;
|
||||
});
|
||||
|
||||
this.init(() => {});
|
||||
this.init(readyCb);
|
||||
}, this.executeCommand.bind(this));
|
||||
}
|
||||
|
||||
get web3() {
|
||||
|
@ -122,73 +71,26 @@ class ENS {
|
|||
this.enabled = true;
|
||||
this.doSetENSProvider = this.config.namesystemConfig.provider === 'ens';
|
||||
|
||||
this.registerEvents();
|
||||
this.registerConsoleCommands();
|
||||
this.events.request2("runcode:whitelist", 'eth-ens-namehash');
|
||||
this.registerActions();
|
||||
this.ensAPI.registerConsoleCommands();
|
||||
this.events.request("runcode:whitelist", 'eth-ens-namehash');
|
||||
this.initated = true;
|
||||
cb();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.configured = false;
|
||||
}
|
||||
|
||||
registerConsoleCommands() {
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'resolve [name]',
|
||||
description: __('Resolves an ENS name'),
|
||||
matches: (cmd) => {
|
||||
let [cmdName] = cmd.split(' ');
|
||||
return cmdName === 'resolve';
|
||||
},
|
||||
process: (cmd, cb) => {
|
||||
let [_cmdName, domain] = cmd.split(' ');
|
||||
EmbarkJS.Names.resolve(domain, cb);
|
||||
}
|
||||
});
|
||||
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'lookup [address]',
|
||||
description: __('Lookup an ENS address'),
|
||||
matches: (cmd) => {
|
||||
let [cmdName] = cmd.split(' ');
|
||||
return cmdName === 'lookup';
|
||||
},
|
||||
process: (cmd, cb) => {
|
||||
let [_cmdName, address] = cmd.split(' ');
|
||||
EmbarkJS.Names.lookup(address, cb);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.embark.registerConsoleCommand({
|
||||
usage: 'registerSubDomain [subDomain] [address]',
|
||||
description: __('Register an ENS sub-domain'),
|
||||
matches: (cmd) => {
|
||||
let [cmdName] = cmd.split(' ');
|
||||
return cmdName === 'registerSubDomain';
|
||||
},
|
||||
process: (cmd, cb) => {
|
||||
let [_cmdName, name, address] = cmd.split(' ');
|
||||
EmbarkJS.Names.registerSubDomain(name, address, cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
registerEvents() {
|
||||
if (this.eventsRegistered) {
|
||||
registerActions() {
|
||||
if (this.actionsRegistered) {
|
||||
return;
|
||||
}
|
||||
this.eventsRegistered = true;
|
||||
this.actionsRegistered = true;
|
||||
this.embark.registerActionForEvent("deployment:deployContracts:beforeAll", this.configureContractsAndRegister.bind(this));
|
||||
this.embark.registerActionForEvent('deployment:contract:beforeDeploy', this.modifyENSArguments.bind(this));
|
||||
this.events.on('blockchain:reseted', this.reset.bind(this));
|
||||
this.events.setCommandHandler("storage:ens:associate", this.associateStorageToEns.bind(this));
|
||||
this.events.setCommandHandler("ens:config", this.getEnsConfig.bind(this));
|
||||
this.embark.registerActionForEvent("deployment:deployContracts:afterAll", this.associateContractAddresses.bind(this));
|
||||
this.embark.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
||||
}
|
||||
|
||||
getEnsConfig(cb) {
|
||||
cb({
|
||||
getEnsConfig() {
|
||||
return {
|
||||
env: this.env,
|
||||
registration: this.config.namesystemConfig.register,
|
||||
registryAbi: this.ensConfig.ENSRegistry.abiDefinition,
|
||||
|
@ -197,26 +99,43 @@ class ENS {
|
|||
registrarAddress: this.ensConfig.FIFSRegistrar.deployedAddress,
|
||||
resolverAbi: this.ensConfig.Resolver.abiDefinition,
|
||||
resolverAddress: this.ensConfig.Resolver.deployedAddress
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
setProviderAndRegisterDomains(cb = (() => {})) {
|
||||
this.getEnsConfig(async (config) => {
|
||||
if (this.doSetENSProvider) {
|
||||
this.setupEmbarkJS(config);
|
||||
}
|
||||
executeCommand(command, args, cb) {
|
||||
switch (command) {
|
||||
case 'resolve': this.ensResolve(args[0], cb); break;
|
||||
case 'lookup': this.ensLookup(args[0], cb); break;
|
||||
case 'registerSubdomain': this.ensRegisterSubdomain(args[0], args[1], cb); break;
|
||||
default: cb(__('Unknown command %s', command));
|
||||
}
|
||||
}
|
||||
|
||||
const web3 = await this.web3;
|
||||
addArtifactFile(_params, cb) {
|
||||
const config = this.getEnsConfig();
|
||||
this.events.request("pipeline:register", {
|
||||
path: [this.config.embarkConfig.generationDir, 'config'],
|
||||
file: 'namesystem.json',
|
||||
format: 'json',
|
||||
content: Object.assign({}, this.embark.config.namesystemConfig, config)
|
||||
}, cb);
|
||||
}
|
||||
|
||||
const networkId = await web3.eth.net.getId();
|
||||
const isKnownNetwork = Boolean(ENS_CONTRACTS_CONFIG[networkId]);
|
||||
const shouldRegisterSubdomain = this.config.namesystemConfig.register && this.config.namesystemConfig.register.subdomains && Object.keys(this.config.namesystemConfig.register.subdomains).length;
|
||||
if (isKnownNetwork || !shouldRegisterSubdomain) {
|
||||
return cb();
|
||||
}
|
||||
async setProviderAndRegisterDomains(cb = (() => {})) {
|
||||
const config = this.getEnsConfig();
|
||||
if (this.doSetENSProvider) {
|
||||
this.setupEmbarkJS(config);
|
||||
}
|
||||
|
||||
this.registerConfigDomains(config, cb);
|
||||
});
|
||||
const web3 = await this.web3;
|
||||
const networkId = await web3.eth.net.getId();
|
||||
const isKnownNetwork = Boolean(ensContractAddresses[networkId]);
|
||||
const shouldRegisterSubdomain = this.config.namesystemConfig.register && this.config.namesystemConfig.register.subdomains && Object.keys(this.config.namesystemConfig.register.subdomains).length;
|
||||
if (isKnownNetwork || !shouldRegisterSubdomain) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
this.registerConfigDomains(config, cb);
|
||||
}
|
||||
|
||||
async setupEmbarkJS(config) {
|
||||
|
@ -225,75 +144,6 @@ class ENS {
|
|||
this.events.request("embarkjs:console:setProvider", 'names', 'ens', config);
|
||||
}
|
||||
|
||||
associateStorageToEns(options, cb) {
|
||||
const self = this;
|
||||
// Code inspired by https://github.com/monkybrain/ipfs-to-ens
|
||||
const {name, storageHash} = options;
|
||||
|
||||
if (!this.isENSName(name)) {
|
||||
return cb(__('Invalid domain name: {{name}}\nValid extensions are: {{extenstions}}', {name, extenstions: ENS_WHITELIST.join(', ')}));
|
||||
}
|
||||
|
||||
let hashedName = namehash.hash(name);
|
||||
let contentHash;
|
||||
try {
|
||||
contentHash = 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 === ZERO_ADDRESS) {
|
||||
return cb(NOT_REGISTERED_ERROR);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
async registerConfigDomains(config, cb) {
|
||||
const defaultAccount = await this.web3DefaultAccount;
|
||||
async.each(Object.keys(this.config.namesystemConfig.register.subdomains), (subDomainName, eachCb) => {
|
||||
|
@ -301,21 +151,28 @@ class ENS {
|
|||
const directivesRegExp = new RegExp(/\$(\w+\[?\d?\]?)/g);
|
||||
|
||||
const directives = directivesRegExp.exec(address);
|
||||
if (!directives || !directives.length) {
|
||||
return this.safeRegisterSubDomain(subDomainName, address, defaultAccount, eachCb);
|
||||
if (directives && directives.length) {
|
||||
return eachCb();
|
||||
}
|
||||
this.safeRegisterSubDomain(subDomainName, address, defaultAccount, eachCb);
|
||||
}, cb);
|
||||
}
|
||||
|
||||
// Register as an afterAll to get the contract the directive is pointing to
|
||||
this.embark.registerActionForEvent("contracts:deploy:afterAll", async (deployActionCb) => {
|
||||
if (!this.config.namesystemConfig.enabled) {
|
||||
// ENS was disabled
|
||||
return deployActionCb();
|
||||
}
|
||||
async associateContractAddresses(params, cb) {
|
||||
if (!this.config.namesystemConfig.enabled) {
|
||||
return cb();
|
||||
}
|
||||
|
||||
const currentDefaultAccount = await this.events.request2("blockchain:defaultAccount:get");
|
||||
if (defaultAccount !== currentDefaultAccount) {
|
||||
this.logger.trace(`Skipping registration of subdomain "${directives[1]}" as this action was registered for a previous configuration`);
|
||||
return deployActionCb();
|
||||
const defaultAccount = await this.web3DefaultAccount;
|
||||
|
||||
await Promise.all(Object.keys(this.config.namesystemConfig.register.subdomains).map((subDomainName) => {
|
||||
return new Promise(async (resolve, _reject) => {
|
||||
const address = this.config.namesystemConfig.register.subdomains[subDomainName];
|
||||
const directivesRegExp = new RegExp(/\$(\w+\[?\d?\]?)/g);
|
||||
|
||||
const directives = directivesRegExp.exec(address);
|
||||
if (!directives || !directives.length) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
const contract = await this.events.request2("contracts:contract", directives[1]);
|
||||
|
@ -326,12 +183,18 @@ class ENS {
|
|||
contractName: directives[1],
|
||||
subdomain: subDomainName
|
||||
}));
|
||||
return deployActionCb();
|
||||
return resolve();
|
||||
}
|
||||
this.safeRegisterSubDomain(subDomainName, contract.deployedAddress, defaultAccount, deployActionCb);
|
||||
this.safeRegisterSubDomain(subDomainName, contract.deployedAddress, defaultAccount, (err) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
return eachCb();
|
||||
}, cb);
|
||||
}));
|
||||
|
||||
cb();
|
||||
}
|
||||
|
||||
safeRegisterSubDomain(subDomainName, address, defaultAccount, callback) {
|
||||
|
@ -346,7 +209,7 @@ class ENS {
|
|||
}
|
||||
|
||||
const reverseNode = namehash.hash(address.toLowerCase().substr(2) + reverseAddrSuffix);
|
||||
this.registerSubDomain(defaultAccount, subDomainName, reverseNode, address, secureSend, callback);
|
||||
this.registerSubDomain(defaultAccount, subDomainName, reverseNode, address.toLowerCase(), secureSend, callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -356,73 +219,15 @@ class ENS {
|
|||
subDomainName, this.config.namesystemConfig.register.rootDomain, reverseNode, address, this.logger, secureSend, cb, namehash);
|
||||
}
|
||||
|
||||
createResolverContract(config, callback) {
|
||||
createResolverContract(resolverAddress, callback) {
|
||||
this.events.request("blockchain:contract:create", {
|
||||
abi: config.resolverAbi,
|
||||
address: config.resolverAddress
|
||||
abi: this.ensConfig.Resolver.abiDefinition,
|
||||
address: resolverAddress
|
||||
}, (resolver) => {
|
||||
callback(null, resolver);
|
||||
});
|
||||
}
|
||||
|
||||
registerAPI() {
|
||||
let self = this;
|
||||
|
||||
const createInternalResolverContract = function (resolverAddress, callback) {
|
||||
self.createResolverContract({resolverAbi: self.ensConfig.Resolver.abiDefinition, resolverAddress}, callback);
|
||||
};
|
||||
|
||||
self.embark.registerAPICall(
|
||||
'get',
|
||||
'/embark-api/ens/resolve',
|
||||
(req, res) => {
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
ENSFunctions.resolveName(req.query.name, self.ensContract, createInternalResolverContract.bind(self), callback, namehash);
|
||||
}
|
||||
], function (error, address) {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({address});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
self.embark.registerAPICall(
|
||||
'get',
|
||||
'/embark-api/ens/lookup',
|
||||
(req, res) => {
|
||||
async.waterfall([
|
||||
function (callback) {
|
||||
ENSFunctions.lookupAddress(req.query.address, self.ensContract, namehash, createInternalResolverContract.bind(self), callback);
|
||||
}
|
||||
], function (error, name) {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({name});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
self.embark.registerAPICall(
|
||||
'post',
|
||||
'/embark-api/ens/register',
|
||||
(req, res) => {
|
||||
self.events.request("blockchain:defaultAccount:get", (defaultAccount) => {
|
||||
const {subdomain, address} = req.body;
|
||||
this.safeRegisterSubDomain(subdomain, address, defaultAccount, (error) => {
|
||||
if (error) {
|
||||
return res.send({error: error.message || error});
|
||||
}
|
||||
res.send({name: `${req.body.subdomain}.${self.config.namesystemConfig.register.rootDomain}`, address: req.body.address});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async configureContractsAndRegister(_options, cb) {
|
||||
const NO_REGISTRATION = 'NO_REGISTRATION';
|
||||
const self = this;
|
||||
|
@ -434,8 +239,8 @@ class ENS {
|
|||
|
||||
const networkId = await web3.eth.net.getId();
|
||||
|
||||
if (ENS_CONTRACTS_CONFIG[networkId]) {
|
||||
this.ensConfig = recursiveMerge(this.ensConfig, ENS_CONTRACTS_CONFIG[networkId]);
|
||||
if (ensContractAddresses[networkId]) {
|
||||
this.ensConfig = recursiveMerge(this.ensConfig, ensContractAddresses[networkId]);
|
||||
}
|
||||
|
||||
this.ensConfig.ENSRegistry = await this.events.request2('contracts:add', this.ensConfig.ENSRegistry);
|
||||
|
@ -540,7 +345,7 @@ class ENS {
|
|||
self.logger.error(err.message || err);
|
||||
return cb(err);
|
||||
}
|
||||
self.registerAPI();
|
||||
self.ensAPI.registerAPIs();
|
||||
self.setProviderAndRegisterDomains(cb);
|
||||
});
|
||||
}
|
||||
|
@ -575,36 +380,18 @@ class ENS {
|
|||
});
|
||||
}
|
||||
|
||||
async ensResolve(name, cb) {
|
||||
const self = this;
|
||||
if (!self.enabled) {
|
||||
return cb('ENS not enabled');
|
||||
}
|
||||
if (!self.configured) {
|
||||
return cb('ENS not configured');
|
||||
}
|
||||
const hashedName = namehash.hash(name);
|
||||
const web3 = await this.web3;
|
||||
async.waterfall([
|
||||
function getResolverAddress(next) {
|
||||
self.ensContract.methods.resolver(hashedName).call((err, resolverAddress) => {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (resolverAddress === ZERO_ADDRESS) {
|
||||
return next(NOT_REGISTERED_ERROR);
|
||||
}
|
||||
next(null, resolverAddress);
|
||||
});
|
||||
},
|
||||
function createResolverContract(resolverAddress, next) {
|
||||
const resolverContract = new web3.eth.Contract(self.ensConfig.Resolver.abiDefinition, resolverAddress);
|
||||
next(null, resolverContract);
|
||||
},
|
||||
function resolveName(resolverContract, next) {
|
||||
resolverContract.methods.addr(hashedName).call(next);
|
||||
}
|
||||
], cb);
|
||||
ensResolve(name, cb) {
|
||||
ENSFunctions.resolveName(name, this.ensContract, this.createResolverContract.bind(this), cb, namehash);
|
||||
}
|
||||
|
||||
ensLookup(address, cb) {
|
||||
ENSFunctions.lookupAddress(address, this.ensContract, namehash, this.createResolverContract.bind(this), cb);
|
||||
}
|
||||
|
||||
ensRegisterSubdomain(subdomain, address, cb) {
|
||||
this.events.request("blockchain:defaultAccount:get", (_err, defaultAccount) => {
|
||||
this.safeRegisterSubDomain(subdomain, address, defaultAccount, cb);
|
||||
});
|
||||
}
|
||||
|
||||
isENSName(name) {
|
||||
|
|
|
@ -100,8 +100,8 @@ class ListConfigs {
|
|||
return stringReplaceAsync.seq(cmd, regex, (ensDomain) => {
|
||||
ensDomain = ensDomain.slice(1, ensDomain.length - 1);
|
||||
return (new Promise((resolve, reject) => {
|
||||
this.events.request("ens:resolve", ensDomain, (err, address) => {
|
||||
if(err) {
|
||||
this.events.request("namesystem:resolve", ensDomain, (err, address) => {
|
||||
if (err) {
|
||||
return reject(new Error(err));
|
||||
}
|
||||
address = `'${address}'`;
|
||||
|
|
|
@ -1,43 +1,54 @@
|
|||
import {__} from 'embark-i18n';
|
||||
// import {canonicalHost, defaultHost} from 'embark-utils';
|
||||
|
||||
export default class Namesystem {
|
||||
constructor(embark, _options) {
|
||||
this.embark = embark;
|
||||
this.events = this.embark.events;
|
||||
this.embarkConfig = embark.config.embarkConfig;
|
||||
this.namesystemConfig = this.embark.config.namesystemConfig;
|
||||
|
||||
this.namesystemNodes = {};
|
||||
this.events.setCommandHandler("namesystem:node:register", (clientName, startCb) => {
|
||||
this.namesystemNodes[clientName] = startCb;
|
||||
|
||||
this.registerCommandHandlers();
|
||||
}
|
||||
|
||||
registerCommandHandlers() {
|
||||
this.events.setCommandHandler("namesystem:node:register", (nodeName, startFunction, executeCommand) => {
|
||||
this.namesystemNodes[nodeName] = {startFunction, executeCommand, started: false};
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("namesystem:node:start", (namesystemConfig, cb) => {
|
||||
const clientName = namesystemConfig.provider;
|
||||
const client = this.namesystemNodes[clientName];
|
||||
if (!client) return cb(__("Namesystem client %s not found", clientName));
|
||||
const nodeName = namesystemConfig.provider;
|
||||
const client = this.namesystemNodes[nodeName];
|
||||
if (!client) return cb(__("Namesystem client %s not found", nodeName));
|
||||
|
||||
client.apply(client, [
|
||||
client.startFunction.apply(client, [
|
||||
() => {
|
||||
this.events.emit("namesystem:started", clientName);
|
||||
client.started = true;
|
||||
cb();
|
||||
}
|
||||
]);
|
||||
});
|
||||
embark.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
||||
}
|
||||
|
||||
async addArtifactFile(_params, cb) {
|
||||
// FIXME this shouldn't be done as the stack component calls the plugins
|
||||
// FIXME this will be refactored along with the ENS plugin refactor
|
||||
this.events.request("ens:config", (config) => {
|
||||
this.events.request("pipeline:register", {
|
||||
path: [this.embarkConfig.generationDir, 'config'],
|
||||
file: 'namesystem.json',
|
||||
format: 'json',
|
||||
content: Object.assign({}, this.namesystemConfig, config)
|
||||
}, cb);
|
||||
this.events.setCommandHandler("namesystem:resolve", (name, cb) => {
|
||||
this.executeNodeCommand('resolve', [name], cb);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("namesystem:lookup", (address, cb) => {
|
||||
this.executeNodeCommand('lookup', [address], cb);
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("namesystem:registerSubdomain", (name, address, cb) => {
|
||||
this.executeNodeCommand('registerSubdomain', [name, address], cb);
|
||||
});
|
||||
}
|
||||
|
||||
executeNodeCommand(command, args, cb) {
|
||||
const startedNode = Object.values(this.namesystemNodes).find(node => node.started);
|
||||
|
||||
if (!startedNode) {
|
||||
return cb(__("No namesystem client started"));
|
||||
}
|
||||
|
||||
startedNode.executeCommand(command, args, cb);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue