Merge pull request #452 from embark-framework/DomainNameResolution
ENS Domain name resolution initial integration
This commit is contained in:
commit
8fa325a7af
45
js/embark.js
45
js/embark.js
|
@ -272,6 +272,51 @@ EmbarkJS.Messages.listenTo = function(options, callback) {
|
||||||
return this.currentMessages.listenTo(options, callback);
|
return this.currentMessages.listenTo(options, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EmbarkJS.Names = {};
|
||||||
|
|
||||||
|
EmbarkJS.Names.Providers = {};
|
||||||
|
|
||||||
|
EmbarkJS.Names.registerProvider = function(providerName, obj) {
|
||||||
|
EmbarkJS.Names.Providers[providerName] = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbarkJS.Names.setProvider = function(provider, options) {
|
||||||
|
let providerObj = this.Providers[provider];
|
||||||
|
|
||||||
|
if (!providerObj) {
|
||||||
|
throw new Error('Unknown name system provider');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentNameSystems = providerObj;
|
||||||
|
|
||||||
|
return providerObj.setProvider(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
// resolve resolves a name into an identifier of some kind
|
||||||
|
EmbarkJS.Names.resolve = function(name) {
|
||||||
|
if (!this.currentNameSystems) {
|
||||||
|
throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")');
|
||||||
|
}
|
||||||
|
return this.currentNameSystems.resolve(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the reverse of resolve, resolves using an identifier to get to a name
|
||||||
|
EmbarkJS.Names.lookup = function(identifier) {
|
||||||
|
if (!this.currentNameSystems) {
|
||||||
|
throw new Error('Name system provider not set; e.g EmbarkJS.Names.setProvider("ens")');
|
||||||
|
}
|
||||||
|
return this.currentNameSystems.lookup(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// To Implement
|
||||||
|
|
||||||
|
/*
|
||||||
|
// register a name
|
||||||
|
EmbarkJS.Names.register = function(name, options) {
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
EmbarkJS.Utils = {
|
EmbarkJS.Utils = {
|
||||||
fromAscii: function(str) {
|
fromAscii: function(str) {
|
||||||
var _web3 = new Web3();
|
var _web3 = new Web3();
|
||||||
|
|
|
@ -45,6 +45,7 @@ Config.prototype.loadConfigFiles = function(options) {
|
||||||
this.loadBlockchainConfigFile();
|
this.loadBlockchainConfigFile();
|
||||||
this.loadStorageConfigFile();
|
this.loadStorageConfigFile();
|
||||||
this.loadCommunicationConfigFile();
|
this.loadCommunicationConfigFile();
|
||||||
|
this.loadNameSystemConfigFile();
|
||||||
|
|
||||||
this.loadContractsConfigFile();
|
this.loadContractsConfigFile();
|
||||||
this.loadPipelineConfigFile();
|
this.loadPipelineConfigFile();
|
||||||
|
@ -63,6 +64,7 @@ Config.prototype.reloadConfig = function() {
|
||||||
this.loadBlockchainConfigFile();
|
this.loadBlockchainConfigFile();
|
||||||
this.loadStorageConfigFile();
|
this.loadStorageConfigFile();
|
||||||
this.loadCommunicationConfigFile();
|
this.loadCommunicationConfigFile();
|
||||||
|
this.loadNameSystemConfigFile();
|
||||||
this.loadContractsConfigFile();
|
this.loadContractsConfigFile();
|
||||||
this.loadPipelineConfigFile();
|
this.loadPipelineConfigFile();
|
||||||
this.loadContractsConfigFile();
|
this.loadContractsConfigFile();
|
||||||
|
@ -228,6 +230,20 @@ Config.prototype.loadStorageConfigFile = function() {
|
||||||
this.storageConfig = this._mergeConfig(configFilePath, configObject, this.env);
|
this.storageConfig = this._mergeConfig(configFilePath, configObject, this.env);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Config.prototype.loadNameSystemConfigFile = function() {
|
||||||
|
// todo: spec out names for registration in the file itself for a dev chain
|
||||||
|
var configObject = {
|
||||||
|
"default": {
|
||||||
|
"available_providers": ["ens"],
|
||||||
|
"provider": "ens"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let configFilePath = this._getFileOrOject(this.configDir, 'namesystem', 'namesystem');
|
||||||
|
|
||||||
|
this.namesystemConfig = this._mergeConfig(configFilePath, configObject, this.env);
|
||||||
|
};
|
||||||
|
|
||||||
Config.prototype.loadCommunicationConfigFile = function() {
|
Config.prototype.loadCommunicationConfigFile = function() {
|
||||||
var configObject = {
|
var configObject = {
|
||||||
"default": {
|
"default": {
|
||||||
|
|
|
@ -105,6 +105,7 @@ class Engine {
|
||||||
"deployment": this.deploymentService,
|
"deployment": this.deploymentService,
|
||||||
"fileWatcher": this.fileWatchService,
|
"fileWatcher": this.fileWatchService,
|
||||||
"webServer": this.webServerService,
|
"webServer": this.webServerService,
|
||||||
|
"namingSystem": this.namingSystem,
|
||||||
"ipfs": this.ipfsService,
|
"ipfs": this.ipfsService,
|
||||||
"web3": this.web3Service,
|
"web3": this.web3Service,
|
||||||
"libraryManager": this.libraryManagerService,
|
"libraryManager": this.libraryManagerService,
|
||||||
|
|
|
@ -123,6 +123,7 @@ class Embark {
|
||||||
engine.startService("pipeline");
|
engine.startService("pipeline");
|
||||||
engine.startService("deployment");
|
engine.startService("deployment");
|
||||||
engine.startService("codeGenerator");
|
engine.startService("codeGenerator");
|
||||||
|
engine.startService("namingSystem");
|
||||||
// TODO: this should be just 'storage' and the storage should figure out the module
|
// TODO: this should be just 'storage' and the storage should figure out the module
|
||||||
engine.startService(engine.config.storageConfig.provider);
|
engine.startService(engine.config.storageConfig.provider);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,296 @@
|
||||||
|
const namehash = require('eth-ens-namehash');
|
||||||
|
/*global web3*/
|
||||||
|
let __embarkENS = {};
|
||||||
|
|
||||||
|
// registry interface for later
|
||||||
|
__embarkENS.registryInterface = [
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "resolver",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "owner",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "resolver",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setResolver",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "label",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setSubnodeOwner",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setOwner",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
__embarkENS.resolverInterface = [
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "addr",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "content",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "name",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kind",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "has",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "addr",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setAddr",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hash",
|
||||||
|
"type": "bytes32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setContent",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "setName",
|
||||||
|
"outputs": [],
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"name": "node",
|
||||||
|
"type": "bytes32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "contentType",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ABI",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "",
|
||||||
|
"type": "bytes"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
__embarkENS.registryAddresses = {
|
||||||
|
// Mainnet
|
||||||
|
"1": "0x314159265dd8dbb310642f98f50c066173c1259b",
|
||||||
|
// Ropsten
|
||||||
|
"3": "0x112234455c3a32fd11230c42e7bccd4a84e02010",
|
||||||
|
// Rinkeby
|
||||||
|
"4": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
|
||||||
|
};
|
||||||
|
|
||||||
|
__embarkENS.setProvider = function () {
|
||||||
|
// get network id and then assign ENS contract based on that
|
||||||
|
let registryAddresses = this.registryAddresses;
|
||||||
|
this.ens = web3.eth.net.getId().then(id => {
|
||||||
|
if (registryAddresses[id] !== undefined) {
|
||||||
|
return new web3.eth.Contract(this.registryInterface, registryAddresses[id]);
|
||||||
|
}
|
||||||
|
// todo: deploy at this point
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
__embarkENS.resolve = function(name) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (self.ens === undefined) return undefined;
|
||||||
|
|
||||||
|
let node = namehash(name);
|
||||||
|
|
||||||
|
self.ens.methods.resolver(node).call().then((resolverAddress) => {
|
||||||
|
let resolverContract = new web3.eth.Contract(self.resolverInterface, resolverAddress);
|
||||||
|
return resolverContract.methods.addr(node).call();
|
||||||
|
}).then((addr) => {
|
||||||
|
return addr;
|
||||||
|
}).catch(err => err);
|
||||||
|
};
|
||||||
|
|
||||||
|
__embarkENS.lookup = function(address) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (self.ens === undefined) return undefined;
|
||||||
|
|
||||||
|
if (address.startsWith("0x")) address = address.slice(2);
|
||||||
|
|
||||||
|
let node = namehash(address.toLowerCase() + ".addr.reverse");
|
||||||
|
|
||||||
|
self.ens.methods.resolver(node).call().then((resolverAddress) => {
|
||||||
|
let resolverContract = new web3.eth.Contract(self.resolverInterface, resolverAddress);
|
||||||
|
return resolverContract.methods.name(node).call();
|
||||||
|
}).then((name) => {
|
||||||
|
if (name === "" || name === undefined) throw Error("ENS name not found");
|
||||||
|
return name;
|
||||||
|
}).catch(err => err);
|
||||||
|
};
|
|
@ -0,0 +1,56 @@
|
||||||
|
const fs = require('../../core/fs.js');
|
||||||
|
const utils = require('../../utils/utils.js');
|
||||||
|
|
||||||
|
class ENS {
|
||||||
|
constructor(embark, options) {
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.events = embark.events;
|
||||||
|
this.web3 = options.web3;
|
||||||
|
this.namesConfig = options.namesConfig;
|
||||||
|
this.embark = embark;
|
||||||
|
|
||||||
|
this.addENSToEmbarkJS();
|
||||||
|
this.addSetProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
addENSToEmbarkJS() {
|
||||||
|
const self = this;
|
||||||
|
// TODO: make this a shouldAdd condition
|
||||||
|
if (this.namesConfig === {}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this.namesConfig.available_providers.indexOf('ens') < 0) && (this.namesConfig.provider !== 'ens' || this.namesConfig.enabled !== true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = "";
|
||||||
|
code += "\n" + fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
|
||||||
|
code += "\nEmbarkJS.Names.registerProvider('ens', __embarkENS);";
|
||||||
|
|
||||||
|
this.embark.addCodeToEmbarkJS(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
addSetProvider() {
|
||||||
|
let config = JSON.stringify({});
|
||||||
|
|
||||||
|
let code = "\nEmbarkJS.Names.setProvider('ens'," + config + ");";
|
||||||
|
|
||||||
|
let shouldInit = (namesConfig) => {
|
||||||
|
return (namesConfig.provider === 'ens' && namesConfig.enabled === true);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.embark.addProviderInit('names', code, shouldInit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ENS;
|
File diff suppressed because it is too large
Load Diff
|
@ -38,6 +38,7 @@
|
||||||
"css-loader": "^0.28.11",
|
"css-loader": "^0.28.11",
|
||||||
"deep-equal": "^1.0.1",
|
"deep-equal": "^1.0.1",
|
||||||
"ejs": "^2.5.8",
|
"ejs": "^2.5.8",
|
||||||
|
"eth-ens-namehash": "^2.0.8",
|
||||||
"eth-lib": "^0.2.8",
|
"eth-lib": "^0.2.8",
|
||||||
"ethereumjs-testrpc": "^6.0.3",
|
"ethereumjs-testrpc": "^6.0.3",
|
||||||
"ethereumjs-wallet": "^0.6.0",
|
"ethereumjs-wallet": "^0.6.0",
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"default": {
|
||||||
|
"available_providers": ["ens"],
|
||||||
|
"provider": "ens"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"default": {
|
||||||
|
"available_providers": ["ens"],
|
||||||
|
"provider": "ens"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue