diff --git a/.gitignore b/.gitignore index 03a8da3..e83f5bd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ demo — копия.html demo — копия — копия.html +node_modules diff --git a/NodeMetaInfo.js b/NodeMetaInfo.js index 2fbc5fa..7fc7a24 100644 --- a/NodeMetaInfo.js +++ b/NodeMetaInfo.js @@ -63,3 +63,9 @@ class NodeMetaInfo { } } + + +//unify browser and node +if (this.window === undefined){ + module.exports = NodeMetaInfo; +} \ No newline at end of file diff --git a/candy.js b/candy.js index 8b42aab..c55e0c0 100644 --- a/candy.js +++ b/candy.js @@ -9,6 +9,10 @@ */ 'use strict'; +//unify browser and node +if (typeof _this ==='undefined') { + var _this = this; +} const MessageType = { QUERY_LATEST: 0, @@ -17,7 +21,8 @@ const MessageType = { MY_PEERS: 3, BROADCAST: 4, META: 5, - SW_BROADCAST: 6 + SW_BROADCAST: 6, + TRANS_COLL:7, }; const BlockchainRequestors = { @@ -27,8 +32,30 @@ const BlockchainRequestors = { } }; + function Candy(nodeList) { - 'use strict'; + + //modules list(for compability with node) + try { + if (_this.window === undefined) { + this.WebSocket = require('ws'); + this.starwaveProtocol = require('./starwaveProtocol.js'); + this.NodeMetaInfo = require('./NodeMetaInfo.js'); + this.DigitalSignature = require('./digitalSignature.js'); + this.StarwaveCrypto = require('./starwaveCrypto.js'); + this.URL = require('url').Url; + } else { //if browser + this.WebSocket = typeof WebSocket !== 'undefined' ? WebSocket : undefined; + this.starwaveProtocol = typeof starwaveProtocol !== 'undefined' ? starwaveProtocol : undefined; + this.NodeMetaInfo = typeof NodeMetaInfo !== 'undefined' ? NodeMetaInfo : undefined; + this.DigitalSignature = typeof DigitalSignature !== 'undefined' ? DigitalSignature : undefined; + this.StarwaveCrypto = typeof StarwaveCrypto !== 'undefined' ? StarwaveCrypto : undefined; + this.URL = URL; + } + } catch (e) { + console.log('Error trying to include libraries: ' + e); + } + let that = this; this.maxConnections = 30; this.nodeList = nodeList; @@ -47,13 +74,11 @@ function Candy(nodeList) { this.secretKeys = {}; //consist of secret keys of different busAddresses of peers - - if(typeof starwaveProtocol === 'function') { - this.starwave = new starwaveProtocol(this, MessageType); + if (typeof this.starwaveProtocol === 'function') { + this.starwave = new this.starwaveProtocol(this, MessageType); } else { console.log("Error: Can't find starwaveProtocol module"); } - ; /** * Current reciever address. Override allowed @@ -91,23 +116,22 @@ function Candy(nodeList) { * @param {Object} data */ this._dataRecieved = function (source, data) { - //prevent multiple sockets on one busaddress - if(!this.allowMultiplySocketsOnBus && (this.starwave)) { - if(this.starwave.preventMultipleSockets(source) === 0) { + if (!this.allowMultiplySocketsOnBus && (this.starwave)) { + if (this.starwave.preventMultipleSockets(source) === 0) { data = null; return; } } - if(typeof that.ondata === 'function') { - if(that.ondata(data)) { + if (typeof that.ondata === 'function') { + if (that.ondata(data)) { return; } } //Data block recived - if(data.type === MessageType.RESPONSE_BLOCKCHAIN) { + if (data.type === MessageType.RESPONSE_BLOCKCHAIN) { try { /** * @var {Block} block @@ -115,11 +139,11 @@ function Candy(nodeList) { let blocks = JSON.parse(data.data); for (let a in blocks) { let block = blocks[a]; - if(that.blockHeight < block.index) { + if (that.blockHeight < block.index) { that.blockHeight = block.index } //Loading requested resource - if(typeof that._resourceQueue[block.index] !== 'undefined') { + if (typeof that._resourceQueue[block.index] !== 'undefined') { that._resourceQueue[block.index](block.data, block); that._resourceQueue[block.index] = undefined; } @@ -130,12 +154,12 @@ function Candy(nodeList) { } //New peers recived - if(data.type === MessageType.MY_PEERS) { + if (data.type === MessageType.MY_PEERS) { for (let a in data.data) { - if(data.data.hasOwnProperty(a)) { - if(that.nodeList.indexOf(data.data[a]) == -1) { + if (data.data.hasOwnProperty(a)) { + if (that.nodeList.indexOf(data.data[a]) == -1) { that.nodeList.push(data.data[a]); - if(that.getActiveConnections().length < that.maxConnections - 1) { + if (that.getActiveConnections().length < that.maxConnections - 1) { that.connectPeer(data.data[a]); } } @@ -144,21 +168,21 @@ function Candy(nodeList) { that.nodeList = Array.from(new Set(that.nodeList)); } - if(data.type === MessageType.BROADCAST) { + if (data.type === MessageType.BROADCAST) { /*if(that._lastMsgIndex < data.index) {*/ - if(data.reciver === that.recieverAddress) { + if (data.reciver === that.recieverAddress) { - if(data.id === 'CANDY_APP_RESPONSE') { - if(typeof that._candyAppResponse === 'function') { + if (data.id === 'CANDY_APP_RESPONSE') { + if (typeof that._candyAppResponse === 'function') { that._candyAppResponse(data); } } else { - if(typeof that.onmessage === 'function') { + if (typeof that.onmessage === 'function') { that.onmessage(data); } } } else { - if(data.recepient !== that.recieverAddress) { + if (data.recepient !== that.recieverAddress) { data.TTL++; that.broadcast(data); } @@ -169,11 +193,11 @@ function Candy(nodeList) { } //add meta info handling //required NodeMetaInfo.js included - if(data.type === MessageType.META) { - if(typeof NodeMetaInfo === 'function') { + if (data.type === MessageType.META) { + if (typeof this.NodeMetaInfo === 'function') { let ind = that.sockets.indexOf(source); - if(ind > -1) { - that.sockets[ind].nodeMetaInfo = (new NodeMetaInfo()).parse(data.data); + if (ind > -1) { + that.sockets[ind].nodeMetaInfo = (new this.NodeMetaInfo()).parse(data.data); } else { console.log('Error: Unexpected error occurred when trying to add validators'); } @@ -182,8 +206,8 @@ function Candy(nodeList) { } } - if(data.type === MessageType.SW_BROADCAST) { - if(this.starwave) { + if (data.type === MessageType.SW_BROADCAST) { + if (this.starwave) { this._lastMsgIndex = this.starwave.handleMessage(data, this.messagesHandlers, source); } } @@ -198,8 +222,8 @@ function Candy(nodeList) { that.getActiveConnections = function () { let activeSockets = []; for (let a in that.sockets) { - if(that.sockets[a]) { - if(that.sockets[a].readyState === WebSocket.OPEN) { + if (that.sockets[a]) { + if (that.sockets[a].readyState === this.WebSocket.OPEN) { activeSockets.push(that.sockets[a]); } } @@ -215,14 +239,15 @@ function Candy(nodeList) { this.connectPeer = function (peer) { let socket = null; try { - socket = new WebSocket(peer); + socket = new this.WebSocket(peer); } catch (e) { return; } + socket.onopen = function () { setTimeout(function () { - if(typeof that.onready !== 'undefined') { - if(typeof that._autoloader !== 'undefined') { + if (typeof that.onready !== 'undefined') { + if (typeof that._autoloader !== 'undefined') { that._autoloader.onready(); } that.onready(); @@ -248,6 +273,12 @@ function Candy(nodeList) { socket.onerror = function (error) { //console.log("Ошибка " + error.message); }; + if (_this.window === undefined){ + socket.on('open', ()=> socket.onopen()); + socket.on('close', ()=> socket.onclose()); + socket.on('message', ()=> socket.onmessage()); + socket.on('error', ()=> socket.onerror()); + } that.sockets.push(socket); }; @@ -258,11 +289,11 @@ function Candy(nodeList) { */ this.broadcast = function (message) { let sended = false; - if(typeof message !== 'string') { + if (typeof message !== 'string') { message = JSON.stringify(message); } for (let a in that.sockets) { - if(that.sockets.hasOwnProperty(a) && that.sockets[a] !== null) { + if (that.sockets.hasOwnProperty(a) && that.sockets[a] !== null) { try { that.sockets[a].send(message); sended = true; @@ -295,7 +326,7 @@ function Candy(nodeList) { index: that._lastMsgIndex, mutex: this.getid() + this.getid() + this.getid() }; - if(!that.broadcast(message)) { + if (!that.broadcast(message)) { that.autoconnect(true); return false; } @@ -308,10 +339,10 @@ function Candy(nodeList) { * @param {boolean} force reconnection */ this.autoconnect = function (force) { - if(that.getActiveConnections().length < 1 || force) { + if (that.getActiveConnections().length < 1 || force) { for (let a in that.nodeList) { - if(that.nodeList.hasOwnProperty(a)) { - if(that.getActiveConnections().length < that.maxConnections - 1) { + if (that.nodeList.hasOwnProperty(a)) { + if (that.getActiveConnections().length < that.maxConnections - 1) { that.connectPeer(that.nodeList[a]); } } @@ -327,8 +358,8 @@ function Candy(nodeList) { */ this.start = function () { for (let a in that.nodeList) { - if(that.nodeList.hasOwnProperty(a)) { - if(that.getActiveConnections().length < that.maxConnections - 1) { + if (that.nodeList.hasOwnProperty(a)) { + if (that.getActiveConnections().length < that.maxConnections - 1) { that.connectPeer(that.nodeList[a]); } } @@ -349,8 +380,7 @@ function Candy(nodeList) { * @param {int} timeout */ this._candyAppRequest = function (uri, requestData, backId, timeout) { - let url = document.createElement('a'); - url.href = uri.replace('candy:', 'http:'); + let url = new this.URL(uri.replace('candy:', 'http:')); let data = { uri: uri, data: requestData, @@ -365,7 +395,7 @@ function Candy(nodeList) { * @param message */ this._candyAppResponse = function (message) { - if(typeof that._requestQueue[message.data.backId] !== 'undefined') { + if (typeof that._requestQueue[message.data.backId] !== 'undefined') { let request = that._requestQueue[message.data.backId]; clearTimeout(request.timer); request.callback(message.err, typeof message.data.data.body !== 'undefined' ? message.data.data.body : message.data.data, message); @@ -383,7 +413,7 @@ function Candy(nodeList) { * @param {int} timeout */ this.requestApp = function (uri, data, callback, timeout) { - if(typeof timeout === 'undefined') { + if (typeof timeout === 'undefined') { timeout = 10000; } let requestId = that.getid(); @@ -418,9 +448,8 @@ function Candy(nodeList) { * @param {int} timeout */ this.request = function (uri, data, callback, timeout) { - let url = document.createElement('a'); - url.href = uri.replace('candy:', 'http:'); - if(url.hostname === 'block') { + let url = new this.URL(uri.replace('candy:', 'http:')); + if (url.hostname === 'block') { that.loadResource(url.pathname.replace('/', ''), function (err, data) { callback(err, data.candyData, data); }); @@ -436,7 +465,7 @@ function Candy(nodeList) { * @param {Function} callback */ this.loadResource = function (blockId, callback) { - if(blockId > that.blockHeigth && blockId < 1) { + if (blockId > that.blockHeigth && blockId < 1) { callback(404); } that._resourceQueue[blockId] = function (data, rawBlock) { @@ -457,6 +486,9 @@ function Candy(nodeList) { this.messagesHandlers.sort((a, b) => a.id > b.id); }; - return this; -} \ No newline at end of file +} + +if (this.window === undefined) { + module.exports = Candy; +} diff --git a/digitalSignature.js b/digitalSignature.js index 1336688..90855a0 100644 --- a/digitalSignature.js +++ b/digitalSignature.js @@ -7,9 +7,18 @@ 'use strict'; +//unify browser and node +if (typeof _this ==='undefined') { + var _this = this; +} function DigitalSignature(dataToSign) { //data in string format - + if (_this.window === undefined){ + this.forge = require('node-forge'); + } else { + this.forge = forge; + } + /** * RSA keys for sign */ @@ -19,7 +28,7 @@ function DigitalSignature(dataToSign) { //data in string format * Sign */ this.sign = ''; - + /** * data format as presented in 'block data' */ @@ -35,11 +44,11 @@ function DigitalSignature(dataToSign) { //data in string format */ this.generate = (len = 2048) => { - let rsa = forge.pki.rsa; - let keypair = forge.rsa.generateKeyPair({len}); + let rsa = this.forge.pki.rsa; + let keypair = this.forge.rsa.generateKeyPair({len}); keypair = { - public: repairKey(fix(forge.pki.publicKeyToRSAPublicKeyPem(keypair.publicKey, 72))), - private: repairKey(fix(forge.pki.privateKeyToPem(keypair.privateKey, 72))) + public: repairKey(fix(this.forge.pki.publicKeyToRSAPublicKeyPem(keypair.publicKey, 72))), + private: repairKey(fix(this.forge.pki.privateKeyToPem(keypair.privateKey, 72))) }; this.keysPair = keypair; console.log('Info: Keypair generated'); @@ -66,7 +75,7 @@ function DigitalSignature(dataToSign) { //data in string format /** * Signs data * @param {data} data for signing - * @param {privateKey} private key + * @param {key} key */ @@ -74,35 +83,36 @@ function DigitalSignature(dataToSign) { //data in string format if (!data) { console.log('No data to sign'); return ''; - }; - let md= forge.md.sha256.create(); + } + let md= this.forge.md.sha256.create(); md.update(data,'utf8'); - let privateKey = forge.pki.privateKeyFromPem(key); + let privateKey = this.forge.pki.privateKeyFromPem(key); this.sign = privateKey.sign(md); console.log('Info: Data signed'); - return {data: data, sign: forge.util.bytesToHex(this.sign)}; + return {data: data, sign: this.forge.util.bytesToHex(this.sign)}; }; /** * Signs data * @param {data} data for signing - * @param {puBkey} private key + * @param {sign} sign + * @param {key} key */ this.verifyData = (data = this.signedData, sign = this.signedData.sign, key = this.signedData.pubkey) => { if (typeof data === 'object'){ sign = data.sign; data = data.data; - }; + } try { - let publicKey = forge.pki.publicKeyFromPem(repairKey(fix(key))); - let md = forge.md.sha256.create(); + let publicKey = this.forge.pki.publicKeyFromPem(repairKey(fix(key))); + let md = this.forge.md.sha256.create(); md.update(data,'utf8'); - return publicKey.verify(md.digest().bytes(), forge.util.hexToBytes(sign)); //verifying only in bytes format + return publicKey.verify(md.digest().bytes(), this.forge.util.hexToBytes(sign)); //verifying only in bytes format } catch (e){ console.log(e); return false; - }; + } }; if (dataToSign !== undefined){ @@ -112,7 +122,12 @@ function DigitalSignature(dataToSign) { //data in string format if(this.verifyData() === false) { console.log('Sign self-validation error! Invalid key or sign checking'); } - }; + } return this; -}; \ No newline at end of file +} + +//unify browser and node +if (this.window === undefined){ + module.exports = DigitalSignature; +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1c1f199 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,92 @@ +{ + "name": "candy", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "crypto-js": { + "version": "file:crypto-js" + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.5", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "hash.js": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", + "requires": { + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "1.1.5", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" + }, + "node-forge": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", + "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==" + }, + "ws": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz", + "integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==", + "requires": { + "async-limiter": "1.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..eacd20f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "candy", + "version": "1.0.0", + "description": "iZ³ blockchain connection provider for browsers", + "main": "main.js", + "dependencies": { + "crypto-js": "file:crypto-js", + "elliptic": "^6.4.1", + "moment": "^2.22.2", + "node-forge": "^0.7.6", + "ws": "^6.0.0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Izzzio/Candy.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/Izzzio/Candy/issues" + }, + "homepage": "https://github.com/Izzzio/Candy#readme" +} diff --git a/starwaveCrypto.js b/starwaveCrypto.js index 51b86ba..abc6e66 100644 --- a/starwaveCrypto.js +++ b/starwaveCrypto.js @@ -12,11 +12,27 @@ 'use strict'; +//unify browser and node +if (typeof _this ==='undefined') { + var _this = this; +} +if (_this.window === undefined){ + _this.elliptic = require('elliptic'); + _this.CryptoJS = require('crypto-js'); +} + const SWCRYPTO_CONNECTION_MESSAGE_TYPE = 'DH-CONNECTION'; class StarwaveCrypto { constructor(starwaveProtocolObject, secretKeysKeyring, curve = 'secp256k1') { + if (_this.window === undefined){ + this.elliptic = require('elliptic'); + this.CryptoJS = require('crypto-js'); + } else { + this.elliptic = elliptic; + this.CryptoJS = CryptoJS; + } let that = this; // EСDH object this.ec = new elliptic.ec(curve); @@ -222,3 +238,8 @@ class StarwaveCrypto { } } + +//unify browser and node +if (this.window === undefined){ + module.exports = StarwaveCrypto; +} \ No newline at end of file diff --git a/starwaveProtocol.js b/starwaveProtocol.js index 97062ad..04438c6 100644 --- a/starwaveProtocol.js +++ b/starwaveProtocol.js @@ -11,7 +11,12 @@ const MESSAGE_MUTEX_TIMEOUT = 1000; const LATENCY_TIME = 100 * 1000; //time on obsolescence of message -//const moment = require('moment'); + +//unify browser and node +if (typeof _this ==='undefined') { + var _this = this; +} + class starwaveProtocol { @@ -25,8 +30,11 @@ class starwaveProtocol { * @private */ this._messageMutex = {}; - - //this.starwaveCrypto = new StarwaveCrypto(this, this.candy.secretKeys); + if (_this.window === undefined){ + this.moment = require('moment'); + } else{ + this.moment = moment; + } } /** @@ -49,13 +57,13 @@ class starwaveProtocol { reciver: reciver, sender: sender !== undefined ? sender : this.candy.recieverAddress, id: id, - timestamp: timestamp !== undefined ? timestamp : moment().utc().valueOf(), + timestamp: timestamp !== undefined ? timestamp : this.moment().utc().valueOf(), TTL: typeof TTL !== 'undefined' ? TTL : 0, mutex: this.candy.getid() + this.candy.getid() + this.candy.getid(), relevancyTime: relevancyTime !== undefined ? relevancyTime : LATENCY_TIME, //time of message's relevancy route: route !== undefined ? route : [], type: type !== undefined ? type : this.candy.MessageType.SW_BROADCAST, - timestampOfStart: timestampOfStart !== undefined ? timestampOfStart : moment().utc().valueOf() + timestampOfStart: timestampOfStart !== undefined ? timestampOfStart : this.moment().utc().valueOf() }; }; @@ -171,7 +179,7 @@ class starwaveProtocol { } //check if the message is't too old - let m = moment().utc().valueOf(); + let m = this.moment().utc().valueOf(); if(m > (message.timestamp + message.relevancyTime + LATENCY_TIME)) { return 0; //do nothing } @@ -383,3 +391,7 @@ class starwaveProtocol { } +//unify browser and node +if (this.window === undefined){ + module.exports = starwaveProtocol; +} \ No newline at end of file diff --git a/transactionCollector.js b/transactionCollector.js new file mode 100644 index 0000000..f7dfcb7 --- /dev/null +++ b/transactionCollector.js @@ -0,0 +1,53 @@ +/** + Module which made transactions collections + */ + +'use strict'; +//unify browser and node +if (typeof _this ==='undefined') { + var _this = this; +} +if (_this.window === undefined){ + +} + +class TransactionCollector { + + constructor (candy) { + this.candy = candy; + this.lastAddedTransaction = {}; + } + + + /** + * create alert about new transaction + * @param data + * @param index + * @returns {{type: number, data: *, index: string}} + */ + createMessage(data, index = ''){ + let JSONdata = JSON.stringify(data); + return { + type: this.candy.MessageType.TRANS_COLL, + data: JSONdata, + index:index + } + } + + /** + * broadcasting message to all peers about new element of collection, excluding excludeSocket + * @param data + * @param broadcastFunction + * @param excludeSocket + */ + sendTransactionToAllPeers(data, broadcastFunction, excludeSocket){ + let message = this.createMessage(data); + broadcastFunction (message, excludeSocket); + return message; + } +} + +//unify browser and node +if (this.window === undefined){ + module.exports = TransactionCollector; +} \ No newline at end of file