Merge pull request #390 from embark-framework/features/add-swarm-to-embarkjs

Added swarm support in embarkjs, isAvailable for messages/storage, swarm/ipfs checks
This commit is contained in:
Iuri Matias 2018-05-01 18:52:22 -04:00 committed by GitHub
commit 0cffff067a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 456 additions and 92 deletions

View File

@ -182,9 +182,7 @@ EmbarkJS.Contract.prototype.send = function(value, unit, _options) {
EmbarkJS.Storage = {};
EmbarkJS.Storage.Providers = {
SWARM: 'swarm'
};
EmbarkJS.Storage.Providers = {};
EmbarkJS.Storage.saveText = function(text) {
if (!this.currentStorage) {
@ -230,6 +228,10 @@ EmbarkJS.Storage.setProvider = function(provider, options) {
return providerObj.setProvider(options);
};
EmbarkJS.Storage.isAvailable = function(){
return this.currentStorage.isAvailable();
};
EmbarkJS.Messages = {};
EmbarkJS.Messages.Providers = {};
@ -250,6 +252,10 @@ EmbarkJS.Messages.setProvider = function(provider, options) {
return providerObj.setProvider(options);
};
EmbarkJS.Messages.isAvailable = function(){
return this.currentMessages.isAvailable();
};
EmbarkJS.Messages.sendMessage = function(options) {
if (!this.currentMessages) {
throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")');

View File

@ -85,3 +85,11 @@ EmbarkJS.Messages.Orbit.listenTo = function(options) {
return promise;
};
// TODO: needs a real check for availability
// TODO: not tested as orbit is not loaded and therefore the provider is not available
EmbarkJS.Messages.Orbit.isAvailable = function(){
return new Promise((resolve) => {
if(!this.orbit) resolve(false);
resolve(true);
});
}

View File

@ -103,7 +103,9 @@ Config.prototype._getFileOrOject = function(object, filePath, property) {
Config.prototype.loadBlockchainConfigFile = function() {
var configObject = {
"default": {
"enabled": true
"enabled": true,
"rpcCorsDomain": "auto",
"wsOrigins": "auto"
}
};
@ -181,9 +183,10 @@ Config.prototype.loadStorageConfigFile = function() {
"default": {
"versions": versions,
"enabled": true,
"available_providers": ["ipfs"],
"available_providers": ["ipfs", "swarm"],
"ipfs_bin": "ipfs",
"provider": "ipfs",
"protocol": "http",
"host": "localhost",
"port": 5001,
"getUrl": "http://localhost:8080/ipfs/"

View File

@ -249,7 +249,7 @@ class Engine {
this.registerModule('swarm', {
addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor),
storageConfig: this.config.storageConfig,
web3: _options.web3
bzz: _options.bzz
});
}

View File

@ -1,5 +1,6 @@
let async = require('async');
const constants = require('./constants');
const _ = require('underscore');
// require("./utils/debug_util.js")(__filename, async);
require('colors');
@ -45,11 +46,11 @@ class Embark {
if(blockchainConfig.rpcCorsDomain === 'auto') {
if(webServerConfig) blockchainConfig.rpcCorsDomain = `http://${webServerConfig.host}:${webServerConfig.port}`;
if(storageConfig) blockchainConfig.rpcCorsDomain += `${blockchainConfig.rpcCorsDomain.length ? ',' : ''}http://${storageConfig.host}:${storageConfig.port}`;
if(storageConfig) blockchainConfig.rpcCorsDomain += `${blockchainConfig.rpcCorsDomain.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`;
}
if(blockchainConfig.wsOrigins === 'auto') {
if(webServerConfig) blockchainConfig.wsOrigins = `http://${webServerConfig.host}:${webServerConfig.port}`;
if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}http://${storageConfig.host}:${storageConfig.port}`;
if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`;
}
return require('./cmds/blockchain/blockchain.js')(blockchainConfig, client, env).run();
}
@ -121,7 +122,7 @@ class Embark {
engine.startService("pipeline");
engine.startService("codeGenerator");
engine.startService("deployment");
engine.startService("ipfs");
engine.startService(engine.config.storageConfig.provider, {bzz: engine.web3.bzz});
engine.events.on('check:backOnline:Ethereum', function () {
engine.logger.info('Ethereum node detected..');
@ -134,6 +135,7 @@ class Embark {
engine.events.on('outputDone', function () {
engine.logger.info("Looking for documentation? You can find it at ".cyan + "http://embark.readthedocs.io/".green.underline + ".".cyan);
engine.logger.info("Ready".underline);
engine.events.emit("status", "Ready".green);
});
engine.deployManager.deployContracts(function (err) {
@ -153,7 +155,6 @@ class Embark {
engine.logger.info(err.stack);
} else {
engine.events.emit('firstDeploymentDone');
engine.events.emit("status", "Ready".green);
let size = windowSize.get();
if (size.height < 40 || size.width < 118) {
@ -194,6 +195,7 @@ class Embark {
engine.startService("codeGenerator");
engine.startService("deployment");
engine.startService("ipfs");
engine.startService("swarm", {bzz: engine.web3.bzz});
callback();
},
function deploy(callback) {
@ -303,10 +305,28 @@ class Embark {
engine.startService("pipeline");
engine.startService("codeGenerator");
engine.startService("deployment");
engine.startService("ipfs");
engine.startService("swarm", {buildDir:'dist/',web3: engine.web3});
engine.startService(platform.toLowerCase(), {bzz: engine.web3.bzz});
engine.startMonitor();
callback();
},
function checkStorageService(callback){
let checkFn;
_.find(engine.servicesMonitor.checkList, (value, key) => {
if(key.toLowerCase() === platform.toLowerCase()){
checkFn = value;
return true;
}
});
if (!checkFn || typeof checkFn.fn !== 'function') {
return callback();
}
checkFn.fn(function (serviceCheckResult) {
if (!serviceCheckResult.status || serviceCheckResult.status === 'off') {
return callback({message: `Cannot upload: ${platform} node is not running on http://${engine.config.storageConfig.host}:${engine.config.storageConfig.port}.`});
}
callback();
});
},
function setupStoragePlugin(callback){
let pluginList = engine.plugins.listPlugins();
if (pluginList.length > 0) {
@ -325,10 +345,9 @@ class Embark {
}
if (!cmdPlugin) {
engine.logger.info('try "embark upload ipfs" or "embark upload swarm"'.green);
callback({message: 'unknown platform: ' + platform});
} else {
callback();
return callback({message: 'unknown platform: ' + platform});
}
callback();
},
function deploy(callback) {
// 2. upload to storage (outputDone event triggered after webpack finished)

View File

@ -2,9 +2,9 @@ import IpfsApi from 'ipfs-api';
let __embarkIPFS = {};
__embarkIPFS.setProvider = function(options) {
__embarkIPFS.setProvider = function (options) {
var self = this;
var promise = new Promise(function(resolve, reject) {
var promise = new Promise(function (resolve, reject) {
try {
if (options === undefined) {
self.ipfsConnection = IpfsApi('localhost', '5001');
@ -30,14 +30,14 @@ __embarkIPFS.setProvider = function(options) {
return promise;
};
__embarkIPFS.saveText = function(text) {
__embarkIPFS.saveText = function (text) {
const self = this;
var promise = new Promise(function(resolve, reject) {
var promise = new Promise(function (resolve, reject) {
if (!self.ipfsConnection) {
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
reject(connectionError);
}
self.ipfsConnection.add(self.ipfsConnection.Buffer.from(text), function(err, result) {
self.ipfsConnection.add(self.ipfsConnection.Buffer.from(text), function (err, result) {
if (err) {
reject(err);
} else {
@ -49,11 +49,11 @@ __embarkIPFS.saveText = function(text) {
return promise;
};
__embarkIPFS.get = function(hash) {
__embarkIPFS.get = function (hash) {
const self = this;
// TODO: detect type, then convert if needed
//var ipfsHash = web3.toAscii(hash);
var promise = new Promise(function(resolve, reject) {
var promise = new Promise(function (resolve, reject) {
if (!self.ipfsConnection) {
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
reject(connectionError);
@ -69,7 +69,7 @@ __embarkIPFS.get = function(hash) {
return promise;
};
__embarkIPFS.uploadFile = function(inputSelector) {
__embarkIPFS.uploadFile = function (inputSelector) {
const self = this;
var file = inputSelector[0].files[0];
@ -77,16 +77,16 @@ __embarkIPFS.uploadFile = function(inputSelector) {
throw new Error('no file found');
}
var promise = new Promise(function(resolve, reject) {
var promise = new Promise(function (resolve, reject) {
if (!self.ipfsConnection) {
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
reject(connectionError);
}
var reader = new FileReader();
reader.onloadend = function() {
reader.onloadend = function () {
var fileContent = reader.result;
var buffer = self.ipfsConnection.Buffer.from(fileContent);
self.ipfsConnection.add(buffer, function(err, result) {
self.ipfsConnection.add(buffer, function (err, result) {
if (err) {
reject(err);
} else {
@ -100,7 +100,22 @@ __embarkIPFS.uploadFile = function(inputSelector) {
return promise;
};
__embarkIPFS.getUrl = function(hash) {
__embarkIPFS.isAvailable = function () {
return new Promise((resolve) => {
if (!this.ipfsConnection) {
return resolve(false);
}
this.ipfsConnection.id()
.then((id) => {
resolve(Boolean(id));
})
.catch(() => {
resolve(false);
});
});
};
__embarkIPFS.getUrl = function (hash) {
return (this._getUrl || "http://localhost:8080/ipfs/") + hash;
};

View File

@ -29,7 +29,7 @@ class IPFS {
function runCommand(ipfs_bin, callback) {
let cmd = `"${ipfs_bin}" add -r ${self.buildDir}`;
console.log(("=== adding " + self.buildDir + " to ipfs").green);
console.trace(cmd);
console.debug(cmd);
shelljs.exec(cmd, {silent:true}, function(code, stdout, stderr){ // {silent:true}: don't echo cmd output so it can be controlled via logLevel
console.log(stdout.green);
callback(stderr, stdout);

View File

@ -0,0 +1,94 @@
/*global web3 */
let __embarkSwarm = {};
const bytes = require("eth-lib/lib/bytes");
__embarkSwarm.setProvider = function (options) {
this.bzz = web3.bzz;
this.protocol = options.protocol;
this.host = options.host;
this.port = options.port;
this.connectUrl = `${options.protocol}://${options.host}:${options.port}`;
this.connectError = new Error(`Cannot connect to Swarm node on ${this.connectUrl}`);
this._getUrl = options.getUrl || `${this.connectUrl}/bzzr:/`;
return new Promise((resolve, reject) => {
try {
if (!this.bzz.currentProvider) {
this.bzz.setProvider(`${options.protocol}://${options.host}:${options.port}`);
}
resolve(this);
} catch (err) {
console.log(err);
reject(this.connectError);
}
});
};
__embarkSwarm.isAvailable = function () {
return new Promise((resolve, reject) => {
if (!this.bzz) {
return resolve(false);
}
this.bzz.isAvailable()
.then(resolve)
.catch(() => {
reject(this.connectError);
});
});
};
__embarkSwarm.saveText = function (text) {
return new Promise((resolve, reject) => {
this.isAvailable().then((isAvailable) => {
if (!isAvailable) {
return reject(this.connectError);
}
this.bzz.upload(text)
.then(resolve)
.catch(reject);
}).catch(reject);
});
};
__embarkSwarm.get = function (hash) {
return new Promise((resolve, reject) => {
this.isAvailable().then((isAvailable) => {
if (!isAvailable) {
return reject(this.connectError);
}
this.bzz.download(hash)
.then((uint8Array) => resolve(bytes.toString(bytes.fromUint8Array(uint8Array))))
.catch(reject);
}).catch(reject);
});
};
__embarkSwarm.uploadFile = function (inputSelector) {
let file = inputSelector[0].files[0];
if (file === undefined) {
throw new Error('no file found');
}
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = (event) => {
const fileContent = new Uint8Array(event.target.result);
this.isAvailable().then((isAvailable) => {
if (!isAvailable) {
return reject(this.connectError);
}
this.bzz.upload(fileContent)
.then(resolve)
.catch(reject);
}).catch(reject);
};
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
};
__embarkSwarm.getUrl = function (hash) {
return this._getUrl + hash;
};

View File

@ -1,19 +1,112 @@
let UploadSwarm = require('./upload.js');
let utils = require('../../utils/utils.js');
let fs = require('../../core/fs.js');
class Swarm {
constructor(embark, options) {
this.logger = embark.logger;
this.events = embark.events;
this.buildDir = options.buildDir;
this.storageConfig = options.storageConfig;
this.host = options.host || this.storageConfig.host;
this.port = options.port || this.storageConfig.port;
this.addCheck = options.addCheck;
this.embark = embark;
this.bzz = options.bzz;
this.upload_swarm = new UploadSwarm({
buildDir: options.buildDir || 'dist/',
storageConfig: options.storageConfig,
web3: options.web3
});
embark.registerUploadCommand('swarm', this.upload_swarm.deploy.bind(this.upload_swarm));
this.initSwarmProvider();
this.commandlineDeploy();
this.setServiceCheck();
this.addSwarmToEmbarkJS();
this.addSetProvider();
}
initSwarmProvider(){
if(!this.bzz.currentProvider) {
this.bzz.setProvider(`http://${this.host}:${this.port}`);
}
}
commandlineDeploy() {
this.upload_swarm = new UploadSwarm({
buildDir: this.buildDir || 'dist/',
storageConfig: this.storageConfig,
bzz: this.bzz
});
this.embark.registerUploadCommand('swarm', this.upload_swarm.deploy.bind(this.upload_swarm));
}
setServiceCheck() {
let self = this;
let storageConfig = this.storageConfig;
if (!storageConfig.enabled) {
return;
}
if (storageConfig.provider !== 'swarm' && storageConfig.available_providers.indexOf("swarm") < 0) {
return;
}
this.events.on('check:backOnline:Swarm', function () {
self.logger.info('Swarm node detected...');
});
this.events.on('check:wentOffline:Swarm', function () {
self.logger.info('Swarm node is offline...');
});
if (!this.addCheck) {
return;
}
// add check for console
this.addCheck('Swarm', function(cb){
self.logger.trace("Checking Swarm availability...");
self.bzz.isAvailable().then(result => {
return cb({name: "Swarm ", status: result ? 'on':'off'});
}).catch(err => {
self.logger.trace("Check Swarm availability error: " + err);
return cb({name: "Swarm ", status: 'off'});
});
});
}
addSwarmToEmbarkJS() {
// TODO: make this a shouldAdd condition
if (this.storageConfig === {}) {
return;
}
if ((this.storageConfig.available_providers.indexOf('swarm') < 0) && (this.storageConfig.provider !== 'swarm' || this.storageConfig.enabled !== true)) {
return;
}
let code = "";
code += "\n" + fs.readFileSync(utils.joinPath(__dirname, 'embarkjs.js')).toString();
code += "\nEmbarkJS.Storage.registerProvider('swarm', __embarkSwarm);";
this.embark.addCodeToEmbarkJS(code);
}
addSetProvider() {
let config = JSON.stringify({
host: this.storageConfig.host,
port: this.storageConfig.port,
protocol: this.storageConfig.protocol,
getUrl: this.storageConfig.getUrl
});
let code = "\nEmbarkJS.Storage.setProvider('swarm'," + config + ");";
let shouldInit = (storageConfig) => {
return (storageConfig.provider === 'swarm' && storageConfig.enabled === true);
};
this.embark.addProviderInit('storage', code, shouldInit);
}
}
module.exports = Swarm;

View File

@ -5,7 +5,7 @@ class Swarm {
constructor(options) {
this.options = options;
this.buildDir = options.buildDir || 'dist/';
this.web3 = options.web3;
this.bzz = options.bzz;
this.storageConfig = options.storageConfig;
}
@ -13,15 +13,11 @@ class Swarm {
return new Promise((resolve, reject) => {
console.log("deploying to swarm!");
let self = this;
let web3 = this.web3;
let bzz = this.bzz;
async.waterfall([
function setProvider(callback){
web3.bzz.setProvider(`http://${self.storageConfig.host}:${self.storageConfig.port}`);
callback();
},
function runCommand(callback) {
console.log(("=== adding " + self.buildDir + " to swarm").green);
web3.bzz.upload({
bzz.upload({
path: self.buildDir, // path to data / file / directory
kind: "directory", // could also be "file" or "data"
defaultFile: "index.html" // optional, and only for kind === "directory"
@ -32,6 +28,9 @@ class Swarm {
.catch(callback);
},
function printUrls(dir_hash, callback) {
if (!dir_hash) {
return callback('No directory hash was returned');
}
console.log((`=== DApp available at ${self.storageConfig.getUrl}${dir_hash}/`).green);
callback();
@ -40,9 +39,9 @@ class Swarm {
if (err) {
console.log("error uploading to swarm".red);
console.log(err);
reject(err);
return reject(err);
}
else resolve('successfully uploaded to swarm');
resolve('successfully uploaded to swarm');
});
});
}

View File

@ -3,7 +3,7 @@
// for the whisper v5 and web3.js 1.0
let __embarkWhisperNewWeb3 = {};
__embarkWhisperNewWeb3.setProvider = function(options) {
__embarkWhisperNewWeb3.setProvider = function (options) {
const self = this;
let provider;
if (options === undefined) {
@ -13,12 +13,16 @@ __embarkWhisperNewWeb3.setProvider = function(options) {
}
// TODO: take into account type
self.web3 = new Web3(new Web3.providers.WebsocketProvider("ws://" + provider));
self.getWhisperVersion(function(err, version) {
self.getWhisperVersion(function (err, version) {
if (err) {
console.log("whisper not available");
} else if (version >= 5) {
self.web3.shh.newSymKey().then((id) => { self.symKeyID = id; });
self.web3.shh.newKeyPair().then((id) => { self.sig = id; });
self.web3.shh.newSymKey().then((id) => {
self.symKeyID = id;
});
self.web3.shh.newKeyPair().then((id) => {
self.sig = id;
});
} else {
throw new Error("version of whisper not supported");
}
@ -26,7 +30,7 @@ __embarkWhisperNewWeb3.setProvider = function(options) {
});
};
__embarkWhisperNewWeb3.sendMessage = function(options) {
__embarkWhisperNewWeb3.sendMessage = function (options) {
var topics, data, ttl, payload;
topics = options.topic || options.topics;
data = options.data || options.payload;
@ -56,10 +60,11 @@ __embarkWhisperNewWeb3.sendMessage = function(options) {
powTarget: powTarget
};
this.web3.shh.post(message, function() { });
this.web3.shh.post(message, function () {
});
};
__embarkWhisperNewWeb3.listenTo = function(options) {
__embarkWhisperNewWeb3.listenTo = function (options) {
var topics = options.topic || options.topics;
let promise = new __MessageEvents();
@ -73,7 +78,7 @@ __embarkWhisperNewWeb3.listenTo = function(options) {
let filter = this.web3.shh.subscribe("messages", {
symKeyID: this.symKeyID,
topics: topics
}).on('data', function(result) {
}).on('data', function (result) {
var payload = JSON.parse(EmbarkJS.Utils.toAscii(result.payload));
var data;
data = {
@ -91,9 +96,25 @@ __embarkWhisperNewWeb3.listenTo = function(options) {
return promise;
};
__embarkWhisperNewWeb3.getWhisperVersion = function(cb) {
this.web3.shh.getVersion(function(err, version) {
__embarkWhisperNewWeb3.getWhisperVersion = function (cb) {
this.web3.shh.getVersion(function (err, version) {
cb(err, version);
});
};
__embarkWhisperNewWeb3.isAvailable = function () {
return new Promise((resolve, reject) => {
if (!this.web3.shh) {
return resolve(false);
}
try {
this.getWhisperVersion((err) => {
resolve(Boolean(!err));
});
}
catch (err) {
reject(err);
}
});
};

View File

@ -3,7 +3,7 @@
// for the old version of whisper and web3.js
let __embarkWhisperOld = {};
__embarkWhisperOld.setProvider = function(options) {
__embarkWhisperOld.setProvider = function (options) {
const self = this;
let provider;
if (options === undefined) {
@ -12,7 +12,7 @@ __embarkWhisperOld.setProvider = function(options) {
provider = options.server + ':' + options.port;
}
self.web3 = new Web3(new Web3.providers.HttpProvider("http://" + provider));
self.getWhisperVersion(function(err, version) {
self.getWhisperVersion(function (err, version) {
if (err) {
console.log("whisper not available");
} else if (version >= 5) {
@ -24,7 +24,7 @@ __embarkWhisperOld.setProvider = function(options) {
});
};
__embarkWhisperOld.sendMessage = function(options) {
__embarkWhisperOld.sendMessage = function (options) {
var topics, data, ttl, priority, payload;
topics = options.topic || options.topics;
data = options.data || options.payload;
@ -59,10 +59,11 @@ __embarkWhisperOld.sendMessage = function(options) {
priority: priority
};
return this.web3.shh.post(message, function() { });
return this.web3.shh.post(message, function () {
});
};
__embarkWhisperOld.listenTo = function(options) {
__embarkWhisperOld.listenTo = function (options) {
var topics, _topics;
topics = options.topic || options.topics;
_topics = [];
@ -80,7 +81,7 @@ __embarkWhisperOld.listenTo = function(options) {
let promise = new __MessageEvents();
let filter = this.web3.shh.filter(filterOptions, function(err, result) {
let filter = this.web3.shh.filter(filterOptions, function (err, result) {
var payload = JSON.parse(EmbarkJS.Utils.toAscii(result.payload));
var data;
if (err) {
@ -101,9 +102,24 @@ __embarkWhisperOld.listenTo = function(options) {
return promise;
};
__embarkWhisperOld.getWhisperVersion = function(cb) {
this.web3.version.getWhisper(function(err, _res) {
__embarkWhisperOld.getWhisperVersion = function (cb) {
this.web3.version.getWhisper(function (err, _res) {
cb(err, self.web3.version.whisper);
});
};
__embarkWhisperOld.isAvailable = function () {
return new Promise((resolve, reject) => {
if (!this.web3) {
return resolve(false);
}
try {
this.getWhisperVersion((err) => {
resolve(Boolean(!err));
});
}
catch (err) {
reject(err);
}
});
};

136
package-lock.json generated
View File

@ -3000,16 +3000,12 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"eth-lib": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
"integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz",
"integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==",
"requires": {
"bn.js": "4.11.8",
"elliptic": "6.4.0",
"keccakjs": "0.2.1",
"nano-json-stream-parser": "0.1.2",
"servify": "0.1.12",
"ws": "3.3.3",
"xhr-request-promise": "0.1.2"
}
},
@ -3146,20 +3142,6 @@
"vary": "1.1.2"
},
"dependencies": {
"finalhandler": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"requires": {
"debug": "2.6.9",
"encodeurl": "1.0.2",
"escape-html": "1.0.3",
"on-finished": "2.3.0",
"parseurl": "1.3.2",
"statuses": "1.4.0",
"unpipe": "1.0.0"
}
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
@ -9941,6 +9923,20 @@
"base64-js": "1.2.3",
"ieee754": "1.1.8"
}
},
"eth-lib": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
"integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
"requires": {
"bn.js": "4.11.8",
"elliptic": "6.4.0",
"keccakjs": "0.2.1",
"nano-json-stream-parser": "0.1.2",
"servify": "0.1.12",
"ws": "3.3.3",
"xhr-request-promise": "0.1.2"
}
}
}
},
@ -10366,9 +10362,9 @@
}
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.0.tgz",
"integrity": "sha512-4IV1DSSxC1QK48j9ONFK1MoIAKKkbE8i7u55w2R6IqBqbT7A/iG7aZBCR2Bi8piF0Uz+i/MG1aeqLwl/5vqF+A=="
},
"underscore.string": {
"version": "3.3.4",
@ -10994,6 +10990,13 @@
"got": "7.1.0",
"swarm-js": "0.1.37",
"underscore": "1.8.3"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-core": {
@ -11015,6 +11018,13 @@
"underscore": "1.8.3",
"web3-eth-iban": "1.0.0-beta.34",
"web3-utils": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-core-method": {
@ -11027,6 +11037,13 @@
"web3-core-promievent": "1.0.0-beta.34",
"web3-core-subscriptions": "1.0.0-beta.34",
"web3-utils": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-core-promievent": {
@ -11048,6 +11065,13 @@
"web3-providers-http": "1.0.0-beta.34",
"web3-providers-ipc": "1.0.0-beta.34",
"web3-providers-ws": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-core-subscriptions": {
@ -11058,6 +11082,13 @@
"eventemitter3": "1.1.1",
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-eth": {
@ -11077,6 +11108,13 @@
"web3-eth-personal": "1.0.0-beta.34",
"web3-net": "1.0.0-beta.34",
"web3-utils": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-eth-abi": {
@ -11094,6 +11132,11 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
@ -11124,6 +11167,11 @@
"xhr-request-promise": "0.1.2"
}
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
},
"uuid": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz",
@ -11144,6 +11192,13 @@
"web3-core-subscriptions": "1.0.0-beta.34",
"web3-eth-abi": "1.0.0-beta.34",
"web3-utils": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-eth-iban": {
@ -11201,6 +11256,13 @@
"oboe": "2.1.3",
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.34"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-providers-ws": {
@ -11211,6 +11273,13 @@
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.34",
"websocket": "1.0.25"
},
"dependencies": {
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},
"web3-shh": {
@ -11242,6 +11311,25 @@
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
},
"eth-lib": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
"integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
"requires": {
"bn.js": "4.11.6",
"elliptic": "6.4.0",
"keccakjs": "0.2.1",
"nano-json-stream-parser": "0.1.2",
"servify": "0.1.12",
"ws": "3.3.3",
"xhr-request-promise": "0.1.2"
}
},
"underscore": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz",
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
}
}
},

View File

@ -36,6 +36,7 @@
"css-loader": "^0.28.11",
"deep-equal": "^1.0.1",
"ejs": "^2.5.8",
"eth-lib": "^0.2.8",
"ethereumjs-testrpc": "^6.0.3",
"file-loader": "^1.1.5",
"finalhandler": "^1.1.1",
@ -58,7 +59,7 @@
"style-loader": "^0.19.0",
"tar": "^3.1.5",
"toposort": "^1.0.0",
"underscore": "^1.8.3",
"underscore": "^1.9.0",
"underscore.string": "^3.3.4",
"url-loader": "^0.6.2",
"viz.js": "^1.8.1",

View File

@ -27,6 +27,7 @@ describe('embark.Config', function () {
"rpcHost": "localhost",
"rpcPort": 8545,
"rpcCorsDomain": "http://localhost:8000",
"wsOrigins": "auto",
"account": {
"password": "config/development/password"
}

View File

@ -1,7 +1,7 @@
{
"default": {
"enabled": true,
"available_providers": ["ipfs"],
"available_providers": ["ipfs", "swarm"],
"ipfs_bin": "ipfs",
"provider": "ipfs",
"host": "localhost",
@ -9,10 +9,10 @@
},
"development": {
"enabled": true,
"provider": "ipfs",
"host": "localhost",
"port": 5001,
"getUrl": "http://localhost:8080/ipfs/"
"provider": "swarm",
"host": "swarm-gateways.net",
"port": 80,
"getUrl": "http://swarm-gateways.net/bzzr:/"
},
"livenet": {
"enabled": true,