var Promise = require('bluebird'); //var Ipfs = require('./ipfs.js'); var EmbarkJS = { }; EmbarkJS.Contract = function(options) { var self = this; var i, abiElement; this.abi = options.abi; this.address = options.address; this.code = options.code; this.web3 = options.web3 || web3; var ContractClass = this.web3.eth.contract(this.abi); this.eventList = []; if (this.abi) { for (i = 0; i < this.abi.length; i++) { abiElement = this.abi[i]; if (abiElement.type === 'event') { this.eventList.push(abiElement.name); } } } var messageEvents = function() { this.cb = function() {}; }; messageEvents.prototype.then = function(cb) { this.cb = cb; }; messageEvents.prototype.error = function(err) { return err; }; this._originalContractObject = ContractClass.at(this.address); this._methods = Object.getOwnPropertyNames(this._originalContractObject).filter(function (p) { // TODO: check for forbidden properties if (self.eventList.indexOf(p) >= 0) { self[p] = function() { var promise = new messageEvents(); var args = Array.prototype.slice.call(arguments); args.push(function(err, result) { if (err) { promise.error(err); } else { promise.cb(result); } }); self._originalContractObject[p].apply(self._originalContractObject[p], args); return promise; }; return true; } else if (typeof self._originalContractObject[p] === 'function') { self[p] = Promise.promisify(self._originalContractObject[p]); return true; } return false; }); }; EmbarkJS.Contract.prototype.deploy = function(args) { var self = this; var contractParams; contractParams = args || []; contractParams.push({ from: this.web3.eth.accounts[0], data: this.code, gas: 500000, gasPrice: 10000000000000 }); var contractObject = this.web3.eth.contract(this.abi); var promise = new Promise(function(resolve, reject) { contractParams.push(function(err, transaction) { console.log("callback"); if (err) { console.log("error"); reject(err); } else if (transaction.address !== undefined) { console.log("address contract: " + transaction.address); resolve(new EmbarkJS.Contract({abi: self.abi, code: self.code, address: transaction.address})); } }); console.log(contractParams); // returns promise // deploys contract // wraps it around EmbarkJS.Contract contractObject["new"].apply(contractObject, contractParams); }); return promise; }; EmbarkJS.IPFS = 'ipfs'; EmbarkJS.Storage = { }; // EmbarkJS.Storage.setProvider('ipfs',{server: 'localhost', port: '5001'}) EmbarkJS.Storage.setProvider = function(provider, options) { if (provider === 'ipfs') { this.currentStorage = EmbarkJS.Storage.IPFS; if (options === undefined) { this.ipfsConnection = IpfsApi('localhost', '5001'); } else { this.ipfsConnection = IpfsApi(options.server, options.port); } } else { throw Error('unknown provider'); } }; EmbarkJS.Storage.saveText = function(text) { var self = this; if (!this.ipfsConnection) { this.setProvider('ipfs'); } var promise = new Promise(function(resolve, reject) { self.ipfsConnection.add((new self.ipfsConnection.Buffer(text)), function(err, result) { if (err) { reject(err); } else { resolve(result[0].path); } }); }); return promise; }; EmbarkJS.Storage.uploadFile = function(inputSelector) { var self = this; var file = inputSelector[0].files[0]; if (file === undefined) { throw new Error('no file found'); } if (!this.ipfsConnection) { this.setProvider('ipfs'); } var promise = new Promise(function(resolve, reject) { var reader = new FileReader(); reader.onloadend = function() { var fileContent = reader.result; var buffer = self.ipfsConnection.Buffer.from(fileContent); self.ipfsConnection.add(buffer, function(err, result) { if (err) { reject(err); } else { resolve(result[0].path); } }); }; reader.readAsArrayBuffer(file); }); return promise; }; EmbarkJS.Storage.get = function(hash) { var self = this; // TODO: detect type, then convert if needed //var ipfsHash = web3.toAscii(hash); if (!this.ipfsConnection) { this.setProvider('ipfs'); } var promise = new Promise(function(resolve, reject) { self.ipfsConnection.object.get([hash]).then(function(node) { resolve(node.data); }); }); return promise; }; EmbarkJS.Storage.getUrl = function(hash) { //var ipfsHash = web3.toAscii(hash); return 'http://localhost:8080/ipfs/' + hash; }; EmbarkJS.Messages = { }; EmbarkJS.Messages.setProvider = function(provider, options) { var ipfs; if (provider === 'whisper') { this.currentMessages = EmbarkJS.Messages.Whisper; } else if (provider === 'orbit') { this.currentMessages = EmbarkJS.Messages.Orbit; if (options === undefined) { ipfs = HaadIpfsApi('localhost', '5001'); } else { ipfs = HaadIpfsApi(options.server, options.port); } this.currentMessages.orbit = new Orbit(ipfs); this.currentMessages.orbit.connect(web3.eth.accounts[0]); } else { throw Error('unknown provider'); } }; EmbarkJS.Messages.sendMessage = function(options) { return this.currentMessages.sendMessage(options); }; EmbarkJS.Messages.listenTo = function(options) { return this.currentMessages.listenTo(options); }; EmbarkJS.Messages.Whisper = { }; EmbarkJS.Messages.Whisper.sendMessage = function(options) { var topics = options.topic || options.topics; var data = options.data || options.payload; var identity = options.identity || web3.shh.newIdentity(); var ttl = options.ttl || 100; var priority = options.priority || 1000; if (topics === undefined) { throw new Error("missing option: topic"); } if (data === undefined) { throw new Error("missing option: data"); } // do fromAscii to each topics unless it's already a string if (typeof topics === 'string') { topics = topics; } else { // TODO: replace with es6 + babel; var _topics = []; for (var i = 0; i < topics.length; i++) { _topics.push(web3.fromAscii(topics[i])); } topics = _topics; } var payload = JSON.stringify(data); var message = { from: identity, topics: [web3.fromAscii(topics)], payload: web3.fromAscii(payload), ttl: ttl, priority: priority }; return web3.shh.post(message); }; EmbarkJS.Messages.Whisper.listenTo = function(options) { var topics = options.topic || options.topics; if (typeof topics === 'string') { topics = [topics]; } else { // TODO: replace with es6 + babel; var _topics = []; for (var i = 0; i < topics.length; i++) { _topics.push(web3.fromAscii(topics[i])); } topics = _topics; } var filterOptions = { topics: topics }; var messageEvents = function() { this.cb = function() {}; }; messageEvents.prototype.then = function(cb) { this.cb = cb; }; messageEvents.prototype.error = function(err) { return err; }; var promise = new messageEvents(); var filter = web3.shh.filter(filterOptions, function(err, result) { var payload = JSON.parse(web3.toAscii(result.payload)); if (err) { promise.error(err); } else { promise.cb(payload); } }); return promise; }; EmbarkJS.Messages.Orbit = { }; EmbarkJS.Messages.Orbit.sendMessage = function(options) { var topics = options.topic || options.topics; var data = options.data || options.payload; if (topics === undefined) { throw new Error("missing option: topic"); } if (data === undefined) { throw new Error("missing option: data"); } // do fromAscii to each topics unless it's already a string if (typeof topics === 'string') { topics = topics; } else { // TODO: better to just send to different channels instead topics = topics.join(','); } // TODO: if it's array then join and send ot several // keep list of channels joined this.orbit.join(topics); var payload = JSON.stringify(data); this.orbit.send(topics, data); }; EmbarkJS.Messages.Orbit.listenTo = function(options) { var self = this; var topics = options.topic || options.topics; // do fromAscii to each topics unless it's already a string if (typeof topics === 'string') { topics = topics; } else { // TODO: better to just send to different channels instead topics = topics.join(','); } var messageEvents = function() { this.cb = function() {}; }; messageEvents.prototype.then = function(cb) { this.cb = cb; }; messageEvents.prototype.error = function(err) { return err; }; var promise = new messageEvents(); this.orbit.events.on('message', (topics, message) => { // Get the actual content of the message self.orbit.getPost(message.payload.value, true).then((post) => { promise.cb(post.content); }); }); return promise; }; module.exports = EmbarkJS;