2020-01-28 12:07:17 -05:00

223 lines
7.2 KiB
JavaScript

import {__} from 'embark-i18n';
const IpfsHttpClient = require('ipfs-http-client');
const StorageProcessesLauncher = require('./storageProcessesLauncher.js');
import {buildUrlFromConfig, getJson} from 'embark-utils';
const UploadIPFS = require('./upload.js');
const constants = require('embark-core/constants');
require('ejs');
class IPFS {
constructor(embark) {
this.logger = embark.logger;
this.events = embark.events;
this.logger = embark.logger;
this.embarkConfig = embark.config.embarkConfig;
this.storageConfig = embark.config.storageConfig;
this.blockchainConfig = embark.config.blockchainConfig;
this.webServerConfig = embark.config.webServerConfig;
this.embark = embark;
this.fs = embark.fs;
this.storageProcessesLauncher = null;
this._config = null; // backing variable for config property
this._enabled = null; // backing variable for enabled property
if (this.enabled && this.config === {}) {
console.warn('\n===== IPFS module will not be loaded =====');
console.warn(`IPFS is enabled in the config, however the config is not setup to provide a URL for IPFS and therefore the IPFS module will not be loaded. Please either change the ${'config/storage > upload'.bold} setting to IPFS or add the IPFS config to the ${'config/storage > dappConnection'.bold} array. Please see ${'https://framework.embarklabs.io/docs/storage_configuration.html'.underline} for more information.\n`);
return;
}
if (!this.enabled) {
this.embark.registerConsoleCommand({
matches: cmd => cmd === "ipfs" || cmd.indexOf('ipfs ') === 0,
process: (_cmd, cb) => {
console.warn(__(`IPFS is disabled or not configured. Please see %s for more information.`, 'https://framework.embarklabs.io/docs/storage_configuration.html'.underline));
cb();
}
});
return;
}
this.setupIpfsHttpClient();
this.setupEmbarkJS();
this.events.request("storage:node:register", "ipfs", (readyCb) => {
this.events.request('processes:register', 'storage', {
launchFn: (cb) => {
this.startProcess(cb);
},
stopFn: (cb) => {
this.stopProcess(cb);
}
});
this.events.request("processes:launch", "storage", (err) => {
readyCb(err);
});
this.registerServiceCheck();
});
this.events.request("storage:upload:register", "ipfs", (readyCb) => {
let upload_ipfs = new UploadIPFS({
buildDir: this.buildDir || 'dist/',
storageConfig: this.storageConfig,
configIpfsBin: this.storageConfig.ipfs_bin || "ipfs",
env: this.embark.env
});
upload_ipfs.deploy(readyCb);
});
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);
}
});
}
async setupIpfsHttpClient() {
this.events.request("runcode:whitelist", 'ipfs-http-client', () => {});
this.events.on("storage:started", this.registerIpfsObject.bind(this));
this.registerIpfsObject();
this.registerIpfsHelp();
}
async registerIpfsObject() {
const {host, port, protocol} = this.config;
const ipfsOptions = protocol ? {host, port, protocol} : {host, port, protocol: 'http'};
let ipfs = IpfsHttpClient(ipfsOptions);
await this.events.request2("runcode:register", "ipfs", ipfs);
}
async registerIpfsHelp() {
await this.events.request2('console:register:helpCmd', {
cmdName: "ipfs",
cmdHelp: __("instantiated js-ipfs object configured to the current environment (available if ipfs is enabled)")
});
}
async setupEmbarkJS() {
this.events.request("embarkjs:plugin:register", 'storage', 'ipfs', 'embarkjs-ipfs');
await this.events.request2("embarkjs:console:register", 'storage', 'ipfs', 'embarkjs-ipfs');
this.events.on("storage:started", () => {
let config = this.embark.config.storageConfig.dappConnection || [];
this.events.request("embarkjs:console:setProvider", 'storage', 'ipfs', config);
});
}
get config() {
if (this._config) {
return this._config;
}
let {dappConnection, upload} = this.storageConfig;
const {currentContext} = this.embark;
if (!this.enabled) {
this._config = {};
return this._config;
}
if (currentContext.includes(constants.contexts.upload)) {
this._config = upload;
return this._config;
}
this._config = dappConnection.find(c => c.provider === 'ipfs') || {};
return this._config;
}
get enabled() {
if (this._enabled !== null) {
return this._enabled;
}
let {enabled, available_providers, dappConnection, upload} = this.storageConfig;
this._enabled = (enabled || this.embark.currentContext.includes(constants.contexts.upload)) &&
available_providers.includes('ipfs') &&
(
dappConnection.some(c => c.provider === 'ipfs') ||
upload.provider === "ipfs"
);
return this._enabled;
}
registerServiceCheck() {
this.events.on('check:backOnline:IPFS', () => {
this.logger.info(__('IPFS node detected') + '...');
});
this.events.on('check:wentOffline:IPFS', () => {
this.logger.info(__('IPFS node is offline') + '...');
});
this.events.request("services:register", 'IPFS', (cb) => {
this._checkService((err, body) => {
if (err) {
this.logger.trace("IPFS unavailable");
return cb({name: "IPFS ", status: 'off'});
}
if (body.Version) {
this.logger.trace("IPFS available");
return cb({name: ("IPFS " + body.Version), status: 'on'});
}
this.logger.trace("IPFS available");
return cb({name: "IPFS ", status: 'on'});
});
});
}
_getNodeUrl() {
return buildUrlFromConfig(this.config) + '/api/v0/version';
}
_checkService(cb) {
let url = this._getNodeUrl();
getJson(url, cb);
}
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.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);
}
}
module.exports = IPFS;