mirror of https://github.com/embarklabs/embark.git
implement communication stack component, whisper plugin
This commit is contained in:
parent
90ea1f0c27
commit
e432dc328c
|
@ -1,312 +0,0 @@
|
|||
import { __ } from 'embark-i18n';
|
||||
const UploadIPFS = require('./upload.js');
|
||||
const IpfsApi = require('ipfs-api');
|
||||
const StorageProcessesLauncher = require('embark-storage/processes');
|
||||
const constants = require('embark-core/constants');
|
||||
import { buildUrlFromConfig, dappPath, embarkPath, getJson } from 'embark-utils';
|
||||
import * as path from 'path';
|
||||
|
||||
class IPFS {
|
||||
|
||||
constructor(embark, options) {
|
||||
this.logger = embark.logger;
|
||||
this.events = embark.events;
|
||||
this.buildDir = options.buildDir;
|
||||
this.embarkConfig = embark.config.embarkConfig;
|
||||
this.config = embark.config;
|
||||
this.namesystemConfig = embark.config.namesystemConfig;
|
||||
this.embark = embark;
|
||||
this.fs = embark.fs;
|
||||
this.addedToConsole = false;
|
||||
this.storageProcessesLauncher = null;
|
||||
this.usingRunningNode = false;
|
||||
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
|
||||
this.registered = false;
|
||||
|
||||
this.webServerConfig = embark.config.webServerConfig;
|
||||
this.blockchainConfig = embark.config.blockchainConfig;
|
||||
|
||||
this.setServiceCheck()
|
||||
// this.embark.events.setCommandHandler("module:ipfs:reset", (cb) => {
|
||||
// this.events.request("processes:stop", "ipfs", (err) => {
|
||||
// if (err) {
|
||||
// this.logger.error(__('Error stopping IPFS process'), err);
|
||||
// }
|
||||
// this.init(cb);
|
||||
// });
|
||||
// });
|
||||
|
||||
// this.init();
|
||||
|
||||
this.events.on("ipfs:process:started", () => {
|
||||
// this.events.on("blockchain:ready", () => {
|
||||
this.registerAndSetIpfs();
|
||||
});
|
||||
|
||||
this.events.request("processes:register", "ipfs", {
|
||||
launchFn: (cb) => {
|
||||
// if (this.usingRunningNode) {
|
||||
// return cb(__("IPFS process is running in a separate process and cannot be started by Embark."));
|
||||
// }
|
||||
this.startProcess((err, newProcessStarted) => {
|
||||
this.addObjectToConsole();
|
||||
this.events.emit("ipfs:process:started", err, newProcessStarted);
|
||||
cb();
|
||||
});
|
||||
},
|
||||
stopFn: (cb) => {
|
||||
// if (this.usingRunningNode) {
|
||||
// return cb(__("IPFS process is running in a separate process and cannot be stopped by Embark."));
|
||||
// }
|
||||
// this.stopProcess(cb);
|
||||
}
|
||||
});
|
||||
|
||||
this.events.request("processes:launch", "ipfs", (err, msg) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
// return callback(err);
|
||||
}
|
||||
if (msg) {
|
||||
this.logger.info(msg);
|
||||
}
|
||||
// callback();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
addObjectToConsole() {
|
||||
const {host, port} = this._getNodeUrlConfig();
|
||||
let ipfs = IpfsApi(host, port);
|
||||
this.events.emit("runcode:register", "ipfs", ipfs);
|
||||
|
||||
this.events.request('console:register:helpCmd', {
|
||||
cmdName: "ipfs",
|
||||
cmdHelp: __("instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)")
|
||||
}, () => { })
|
||||
|
||||
}
|
||||
|
||||
// TODO: should be done in embarkjs-ipfs
|
||||
// TODO: check config, etc..
|
||||
registerAndSetIpfs() {
|
||||
// TODO: this should be at the start
|
||||
const code = `
|
||||
const __embarkIPFS = require('embarkjs-ipfs');
|
||||
EmbarkJS.Storage.registerProvider('ipfs', __embarkIPFS.default || __embarkIPFS);
|
||||
`;
|
||||
|
||||
// TODO: this should be done when a connection is detected
|
||||
this.events.request('runcode:eval', code, (err) => {
|
||||
let providerCode = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.embark.config.storageConfig.dappConnection || [])}, {web3});`;
|
||||
this.events.request('runcode:eval', providerCode, (err) => {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ===================
|
||||
// ===================
|
||||
// ===================
|
||||
// ===================
|
||||
// ===================
|
||||
|
||||
init(callback = () => {}) {
|
||||
if (!this.isIpfsStorageEnabledInTheConfig()) {
|
||||
this.events.emit("ipfs:process:started", null, false);
|
||||
return callback();
|
||||
}
|
||||
if (!this.registered) {
|
||||
this.registered = true;
|
||||
this.setServiceCheck();
|
||||
this.registerUploadCommand();
|
||||
this.listenToCommands();
|
||||
this.registerConsoleCommands();
|
||||
this.events.request("processes:register", "ipfs", {
|
||||
launchFn: (cb) => {
|
||||
if(this.usingRunningNode) {
|
||||
return cb(__("IPFS process is running in a separate process and cannot be started by Embark."));
|
||||
}
|
||||
this.startProcess((err, newProcessStarted) => {
|
||||
this.addObjectToConsole();
|
||||
this.events.emit("ipfs:process:started", err, newProcessStarted);
|
||||
cb();
|
||||
});
|
||||
},
|
||||
stopFn: (cb) => {
|
||||
if(this.usingRunningNode) {
|
||||
return cb(__("IPFS process is running in a separate process and cannot be stopped by Embark."));
|
||||
}
|
||||
this.stopProcess(cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.events.request("processes:launch", "ipfs", (err, msg) => {
|
||||
if (err) {
|
||||
this.logger.error(err);
|
||||
return callback(err);
|
||||
}
|
||||
if (msg) {
|
||||
this.logger.info(msg);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
|
||||
// TODO: it will have the issue of waiting for the ipfs to start when the code is generator
|
||||
// TODO: could be solved by having a list of services to wait on before attempting to execute code in the console
|
||||
this.addStorageProviderToEmbarkJS();
|
||||
}
|
||||
|
||||
downloadIpfsApi(cb) {
|
||||
this.events.request("version:get:ipfs-api", (ipfsApiVersion) => {
|
||||
let currentIpfsApiVersion = require('../package.json').dependencies["ipfs-api"];
|
||||
if (ipfsApiVersion === currentIpfsApiVersion) {
|
||||
const nodePath = embarkPath('node_modules');
|
||||
const ipfsPath = require.resolve("ipfs-api", {paths: [nodePath]});
|
||||
return cb(null, ipfsPath);
|
||||
}
|
||||
this.events.request("version:getPackageLocation", "ipfs-api", ipfsApiVersion, (err, location) => {
|
||||
cb(err, dappPath(location));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_getNodeUrlConfig() {
|
||||
if (this.config.storageConfig.upload.provider === 'ipfs') {
|
||||
return this.config.storageConfig.upload;
|
||||
}
|
||||
|
||||
for (let connection of this.config.storageConfig.dappConnection) {
|
||||
if (connection.provider === 'ipfs') {
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addStorageProviderToEmbarkJS() {
|
||||
this.events.request('version:downloadIfNeeded', 'ipfs-api', (err, location) => {
|
||||
if (err) {
|
||||
this.logger.error(__('Error downloading IPFS API'));
|
||||
return this.logger.error(err.message || err);
|
||||
}
|
||||
this.events.request('code-generator:ready', () => {
|
||||
this.events.request('code-generator:symlink:generate', location, 'ipfs-api', (err, _symlinkDest) => {
|
||||
if (err) {
|
||||
this.logger.error(__('Error creating a symlink to IPFS API'));
|
||||
return this.logger.error(err.message || err);
|
||||
}
|
||||
|
||||
this.events.emit('runcode:register', 'IpfsApi', require('ipfs-api'), () => {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
let linkedModulePath = path.join(this.modulesPath, 'embarkjs-ipfs');
|
||||
if (process.platform === 'win32') linkedModulePath = linkedModulePath.replace(/\\/g, '\\\\');
|
||||
|
||||
const code = `
|
||||
const __embarkIPFS = require('${linkedModulePath}');
|
||||
EmbarkJS.Storage.registerProvider('ipfs', __embarkIPFS.default || __embarkIPFS);
|
||||
`;
|
||||
|
||||
this.events.request('version:downloadIfNeeded', 'embarkjs-ipfs', (err, location) => {
|
||||
if (err) {
|
||||
this.logger.error(__('Error downloading embarkjs-ipfs'));
|
||||
throw err;
|
||||
}
|
||||
this.embark.addProviderInit("storage", code, () => { return true; });
|
||||
this.embark.addConsoleProviderInit("storage", code, () => { return true; });
|
||||
this.embark.addGeneratedCode((cb) => {
|
||||
return cb(null, code, `embarkjs-ipfs`, location);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
startProcess(callback) {
|
||||
this._checkService((err) => {
|
||||
if (!err) {
|
||||
this.usingRunningNode = true;
|
||||
this.logger.info("IPFS node found, using currently running node");
|
||||
return callback(null, false);
|
||||
}
|
||||
this.logger.info("IPFS node not found, attempting to start own node");
|
||||
let self = this;
|
||||
if(this.storageProcessesLauncher === null) {
|
||||
this.storageProcessesLauncher = new StorageProcessesLauncher({
|
||||
logger: self.logger,
|
||||
events: self.events,
|
||||
storageConfig: self.config.storageConfig,
|
||||
webServerConfig: self.webServerConfig,
|
||||
blockchainConfig: self.blockchainConfig,
|
||||
corsParts: self.embark.config.corsParts,
|
||||
embark: self.embark
|
||||
});
|
||||
}
|
||||
self.logger.trace(`Storage module: Launching ipfs process...`);
|
||||
return this.storageProcessesLauncher.launchProcess('ipfs', (err) => {
|
||||
callback(err, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
stopProcess(cb) {
|
||||
if(!this.storageProcessesLauncher) return cb();
|
||||
this.storageProcessesLauncher.stopProcess("ipfs", cb);
|
||||
}
|
||||
|
||||
registerUploadCommand() {
|
||||
const self = this;
|
||||
this.embark.registerUploadCommand('ipfs', (cb) => {
|
||||
let upload_ipfs = new UploadIPFS({
|
||||
buildDir: self.buildDir || 'dist/',
|
||||
storageConfig: self.config.storageConfig,
|
||||
configIpfsBin: self.config.storageConfig.ipfs_bin || "ipfs",
|
||||
env: this.embark.env
|
||||
});
|
||||
|
||||
upload_ipfs.deploy(cb);
|
||||
});
|
||||
}
|
||||
|
||||
listenToCommands() {
|
||||
this.events.setCommandHandler('logs:ipfs:enable', (cb) => {
|
||||
this.events.emit('logs:storage:enable');
|
||||
return cb(null, 'Enabling IPFS logs');
|
||||
});
|
||||
|
||||
this.events.setCommandHandler('logs:ipfs:disable', (cb) => {
|
||||
this.events.emit('logs:storage:disable');
|
||||
return cb(null, 'Disabling IPFS logs');
|
||||
});
|
||||
}
|
||||
|
||||
registerConsoleCommands() {
|
||||
this.embark.registerConsoleCommand({
|
||||
matches: ['log ipfs on'],
|
||||
process: (cmd, callback) => {
|
||||
this.events.request('logs:ipfs:enable', callback);
|
||||
}
|
||||
});
|
||||
this.embark.registerConsoleCommand({
|
||||
matches: ['log ipfs off'],
|
||||
process: (cmd, callback) => {
|
||||
this.events.request('logs:ipfs:disable', callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
isIpfsStorageEnabledInTheConfig() {
|
||||
let {enabled, available_providers, dappConnection, upload} = this.config.storageConfig;
|
||||
return (enabled || this.embark.currentContext.includes(constants.contexts.upload)) &&
|
||||
(
|
||||
available_providers.includes('ipfs') &&
|
||||
(
|
||||
dappConnection.some(c => c.provider === 'ipfs') ||
|
||||
upload.provider === 'ipfs'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IPFS;
|
|
@ -63,9 +63,6 @@ class IPFS {
|
|||
this.registerEmbarkJSStorage()
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// * generate embarkjs storage artifact
|
||||
|
||||
async addEmbarkJSIpfsArtifact(params, cb) {
|
||||
const code = `
|
||||
var EmbarkJS;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { __ } from 'embark-i18n';
|
||||
import * as async from 'async';
|
||||
|
||||
class Storage {
|
||||
constructor(embark, options){
|
||||
|
@ -14,25 +13,15 @@ class Storage {
|
|||
|
||||
this.storageNodes = {};
|
||||
this.events.setCommandHandler("storage:node:register", (clientName, startCb) => {
|
||||
console.dir("---- registering " + clientName)
|
||||
this.storageNodes[clientName] = startCb
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("storage:node:start", (storageConfig, cb) => {
|
||||
console.dir("--------------------------");
|
||||
console.dir("--------------------------");
|
||||
console.dir("--------------------------");
|
||||
console.dir("--------------------------");
|
||||
console.dir("--------------------------");
|
||||
console.dir("--------------------------");
|
||||
console.dir("--- storage:node:start");
|
||||
const clientName = storageConfig.upload.provider;
|
||||
console.dir("---- starting...." + clientName);
|
||||
const client = this.storageNodes[clientName];
|
||||
if (!client) return cb("storage " + clientName + " not found");
|
||||
|
||||
let onStart = () => {
|
||||
console.dir("--- storage started")
|
||||
this.events.emit("storage:started", clientName);
|
||||
cb();
|
||||
}
|
||||
|
@ -65,61 +54,6 @@ class Storage {
|
|||
}, cb);
|
||||
}
|
||||
|
||||
// handleUploadCommand() {
|
||||
// const self = this;
|
||||
// this.embark.events.setCommandHandler('storage:upload', (cb) => {
|
||||
// let platform = this.embark.config.storageConfig.upload.provider;
|
||||
|
||||
// let uploadCmds = self.plugins.getPluginsProperty('uploadCmds', 'uploadCmds');
|
||||
// for (let uploadCmd of uploadCmds) {
|
||||
// if (uploadCmd.cmd === platform) {
|
||||
// return uploadCmd.cb.call(uploadCmd.cb, cb);
|
||||
// }
|
||||
// }
|
||||
|
||||
// cb({message: __('platform "{{platform}}" is specified as the upload provider, however no plugins have registered an upload command for "{{platform}}".', {platform: platform})});
|
||||
// });
|
||||
// }
|
||||
|
||||
// addSetProviders(cb) {
|
||||
// let code = `\nEmbarkJS.Storage.setProviders(${JSON.stringify(this.embark.config.storageConfig.dappConnection || [])}, {web3});`;
|
||||
|
||||
// let shouldInit = (storageConfig) => {
|
||||
// return storageConfig.enabled;
|
||||
// };
|
||||
|
||||
// this.embark.addProviderInit('storage', code, shouldInit);
|
||||
|
||||
// async.parallel([
|
||||
// (next) => {
|
||||
// if (!this.storageConfig.available_providers.includes('ipfs')) {
|
||||
// return next();
|
||||
// }
|
||||
// this.embark.events.once('ipfs:process:started', next);
|
||||
// },
|
||||
// (next) => {
|
||||
// if (!this.storageConfig.available_providers.includes('swarm')) {
|
||||
// return next();
|
||||
// }
|
||||
// this.embark.events.once('swarm:process:started', next);
|
||||
// }
|
||||
// ], (err) => {
|
||||
// if (err) {
|
||||
// console.error(__('Error starting storage process(es): %s', err));
|
||||
// }
|
||||
|
||||
// this.embark.addConsoleProviderInit('storage', code, shouldInit);
|
||||
// // TODO: fix me, this is an ugly workaround for race conditions
|
||||
// // in the case where the storage process is too slow when starting up we
|
||||
// // execute ourselves the setProviders because the console provider init
|
||||
// // was already executed
|
||||
// this.embark.events.request('runcode:eval', `if (Object.keys(EmbarkJS.Storage.Providers).length) { ${code} }`, () => {
|
||||
// this.ready = true;
|
||||
// this.embark.events.emit("module:storage:ready");
|
||||
// }, true);
|
||||
// });
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
module.exports = Storage;
|
||||
|
|
|
@ -2,7 +2,6 @@ import { __ } from 'embark-i18n';
|
|||
import {dappPath, canonicalHost, defaultHost} from 'embark-utils';
|
||||
let Web3 = require('web3');
|
||||
const constants = require('embark-core/constants');
|
||||
import * as path from 'path';
|
||||
const API = require('./api.js');
|
||||
|
||||
const EMBARK_RESOURCE_ORIGIN = "http://embark";
|
||||
|
@ -21,203 +20,93 @@ class Whisper {
|
|||
this.modulesPath = dappPath(embark.config.embarkConfig.generationDir, constants.dappArtifacts.symlinkDir);
|
||||
this.plugins = options.plugins;
|
||||
|
||||
if (embark.currentContext.includes('test') && options.node &&options.node === 'vm') {
|
||||
this.logger.info(__('Whisper disabled in the tests'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.communicationConfig.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.api = new API(embark, this.web3);
|
||||
this.api.registerAPICalls();
|
||||
|
||||
// ================
|
||||
// TODO:
|
||||
// figure out best way to detect is a node exists or launch a whisper process or wait for the blockchain process
|
||||
// ================
|
||||
// this.events.on("blockchain:ready", this.executeEmbarkJSBlockchain.bind(this));
|
||||
this.events.request("runcode:whitelist", 'embarkjs', () => { });
|
||||
this.events.request("runcode:whitelist", 'embarkjs-whisper', () => { });
|
||||
|
||||
this.setServiceCheck();
|
||||
|
||||
// TODO: see above, not ideal to do this, need engine.start process
|
||||
// can also register service and instead react to it and connect
|
||||
// this.waitForWeb3Ready(() => {
|
||||
// this.registerAndSetWhisper();
|
||||
// });
|
||||
this.events.on("blockchain:ready", () => {
|
||||
this.registerAndSetWhisper();
|
||||
});
|
||||
// TODO: should launch its own whisper node
|
||||
// this.events.on("communication:started", this.connectEmbarkJSProvider.bind(this));
|
||||
this.events.on("blockchain:started", this.connectEmbarkJSProvider.bind(this));
|
||||
|
||||
let plugin = this.plugins.createPlugin('whisperplugin', {});
|
||||
plugin.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
||||
plugin.registerActionForEvent("pipeline:generateAll:before", this.addEmbarkJSWhisperArtifact.bind(this));
|
||||
|
||||
// ===============================
|
||||
// this.connectToProvider();
|
||||
this.events.request("communication:node:register", "whisper", (readyCb) => {
|
||||
// TODO: should launch its own whisper node
|
||||
console.dir("--- whisper readyCb")
|
||||
console.dir('--- registering whisper node')
|
||||
// this.events.request('processes:register', 'communication', {
|
||||
// launchFn: (cb) => {
|
||||
// this.startProcess(cb);
|
||||
// },
|
||||
// stopFn: (cb) => { this.stopProcess(cb); }
|
||||
// });
|
||||
// this.events.request("processes:launch", "communication", (err) => {
|
||||
readyCb()
|
||||
// });
|
||||
// this.registerServiceCheck()
|
||||
});
|
||||
|
||||
// this.events.request('processes:register', 'whisper', (cb) => {
|
||||
// this.waitForWeb3Ready(() => {
|
||||
// this.web3.shh.getInfo((err) => {
|
||||
// if (err) {
|
||||
// const message = err.message || err;
|
||||
// if (message.indexOf('not supported') > -1) {
|
||||
// this.logger.error('Whisper is not supported on your node. Are you using the simulator?');
|
||||
// return this.logger.trace(message);
|
||||
// }
|
||||
// }
|
||||
// this.setServiceCheck();
|
||||
// this.addWhisperToEmbarkJS();
|
||||
// this.addSetProvider();
|
||||
// this.registerAPICalls();
|
||||
// cb();
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// this.events.request('processes:launch', 'whisper');
|
||||
this.registerEmbarkJSCommunication()
|
||||
}
|
||||
|
||||
// TODO: should load the latest config
|
||||
addArtifactFile(_params, cb) {
|
||||
let config = {
|
||||
// TODO: for consistency we should change this to be dappConnection or connection
|
||||
connection: this.communicationConfig.connection
|
||||
async addEmbarkJSWhisperArtifact(params, cb) {
|
||||
let connection = this.communicationConfig.connection || {};
|
||||
const config = {
|
||||
server: canonicalHost(connection.host || defaultHost),
|
||||
port: connection.port || '8546',
|
||||
type: connection.type || 'ws'
|
||||
};
|
||||
|
||||
const code = `
|
||||
var EmbarkJS;
|
||||
if (typeof EmbarkJS === 'undefined') {
|
||||
EmbarkJS = require('embarkjs');
|
||||
}
|
||||
const __embarkWhisper = require('embarkjs-whisper');
|
||||
EmbarkJS.Messages.registerProvider('whisper', __embarkWhisper.default || __embarkWhisper);
|
||||
EmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});
|
||||
`;
|
||||
this.events.request("pipeline:register", {
|
||||
path: [this.embarkConfig.generationDir, 'config'],
|
||||
file: 'storage.json',
|
||||
format: 'json',
|
||||
content: config
|
||||
path: [this.embarkConfig.generationDir, 'storage'],
|
||||
file: 'init.js',
|
||||
format: 'js',
|
||||
content: code
|
||||
}, cb);
|
||||
}
|
||||
|
||||
connectToProvider() {
|
||||
let {host, port} = this.communicationConfig.connection;
|
||||
let web3Endpoint = 'ws://' + host + ':' + port;
|
||||
// Note: dont't pass to the provider things like {headers: {Origin: "embark"}}. Origin header is for browser to fill
|
||||
// to protect user, it has no meaning if it is used server-side. See here for more details: https://github.com/ethereum/go-ethereum/issues/16608
|
||||
// Moreover, Parity reject origins that are not urls so if you try to connect with Origin: "embark" it gives the followin error:
|
||||
// << Blocked connection to WebSockets server from untrusted origin: Some("embark") >>
|
||||
// The best choice is to use void origin, BUT Geth rejects void origin, so to keep both clients happy we can use http://embark
|
||||
this.web3.setProvider(new Web3.providers.WebsocketProvider(web3Endpoint, {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}));
|
||||
}
|
||||
async registerEmbarkJSCommunication() {
|
||||
let checkEmbarkJS = `
|
||||
return (typeof EmbarkJS === 'undefined');
|
||||
`;
|
||||
let EmbarkJSNotDefined = await this.events.request2('runcode:eval', checkEmbarkJS);
|
||||
|
||||
registerAndSetWhisper() {
|
||||
if (this.communicationConfig === {}) {
|
||||
return;
|
||||
}
|
||||
if ((this.communicationConfig.available_providers.indexOf('whisper') < 0) && (this.communicationConfig.provider !== 'whisper' || this.communicationConfig.enabled !== true)) {
|
||||
return;
|
||||
if (EmbarkJSNotDefined) {
|
||||
await this.events.request2("runcode:register", 'EmbarkJS', require('embarkjs'));
|
||||
}
|
||||
|
||||
// let linkedModulePath = path.join(this.modulesPath, 'embarkjs-whisper');
|
||||
// if (process.platform === 'win32') linkedModulePath = linkedModulePath.replace(/\\/g, '\\\\');
|
||||
|
||||
// const code = `
|
||||
// const __embarkWhisperNewWeb3 = EmbarkJS.isNode ? require('${linkedModulePath}') : require('embarkjs-whisper');
|
||||
// EmbarkJS.Messages.registerProvider('whisper', __embarkWhisperNewWeb3.default || __embarkWhisperNewWeb3);
|
||||
// `;
|
||||
|
||||
let code = `
|
||||
const __embarkWhisperNewWeb3 = require('embarkjs-whisper');
|
||||
EmbarkJS.Messages.registerProvider('whisper', __embarkWhisperNewWeb3.default || __embarkWhisperNewWeb3);
|
||||
const registerProviderCode = `
|
||||
const __embarkWhisper = require('embarkjs-whisper');
|
||||
EmbarkJS.Messages.registerProvider('whisper', __embarkWhisper.default || __embarkWhisper);
|
||||
`;
|
||||
|
||||
await this.events.request2('runcode:eval', registerProviderCode);
|
||||
}
|
||||
|
||||
async connectEmbarkJSProvider() {
|
||||
let connection = this.communicationConfig.connection || {};
|
||||
|
||||
if (!(this.communicationConfig.provider === 'whisper' && this.communicationConfig.enabled === true)) {
|
||||
return this.events.request('runcode:eval', code, () => {
|
||||
});
|
||||
}
|
||||
|
||||
// todo: make the add code a function as well
|
||||
const config = {
|
||||
server: canonicalHost(connection.host || defaultHost),
|
||||
port: connection.port || '8546',
|
||||
type: connection.type || 'ws'
|
||||
};
|
||||
code += `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`;
|
||||
const code = `
|
||||
EmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});
|
||||
`;
|
||||
|
||||
// this.embark.addCodeToEmbarkJS(code);
|
||||
this.events.request('runcode:eval', code, (err) => {
|
||||
// if (err) {
|
||||
// return cb(err);
|
||||
// }
|
||||
});
|
||||
}
|
||||
|
||||
// ===============================
|
||||
// ===============================
|
||||
// ===============================
|
||||
// ===============================
|
||||
// ===============================
|
||||
// ===============================
|
||||
|
||||
waitForWeb3Ready(cb) {
|
||||
if (this.web3Ready) {
|
||||
return cb();
|
||||
}
|
||||
if (this.web3.currentProvider.connection.readyState !== 1) {
|
||||
this.connectToProvider();
|
||||
return setTimeout(this.waitForWeb3Ready.bind(this, cb), 50);
|
||||
}
|
||||
this.web3Ready = true;
|
||||
cb();
|
||||
}
|
||||
|
||||
setServiceCheck() {
|
||||
const self = this;
|
||||
self.events.request("services:register", 'Whisper', function(cb) {
|
||||
if (!self.web3.currentProvider || self.web3.currentProvider.connection.readyState !== 1) {
|
||||
return self.connectToProvider();
|
||||
}
|
||||
// 1) Parity does not implement shh_version JSON-RPC method
|
||||
// 2) web3 1.0 still does not implement web3_clientVersion
|
||||
// so we must do all by our own
|
||||
self.web3._requestManager.send({method: 'web3_clientVersion', params: []}, (err, clientVersion) => {
|
||||
if (err) return cb(err);
|
||||
if (clientVersion.indexOf("Parity-Ethereum//v2") === 0) {
|
||||
// This is Parity
|
||||
return self.web3.shh.getInfo(function(err) {
|
||||
if (err) {
|
||||
return cb({name: 'Whisper', status: 'off'});
|
||||
}
|
||||
// TOFIX Assume Whisper v6 until there's a way to understand it via JSON-RPC
|
||||
return cb({name: 'Whisper (version 6)', status: 'on'});
|
||||
});
|
||||
}
|
||||
// Assume it is a Geth compliant client
|
||||
self.web3.shh.getVersion(function(err, version) {
|
||||
if (err || version === "2") {
|
||||
return cb({name: 'Whisper', status: 'off'});
|
||||
}
|
||||
return cb({name: 'Whisper (version ' + version + ')', status: 'on'});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
addSetProvider() {
|
||||
let connection = this.communicationConfig.connection || {};
|
||||
const shouldInit = (communicationConfig) => {
|
||||
return (communicationConfig.provider === 'whisper' && communicationConfig.enabled === true);
|
||||
};
|
||||
|
||||
// todo: make the add code a function as well
|
||||
const config = {
|
||||
server: canonicalHost(connection.host || defaultHost),
|
||||
port: connection.port || '8546',
|
||||
type: connection.type || 'ws'
|
||||
};
|
||||
const code = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(config)});`;
|
||||
|
||||
this.embark.addProviderInit('communication', code, shouldInit);
|
||||
|
||||
const consoleConfig = Object.assign({}, config, {providerOptions: {headers: {Origin: EMBARK_RESOURCE_ORIGIN}}});
|
||||
const consoleCode = `\nEmbarkJS.Messages.setProvider('whisper', ${JSON.stringify(consoleConfig)});`;
|
||||
this.embark.addConsoleProviderInit('communication', consoleCode, shouldInit);
|
||||
await this.events.request2('runcode:eval', code);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,6 +170,7 @@ class EmbarkController {
|
|||
engine.registerModuleGroup("webserver");
|
||||
engine.registerModuleGroup("filewatcher");
|
||||
engine.registerModuleGroup("storage");
|
||||
engine.registerModuleGroup("communication");
|
||||
|
||||
engine.events.on('deployment:deployContracts:afterAll', () => {
|
||||
console.dir("--- generating files...")
|
||||
|
@ -187,6 +188,10 @@ class EmbarkController {
|
|||
console.dir("====> requesting storage node to start...")
|
||||
await engine.events.request2("storage:node:start", engine.config.storageConfig, cb);
|
||||
});
|
||||
plugin.registerActionForEvent("embark:engine:started", async (_params, cb) => {
|
||||
console.dir("====> requesting communication node to start...")
|
||||
await engine.events.request2("communication:node:start", engine.config.communicationConfig, cb);
|
||||
});
|
||||
|
||||
engine.events.request('watcher:start');
|
||||
|
||||
|
@ -856,6 +861,8 @@ class EmbarkController {
|
|||
|
||||
const Engine = require('../lib/core/engine.js');
|
||||
const engine = new Engine({
|
||||
// TODO: we should NOT use env, it's here because it's being used somewhere deep in the code
|
||||
// but we should/need to remove it as it's causing unexpected behaviour
|
||||
env: options.env,
|
||||
client: options.client,
|
||||
locale: options.locale,
|
||||
|
|
|
@ -83,6 +83,7 @@ class Engine {
|
|||
"pipeline": this.pipelineService,
|
||||
"webserver": this.webserverService,
|
||||
"storage": this.storageComponent,
|
||||
"communication": this.communicationComponents,
|
||||
"filewatcher": this.filewatcherService
|
||||
};
|
||||
|
||||
|
@ -196,6 +197,11 @@ class Engine {
|
|||
this.registerModulePackage('embark-ipfs', {plugins: this.plugins});
|
||||
}
|
||||
|
||||
communicationComponents() {
|
||||
this.registerModule('communication', {plugins: this.plugins});
|
||||
this.registerModulePackage('embark-whisper', {plugins: this.plugins});
|
||||
}
|
||||
|
||||
startService(serviceName, _options) {
|
||||
let options = _options || {};
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import { __ } from 'embark-i18n';
|
||||
|
||||
class Communication {
|
||||
constructor(embark, options){
|
||||
this.embark = embark;
|
||||
this.embarkConfig = embark.config.embarkConfig;
|
||||
this.events = this.embark.events;
|
||||
this.communicationConfig = embark.config.communicationConfig;
|
||||
this.plugins = options.plugins;
|
||||
|
||||
let plugin = this.plugins.createPlugin('communicationplugin', {});
|
||||
plugin.registerActionForEvent("pipeline:generateAll:before", this.addArtifactFile.bind(this));
|
||||
|
||||
this.communicationNodes = {};
|
||||
this.events.setCommandHandler("communication:node:register", (clientName, startCb) => {
|
||||
this.communicationNodes[clientName] = startCb
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("communication:node:start", (communicationConfig, cb) => {
|
||||
const clientName = communicationConfig.provider;
|
||||
const client = this.communicationNodes[clientName];
|
||||
if (!client) return cb("communication " + clientName + " not found");
|
||||
|
||||
let onStart = () => {
|
||||
this.events.emit("communication:started", clientName);
|
||||
cb();
|
||||
}
|
||||
|
||||
client.apply(client, [onStart]);
|
||||
});
|
||||
}
|
||||
|
||||
addArtifactFile(_params, cb) {
|
||||
let config = {
|
||||
// TODO: for consistency we should change this to be dappConnection or connection
|
||||
connection: this.communicationConfig.connection
|
||||
}
|
||||
this.events.request("pipeline:register", {
|
||||
path: [this.embarkConfig.generationDir, 'config'],
|
||||
file: 'communication.json',
|
||||
format: 'json',
|
||||
content: config
|
||||
}, cb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Communication;
|
Loading…
Reference in New Issue