Skip to content

Commit 0cffff0

Browse files
authored
Merge pull request #390 from embark-framework/features/add-swarm-to-embarkjs
Added swarm support in embarkjs, isAvailable for messages/storage, swarm/ipfs checks
2 parents 8102b91 + 3bf5093 commit 0cffff0

File tree

16 files changed

+453
-89
lines changed

16 files changed

+453
-89
lines changed

js/embark.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,7 @@ EmbarkJS.Contract.prototype.send = function(value, unit, _options) {
182182

183183
EmbarkJS.Storage = {};
184184

185-
EmbarkJS.Storage.Providers = {
186-
SWARM: 'swarm'
187-
};
185+
EmbarkJS.Storage.Providers = {};
188186

189187
EmbarkJS.Storage.saveText = function(text) {
190188
if (!this.currentStorage) {
@@ -230,6 +228,10 @@ EmbarkJS.Storage.setProvider = function(provider, options) {
230228
return providerObj.setProvider(options);
231229
};
232230

231+
EmbarkJS.Storage.isAvailable = function(){
232+
return this.currentStorage.isAvailable();
233+
};
234+
233235
EmbarkJS.Messages = {};
234236

235237
EmbarkJS.Messages.Providers = {};
@@ -250,6 +252,10 @@ EmbarkJS.Messages.setProvider = function(provider, options) {
250252
return providerObj.setProvider(options);
251253
};
252254

255+
EmbarkJS.Messages.isAvailable = function(){
256+
return this.currentMessages.isAvailable();
257+
};
258+
253259
EmbarkJS.Messages.sendMessage = function(options) {
254260
if (!this.currentMessages) {
255261
throw new Error('Messages provider not set; e.g EmbarkJS.Messages.setProvider("whisper")');

js/embarkjs/orbit.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,11 @@ EmbarkJS.Messages.Orbit.listenTo = function(options) {
8585
return promise;
8686
};
8787

88+
// TODO: needs a real check for availability
89+
// TODO: not tested as orbit is not loaded and therefore the provider is not available
90+
EmbarkJS.Messages.Orbit.isAvailable = function(){
91+
return new Promise((resolve) => {
92+
if(!this.orbit) resolve(false);
93+
resolve(true);
94+
});
95+
}

lib/core/config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ Config.prototype._getFileOrOject = function(object, filePath, property) {
103103
Config.prototype.loadBlockchainConfigFile = function() {
104104
var configObject = {
105105
"default": {
106-
"enabled": true
106+
"enabled": true,
107+
"rpcCorsDomain": "auto",
108+
"wsOrigins": "auto"
107109
}
108110
};
109111

@@ -181,9 +183,10 @@ Config.prototype.loadStorageConfigFile = function() {
181183
"default": {
182184
"versions": versions,
183185
"enabled": true,
184-
"available_providers": ["ipfs"],
186+
"available_providers": ["ipfs", "swarm"],
185187
"ipfs_bin": "ipfs",
186188
"provider": "ipfs",
189+
"protocol": "http",
187190
"host": "localhost",
188191
"port": 5001,
189192
"getUrl": "http://localhost:8080/ipfs/"

lib/core/engine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ class Engine {
249249
this.registerModule('swarm', {
250250
addCheck: this.servicesMonitor.addCheck.bind(this.servicesMonitor),
251251
storageConfig: this.config.storageConfig,
252-
web3: _options.web3
252+
bzz: _options.bzz
253253
});
254254
}
255255

lib/index.js

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
let async = require('async');
22
const constants = require('./constants');
3+
const _ = require('underscore');
34
// require("./utils/debug_util.js")(__filename, async);
45

56
require('colors');
@@ -45,11 +46,11 @@ class Embark {
4546

4647
if(blockchainConfig.rpcCorsDomain === 'auto') {
4748
if(webServerConfig) blockchainConfig.rpcCorsDomain = `http://${webServerConfig.host}:${webServerConfig.port}`;
48-
if(storageConfig) blockchainConfig.rpcCorsDomain += `${blockchainConfig.rpcCorsDomain.length ? ',' : ''}http://${storageConfig.host}:${storageConfig.port}`;
49+
if(storageConfig) blockchainConfig.rpcCorsDomain += `${blockchainConfig.rpcCorsDomain.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`;
4950
}
5051
if(blockchainConfig.wsOrigins === 'auto') {
5152
if(webServerConfig) blockchainConfig.wsOrigins = `http://${webServerConfig.host}:${webServerConfig.port}`;
52-
if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}http://${storageConfig.host}:${storageConfig.port}`;
53+
if(storageConfig) blockchainConfig.wsOrigins += `${blockchainConfig.wsOrigins.length ? ',' : ''}${storageConfig.protocol}://${storageConfig.host}:${storageConfig.port}`;
5354
}
5455
return require('./cmds/blockchain/blockchain.js')(blockchainConfig, client, env).run();
5556
}
@@ -121,7 +122,7 @@ class Embark {
121122
engine.startService("pipeline");
122123
engine.startService("codeGenerator");
123124
engine.startService("deployment");
124-
engine.startService("ipfs");
125+
engine.startService(engine.config.storageConfig.provider, {bzz: engine.web3.bzz});
125126

126127
engine.events.on('check:backOnline:Ethereum', function () {
127128
engine.logger.info('Ethereum node detected..');
@@ -134,6 +135,7 @@ class Embark {
134135
engine.events.on('outputDone', function () {
135136
engine.logger.info("Looking for documentation? You can find it at ".cyan + "http://embark.readthedocs.io/".green.underline + ".".cyan);
136137
engine.logger.info("Ready".underline);
138+
engine.events.emit("status", "Ready".green);
137139
});
138140

139141
engine.deployManager.deployContracts(function (err) {
@@ -153,7 +155,6 @@ class Embark {
153155
engine.logger.info(err.stack);
154156
} else {
155157
engine.events.emit('firstDeploymentDone');
156-
engine.events.emit("status", "Ready".green);
157158

158159
let size = windowSize.get();
159160
if (size.height < 40 || size.width < 118) {
@@ -194,6 +195,7 @@ class Embark {
194195
engine.startService("codeGenerator");
195196
engine.startService("deployment");
196197
engine.startService("ipfs");
198+
engine.startService("swarm", {bzz: engine.web3.bzz});
197199
callback();
198200
},
199201
function deploy(callback) {
@@ -303,10 +305,28 @@ class Embark {
303305
engine.startService("pipeline");
304306
engine.startService("codeGenerator");
305307
engine.startService("deployment");
306-
engine.startService("ipfs");
307-
engine.startService("swarm", {buildDir:'dist/',web3: engine.web3});
308+
engine.startService(platform.toLowerCase(), {bzz: engine.web3.bzz});
309+
engine.startMonitor();
308310
callback();
309311
},
312+
function checkStorageService(callback){
313+
let checkFn;
314+
_.find(engine.servicesMonitor.checkList, (value, key) => {
315+
if(key.toLowerCase() === platform.toLowerCase()){
316+
checkFn = value;
317+
return true;
318+
}
319+
});
320+
if (!checkFn || typeof checkFn.fn !== 'function') {
321+
return callback();
322+
}
323+
checkFn.fn(function (serviceCheckResult) {
324+
if (!serviceCheckResult.status || serviceCheckResult.status === 'off') {
325+
return callback({message: `Cannot upload: ${platform} node is not running on http://${engine.config.storageConfig.host}:${engine.config.storageConfig.port}.`});
326+
}
327+
callback();
328+
});
329+
},
310330
function setupStoragePlugin(callback){
311331
let pluginList = engine.plugins.listPlugins();
312332
if (pluginList.length > 0) {
@@ -325,10 +345,9 @@ class Embark {
325345
}
326346
if (!cmdPlugin) {
327347
engine.logger.info('try "embark upload ipfs" or "embark upload swarm"'.green);
328-
callback({message: 'unknown platform: ' + platform});
329-
} else {
330-
callback();
348+
return callback({message: 'unknown platform: ' + platform});
331349
}
350+
callback();
332351
},
333352
function deploy(callback) {
334353
// 2. upload to storage (outputDone event triggered after webpack finished)

lib/modules/ipfs/embarkjs.js

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import IpfsApi from 'ipfs-api';
22

33
let __embarkIPFS = {};
44

5-
__embarkIPFS.setProvider = function(options) {
5+
__embarkIPFS.setProvider = function (options) {
66
var self = this;
7-
var promise = new Promise(function(resolve, reject) {
7+
var promise = new Promise(function (resolve, reject) {
88
try {
99
if (options === undefined) {
1010
self.ipfsConnection = IpfsApi('localhost', '5001');
@@ -30,14 +30,14 @@ __embarkIPFS.setProvider = function(options) {
3030
return promise;
3131
};
3232

33-
__embarkIPFS.saveText = function(text) {
33+
__embarkIPFS.saveText = function (text) {
3434
const self = this;
35-
var promise = new Promise(function(resolve, reject) {
35+
var promise = new Promise(function (resolve, reject) {
3636
if (!self.ipfsConnection) {
3737
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
3838
reject(connectionError);
3939
}
40-
self.ipfsConnection.add(self.ipfsConnection.Buffer.from(text), function(err, result) {
40+
self.ipfsConnection.add(self.ipfsConnection.Buffer.from(text), function (err, result) {
4141
if (err) {
4242
reject(err);
4343
} else {
@@ -49,11 +49,11 @@ __embarkIPFS.saveText = function(text) {
4949
return promise;
5050
};
5151

52-
__embarkIPFS.get = function(hash) {
52+
__embarkIPFS.get = function (hash) {
5353
const self = this;
5454
// TODO: detect type, then convert if needed
5555
//var ipfsHash = web3.toAscii(hash);
56-
var promise = new Promise(function(resolve, reject) {
56+
var promise = new Promise(function (resolve, reject) {
5757
if (!self.ipfsConnection) {
5858
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
5959
reject(connectionError);
@@ -69,24 +69,24 @@ __embarkIPFS.get = function(hash) {
6969
return promise;
7070
};
7171

72-
__embarkIPFS.uploadFile = function(inputSelector) {
72+
__embarkIPFS.uploadFile = function (inputSelector) {
7373
const self = this;
7474
var file = inputSelector[0].files[0];
7575

7676
if (file === undefined) {
7777
throw new Error('no file found');
7878
}
7979

80-
var promise = new Promise(function(resolve, reject) {
80+
var promise = new Promise(function (resolve, reject) {
8181
if (!self.ipfsConnection) {
8282
var connectionError = new Error('No IPFS connection. Please ensure to call Embark.Storage.setProvider()');
8383
reject(connectionError);
8484
}
8585
var reader = new FileReader();
86-
reader.onloadend = function() {
86+
reader.onloadend = function () {
8787
var fileContent = reader.result;
8888
var buffer = self.ipfsConnection.Buffer.from(fileContent);
89-
self.ipfsConnection.add(buffer, function(err, result) {
89+
self.ipfsConnection.add(buffer, function (err, result) {
9090
if (err) {
9191
reject(err);
9292
} else {
@@ -100,7 +100,22 @@ __embarkIPFS.uploadFile = function(inputSelector) {
100100
return promise;
101101
};
102102

103-
__embarkIPFS.getUrl = function(hash) {
103+
__embarkIPFS.isAvailable = function () {
104+
return new Promise((resolve) => {
105+
if (!this.ipfsConnection) {
106+
return resolve(false);
107+
}
108+
this.ipfsConnection.id()
109+
.then((id) => {
110+
resolve(Boolean(id));
111+
})
112+
.catch(() => {
113+
resolve(false);
114+
});
115+
});
116+
};
117+
118+
__embarkIPFS.getUrl = function (hash) {
104119
return (this._getUrl || "http://localhost:8080/ipfs/") + hash;
105120
};
106121

lib/modules/ipfs/upload.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class IPFS {
2929
function runCommand(ipfs_bin, callback) {
3030
let cmd = `"${ipfs_bin}" add -r ${self.buildDir}`;
3131
console.log(("=== adding " + self.buildDir + " to ipfs").green);
32-
console.trace(cmd);
32+
console.debug(cmd);
3333
shelljs.exec(cmd, {silent:true}, function(code, stdout, stderr){ // {silent:true}: don't echo cmd output so it can be controlled via logLevel
3434
console.log(stdout.green);
3535
callback(stderr, stdout);

lib/modules/swarm/embarkjs.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*global web3 */
2+
let __embarkSwarm = {};
3+
const bytes = require("eth-lib/lib/bytes");
4+
5+
__embarkSwarm.setProvider = function (options) {
6+
this.bzz = web3.bzz;
7+
this.protocol = options.protocol;
8+
this.host = options.host;
9+
this.port = options.port;
10+
this.connectUrl = `${options.protocol}://${options.host}:${options.port}`;
11+
this.connectError = new Error(`Cannot connect to Swarm node on ${this.connectUrl}`);
12+
this._getUrl = options.getUrl || `${this.connectUrl}/bzzr:/`;
13+
14+
return new Promise((resolve, reject) => {
15+
try {
16+
if (!this.bzz.currentProvider) {
17+
this.bzz.setProvider(`${options.protocol}://${options.host}:${options.port}`);
18+
}
19+
resolve(this);
20+
} catch (err) {
21+
console.log(err);
22+
reject(this.connectError);
23+
}
24+
});
25+
};
26+
27+
__embarkSwarm.isAvailable = function () {
28+
return new Promise((resolve, reject) => {
29+
if (!this.bzz) {
30+
return resolve(false);
31+
}
32+
this.bzz.isAvailable()
33+
.then(resolve)
34+
.catch(() => {
35+
reject(this.connectError);
36+
});
37+
});
38+
};
39+
40+
__embarkSwarm.saveText = function (text) {
41+
return new Promise((resolve, reject) => {
42+
this.isAvailable().then((isAvailable) => {
43+
if (!isAvailable) {
44+
return reject(this.connectError);
45+
}
46+
this.bzz.upload(text)
47+
.then(resolve)
48+
.catch(reject);
49+
}).catch(reject);
50+
});
51+
};
52+
53+
__embarkSwarm.get = function (hash) {
54+
return new Promise((resolve, reject) => {
55+
this.isAvailable().then((isAvailable) => {
56+
if (!isAvailable) {
57+
return reject(this.connectError);
58+
}
59+
this.bzz.download(hash)
60+
.then((uint8Array) => resolve(bytes.toString(bytes.fromUint8Array(uint8Array))))
61+
.catch(reject);
62+
}).catch(reject);
63+
});
64+
};
65+
66+
__embarkSwarm.uploadFile = function (inputSelector) {
67+
let file = inputSelector[0].files[0];
68+
69+
if (file === undefined) {
70+
throw new Error('no file found');
71+
}
72+
73+
return new Promise((resolve, reject) => {
74+
const reader = new FileReader();
75+
reader.onloadend = (event) => {
76+
const fileContent = new Uint8Array(event.target.result);
77+
this.isAvailable().then((isAvailable) => {
78+
if (!isAvailable) {
79+
return reject(this.connectError);
80+
}
81+
this.bzz.upload(fileContent)
82+
.then(resolve)
83+
.catch(reject);
84+
}).catch(reject);
85+
};
86+
reader.onerror = reject;
87+
reader.readAsArrayBuffer(file);
88+
});
89+
};
90+
91+
__embarkSwarm.getUrl = function (hash) {
92+
return this._getUrl + hash;
93+
};
94+

0 commit comments

Comments
 (0)