@leofcoin/chain 1.3.12 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/block-worker.js +1 -1
  2. package/dist/browser/workers/block-worker.js +1977 -5692
  3. package/dist/browser/workers/machine-worker.js +1955 -5670
  4. package/dist/browser/workers/pool-worker.js +1636 -5531
  5. package/dist/browser/workers/transaction-worker.js +1626 -5521
  6. package/dist/chain.js +9865 -1196
  7. package/dist/client-80bc8156.js +491 -0
  8. package/dist/commonjs-7fe3c381.js +270 -0
  9. package/dist/generate-account-445db122.js +46 -0
  10. package/dist/index-57f93805.js +718 -0
  11. package/dist/{messages.browser.js → messages-bce1b91d-81af3b00.js} +26 -39
  12. package/dist/module/chain.js +9821 -1179
  13. package/dist/module/client-8031ec88.js +489 -0
  14. package/dist/module/commonjs-9005d5c0.js +268 -0
  15. package/dist/module/generate-account-489552b6.js +44 -0
  16. package/dist/module/index-ac2285c4.js +688 -0
  17. package/dist/module/messages-bce1b91d-eaf75d83.js +302 -0
  18. package/dist/module/node.js +6833 -2
  19. package/dist/module/workers/block-worker.js +3 -287
  20. package/dist/module/workers/machine-worker.js +3 -287
  21. package/dist/node.js +6845 -8
  22. package/dist/workers/machine-worker.js +1 -1
  23. package/package.json +15 -20
  24. package/src/chain.js +5 -12
  25. package/src/contract.js +2 -2
  26. package/src/machine.js +10 -7
  27. package/src/node.js +2 -2
  28. package/src/transaction.js +5 -5
  29. package/test/chain.js +5 -7
  30. package/test/index.js +1 -3
  31. package/tsconfig.js +15 -0
  32. package/workers/block-worker.js +40 -0
  33. package/workers/machine-worker.js +219 -0
  34. package/workers/pool-worker.js +28 -0
  35. package/workers/transaction-worker.js +20 -0
  36. package/workers/workers.js +9 -0
  37. package/dist/865.browser.js +0 -10
  38. package/dist/chain.browser.js +0 -66842
  39. package/dist/generate-account.browser.js +0 -50
  40. package/dist/multi-wallet.browser.js +0 -15
  41. package/dist/node.browser.js +0 -9858
  42. package/dist/pako.browser.js +0 -6900
  43. package/dist/peernet-swarm.browser.js +0 -839
  44. package/dist/storage.browser.js +0 -3724
  45. package/dist/wrtc.browser.js +0 -28
  46. package/rollup.config.js +0 -229
  47. package/src/standards/initializer.js +0 -10
  48. package/webpack.config.js +0 -109
@@ -0,0 +1,491 @@
1
+ 'use strict';
2
+
3
+ var SocketClient = require('socket-request-client');
4
+ require('@vandeurenglenn/debug');
5
+
6
+ function _interopDefaultLegacy$1 (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
7
+
8
+ function _interopNamespace$1(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n["default"] = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var SocketClient__default = /*#__PURE__*/_interopDefaultLegacy$1(SocketClient);
27
+
28
+ class Peer {
29
+ #connection
30
+ #connected = false
31
+ #messageQue = []
32
+ #chunksQue = {}
33
+ #channel
34
+ #peerId
35
+ #channelName
36
+ #chunkSize = 16 * 1024 // 16384
37
+ #queRunning = false
38
+ #MAX_BUFFERED_AMOUNT = 16 * 1024 * 1024
39
+
40
+ get connection() {
41
+ return this.#connection
42
+ }
43
+
44
+ get connected() {
45
+ return this.#connected
46
+ }
47
+
48
+ get readyState() {
49
+ return this.#channel?.readyState
50
+ }
51
+
52
+ /**
53
+ * @params {Object} options
54
+ * @params {string} options.channelName - this peerid : otherpeer id
55
+ */
56
+ constructor(options = {}) {
57
+ this._in = this._in.bind(this);
58
+ this.offerOptions = options.offerOptions;
59
+ this.initiator = options.initiator;
60
+ this.streams = options.streams;
61
+ this.socketClient = options.socketClient;
62
+ this.id = options.id;
63
+ this.to = options.to;
64
+ this.bw = {
65
+ up: 0,
66
+ down: 0
67
+ };
68
+
69
+ this.#channelName = options.channelName;
70
+
71
+ this.#peerId = options.peerId;
72
+ this.options = options;
73
+ return this.#init()
74
+ }
75
+
76
+ get peerId() {
77
+ return this.#peerId
78
+ }
79
+
80
+ set socketClient(value) {
81
+ // this.socketClient?.pubsub.unsubscribe('signal', this._in)
82
+ this._socketClient = value;
83
+ this._socketClient.pubsub.subscribe('signal', this._in);
84
+ }
85
+
86
+ get socketClient() {
87
+ return this._socketClient
88
+ }
89
+
90
+ splitMessage(message) {
91
+ const chunks = [];
92
+ message = pako.deflate(message);
93
+ const size = message.byteLength || message.length;
94
+ let offset = 0;
95
+ return new Promise((resolve, reject) => {
96
+ const splitMessage = () => {
97
+ const chunk = message.slice(offset, offset + this.#chunkSize > size ? size : offset + this.#chunkSize);
98
+ offset += this.#chunkSize;
99
+ chunks.push(chunk);
100
+ if (offset < size) return splitMessage()
101
+ else resolve({chunks, size});
102
+ };
103
+
104
+ splitMessage();
105
+ })
106
+ }
107
+
108
+ async #runQue() {
109
+ this.#queRunning = true;
110
+ if (this.#messageQue.length > 0 && this.#channel?.bufferedAmount + this.#messageQue[0]?.length < this.#MAX_BUFFERED_AMOUNT) {
111
+ const message = this.#messageQue.shift();
112
+
113
+ switch (this.#channel?.readyState) {
114
+ case 'open':
115
+ await this.#channel.send(message);
116
+ if (this.#messageQue.length > 0) return this.#runQue()
117
+ else this.#queRunning = false;
118
+ break;
119
+ case 'closed':
120
+ case 'closing':
121
+ this.#messageQue = [];
122
+ this.#queRunning = false;
123
+ debug('channel already closed, this usually means a bad implementation, try checking the readyState or check if the peer is connected before sending');
124
+ break;
125
+ case undefined:
126
+ this.#messageQue = [];
127
+ this.#queRunning = false;
128
+ debug(`trying to send before a channel is created`);
129
+ break;
130
+ }
131
+
132
+
133
+ } else {
134
+ return setTimeout(() => this.#runQue(), 50)
135
+ }
136
+ }
137
+
138
+ #trySend({ size, id, chunks }) {
139
+ let offset = 0;
140
+
141
+ for (const chunk of chunks) {
142
+ const start = offset;
143
+ const end = offset + chunk.length;
144
+
145
+ const message = new TextEncoder().encode(JSON.stringify({ size, id, chunk, start, end }));
146
+ this.#messageQue.push(message);
147
+ }
148
+
149
+ if (!this.queRunning) return this.#runQue()
150
+ }
151
+
152
+ async send(message, id) {
153
+ const { chunks, size } = await this.splitMessage(message);
154
+ return this.#trySend({ size, id, chunks })
155
+ }
156
+
157
+ request(data) {
158
+ return new Promise((resolve, reject) => {
159
+ const id = Math.random().toString(36).slice(-12);
160
+
161
+ const _onData = message => {
162
+ if (message.id === id) {
163
+ resolve(message.data);
164
+ pubsub.unsubscribe(`peer:data`, _onData);
165
+ }
166
+ };
167
+
168
+ pubsub.subscribe(`peer:data`, _onData);
169
+
170
+ // cleanup subscriptions
171
+ // setTimeout(() => {
172
+ // pubsub.unsubscribe(`peer:data-request-${id}`, _onData)
173
+ // }, 5000);
174
+
175
+ this.send(data, id);
176
+ })
177
+ }
178
+
179
+ async #init() {
180
+ try {
181
+
182
+ if (!globalThis.pako) {
183
+ const importee = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace$1(require(/* webpackChunkName: "pako" */ 'pako')); });
184
+ globalThis.pako = importee.default;
185
+ }
186
+
187
+ const iceServers = [{
188
+ urls: 'stun:stun.l.google.com:19302' // Google's public STUN server
189
+ }, {
190
+ urls: "stun:openrelay.metered.ca:80",
191
+ }, {
192
+ urls: "turn:openrelay.metered.ca:443",
193
+ username: "openrelayproject",
194
+ credential: "openrelayproject",
195
+ }, {
196
+ urls: "turn:openrelay.metered.ca:443?transport=tcp",
197
+ username: "openrelayproject",
198
+ credential: "openrelayproject",
199
+ }];
200
+
201
+ this.#connection = new wrtc.RTCPeerConnection({iceServers});
202
+
203
+ this.#connection.onicecandidate = ({ candidate }) => {
204
+ if (candidate) {
205
+ this.address = candidate.address;
206
+ this.port = candidate.port;
207
+ this.protocol = candidate.protocol;
208
+ this.ipFamily = this.address.includes('::') ? 'ipv6': 'ipv4';
209
+ this._sendMessage({candidate});
210
+ }
211
+ };
212
+ // if (this.initiator) this.#connection.onnegotiationneeded = () => {
213
+ // console.log('create offer');
214
+ this.#connection.ondatachannel = (message) => {
215
+ message.channel.onopen = () => {
216
+ this.#connected = true;
217
+ // debug(`peer:connected ${this}`)
218
+ pubsub.publish('peer:connected', this);
219
+ };
220
+ message.channel.onclose = () => this.close.bind(this);
221
+
222
+ message.channel.onmessage = (message) => {
223
+ this._handleMessage(this.id, message);
224
+ };
225
+ this.#channel = message.channel;
226
+ };
227
+ if (this.initiator) {
228
+
229
+ this.#channel = this.#connection.createDataChannel('messageChannel');
230
+ this.#channel.onopen = () => {
231
+ this.#connected = true;
232
+ pubsub.publish('peer:connected', this);
233
+ // this.#channel.send('hi')
234
+ };
235
+ this.#channel.onclose = () => this.close.bind(this);
236
+
237
+ this.#channel.onmessage = (message) => {
238
+ this._handleMessage(this.peerId, message);
239
+ };
240
+
241
+ const offer = await this.#connection.createOffer();
242
+ await this.#connection.setLocalDescription(offer);
243
+
244
+ this._sendMessage({'sdp': this.#connection.localDescription});
245
+ }
246
+ } catch (e) {
247
+ console.log(e);
248
+ }
249
+
250
+ return this
251
+ }
252
+
253
+ _handleMessage(peerId, message) {
254
+ // debug(`incoming message from ${peerId}`)
255
+
256
+ message = JSON.parse(new TextDecoder().decode(message.data));
257
+ // allow sharding (multiple peers share data)
258
+ pubsub.publish('peernet:shard', message);
259
+ const { id } = message;
260
+
261
+ if (!this.#chunksQue[id]) this.#chunksQue[id] = [];
262
+
263
+ if (message.size > this.#chunksQue[id].length || message.size === this.#chunksQue[id].length) {
264
+ for (const value of Object.values(message.chunk)) {
265
+ this.#chunksQue[id].push(value);
266
+ }
267
+ }
268
+
269
+ if (message.size === this.#chunksQue[id].length) {
270
+ let data = new Uint8Array(Object.values(this.#chunksQue[id]));
271
+ delete this.#chunksQue[id];
272
+ data = pako.inflate(data);
273
+ pubsub.publish('peer:data', { id, data, from: this.peerId });
274
+ }
275
+ this.bw.down += message.byteLength || message.length;
276
+ }
277
+
278
+ _sendMessage(message) {
279
+ this.socketClient.send({url: 'signal', params: {
280
+ to: this.to,
281
+ from: this.id,
282
+ channelName: this.options.channelName,
283
+ ...message
284
+ }});
285
+ }
286
+
287
+ async _in(message, data) {
288
+ // message = JSON.parse(message);
289
+ if (!this.#connection || message.to !== this.id || message.from !== this.#peerId) return
290
+ // if (data.videocall) return this._startStream(true, false); // start video and audio stream
291
+ // if (data.call) return this._startStream(true, true); // start audio stream
292
+ if (this.#connection?.signalinState === 'stable' && this.#connection?.remoteDescription !== null && this.#connection?.localDescription !== null) return
293
+
294
+
295
+ if (message.candidate) {
296
+ // debug(`incoming candidate ${this.#channelName}`)
297
+ // debug(message.candidate.candidate)
298
+ this.remoteAddress = message.candidate.address;
299
+ this.remotePort = message.candidate.port;
300
+ this.remoteProtocol = message.candidate.protocol;
301
+ this.remoteIpFamily = this.remoteAddress?.includes('::') ? 'ipv6': 'ipv4';
302
+ return this.#connection.addIceCandidate(new wrtc.RTCIceCandidate(message.candidate));
303
+ }
304
+ try {
305
+ if (message.sdp) {
306
+ if (message.sdp.type === 'offer') {
307
+ // debug(`incoming offer ${this.#channelName}`)
308
+ await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
309
+ const answer = await this.#connection.createAnswer();
310
+ await this.#connection.setLocalDescription(answer);
311
+ this._sendMessage({'sdp': this.#connection.localDescription});
312
+ }
313
+ if (message.sdp.type === 'answer') {
314
+ // debug(`incoming answer ${this.#channelName}`)
315
+ await this.#connection.setRemoteDescription(new wrtc.RTCSessionDescription(message.sdp));
316
+ }
317
+ }
318
+ } catch (e) {
319
+ console.log(e);
320
+ }
321
+ }
322
+
323
+ close() {
324
+ // debug(`closing ${this.peerId}`)
325
+ this.#connected = false;
326
+ this.#channel?.close();
327
+ this.#connection?.close();
328
+
329
+ this.socketClient.pubsub.unsubscribe('signal', this._in);
330
+ }
331
+ }
332
+
333
+ class Client {
334
+ #peerConnection
335
+ #connections = {}
336
+ #stars = {}
337
+
338
+ get connections() {
339
+ return { ...this.#connections }
340
+ }
341
+
342
+ get peers() {
343
+ return Object.entries(this.#connections)
344
+ }
345
+
346
+ constructor(id, networkVersion = 'peach', stars = ['wss://peach.leofcoin.org']) {
347
+ this.id = id || Math.random().toString(36).slice(-12);
348
+ this.peerJoined = this.peerJoined.bind(this);
349
+ this.peerLeft = this.peerLeft.bind(this);
350
+ this.starLeft = this.starLeft.bind(this);
351
+ this.starJoined = this.starJoined.bind(this);
352
+ this.networkVersion = networkVersion;
353
+
354
+ this._init(stars);
355
+ }
356
+
357
+ async _init(stars = []) {
358
+ this.starsConfig = stars;
359
+ // reconnectJob()
360
+
361
+ if (!globalThis.RTCPeerConnection) globalThis.wrtc = await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace$1(require(/* webpackChunkName: "wrtc" */ '@koush/wrtc')); });
362
+ else globalThis.wrtc = {
363
+ RTCPeerConnection,
364
+ RTCSessionDescription,
365
+ RTCIceCandidate
366
+ };
367
+
368
+ for (const star of stars) {
369
+ try {
370
+ this.socketClient = await SocketClient__default["default"](star, this.networkVersion);
371
+ const id = await this.socketClient.request({url: 'id', params: {from: this.id}});
372
+ this.socketClient.peerId = id;
373
+ this.#stars[id] = this.socketClient;
374
+ } catch (e) {
375
+ if (stars.indexOf(star) === stars.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
376
+ }
377
+ }
378
+ const peers = await this.socketClient.peernet.join({id: this.id});
379
+ for (const id of peers) {
380
+ if (id !== this.id && !this.#connections[id]) this.#connections[id] = await new Peer({channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
381
+ }
382
+ this.setupListeners();
383
+ }
384
+
385
+ setupListeners() {
386
+ this.socketClient.subscribe('peer:joined', this.peerJoined);
387
+ this.socketClient.subscribe('peer:left', this.peerLeft);
388
+ this.socketClient.subscribe('star:left', this.starLeft);
389
+ }
390
+
391
+ starJoined(id) {
392
+ if (this.#stars[id]) {
393
+ this.#stars[id].close();
394
+ delete this.#stars[id];
395
+ }
396
+ console.log(`star ${id} joined`);
397
+ }
398
+
399
+ async starLeft(id) {
400
+ if (this.#stars[id]) {
401
+ this.#stars[id].close();
402
+ delete this.#stars[id];
403
+ }
404
+ if (this.socketClient?.peerId === id) {
405
+
406
+ this.socketClient.unsubscribe('peer:joined', this.peerJoined);
407
+ this.socketClient.unsubscribe('peer:left', this.peerLeft);
408
+ this.socketClient.unsubscribe('star:left', this.starLeft);
409
+ this.socketClient.close();
410
+ this.socketClient = undefined;
411
+
412
+ for (const star of this.starsConfig) {
413
+ try {
414
+ this.socketClient = await SocketClient__default["default"](star, this.networkVersion);
415
+ if (!this.socketClient?.client?._connection.connected) return
416
+ const id = await this.socketClient.request({url: 'id', params: {from: this.id}});
417
+ this.#stars[id] = this.socketClient;
418
+
419
+ this.socketClient.peerId = id;
420
+
421
+ const peers = await this.socketClient.peernet.join({id: this.id});
422
+ this.setupListeners();
423
+ for (const id of peers) {
424
+ if (id !== this.id) {
425
+ // close connection
426
+ if (this.#connections[id]) {
427
+ if (this.#connections[id].connected) await this.#connections[id].close();
428
+ delete this.#connections[id];
429
+ }
430
+ // reconnect
431
+ if (id !== this.id) this.#connections[id] = await new Peer({channelName: `${id}:${this.id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
432
+ }
433
+
434
+ }
435
+ } catch (e) {
436
+ console.log(e);
437
+ if (this.starsConfig.indexOf(star) === this.starsConfig.length -1 && !this.socketClient) throw new Error(`No star available to connect`);
438
+ }
439
+ }
440
+ }
441
+ debug(`star ${id} left`);
442
+ }
443
+
444
+ peerLeft(peer) {
445
+ const id = peer.peerId || peer;
446
+ if (this.#connections[id]) {
447
+ this.#connections[id].close();
448
+ delete this.#connections[id];
449
+ }
450
+ debug(`peer ${id} left`);
451
+ }
452
+
453
+ async peerJoined(peer, signal) {
454
+ const id = peer.peerId || peer;
455
+ if (this.#connections[id]) {
456
+ if (this.#connections[id].connected) this.#connections[id].close();
457
+ delete this.#connections[id];
458
+ }
459
+ // RTCPeerConnection
460
+ this.#connections[id] = await new Peer({initiator: true, channelName: `${this.id}:${id}`, socketClient: this.socketClient, id: this.id, to: id, peerId: id});
461
+ debug(`peer ${id} joined`);
462
+ }
463
+
464
+ removePeer(peer) {
465
+ const id = peer.peerId || peer;
466
+ if (this.#connections[id]) {
467
+ this.#connections[id].connected && this.#connections[id].close();
468
+ delete this.#connections[id];
469
+ }
470
+ debug(`peer ${id} removed`);
471
+ }
472
+
473
+ async close() {
474
+
475
+ this.socketClient.unsubscribe('peer:joined', this.peerJoined);
476
+ this.socketClient.unsubscribe('peer:left', this.peerLeft);
477
+ this.socketClient.unsubscribe('star:left', this.starLeft);
478
+
479
+ const promises = [
480
+ Object.values(this.#connections).map(connection => connection.close()),
481
+ Object.values(this.#stars).map(connection => connection.close()),
482
+ this.socketClient.close()
483
+ ];
484
+
485
+ return Promise.allSettled(promises)
486
+
487
+ }
488
+
489
+ }
490
+
491
+ module.exports = Client;