trac-peer 0.1.57 → 0.1.59

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "trac-peer",
3
3
  "main": "src/index.js",
4
- "version": "0.1.57",
4
+ "version": "0.1.59",
5
5
  "type": "module",
6
6
  "dependencies": {
7
7
  "assert": "npm:bare-node-assert",
@@ -37,6 +37,7 @@
37
37
  "brittle": "3.0.0",
38
38
  "buffer": "npm:bare-node-buffer",
39
39
  "child_process": "npm:bare-node-child-process",
40
+ "compact-encoding": "^2.16.1",
40
41
  "console": "npm:bare-node-console",
41
42
  "corestore": "7.4.1",
42
43
  "crypto": "npm:bare-node-crypto",
@@ -60,6 +61,7 @@
60
61
  "path": "npm:bare-node-path",
61
62
  "pear-interface": "1.0.0",
62
63
  "process": "npm:bare-node-process",
64
+ "protomux": "^3.10.1",
63
65
  "protomux-wakeup": "^2.2.1",
64
66
  "readline": "npm:bare-node-readline",
65
67
  "ready-resource": "^1.0.0",
package/src/api.js CHANGED
@@ -2,6 +2,14 @@ import b4a from "b4a";
2
2
  import {jsonStringify} from "./functions.js";
3
3
 
4
4
  export class ProtocolApi{
5
+
6
+ /**
7
+ * Exposes read and write functions.
8
+ * May be extended by contract protocol instances.
9
+ *
10
+ * @param peer
11
+ * @param options
12
+ */
5
13
  constructor(peer, options = {}) {
6
14
  this.peer = peer;
7
15
  this.api_tx_exposed = options.api_tx_exposed === true;
@@ -9,30 +17,57 @@ export class ProtocolApi{
9
17
  this.options = options;
10
18
  }
11
19
 
20
+ /**
21
+ *
22
+ * @returns {null|string}
23
+ */
12
24
  getPeerValidatorAddress(){
13
- return this.peer.validator;
25
+ return this.peer.msb.getNetwork().validator;
14
26
  }
15
27
 
28
+ /**
29
+ *
30
+ * @returns {null|string}
31
+ */
16
32
  getPeerBootstrap(){
17
33
  return this.peer.bootstrap;
18
34
  }
19
35
 
36
+ /**
37
+ *
38
+ * @returns {null|string}
39
+ */
20
40
  getPeerMsbBootstrap(){
21
41
  return this.peer.msb.bootstrap;
22
42
  }
23
43
 
44
+ /**
45
+ *
46
+ * @returns {null|string}
47
+ */
24
48
  getPeerWriterKey(){
25
49
  return this.peer.writerLocalKey;
26
50
  }
27
51
 
52
+ /**
53
+ *
54
+ * @returns {string}
55
+ */
28
56
  generateNonce(){
29
57
  return this.peer.protocol_instance.generateNonce();
30
58
  }
31
59
 
32
- async prepareMessage(msg, address, reply_to = null, attachments = []){
60
+ /**
61
+ * @throws Error
62
+ * @param msg
63
+ * @param address
64
+ * @param reply_to
65
+ * @param attachments
66
+ * @returns {{dispatch: {type: string, msg: string, address, attachments: *[], deleted_by: null, reply_to: (number|null), pinned: boolean, pin_id: null}}}
67
+ */
68
+ prepareMessage(msg, address, reply_to = null, attachments = []){
33
69
  if(typeof msg !== 'string') throw new Error('Msg must be a string');
34
- if(b4a.byteLength(jsonStringify(address)) > 64) throw new Error('Address too large.');
35
- if(b4a.byteLength(jsonStringify(reply_to)) > 256) throw new Error('Reply to too large.');
70
+ if(b4a.byteLength(jsonStringify(address)) !== 66) throw new Error('Address too large.');
36
71
  if(reply_to !== null && isNaN(parseInt(reply_to))) throw new Error('Reply to not a number.');
37
72
  if(false === Array.isArray(attachments)) throw new Error('attachments must be an array.');
38
73
  if(attachments.length > 20) throw new Error('Too many attachments');
@@ -54,8 +89,36 @@ export class ProtocolApi{
54
89
  return prepared;
55
90
  }
56
91
 
92
+ /**
93
+ *
94
+ * @returns {boolean}
95
+ */
96
+ msgExposed(){
97
+ return true === this.api_msg_exposed;
98
+ }
99
+
100
+ /**
101
+ * To post a message, an ed25519 signature has to be provided over the given message + nonce.
102
+ *
103
+ * Signing steps:
104
+ *
105
+ * let address = your_ed25519_wallet.getAccountAddress()
106
+ * let nonce = api.generateNonce()
107
+ * let prepared_message = api.prepareMessage("my message", address)
108
+ * let signature = your_ed25519_wallet.sign(JSON.stringify(prepared_message) + nonce)
109
+ * let result = api.post(prepared_message, signature, nonce)
110
+ *
111
+ * Note: new messages can be read from this api's msg functions.
112
+ *
113
+ * @throws Error
114
+ * @param prepared_message
115
+ * @param signature
116
+ * @param nonce
117
+ * @returns {Promise<void>}
118
+ */
57
119
  async post(prepared_message, signature, nonce){
58
- if(false === this.api_msg_exposed) throw new Error('Posting messages not exposed in API.');
120
+ if(true !== this.api_msg_exposed) throw new Error('Posting messages not exposed in API.');
121
+ if(this.peer.base.writable === false) throw new Error('Peer is not writable.');
59
122
  if(b4a.byteLength(jsonStringify(prepared_message)) > this.peer.protocol_instance.msgMaxBytes()) throw new Error('Prepared message too large.');
60
123
  if(typeof prepared_message !== 'object') throw new Error('Prepared message must be an object generated with api.prepareMessage().');
61
124
  if(prepared_message.dispatch === undefined || prepared_message.dispatch.type === undefined ||
@@ -66,6 +129,8 @@ export class ProtocolApi{
66
129
  if(prepared_message.dispatch.type !== 'msg') throw new Error('Invalid type.');
67
130
  if(typeof prepared_message.dispatch.msg !== 'string') throw new Error('Msg must be a string');
68
131
  if(b4a.toString(b4a.from(prepared_message.dispatch.address, 'hex'), 'hex') !== prepared_message.dispatch.address) throw new Error('Invalid address.');
132
+ if(b4a.toString(b4a.from(signature, 'hex'), 'hex') !== signature) throw new Error('Invalid signature.');
133
+ if(b4a.toString(b4a.from(nonce, 'hex'), 'hex') !== nonce) throw new Error('Invalid nonce.');
69
134
  if(false === Array.isArray(prepared_message.dispatch.attachments)) throw new Error('attachments must be an array.');
70
135
  if(prepared_message.dispatch.attachments.length > 20) throw new Error('Too many attachments');
71
136
  for(let i = 0; i < prepared_message.dispatch.attachments.length; i++){
@@ -80,25 +145,52 @@ export class ProtocolApi{
80
145
  await this.peer.base.append({type: 'msg', value: prepared_message, hash : signature, nonce: nonce });
81
146
  }
82
147
 
148
+ /**
149
+ * @throws Error
150
+ * @param address
151
+ * @param command_hash
152
+ * @param nonce
153
+ * @returns {Promise<*>}
154
+ */
83
155
  async generateTx(address, command_hash, nonce) {
156
+ if(this.getPeerValidatorAddress() === null) throw new Error('Peer not connected to a validator.');
84
157
  return await this.peer.protocol_instance.generateTx(this.getPeerBootstrap(),
85
158
  this.getPeerMsbBootstrap(), this.getPeerValidatorAddress(), this.getPeerWriterKey(),
86
159
  address, command_hash, nonce);
87
160
  }
88
161
 
162
+ /**
163
+ *
164
+ * @param command
165
+ * @returns {*}
166
+ */
89
167
  prepareTxCommand(command){
90
168
  return this.peer.protocol_instance.mapTxCommand(command);
91
169
  }
92
170
 
93
171
  /**
94
- * To pass a TX, an ed25519 signature has to be provided over the given tx + nonce.
172
+ *
173
+ * @returns {boolean}
174
+ */
175
+ txExposed(){
176
+ return true === this.api_tx_exposed;
177
+ }
178
+
179
+ /**
180
+ * To broadcast a TX, an ed25519 signature has to be provided over the given tx + nonce.
95
181
  *
96
182
  * Signing steps:
183
+ *
184
+ * let address = your_ed25519_wallet.getAccountAddress()
97
185
  * let nonce = api.generateNonce()
98
186
  * let tx_hash = api.generateTx(address, a_sha256_function(JSON.stringify(api.prepareTxCommand(command))), nonce)
99
- * let signature = your_ed25519_sign_lib.sign(tx + nonce, address)
100
- * api.tx(tx_hash, api.prepareTxCommand(command), address, signature, nonce)
187
+ * let signature = your_ed25519_wallet.sign(tx + nonce)
188
+ * // simulating
189
+ * let sim_result = api.tx(tx_hash, api.prepareTxCommand(command), address, signature, nonce, true)
190
+ * // broadcasting
191
+ * let result = api.tx(tx_hash, api.prepareTxCommand(command), address, signature, nonce)
101
192
  *
193
+ * @throws Error
102
194
  * @param tx
103
195
  * @param prepared_command
104
196
  * @param address
@@ -108,18 +200,19 @@ export class ProtocolApi{
108
200
  * @returns {Promise<boolean|object>}
109
201
  */
110
202
  async tx(tx, prepared_command, address, signature, nonce, sim = false ){
111
- if(false === this.api_tx_exposed) throw new Error('Transactions not exposed in API.');
203
+ if(true !== this.api_tx_exposed) throw new Error('Transactions not exposed in API.');
204
+ if(this.peer.base.writable === false) throw new Error('Peer is not writable.');
112
205
  if(this.getPeerValidatorAddress() === null) throw new Error('Peer not connected to a validator.');
113
206
  if(typeof prepared_command !== 'object') throw new Error('prepared_command must be an object.');
114
207
  if(typeof prepared_command.type !== 'string') throw new Error('prepared_command.type must exist and be a string.');
115
208
  if(prepared_command.value === undefined) throw new Error('prepared_command.value is missing.');
116
209
  if(b4a.byteLength(jsonStringify(prepared_command)) > this.peer.protocol_instance.txMaxBytes()) throw new Error('prepared_command too large.');
117
- if(b4a.byteLength(jsonStringify(address)) !== 64) throw new Error('Address length invalid.');
118
- if(b4a.byteLength(jsonStringify(signature)) !== 128) throw new Error('Signature length invalid.');
119
- if(b4a.byteLength(jsonStringify(nonce)) !== 64) throw new Error('Nonce length invalid.');
120
- if(b4a.toString(b4a.from(signature, 'utf8'), 'hex') !== signature) throw new Error('Invalid signature.');
121
- if(b4a.toString(b4a.from(address, 'utf8'), 'hex') !== address) throw new Error('Invalid address.');
122
- if(b4a.toString(b4a.from(nonce, 'utf8'), 'hex') !== nonce) throw new Error('Invalid nonce.');
210
+ if(b4a.byteLength(jsonStringify(address)) !== 66) throw new Error('Address length invalid.');
211
+ if(b4a.byteLength(jsonStringify(signature)) !== 130) throw new Error('Signature length invalid.');
212
+ if(b4a.byteLength(jsonStringify(nonce)) !== 66) throw new Error('Nonce length invalid.');
213
+ if(b4a.toString(b4a.from(address, 'hex'), 'hex') !== address) throw new Error('Invalid address.');
214
+ if(b4a.toString(b4a.from(signature, 'hex'), 'hex') !== signature) throw new Error('Invalid signature.');
215
+ if(b4a.toString(b4a.from(nonce, 'hex'), 'hex') !== nonce) throw new Error('Invalid nonce.');
123
216
  const verified = this.peer.wallet.verify(signature, tx + nonce, address);
124
217
  if(false === verified) throw new Error('Invalid signature.');
125
218
  const content_hash = await this.peer.createHash('sha256', this.peer.protocol_instance.safeJsonStringify(prepared_command));
@@ -140,6 +233,11 @@ export class ProtocolApi{
140
233
  return res;
141
234
  }
142
235
 
236
+ /**
237
+ *
238
+ * @param signed
239
+ * @returns {Promise<null>}
240
+ */
143
241
  async getAdmin(signed = true){
144
242
  let res = null;
145
243
  if(true === signed) res = await this.peer.protocol_instance.getSigned('admin');
@@ -148,6 +246,11 @@ export class ProtocolApi{
148
246
  return null;
149
247
  }
150
248
 
249
+ /**
250
+ *
251
+ * @param signed
252
+ * @returns {Promise<boolean|null>}
253
+ */
151
254
  async getWhitelistEnabled(signed = true){
152
255
  let res = null;
153
256
  if(true === signed) res = await this.peer.protocol_instance.getSigned('wlst');
@@ -156,6 +259,12 @@ export class ProtocolApi{
156
259
  return false;
157
260
  }
158
261
 
262
+ /**
263
+ *
264
+ * @param address
265
+ * @param signed
266
+ * @returns {Promise<boolean|null>}
267
+ */
159
268
  async getWhitelistStatus(address, signed = true){
160
269
  let res = null;
161
270
  if(true === signed) res = await this.peer.protocol_instance.getSigned('wl/'+address);
@@ -164,6 +273,12 @@ export class ProtocolApi{
164
273
  return false;
165
274
  }
166
275
 
276
+ /**
277
+ *
278
+ * @param address
279
+ * @param signed
280
+ * @returns {Promise<boolean|null>}
281
+ */
167
282
  async getModStatus(address, signed = true){
168
283
  let res = null;
169
284
  if(true === signed) res = await this.peer.protocol_instance.getSigned('mod/'+address);
@@ -172,6 +287,12 @@ export class ProtocolApi{
172
287
  return false;
173
288
  }
174
289
 
290
+ /**
291
+ *
292
+ * @param address
293
+ * @param signed
294
+ * @returns {Promise<boolean|null>}
295
+ */
175
296
  async getMuteStatus(address, signed = true){
176
297
  let res = null;
177
298
  if(true === signed) res = await this.peer.protocol_instance.getSigned('mtd/'+address);
@@ -180,6 +301,11 @@ export class ProtocolApi{
180
301
  return false;
181
302
  }
182
303
 
304
+ /**
305
+ *
306
+ * @param signed
307
+ * @returns {Promise<boolean>}
308
+ */
183
309
  async getAutoAddWritersStatus(signed = true){
184
310
  let res = null;
185
311
  if(true === signed) res = await this.peer.protocol_instance.getSigned('auto_add_writers');
@@ -190,6 +316,11 @@ export class ProtocolApi{
190
316
  return false;
191
317
  }
192
318
 
319
+ /**
320
+ *
321
+ * @param signed
322
+ * @returns {Promise<boolean>}
323
+ */
193
324
  async getChatStatus(signed = true){
194
325
  let res = null;
195
326
  if(true === signed) res = await this.peer.protocol_instance.getSigned('chat_status');
@@ -200,6 +331,12 @@ export class ProtocolApi{
200
331
  return false;
201
332
  }
202
333
 
334
+ /**
335
+ *
336
+ * @param nick
337
+ * @param signed
338
+ * @returns {Promise<null>}
339
+ */
203
340
  async getAddressFromNick(nick, signed = true){
204
341
  let res = null;
205
342
  if(true === signed) res = await this.peer.protocol_instance.getSigned('kcin/'+nick);
@@ -207,6 +344,12 @@ export class ProtocolApi{
207
344
  return res;
208
345
  }
209
346
 
347
+ /**
348
+ *
349
+ * @param address
350
+ * @param signed
351
+ * @returns {Promise<null>}
352
+ */
210
353
  async getNick(address, signed = true){
211
354
  let res = null;
212
355
  if(true === signed) res = await this.peer.protocol_instance.getSigned('nick/'+address);
@@ -214,6 +357,11 @@ export class ProtocolApi{
214
357
  return res;
215
358
  }
216
359
 
360
+ /**
361
+ *
362
+ * @param signed
363
+ * @returns {Promise<number>}
364
+ */
217
365
  async getPinnedMessageLength(signed = true){
218
366
  let res = null;
219
367
  if(true === signed) res = await this.peer.protocol_instance.getSigned('pnl');
@@ -222,6 +370,12 @@ export class ProtocolApi{
222
370
  return res;
223
371
  }
224
372
 
373
+ /**
374
+ *
375
+ * @param index
376
+ * @param signed
377
+ * @returns {Promise<null>}
378
+ */
225
379
  async getPinnedMessage(index, signed = true){
226
380
  let res = null;
227
381
  if(true === signed) res = await this.peer.protocol_instance.getSigned('pni/'+parseInt(index));
@@ -232,6 +386,11 @@ export class ProtocolApi{
232
386
  return await this.getMessage(res.msg, signed);
233
387
  }
234
388
 
389
+ /**
390
+ *
391
+ * @param signed
392
+ * @returns {Promise<number>}
393
+ */
235
394
  async getDeletedMessageLength(signed = true){
236
395
  let res = null;
237
396
  if(true === signed) res = await this.peer.protocol_instance.getSigned('delml');
@@ -240,6 +399,12 @@ export class ProtocolApi{
240
399
  return res;
241
400
  }
242
401
 
402
+ /**
403
+ *
404
+ * @param index
405
+ * @param signed
406
+ * @returns {Promise<null>}
407
+ */
243
408
  async getDeletedMessage(index, signed = true){
244
409
  let res = null;
245
410
  if(true === signed) res = await this.peer.protocol_instance.getSigned('delm/'+parseInt(index));
@@ -250,6 +415,11 @@ export class ProtocolApi{
250
415
  return await this.getMessage(res, signed);
251
416
  }
252
417
 
418
+ /**
419
+ *
420
+ * @param signed
421
+ * @returns {Promise<number>}
422
+ */
253
423
  async getMessageLength(signed = true){
254
424
  let res = null;
255
425
  if(true === signed) res = await this.peer.protocol_instance.getSigned('msgl');
@@ -258,6 +428,12 @@ export class ProtocolApi{
258
428
  return res;
259
429
  }
260
430
 
431
+ /**
432
+ *
433
+ * @param index
434
+ * @param signed
435
+ * @returns {Promise<null>}
436
+ */
261
437
  async getMessage(index, signed = true){
262
438
  let res = null;
263
439
  if(true === signed) res = await this.peer.protocol_instance.getSigned('msg/'+parseInt(index));
@@ -265,6 +441,12 @@ export class ProtocolApi{
265
441
  return res;
266
442
  }
267
443
 
444
+ /**
445
+ *
446
+ * @param address
447
+ * @param signed
448
+ * @returns {Promise<number>}
449
+ */
268
450
  async getUserMessageLength(address, signed = true){
269
451
  let res = null;
270
452
  if(true === signed) res = await this.peer.protocol_instance.getSigned('umsgl/'+address);
@@ -273,6 +455,13 @@ export class ProtocolApi{
273
455
  return res;
274
456
  }
275
457
 
458
+ /**
459
+ *
460
+ * @param address
461
+ * @param index
462
+ * @param signed
463
+ * @returns {Promise<null>}
464
+ */
276
465
  async getUserMessage(address, index, signed = true){
277
466
  let res = null;
278
467
  if(true === signed) res = await this.peer.protocol_instance.getSigned('umsg/'+address+'/'+parseInt(index));
@@ -283,6 +472,11 @@ export class ProtocolApi{
283
472
  return await this.getMessage(res, signed);
284
473
  }
285
474
 
475
+ /**
476
+ *
477
+ * @param signed
478
+ * @returns {Promise<number>}
479
+ */
286
480
  async getTxLength(signed = true){
287
481
  let res = null;
288
482
  if(true === signed) res = await this.peer.protocol_instance.getSigned('txl');
@@ -291,6 +485,12 @@ export class ProtocolApi{
291
485
  return res;
292
486
  }
293
487
 
488
+ /**
489
+ *
490
+ * @param index
491
+ * @param signed
492
+ * @returns {Promise<null>}
493
+ */
294
494
  async getTx(index, signed = true){
295
495
  let res = null;
296
496
  if(true === signed) res = await this.peer.protocol_instance.getSigned('txi/'+parseInt(index));
@@ -298,6 +498,12 @@ export class ProtocolApi{
298
498
  return res;
299
499
  }
300
500
 
501
+ /**
502
+ *
503
+ * @param tx
504
+ * @param signed
505
+ * @returns {Promise<null>}
506
+ */
301
507
  async getTxData(tx, signed = true){
302
508
  let index = null;
303
509
  if(true === signed) index = await this.peer.protocol_instance.getSigned('tx/'+tx);
@@ -308,6 +514,12 @@ export class ProtocolApi{
308
514
  return null;
309
515
  }
310
516
 
517
+ /**
518
+ *
519
+ * @param address
520
+ * @param signed
521
+ * @returns {Promise<number>}
522
+ */
311
523
  async getUserTxLength(address, signed = true){
312
524
  let res = null;
313
525
  if(true === signed) res = await this.peer.protocol_instance.getSigned('utxl/'+address);
@@ -316,6 +528,13 @@ export class ProtocolApi{
316
528
  return res;
317
529
  }
318
530
 
531
+ /**
532
+ *
533
+ * @param address
534
+ * @param index
535
+ * @param signed
536
+ * @returns {Promise<null>}
537
+ */
319
538
  async getUserTx(address, index, signed = true){
320
539
  let res = null;
321
540
  if(true === signed) res = await this.peer.protocol_instance.getSigned('utxi/'+address+'/'+parseInt(index));
package/src/functions.js CHANGED
@@ -341,40 +341,7 @@ export async function joinValidator(input, peer){
341
341
  if(validator === null || false === validator.value.isWriter || true === validator.value.isIndexer){
342
342
  throw new Error('Invalid validator address.');
343
343
  }
344
- const result = await peer.isValidatorAvailable(address);
345
- if(result === null) {
346
- console.log('Validator not available');
347
- } else {
348
- let existing_stream = undefined;
349
- if(peer.msb.getSwarm().peers.has(address)){
350
- const peerInfo = peer.msb.getSwarm().peers.get(address)
351
- existing_stream = peer.msb.getSwarm()._allConnections.get(peerInfo.publicKey)
352
- }
353
- if(existing_stream !== undefined){
354
- peer.validator_stream = existing_stream;
355
- peer.validator = address;
356
- peer.validator_stream.on('close', () => {
357
- peer.validator_stream = null;
358
- peer.validator = null;
359
- console.log('Validator stream closed', address);
360
- });
361
- console.log('Validator stream established', address);
362
- } else {
363
- peer.validator_stream = peer.msb.getSwarm().dht.connect(b4a.from(address, 'hex'));
364
- peer.validator = address;
365
- peer.validator_stream.on('open', () => {
366
- console.log('Validator stream established', address);
367
- });
368
- peer.validator_stream.on('close', () => {
369
- peer.validator_stream = null;
370
- peer.validator = null;
371
- });
372
- peer.validator_stream.on('error', (error) => {
373
- peer.validator_stream = null;
374
- peer.validator = null;
375
- });
376
- }
377
- }
344
+ await peer.tryConnection(address);
378
345
  }
379
346
 
380
347
  export async function tx(input, peer){
@@ -382,7 +349,7 @@ export async function tx(input, peer){
382
349
  let res = false;
383
350
  if(splitted.command === undefined){
384
351
  res = new Error('Missing option. Please use the --command flag.');
385
- } else if(splitted.sim === undefined && peer.validator === null){
352
+ } else if(splitted.sim === undefined && peer.msb.getNetwork().validator === null){
386
353
  res = new Error('No validator available: Please wait for your peer to find an available one or use joinValidator to connect to a specific one.');
387
354
  }
388
355
  let sim = false;
package/src/index.js CHANGED
@@ -11,6 +11,8 @@ import Corestore from 'corestore';
11
11
  import w from 'protomux-wakeup';
12
12
  import BlindPairing from 'blind-pairing'
13
13
  const wakeup = new w();
14
+ import Protomux from 'protomux'
15
+ import c from 'compact-encoding'
14
16
  import {
15
17
  addWriter, addAdmin, setAutoAddWriters, setChatStatus, setMod, deleteMessage,
16
18
  enableWhitelist, postMessage, jsonStringify, visibleLength, setNick,
@@ -44,6 +46,7 @@ export class Peer extends ReadyResource {
44
46
  this.contract = options.contract || null;
45
47
  this.wallet = options.wallet || null;
46
48
  this.features = options.features || [];
49
+ this.custom_validators = options.custom_validators || [];
47
50
  this.protocol_instance = null;
48
51
  this.contract_instance = null;
49
52
  this.channel = b4a.alloc(32).fill(options.channel) || null;
@@ -56,8 +59,6 @@ export class Peer extends ReadyResource {
56
59
  this.check = new Check();
57
60
  this.dhtBootstrap = ['116.202.214.149:10001', '157.180.12.214:10001', 'node1.hyperdht.org:49737', 'node2.hyperdht.org:49737', 'node3.hyperdht.org:49737'];
58
61
  this.invite = null;
59
- this.validator = null;
60
- this.validator_stream = null;
61
62
  this.readline_instance = null;
62
63
  this.enable_interactive_mode = options.enable_interactive_mode !== false;
63
64
  if(this.enable_interactive_mode !== false){
@@ -506,69 +507,10 @@ export class Peer extends ReadyResource {
506
507
  }
507
508
 
508
509
  async sendTx(msg){
509
- if(this.validator_stream === null) return;
510
+ if(this.msb.getNetwork().validator_stream === null) return;
510
511
  let _msg = safeClone(msg);
511
512
  if(_msg['ts'] !== undefined) delete _msg['ts'];
512
- try{ await this.validator_stream.send(b4a.from(jsonStringify(_msg))); } catch(e){ }
513
- }
514
-
515
- async isValidatorAvailable(address){
516
- if(null === this.msb.getSwarm()) return null;
517
- let writer_key = null;
518
-
519
- this.msb.getSwarm().joinPeer(b4a.from(address, 'hex'))
520
-
521
- let existing_stream = undefined;
522
-
523
- if(this.msb.getSwarm().peers.has(address)){
524
- const peerInfo = this.msb.getSwarm().peers.get(address)
525
- existing_stream = this.msb.getSwarm()._allConnections.get(peerInfo.publicKey)
526
- }
527
-
528
- if(existing_stream !== undefined){
529
- existing_stream.on('message', (msg) => {
530
- try{
531
- const response = jsonParse(b4a.toString(msg, 'utf-8'));
532
- if(response.op === 'writer_key' && response.key !== undefined){
533
- writer_key = response.key;
534
- }
535
- }catch(e){}
536
- });
537
- existing_stream.on('open', function () { });
538
- existing_stream.on('close', () => { });
539
- existing_stream.on('error', (error) => { });
540
- await existing_stream.send(b4a.from(jsonStringify('get_writer_key')));
541
- let i = 0;
542
- while(null === writer_key){
543
- if(i >= 1_000) break;
544
- await this.sleep(10);
545
- i += 10;
546
- }
547
- return writer_key;
548
- } else {
549
- const stream = this.msb.getSwarm().dht.connect(b4a.from(address, 'hex'))
550
- stream.on('connect', async function () {
551
- await stream.send(b4a.from(jsonStringify('get_writer_key')));
552
- });
553
- stream.on('message', (msg) => {
554
- try{
555
- const response = jsonParse(b4a.toString(msg, 'utf-8'));
556
- if(response.op === 'writer_key' && response.key !== undefined){
557
- writer_key = response.key;
558
- }
559
- }catch(e){}
560
- });
561
- stream.on('open', function () { });
562
- stream.on('close', () => { });
563
- stream.on('error', (error) => { });
564
- let i = 0;
565
- while(null === writer_key){
566
- if(i >= 5_000) break;
567
- await this.sleep(10);
568
- i += 10;
569
- }
570
- return writer_key;
571
- }
513
+ try{ this.msb.getNetwork().validator_stream.messenger.send(_msg); } catch(e){ }
572
514
  }
573
515
 
574
516
  async _open() {
@@ -587,25 +529,6 @@ export class Peer extends ReadyResource {
587
529
  }
588
530
  });
589
531
  this.updater();
590
-
591
- // test
592
- const pins = this.protocol_instance;
593
- const command = '';
594
-
595
- const prepared_command = pins.api.prepareTxCommand(command);
596
- let nonce = pins.api.generateNonce();
597
-
598
- let tx_hash = pins.api.generateTx(
599
- this.wallet.publicKey, await this.createHash('sha256', JSON.stringify(prepared_command)), nonce
600
- )
601
-
602
- console.log('TX Hash', tx_hash)
603
-
604
- const signature = this.wallet.sign(tx_hash + nonce)
605
-
606
- const res = await pins.api.tx(tx_hash, prepared_command, this.wallet.publicKey, signature, nonce)
607
-
608
- console.log('TX Res', res)
609
532
  }
610
533
 
611
534
  async initContract(){
@@ -633,7 +556,7 @@ export class Peer extends ReadyResource {
633
556
 
634
557
  async validator_observer(){
635
558
  while(true){
636
- if(this.msb.getSwarm() !== null && this.validator_stream === null) {
559
+ if(this.msb.getSwarm() !== null && this.msb.getNetwork().validator_stream === null) {
637
560
  console.log('Looking for available validators, please wait...');
638
561
  const _this = this;
639
562
  let length = await this.msb.base.view.get('wrl');
@@ -642,50 +565,23 @@ export class Peer extends ReadyResource {
642
565
  } else {
643
566
  length = length.value;
644
567
  }
568
+ if(this.custom_validators.length !== 0){
569
+ length = this.custom_validators.length;
570
+ }
645
571
  async function findSome(){
646
- if(_this.validator_stream !== null) return;
572
+ if(_this.msb.getNetwork().validator_stream !== null) return;
647
573
  const rnd_index = Math.floor(Math.random() * length);
648
574
  let validator = await _this.msb.base.view.get('wri/' + rnd_index);
649
- if(_this.validator_stream !== null) return;
575
+ if(_this.custom_validators.length !== 0){
576
+ validator = { value : _this.custom_validators[rnd_index] };
577
+ console.log('Trying custom validator', validator.value);
578
+ }
579
+ if(_this.msb.getNetwork().validator_stream !== null) return;
650
580
  if (null !== validator) {
651
581
  validator = await _this.msb.base.view.get(validator.value);
652
- if(_this.validator_stream !== null) return;
582
+ if(_this.msb.getNetwork().validator_stream !== null) return;
653
583
  if(null !== validator && false !== validator.value.isWriter && false === validator.value.isIndexer) {
654
- const result = await _this.isValidatorAvailable(validator.value.pub);
655
- if(_this.validator_stream !== null) return;
656
- if (null !== result) {
657
- await _this.sleep(100);
658
- if(_this.validator_stream !== null) return;
659
- let existing_stream = undefined;
660
- if(_this.msb.getSwarm().peers.has(validator.value.pub)){
661
- const peerInfo = _this.msb.getSwarm().peers.get(validator.value.pub)
662
- existing_stream = _this.msb.getSwarm()._allConnections.get(peerInfo.publicKey)
663
- }
664
- if(existing_stream !== undefined){
665
- _this.validator_stream = existing_stream;
666
- _this.validator = validator.value.pub;
667
- _this.validator_stream.on('close', () => {
668
- _this.validator_stream = null;
669
- _this.validator = null;
670
- console.log('Validator stream closed', validator.value.pub);
671
- });
672
- console.log('Validator stream established', validator.value.pub);
673
- } else {
674
- _this.validator_stream = _this.msb.getSwarm().dht.connect(b4a.from(validator.value.pub, 'hex'));
675
- _this.validator = validator.value.pub;
676
- _this.validator_stream.on('open', () => {
677
- console.log('Validator stream established', validator.value.pub);
678
- });
679
- _this.validator_stream.on('close', () => {
680
- _this.validator_stream = null;
681
- _this.validator = null;
682
- });
683
- _this.validator_stream.on('error', (error) => {
684
- _this.validator_stream = null;
685
- _this.validator = null;
686
- });
687
- }
688
- }
584
+ await _this.msb.tryConnection(validator.value.pub, 'validator');
689
585
  }
690
586
  }
691
587
  }
package/src/protocol.js CHANGED
@@ -121,7 +121,7 @@ class Protocol{
121
121
  }
122
122
 
123
123
  async broadcastTransaction(validator_pub_key, obj, sim = false, surrogate = null){
124
- if(this.peer.validator_stream !== null &&
124
+ if(this.peer.msb.getNetwork().validator_stream !== null &&
125
125
  this.peer.wallet.publicKey !== null &&
126
126
  this.peer.wallet.secretKey !== null &&
127
127
  this.base.localWriter !== null &&
@@ -190,10 +190,10 @@ class Protocol{
190
190
  }
191
191
 
192
192
  async tx(subject, sim = false, surrogate = null){
193
- if(this.peer.validator_stream === null) throw new Error('HyperMallProtocol::tx(): No validator available.');
193
+ if(this.peer.msb.getNetwork().validator_stream === null) throw new Error('HyperMallProtocol::tx(): No validator available.');
194
194
  const obj = this.mapTxCommand(subject.command);
195
- if(null !== obj) {
196
- return await this.broadcastTransaction(this.peer.validator,{
195
+ if(null !== obj && typeof obj.type === 'string' && obj.value !== undefined) {
196
+ return await this.broadcastTransaction(this.peer.msb.getNetwork().validator,{
197
197
  type : obj.type,
198
198
  value : obj.value
199
199
  }, sim, surrogate);