@leofcoin/peernet 0.18.0 → 0.18.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 (82) hide show
  1. package/exports/browser/{client-13d9b3de.js → client-1c52a169.js} +1 -1
  2. package/exports/browser/dht/dht.d.ts +30 -0
  3. package/exports/browser/discovery/peer-discovery.d.ts +7 -0
  4. package/exports/browser/errors/errors.d.ts +3 -0
  5. package/exports/browser/handlers/data.d.ts +2 -0
  6. package/exports/browser/handlers/message.d.ts +30 -0
  7. package/exports/browser/{index-19803d3b.js → index-4a0fc4ea.js} +1 -1
  8. package/exports/browser/{index-73b8d9b9.js → index-639f2260.js} +2 -2
  9. package/exports/browser/messages/chat.d.ts +6 -0
  10. package/exports/browser/messages/data-response.d.ts +6 -0
  11. package/exports/browser/messages/data.d.ts +10 -0
  12. package/exports/browser/messages/dht-response.d.ts +6 -0
  13. package/exports/browser/messages/dht.d.ts +14 -0
  14. package/exports/browser/messages/file-link.d.ts +10 -0
  15. package/exports/browser/messages/file.d.ts +10 -0
  16. package/exports/browser/messages/peer-response.d.ts +6 -0
  17. package/exports/browser/messages/peer.d.ts +6 -0
  18. package/exports/browser/messages/peernet.d.ts +6 -0
  19. package/exports/browser/messages/ps.d.ts +6 -0
  20. package/exports/browser/messages/request.d.ts +6 -0
  21. package/exports/browser/messages/response.d.ts +6 -0
  22. package/exports/browser/messages-6db1f01d.js +204 -0
  23. package/exports/browser/messages.d.ts +12 -0
  24. package/exports/browser/peer-info.d.ts +4 -0
  25. package/exports/browser/{peernet-24ed8563.js → peernet-3b3933a5.js} +1100 -982
  26. package/exports/browser/peernet.js +1 -1
  27. package/exports/browser/proto/chat-message.proto.d.ts +7 -0
  28. package/exports/browser/proto/data-response.proto.d.ts +5 -0
  29. package/exports/browser/proto/data.proto.d.ts +5 -0
  30. package/exports/browser/proto/dht-response.proto.d.ts +5 -0
  31. package/exports/browser/proto/dht.proto.d.ts +5 -0
  32. package/exports/browser/proto/file-link.proto.d.ts +6 -0
  33. package/exports/browser/proto/file.proto.d.ts +6 -0
  34. package/exports/browser/proto/peer-response.proto.d.ts +4 -0
  35. package/exports/browser/proto/peer.proto.d.ts +4 -0
  36. package/exports/browser/proto/peernet.proto.d.ts +8 -0
  37. package/exports/browser/proto/ps.proto.d.ts +5 -0
  38. package/exports/browser/proto/request.proto.d.ts +4 -0
  39. package/exports/browser/proto/response.proto.d.ts +4 -0
  40. package/exports/browser/utils/utils.d.ts +7 -0
  41. package/exports/dht/dht.d.ts +30 -0
  42. package/exports/discovery/peer-discovery.d.ts +7 -0
  43. package/exports/errors/errors.d.ts +3 -0
  44. package/exports/handlers/data.d.ts +2 -0
  45. package/exports/handlers/message.d.ts +30 -0
  46. package/exports/messages/chat.d.ts +6 -0
  47. package/exports/messages/data-response.d.ts +6 -0
  48. package/exports/messages/data.d.ts +10 -0
  49. package/exports/messages/dht-response.d.ts +6 -0
  50. package/exports/messages/dht.d.ts +14 -0
  51. package/exports/messages/file-link.d.ts +10 -0
  52. package/exports/messages/file.d.ts +10 -0
  53. package/exports/messages/peer-response.d.ts +6 -0
  54. package/exports/messages/peer.d.ts +6 -0
  55. package/exports/messages/peernet.d.ts +6 -0
  56. package/exports/messages/ps.d.ts +6 -0
  57. package/exports/messages/request.d.ts +6 -0
  58. package/exports/messages/response.d.ts +6 -0
  59. package/exports/messages-ebdc8c69.js +203 -0
  60. package/exports/messages.d.ts +12 -0
  61. package/exports/peer-info.d.ts +4 -0
  62. package/exports/peernet.js +863 -930
  63. package/exports/proto/chat-message.proto.d.ts +7 -0
  64. package/exports/proto/data-response.proto.d.ts +5 -0
  65. package/exports/proto/data.proto.d.ts +5 -0
  66. package/exports/proto/dht-response.proto.d.ts +5 -0
  67. package/exports/proto/dht.proto.d.ts +5 -0
  68. package/exports/proto/file-link.proto.d.ts +6 -0
  69. package/exports/proto/file.proto.d.ts +6 -0
  70. package/exports/proto/peer-response.proto.d.ts +4 -0
  71. package/exports/proto/peer.proto.d.ts +4 -0
  72. package/exports/proto/peernet.proto.d.ts +8 -0
  73. package/exports/proto/ps.proto.d.ts +5 -0
  74. package/exports/proto/request.proto.d.ts +4 -0
  75. package/exports/proto/response.proto.d.ts +4 -0
  76. package/exports/utils/utils.d.ts +7 -0
  77. package/package.json +3 -2
  78. package/rollup.config.js +9 -3
  79. package/src/peernet.ts +26 -20
  80. package/tsconfig.json +3 -9
  81. package/exports/browser/messages-bb950ed7.js +0 -224
  82. package/exports/messages-d8852e16.js +0 -223
@@ -1268,6 +1268,22 @@ let BasicInterface$1 = class BasicInterface {
1268
1268
  decoded;
1269
1269
  keys;
1270
1270
  name;
1271
+ #proto;
1272
+ set proto(value) {
1273
+ this.#proto = value;
1274
+ this.keys = Object.keys(value);
1275
+ }
1276
+ get proto() {
1277
+ return this.#proto;
1278
+ }
1279
+ decode(encoded) {
1280
+ encoded = encoded || this.encoded;
1281
+ return new Object();
1282
+ }
1283
+ encode(decoded) {
1284
+ decoded = decoded || this.decoded;
1285
+ return new Uint8Array();
1286
+ }
1271
1287
  // get Codec(): Codec {}
1272
1288
  protoEncode(data) {
1273
1289
  // check schema
@@ -1287,12 +1303,10 @@ let BasicInterface$1 = class BasicInterface {
1287
1303
  return base58$1.isBase58(string);
1288
1304
  }
1289
1305
  fromBs32(encoded) {
1290
- this.encoded = index$7.decode(encoded);
1291
- return this.decode();
1306
+ return this.decode(index$7.decode(encoded));
1292
1307
  }
1293
1308
  fromBs58(encoded) {
1294
- this.encoded = fromBase58(encoded);
1295
- return this.decode();
1309
+ return this.decode(fromBase58(encoded));
1296
1310
  }
1297
1311
  async toArray() {
1298
1312
  const array = [];
@@ -1304,20 +1318,16 @@ let BasicInterface$1 = class BasicInterface {
1304
1318
  fromString(string) {
1305
1319
  const array = string.split(',');
1306
1320
  const arrayLike = array.map(string => Number(string));
1307
- this.encoded = Uint8Array.from(arrayLike);
1308
- return this.decode();
1321
+ return this.decode(Uint8Array.from(arrayLike));
1309
1322
  }
1310
1323
  fromHex(string) {
1311
- this.encoded = fromHex(string);
1312
- return this.decode();
1324
+ return this.decode(fromHex(string));
1313
1325
  }
1314
1326
  fromArray(array) {
1315
- this.encoded = Uint8Array.from([...array]);
1316
- return this.decode();
1327
+ return this.decode(Uint8Array.from([...array]));
1317
1328
  }
1318
1329
  fromEncoded(encoded) {
1319
- this.encoded = encoded;
1320
- return this.decode();
1330
+ return this.decode(encoded);
1321
1331
  }
1322
1332
  toString() {
1323
1333
  if (!this.encoded)
@@ -1327,7 +1337,7 @@ let BasicInterface$1 = class BasicInterface {
1327
1337
  toHex() {
1328
1338
  if (!this.encoded)
1329
1339
  this.encode();
1330
- return toHex(this.encoded);
1340
+ return toHex(this.encoded.toString().split(',').map(number => Number(number)));
1331
1341
  }
1332
1342
  /**
1333
1343
  * @return {String} encoded
@@ -1362,107 +1372,106 @@ let BasicInterface$1 = class BasicInterface {
1362
1372
  });
1363
1373
  }
1364
1374
  this.decoded = decoded;
1365
- return this.encode();
1375
+ return this.encode(decoded);
1366
1376
  }
1367
1377
  }
1368
1378
  };
1369
1379
 
1370
- var codecs = {
1380
+ var codecs$1 = {
1371
1381
  // just a hash
1372
1382
  'disco-hash': {
1373
- codec: parseInt('30', 16),
1383
+ codec: parseInt('0x30', 16),
1374
1384
  hashAlg: 'dbl-keccak-256', // ,
1375
1385
  // testnet: 'olivia'
1376
1386
  },
1377
1387
  'peernet-peer-response': {
1378
- codec: parseInt('707072', 16),
1388
+ codec: parseInt('0x707072', 16),
1379
1389
  hashAlg: 'keccak-256',
1380
1390
  },
1381
1391
  'peernet-peer': {
1382
- codec: parseInt('7070', 16),
1392
+ codec: parseInt('0x7070', 16),
1383
1393
  hashAlg: 'keccak-256',
1384
1394
  },
1385
1395
  'peernet-dht': {
1386
- codec: parseInt('706468', 16),
1396
+ codec: parseInt('0x706468', 16),
1387
1397
  hashAlg: 'keccak-256',
1388
1398
  },
1389
1399
  'peernet-dht-response': {
1390
- codec: parseInt('706472', 16),
1400
+ codec: parseInt('0x706472', 16),
1391
1401
  hashAlg: 'keccak-256',
1392
1402
  },
1393
1403
  // data
1394
1404
  'peernet-data': {
1395
- codec: parseInt('706461', 16),
1405
+ codec: parseInt('0x706461', 16),
1396
1406
  hashAlg: 'keccak-256',
1397
1407
  },
1398
1408
  'peernet-data-response': {
1399
- codec: parseInt('70646172', 16),
1409
+ codec: parseInt('0x70646172', 16),
1400
1410
  hashAlg: 'keccak-256',
1401
1411
  },
1402
1412
  // message
1403
1413
  'peernet-message': {
1404
- codec: parseInt('706d65', 16),
1414
+ codec: parseInt('0x706d65', 16),
1405
1415
  hashAlg: 'keccak-256',
1406
1416
  },
1407
1417
  // pubsub
1408
1418
  'peernet-ps': {
1409
- codec: parseInt('707073', 16),
1419
+ codec: parseInt('0x707073', 16),
1410
1420
  hashAlg: 'keccak-256',
1411
1421
  },
1412
1422
  'peernet-response': {
1413
- codec: parseInt('7072', 16),
1423
+ codec: parseInt('0x7072', 16),
1414
1424
  hashAlg: 'keccak-256',
1415
1425
  },
1416
1426
  'peernet-request': {
1417
- codec: parseInt('707271', 16),
1427
+ codec: parseInt('0x707271', 16),
1418
1428
  hashAlg: 'keccak-256',
1419
1429
  },
1420
1430
  // normal block
1421
1431
  'leofcoin-block': {
1422
- codec: parseInt('6c62', 16),
1432
+ codec: parseInt('0x6c62', 16),
1423
1433
  hashAlg: 'dbl-keccak-512', // ,
1424
1434
  // testnet: 'olivia'
1425
1435
  },
1426
1436
  'leofcoin-tx': {
1427
- codec: parseInt('6c74', 16),
1437
+ codec: parseInt('0x6c74', 16),
1428
1438
  hashAlg: 'dbl-keccak-512', // ,
1429
1439
  // testnet: 'olivia'
1430
1440
  },
1431
1441
  // itx
1432
1442
  'leofcoin-itx': {
1433
- codec: parseInt('6c69', 16),
1443
+ codec: parseInt('0x6c69', 16),
1434
1444
  hashAlg: 'keccak-512', // ,
1435
1445
  // testnet: 'olivia'
1436
1446
  },
1437
1447
  // peer reputation
1438
1448
  'leofcoin-pr': {
1439
- codec: parseInt('6c70', 16),
1449
+ codec: parseInt('0x6c70', 16),
1440
1450
  hashAlg: 'keccak-256', // ,
1441
1451
  // testnet: 'olivia'
1442
1452
  },
1443
1453
  // chat message
1444
1454
  'chat-message': {
1445
- codec: parseInt('70636d', 16),
1455
+ codec: parseInt('0x70636d', 16),
1446
1456
  hashAlg: 'dbl-keccak-256',
1447
1457
  },
1448
1458
  'peernet-file': {
1449
- codec: parseInt('7066', 16),
1459
+ codec: parseInt('0x7066', 16),
1450
1460
  hashAlg: 'keccak-256',
1451
1461
  },
1452
1462
  'peernet-file-response': {
1453
- codec: parseInt('706672', 16),
1463
+ codec: parseInt('0x706672', 16),
1454
1464
  hashAlg: 'keccak-256',
1455
1465
  }
1456
1466
  };
1457
1467
 
1458
- var codecs$1 = /*#__PURE__*/Object.freeze({
1459
- __proto__: null,
1460
- default: codecs
1461
- });
1462
-
1463
1468
  let Codec$1 = class Codec extends BasicInterface$1 {
1469
+ codecBuffer;
1470
+ codec;
1471
+ hashAlg;
1464
1472
  get codecs() {
1465
- return { ...globalThis.peernet.codecs, ...codecs };
1473
+ const globalCodecs = globalThis.peernet?.codecs || {};
1474
+ return { ...globalCodecs, ...codecs$1 };
1466
1475
  }
1467
1476
  constructor(buffer) {
1468
1477
  super();
@@ -1480,16 +1489,17 @@ let Codec$1 = class Codec extends BasicInterface$1 {
1480
1489
  }
1481
1490
  }
1482
1491
  else if (buffer instanceof ArrayBuffer) {
1483
- const encoded = new Uint8Array(buffer.byteLength);
1484
- for (let i = 0; i < buffer.byteLength; i++) {
1485
- encoded[i] = buffer[i];
1492
+ const codec = index$6.decode(buffer);
1493
+ const name = this.getCodecName(codec);
1494
+ if (name) {
1495
+ this.name = name;
1496
+ this.decode(buffer);
1497
+ }
1498
+ else {
1499
+ this.encode(buffer);
1486
1500
  }
1487
- this.encoded = encoded;
1488
- // this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
1489
- this.decode(buffer);
1490
- return;
1491
1501
  }
1492
- if (typeof buffer === 'string') {
1502
+ else if (typeof buffer === 'string') {
1493
1503
  if (this.codecs[buffer])
1494
1504
  this.fromName(buffer);
1495
1505
  else if (this.isHex(buffer))
@@ -1511,7 +1521,7 @@ let Codec$1 = class Codec extends BasicInterface$1 {
1511
1521
  const name = this.getCodecName(codec);
1512
1522
  this.name = name;
1513
1523
  this.encoded = encoded;
1514
- this.decode(encoded);
1524
+ return this.decode(encoded);
1515
1525
  }
1516
1526
  getCodec(name) {
1517
1527
  return this.codecs[name].codec;
@@ -1541,13 +1551,15 @@ let Codec$1 = class Codec extends BasicInterface$1 {
1541
1551
  this.hashAlg = this.getHashAlg(name);
1542
1552
  this.codecBuffer = index$6.encode(codec);
1543
1553
  }
1544
- decode() {
1545
- const codec = index$6.decode(this.encoded);
1554
+ decode(encoded) {
1555
+ encoded = encoded || this.encoded;
1556
+ const codec = index$6.decode(encoded);
1546
1557
  this.fromCodec(codec);
1558
+ return this.decoded;
1547
1559
  }
1548
- encode() {
1549
- const codec = index$6.encode(this.decoded);
1550
- this.encoded = codec;
1560
+ encode(codec) {
1561
+ codec = codec || this.codec;
1562
+ this.encoded = index$6.encode(codec);
1551
1563
  return this.encoded;
1552
1564
  }
1553
1565
  };
@@ -1683,19 +1695,13 @@ let CodecHash$1 = class CodecHash extends BasicInterface$1 {
1683
1695
  };
1684
1696
 
1685
1697
  let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
1686
- set proto(value) {
1687
- this._proto = value;
1688
- this.keys = Object.keys(this._proto);
1689
- }
1690
- get proto() {
1691
- return this._proto;
1692
- }
1698
+ hashFormat;
1693
1699
  init(buffer) {
1694
1700
  if (buffer instanceof Uint8Array)
1695
1701
  this.fromUint8Array(buffer);
1696
1702
  else if (buffer instanceof ArrayBuffer)
1697
1703
  this.fromArrayBuffer(buffer);
1698
- else if (buffer?.name === this.name)
1704
+ else if (buffer instanceof FormatInterface$1 && buffer?.name === this.name)
1699
1705
  return buffer;
1700
1706
  else if (buffer instanceof String) {
1701
1707
  if (this.isHex(buffer))
@@ -1719,18 +1725,17 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
1719
1725
  if (codec.name)
1720
1726
  return true;
1721
1727
  }
1722
- decode() {
1723
- let encoded = this.encoded;
1728
+ decode(encoded) {
1729
+ encoded = encoded || this.encoded;
1724
1730
  const codec = new Codec$1(this.encoded);
1725
1731
  if (codec.codecBuffer) {
1726
1732
  encoded = encoded.slice(codec.codecBuffer.length);
1727
1733
  this.name = codec.name;
1728
1734
  this.decoded = this.protoDecode(encoded);
1729
- try {
1730
- this.decoded = JSON.parse(this.decoded);
1731
- }
1732
- catch {
1733
- }
1735
+ // try {
1736
+ // this.decoded = JSON.parse(this.decoded)
1737
+ // } catch {
1738
+ // }
1734
1739
  }
1735
1740
  else {
1736
1741
  throw new Error(`no codec found`);
@@ -1762,11 +1767,11 @@ let FormatInterface$1 = class FormatInterface extends BasicInterface$1 {
1762
1767
  * @param {Object} proto - {protoObject}
1763
1768
  * @param {Object} options - {hashFormat, name}
1764
1769
  */
1765
- constructor(buffer, proto, options = {}) {
1770
+ constructor(buffer, proto, options) {
1766
1771
  super();
1767
1772
  this.proto = proto;
1768
- this.hashFormat = options.hashFormat || 'bs32';
1769
- if (options.name)
1773
+ this.hashFormat = options?.hashFormat ? options.hashFormat : 'bs32';
1774
+ if (options?.name)
1770
1775
  this.name = options.name;
1771
1776
  this.init(buffer);
1772
1777
  }
@@ -1797,54 +1802,55 @@ const FormatInterface = FormatInterface$1;
1797
1802
  const Codec = Codec$1;
1798
1803
 
1799
1804
  const BufferToUint8Array = data => {
1800
- if (data.type === 'Buffer') {
1801
- data = new Uint8Array(data.data);
1802
- }
1803
- return data
1805
+ if (data.type === 'Buffer') {
1806
+ data = new Uint8Array(data.data);
1807
+ }
1808
+ return data;
1804
1809
  };
1805
-
1806
1810
  const protoFor = (message) => {
1807
- const codec = new Codec(message);
1808
- if (!codec.name) throw new Error('proto not found')
1809
- const Proto = globalThis.peernet.protos[codec.name];
1810
- if (!Proto) throw (new Error(`No proto defined for ${codec.name}`))
1811
- return new Proto(message)
1811
+ const codec = new Codec(message);
1812
+ if (!codec.name)
1813
+ throw new Error('proto not found');
1814
+ const Proto = globalThis.peernet.protos[codec.name];
1815
+ if (!Proto)
1816
+ throw (new Error(`No proto defined for ${codec.name}`));
1817
+ return new Proto(message);
1812
1818
  };
1813
-
1814
1819
  /**
1815
1820
  * wether or not a peernet daemon is active
1816
1821
  * @return {Boolean}
1817
1822
  */
1818
1823
  const hasDaemon = async () => {
1819
- try {
1820
- let response = await fetch('http://127.0.0.1:1000/api/version');
1821
- response = await response.json();
1822
- return Boolean(response.client === '@peernet/api/http')
1823
- } catch (e) {
1824
- return false
1825
- }
1824
+ try {
1825
+ let response = await fetch('http://127.0.0.1:1000/api/version');
1826
+ response = await response.json();
1827
+ return Boolean(response.client === '@peernet/api/http');
1828
+ }
1829
+ catch (e) {
1830
+ return false;
1831
+ }
1826
1832
  };
1827
-
1828
1833
  const https = () => {
1829
- if (!globalThis.location) return false;
1830
- return Boolean(globalThis.location.protocol === 'https:')
1834
+ if (!globalThis.location)
1835
+ return false;
1836
+ return Boolean(globalThis.location.protocol === 'https:');
1831
1837
  };
1832
-
1833
1838
  /**
1834
1839
  * Get current environment
1835
1840
  * @return {String} current environment [node, electron, browser]
1836
1841
  */
1837
1842
  const environment = () => {
1838
- const _navigator = globalThis.navigator;
1839
- if (!_navigator) {
1840
- return 'node'
1841
- } else if (_navigator && /electron/i.test(_navigator.userAgent)) {
1842
- return 'electron'
1843
- } else {
1844
- return 'browser'
1845
- }
1843
+ const _navigator = globalThis.navigator;
1844
+ if (!_navigator) {
1845
+ return 'node';
1846
+ }
1847
+ else if (_navigator && /electron/i.test(_navigator.userAgent)) {
1848
+ return 'electron';
1849
+ }
1850
+ else {
1851
+ return 'browser';
1852
+ }
1846
1853
  };
1847
-
1848
1854
  /**
1849
1855
  * * Get current environment
1850
1856
  * @return {Object} result
@@ -1852,84 +1858,84 @@ const environment = () => {
1852
1858
  * @property {Boolean} reult.environment Current environment
1853
1859
  */
1854
1860
  const target = async () => {
1855
- let daemon = false;
1856
- if (!https()) daemon = await hasDaemon();
1857
-
1858
- return {daemon, environment: environment()}
1861
+ let daemon = false;
1862
+ if (!https())
1863
+ daemon = await hasDaemon();
1864
+ return { daemon, environment: environment() };
1859
1865
  };
1860
1866
 
1861
1867
  class PeerDiscovery {
1862
- constructor(id) {
1863
- this.id = id;
1864
- }
1865
-
1866
- _getPeerId(id) {
1867
- if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
1868
-
1869
- for (const entry of [...peernet.peerMap.entries()]) {
1870
- for (const _id of entry[1]) {
1871
- if (_id === id) return entry[0]
1872
- }
1868
+ constructor(id) {
1869
+ this.id = id;
1873
1870
  }
1874
- }
1875
-
1876
- async discover(peer) {
1877
- let id = this._getPeerId(peer.id);
1878
- if (id) return id
1879
- const data = await new peernet.protos['peernet-peer']({id: this.id});
1880
- const node = await peernet.prepareMessage(peer.id, data.encoded);
1881
-
1882
- let response = await peer.request(node.encoded);
1883
- response = await protoFor(response);
1884
- response = await new peernet.protos['peernet-peer-response'](response.decoded.data);
1885
-
1886
- id = response.decoded.id;
1887
- if (id === this.id) return;
1888
-
1889
- if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id]);
1890
- else {
1891
- const connections = peernet.peerMap.get(id);
1892
- if (connections.indexOf(peer.id) === -1) {
1893
- connections.push(peer.id);
1894
- peernet.peerMap.set(peer.id, connections);
1895
- }
1871
+ _getPeerId(id) {
1872
+ if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0)
1873
+ return false;
1874
+ for (const entry of [...peernet.peerMap.entries()]) {
1875
+ for (const _id of entry[1]) {
1876
+ if (_id === id)
1877
+ return entry[0];
1878
+ }
1879
+ }
1896
1880
  }
1897
- return id
1898
- }
1899
-
1900
- async discoverHandler(message, peer) {
1901
- const {id, proto} = message;
1902
- // if (typeof message.data === 'string') message.data = Buffer.from(message.data)
1903
- if (proto.name === 'peernet-peer') {
1904
- const from = proto.decoded.id;
1905
- if (from === this.id) return;
1906
-
1907
- if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
1908
- else {
1909
- const connections = peernet.peerMap.get(from);
1910
- if (connections.indexOf(peer.id) === -1) {
1911
- connections.push(peer.id);
1912
- peernet.peerMap.set(from, connections);
1913
- }
1914
- }
1915
- const data = await new peernet.protos['peernet-peer-response']({id: this.id});
1916
- const node = await peernet.prepareMessage(from, data.encoded);
1917
-
1918
- peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
1919
- } else if (proto.name === 'peernet-peer-response') {
1920
- const from = proto.decoded.id;
1921
- if (from === this.id) return;
1922
-
1923
- if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
1924
- else {
1925
- const connections = peernet.peerMap.get(from);
1926
- if (connections.indexOf(peer.id) === -1) {
1927
- connections.push(peer.id);
1928
- peernet.peerMap.set(from, connections);
1881
+ async discover(peer) {
1882
+ let id = this._getPeerId(peer.id);
1883
+ if (id)
1884
+ return id;
1885
+ const data = await new peernet.protos['peernet-peer']({ id: this.id });
1886
+ const node = await peernet.prepareMessage(peer.id, data.encoded);
1887
+ let response = await peer.request(node.encoded);
1888
+ response = await protoFor(response);
1889
+ response = await new peernet.protos['peernet-peer-response'](response.decoded.data);
1890
+ id = response.decoded.id;
1891
+ if (id === this.id)
1892
+ return;
1893
+ if (!peernet.peerMap.has(id))
1894
+ peernet.peerMap.set(id, [peer.id]);
1895
+ else {
1896
+ const connections = peernet.peerMap.get(id);
1897
+ if (connections.indexOf(peer.id) === -1) {
1898
+ connections.push(peer.id);
1899
+ peernet.peerMap.set(peer.id, connections);
1900
+ }
1901
+ }
1902
+ return id;
1903
+ }
1904
+ async discoverHandler(message, peer) {
1905
+ const { id, proto } = message;
1906
+ // if (typeof message.data === 'string') message.data = Buffer.from(message.data)
1907
+ if (proto.name === 'peernet-peer') {
1908
+ const from = proto.decoded.id;
1909
+ if (from === this.id)
1910
+ return;
1911
+ if (!peernet.peerMap.has(from))
1912
+ peernet.peerMap.set(from, [peer.id]);
1913
+ else {
1914
+ const connections = peernet.peerMap.get(from);
1915
+ if (connections.indexOf(peer.id) === -1) {
1916
+ connections.push(peer.id);
1917
+ peernet.peerMap.set(from, connections);
1918
+ }
1919
+ }
1920
+ const data = await new peernet.protos['peernet-peer-response']({ id: this.id });
1921
+ const node = await peernet.prepareMessage(from, data.encoded);
1922
+ peer.write(Buffer.from(JSON.stringify({ id, data: node.encoded })));
1923
+ }
1924
+ else if (proto.name === 'peernet-peer-response') {
1925
+ const from = proto.decoded.id;
1926
+ if (from === this.id)
1927
+ return;
1928
+ if (!peernet.peerMap.has(from))
1929
+ peernet.peerMap.set(from, [peer.id]);
1930
+ else {
1931
+ const connections = peernet.peerMap.get(from);
1932
+ if (connections.indexOf(peer.id) === -1) {
1933
+ connections.push(peer.id);
1934
+ peernet.peerMap.set(from, connections);
1935
+ }
1936
+ }
1929
1937
  }
1930
- }
1931
1938
  }
1932
- }
1933
1939
  }
1934
1940
 
1935
1941
  /**
@@ -1938,178 +1944,162 @@ class PeerDiscovery {
1938
1944
  * @property {Object} ptr
1939
1945
  */
1940
1946
  const lastFetched = {
1941
- address: {
1942
- value: undefined,
1943
- timestamp: 0,
1944
- },
1945
- ptr: {
1946
- value: undefined,
1947
- timestamp: 0,
1948
- },
1947
+ address: {
1948
+ value: undefined,
1949
+ timestamp: 0,
1950
+ },
1951
+ ptr: {
1952
+ value: undefined,
1953
+ timestamp: 0,
1954
+ },
1949
1955
  };
1950
-
1951
1956
  const getAddress = async () => {
1952
- const {address} = lastFetched;
1953
- const now = Math.round(new Date().getTime() / 1000);
1954
- if (now - address.timestamp > 1200000) {
1955
- address.value = await fetch('https://icanhazip.com/');
1956
- address.value = await address.value.text();
1957
- address.timestamp = Math.round(new Date().getTime() / 1000);
1958
- lastFetched.address = address;
1959
- }
1960
-
1961
- return address.value
1957
+ const { address } = lastFetched;
1958
+ const now = Math.round(new Date().getTime() / 1000);
1959
+ if (now - address.timestamp > 1200000) {
1960
+ address.value = await fetch('https://icanhazip.com/');
1961
+ address.value = await address.value.text();
1962
+ address.timestamp = Math.round(new Date().getTime() / 1000);
1963
+ lastFetched.address = address;
1964
+ }
1965
+ return address.value;
1962
1966
  };
1963
-
1964
1967
  const degreesToRadians = (degrees) => {
1965
- return degrees * Math.PI / 180;
1968
+ return degrees * Math.PI / 180;
1966
1969
  };
1967
-
1968
1970
  const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
1969
- const earthRadiusKm = 6371;
1970
-
1971
- const dLat = degreesToRadians(lat2-lat1);
1972
- const dLon = degreesToRadians(lon2-lon1);
1973
-
1974
- lat1 = degreesToRadians(lat1);
1975
- lat2 = degreesToRadians(lat2);
1976
- const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
1977
- Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
1978
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
1979
- return earthRadiusKm * c;
1971
+ const earthRadiusKm = 6371;
1972
+ const dLat = degreesToRadians(lat2 - lat1);
1973
+ const dLon = degreesToRadians(lon2 - lon1);
1974
+ lat1 = degreesToRadians(lat1);
1975
+ lat2 = degreesToRadians(lat2);
1976
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
1977
+ Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
1978
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
1979
+ return earthRadiusKm * c;
1980
1980
  };
1981
-
1982
1981
  class DhtEarth {
1983
- /**
1984
- *
1985
- */
1986
- constructor() {
1987
- this.providerMap = new Map();
1988
- }
1989
-
1990
- /**
1991
- * @param {Object} address
1992
- * @return {Object} {latitude: lat, longitude: lon}
1993
- */
1994
- async getCoordinates(address) {
1995
- // const {address} = parseAddress(provider)
1996
- const request = `https://whereis.leofcoin.org/?ip=${address}`;
1997
- let response = await fetch(request);
1998
- response = await response.json();
1999
- const {lat, lon} = response;
2000
- return {latitude: lat, longitude: lon}
2001
- }
2002
-
2003
- /**
2004
- * @param {Object} peer
2005
- * @param {Object} provider
2006
- * @return {Object} {provider, distance}
2007
- */
2008
- async getDistance(peer, provider) {
2009
- const {latitude, longitude} = await this.getCoordinates(provider.address);
2010
- return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
2011
- }
2012
-
2013
- /**
2014
- * @param {Array} providers
2015
- * @return {Object} closestPeer
2016
- */
2017
- async closestPeer(providers) {
2018
- let all = [];
2019
- const address = await getAddress();
2020
- const peerLoc = await this.getCoordinates(address);
2021
-
2022
- for (const provider of providers) {
2023
- if (provider.address === '127.0.0.1') all.push({provider, distance: 0});
2024
- else all.push(this.getDistance(peerLoc, provider));
1982
+ /**
1983
+ *
1984
+ */
1985
+ constructor() {
1986
+ this.providerMap = new Map();
1987
+ }
1988
+ /**
1989
+ * @param {Object} address
1990
+ * @return {Object} {latitude: lat, longitude: lon}
1991
+ */
1992
+ async getCoordinates(address) {
1993
+ // const {address} = parseAddress(provider)
1994
+ const request = `https://whereis.leofcoin.org/?ip=${address}`;
1995
+ let response = await fetch(request);
1996
+ response = await response.json();
1997
+ const { lat, lon } = response;
1998
+ return { latitude: lat, longitude: lon };
1999
+ }
2000
+ /**
2001
+ * @param {Object} peer
2002
+ * @param {Object} provider
2003
+ * @return {Object} {provider, distance}
2004
+ */
2005
+ async getDistance(peer, provider) {
2006
+ const { latitude, longitude } = await this.getCoordinates(provider.address);
2007
+ return { provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude) };
2008
+ }
2009
+ /**
2010
+ * @param {Array} providers
2011
+ * @return {Object} closestPeer
2012
+ */
2013
+ async closestPeer(providers) {
2014
+ let all = [];
2015
+ const address = await getAddress();
2016
+ const peerLoc = await this.getCoordinates(address);
2017
+ for (const provider of providers) {
2018
+ if (provider.address === '127.0.0.1')
2019
+ all.push({ provider, distance: 0 });
2020
+ else
2021
+ all.push(this.getDistance(peerLoc, provider));
2022
+ }
2023
+ all = await Promise.all(all);
2024
+ all = all.sort((previous, current) => previous.distance - current.distance);
2025
+ return all[0].provider;
2026
+ }
2027
+ /**
2028
+ * @param {String} hash
2029
+ * @return {Array} providers
2030
+ */
2031
+ providersFor(hash) {
2032
+ return this.providerMap.get(hash);
2033
+ }
2034
+ /**
2035
+ * @param {String} address
2036
+ * @param {String} hash
2037
+ * @return {Array} providers
2038
+ */
2039
+ async addProvider(address, hash) {
2040
+ let providers = [];
2041
+ if (this.providerMap.has(hash))
2042
+ providers = this.providerMap.get(hash);
2043
+ providers = new Set([...providers, address]);
2044
+ this.providerMap.set(hash, providers);
2045
+ return providers;
2025
2046
  }
2026
-
2027
- all = await Promise.all(all);
2028
- all = all.sort((previous, current) => previous.distance - current.distance);
2029
- return all[0].provider;
2030
- }
2031
-
2032
- /**
2033
- * @param {String} hash
2034
- * @return {Array} providers
2035
- */
2036
- providersFor(hash) {
2037
- return this.providerMap.get(hash);
2038
- }
2039
-
2040
- /**
2041
- * @param {String} address
2042
- * @param {String} hash
2043
- * @return {Array} providers
2044
- */
2045
- async addProvider(address, hash) {
2046
- let providers = [];
2047
- if (this.providerMap.has(hash)) providers = this.providerMap.get(hash);
2048
-
2049
- providers = new Set([...providers, address]);
2050
- this.providerMap.set(hash, providers);
2051
- return providers;
2052
- }
2053
2047
  }
2054
2048
 
2055
2049
  class MessageHandler {
2056
- constructor(network) {
2057
- this.network = network;
2058
- }
2059
- /**
2060
- * hash and sign message
2061
- *
2062
- * @param {object} message
2063
- * @param {Buffer} message.from peer id
2064
- * @param {Buffer} message.to peer id
2065
- * @param {string} message.data Peernet message
2066
- * (PeernetMessage excluded) encoded as a string
2067
- * @return message
2068
- */
2069
- async hashAndSignMessage(message) {
2070
- let identity = await walletStore.get('identity');
2071
- identity = JSON.parse(identity);
2072
- if (!globalThis.MultiWallet) {
2073
- const importee = await import(/* webpackChunkName: "multi-wallet" */ './index-19803d3b.js');
2074
- globalThis.MultiWallet = importee.default;
2075
- }
2076
- const wallet = new MultiWallet(this.network);
2077
- wallet.recover(identity.mnemonic);
2078
- message.decoded.signature = wallet.sign(Buffer.from(await message.hash).slice(0, 32));
2079
- return message
2080
- }
2081
-
2082
- /**
2083
- * @param {String} from - peer id
2084
- * @param {String} to - peer id
2085
- * @param {String|PeernetMessage} data - data encoded message string
2086
- * or the messageNode itself
2087
- */
2088
- async prepareMessage(message) {
2089
- if (message.keys.includes('signature')) {
2090
- message = await this.hashAndSignMessage(message);
2050
+ constructor(network) {
2051
+ this.network = network;
2052
+ }
2053
+ /**
2054
+ * hash and sign message
2055
+ *
2056
+ * @param {object} message
2057
+ * @param {Buffer} message.from peer id
2058
+ * @param {Buffer} message.to peer id
2059
+ * @param {string} message.data Peernet message
2060
+ * (PeernetMessage excluded) encoded as a string
2061
+ * @return message
2062
+ */
2063
+ async hashAndSignMessage(message) {
2064
+ let identity = await walletStore.get('identity');
2065
+ identity = JSON.parse(identity);
2066
+ if (!globalThis.MultiWallet) {
2067
+ const importee = await import(/* webpackChunkName: "multi-wallet" */ './index-4a0fc4ea.js');
2068
+ globalThis.MultiWallet = importee.default;
2069
+ }
2070
+ const wallet = new MultiWallet(this.network);
2071
+ wallet.recover(identity.mnemonic);
2072
+ message.decoded.signature = wallet.sign(Buffer.from(await message.hash).slice(0, 32));
2073
+ return message;
2074
+ }
2075
+ /**
2076
+ * @param {String} from - peer id
2077
+ * @param {String} to - peer id
2078
+ * @param {String|PeernetMessage} data - data encoded message string
2079
+ * or the messageNode itself
2080
+ */
2081
+ async prepareMessage(message) {
2082
+ if (message.keys.includes('signature')) {
2083
+ message = await this.hashAndSignMessage(message);
2084
+ }
2085
+ return message;
2091
2086
  }
2092
-
2093
- return message
2094
- }
2095
2087
  }
2096
2088
 
2097
- const dataHandler = async message => {
2098
- if (!message) return
2099
-
2100
- const {data, id, from} = message;
2101
- const proto = await protoFor(data);
2102
-
2103
- peernet._protoHandler({id, proto}, peernet.client.connections[from], from);
2104
- };
2105
-
2106
- const dhtError = (proto) => {
2107
- const text = `Received proto ${proto.name} expected peernet-dht-response`;
2108
- return new Error(`Routing error: ${text}`)
2089
+ const dataHandler = async (message) => {
2090
+ if (!message)
2091
+ return;
2092
+ const { data, id, from } = message;
2093
+ const proto = await protoFor(data);
2094
+ peernet._protoHandler({ id, proto }, peernet.client.connections[from], from);
2109
2095
  };
2110
2096
 
2111
- const nothingFoundError = (hash) => {
2112
- return new Error(`nothing found for ${hash}`)
2097
+ const dhtError = (proto) => {
2098
+ const text = `Received proto ${proto.name} expected peernet-dht-response`;
2099
+ return new Error(`Routing error: ${text}`);
2100
+ };
2101
+ const nothingFoundError = (hash) => {
2102
+ return new Error(`nothing found for ${hash}`);
2113
2103
  };
2114
2104
 
2115
2105
  // import base32 from '@vandeurenglenn/base32'
@@ -2279,699 +2269,827 @@ class LeofcoinStorage {
2279
2269
 
2280
2270
  }
2281
2271
 
2272
+ const blockchainCodecs = [
2273
+ {
2274
+ name: 'leofcoin-block',
2275
+ codec: '0x6c62',
2276
+ hashAlg: 'dbl-keccak-512',
2277
+ },
2278
+ {
2279
+ name: 'leofcoin-tx',
2280
+ codec: '0x6c74',
2281
+ hashAlg: 'dbl-keccak-512',
2282
+ },
2283
+ {
2284
+ name: 'leofcoin-itx',
2285
+ codec: '0x6c69',
2286
+ hashAlg: 'keccak-512',
2287
+ },
2288
+ {
2289
+ name: 'leofcoin-pr',
2290
+ codec: '0x6c70',
2291
+ hashAlg: 'keccak-256',
2292
+ },
2293
+ {
2294
+ name: 'contract-message',
2295
+ codec: '0x63636d',
2296
+ hashAlg: 'keccak-256'
2297
+ },
2298
+ {
2299
+ name: 'transaction-message',
2300
+ codec: '0x746d',
2301
+ hashAlg: 'keccak-256'
2302
+ },
2303
+ {
2304
+ name: 'block-message',
2305
+ codec: '0x626d',
2306
+ hashAlg: 'keccak-256'
2307
+ },
2308
+ {
2309
+ name: 'bw-message',
2310
+ codec: '0x62776d',
2311
+ hashAlg: 'keccak-256'
2312
+ },
2313
+ {
2314
+ name: 'bw-request-message',
2315
+ codec: '0x6277726d',
2316
+ hashAlg: 'keccak-256'
2317
+ },
2318
+ {
2319
+ name: 'validator-message',
2320
+ codec: '0x766d',
2321
+ hashAlg: 'keccak-256'
2322
+ }
2323
+ ];
2324
+
2325
+ const internalCodecs = [
2326
+ {
2327
+ name: 'disco-hash',
2328
+ codec: '0x30',
2329
+ hashAlg: 'dbl-keccak-256',
2330
+ },
2331
+ {
2332
+ name: 'peernet-peer-response',
2333
+ codec: '0x707072',
2334
+ hashAlg: 'keccak-256',
2335
+ },
2336
+ {
2337
+ name: 'peernet-peer',
2338
+ codec: '0x7070',
2339
+ hashAlg: 'keccak-256',
2340
+ },
2341
+ {
2342
+ name: 'peernet-dht',
2343
+ codec: '0x706468',
2344
+ hashAlg: 'keccak-256',
2345
+ },
2346
+ {
2347
+ name: 'peernet-dht-response',
2348
+ codec: '0x706472',
2349
+ hashAlg: 'keccak-256',
2350
+ },
2351
+ {
2352
+ name: 'peernet-data',
2353
+ codec: '0x706461',
2354
+ hashAlg: 'keccak-256',
2355
+ },
2356
+ {
2357
+ name: 'peernet-data-response',
2358
+ codec: '0x70646172',
2359
+ hashAlg: 'keccak-256',
2360
+ },
2361
+ {
2362
+ name: 'peernet-message',
2363
+ codec: '0x706d65',
2364
+ hashAlg: 'keccak-256',
2365
+ },
2366
+ {
2367
+ name: 'peernet-ps',
2368
+ codec: '707073',
2369
+ hashAlg: 'keccak-256',
2370
+ },
2371
+ {
2372
+ name: 'peernet-response',
2373
+ codec: '0x7072',
2374
+ hashAlg: 'keccak-256',
2375
+ },
2376
+ {
2377
+ name: 'peernet-request',
2378
+ codec: '0x707271',
2379
+ hashAlg: 'keccak-256',
2380
+ },
2381
+ {
2382
+ name: 'peernet-file',
2383
+ codec: '0x7066',
2384
+ hashAlg: 'keccak-256',
2385
+ },
2386
+ {
2387
+ name: 'peernet-file-response',
2388
+ codec: '0x706672',
2389
+ hashAlg: 'keccak-256',
2390
+ }
2391
+ ];
2392
+
2393
+ const codecs = [
2394
+ ...internalCodecs,
2395
+ ...blockchainCodecs,
2396
+ {
2397
+ name: 'chat-message',
2398
+ codec: '0x70636d',
2399
+ hashAlg: 'dbl-keccak-256',
2400
+ }
2401
+ ];
2402
+
2403
+ globalThis.peernet = globalThis.peernet || {};
2404
+ globalThis.peernet.codecs = globalThis.peernet.codecs || {};
2405
+ const addCodec = (codecInput) => {
2406
+ let { hashAlg, codec, name } = codecInput;
2407
+ if (!globalThis.peernet.codecs[name])
2408
+ globalThis.peernet.codecs[name] = {
2409
+ hashAlg,
2410
+ codec: parseInt(codec, 16)
2411
+ };
2412
+ };
2413
+ const getCodec = (name) => globalThis.peernet.codecs[name];
2414
+ const getCodecName = (codec) => {
2415
+ return Object.keys(globalThis.peernet.codecs).reduce((p, c) => {
2416
+ const item = globalThis.peernet.codecs[c];
2417
+ if (item.codec === codec)
2418
+ return c;
2419
+ else
2420
+ return p;
2421
+ }, undefined);
2422
+ };
2423
+ const getCodecByName = (name) => globalThis.peernet.codecs[name];
2424
+ const getHashAlg = (name) => {
2425
+ if (typeof name === 'number')
2426
+ return getCodecByName(getCodecName(name)).hashAlg;
2427
+ return getCodecByName(name).hashAlg;
2428
+ };
2429
+ const isCodec = (codec) => {
2430
+ if (codec.codec !== undefined && codec.hashAlg)
2431
+ return true;
2432
+ return false;
2433
+ };
2434
+ const validateCodec = (codec) => {
2435
+ if (codec.codec === undefined ||
2436
+ codec.hashAlg === undefined ||
2437
+ codec.name === undefined)
2438
+ throw new Error(`invalid codecInput: ${codec}`);
2439
+ };
2440
+ for (const codec of codecs) {
2441
+ addCodec(codec);
2442
+ }
2443
+ var utils = {
2444
+ isCodec,
2445
+ addCodec,
2446
+ getCodec,
2447
+ getHashAlg,
2448
+ getCodecName,
2449
+ validateCodec,
2450
+ codecs: globalThis.peernet.codecs
2451
+ };
2452
+
2282
2453
  globalThis.LeofcoinStorage = LeofcoinStorage;
2283
-
2284
2454
  globalThis.leofcoin = globalThis.leofcoin || {};
2285
2455
  globalThis.pubsub = globalThis.pubsub || new LittlePubSub();
2286
- globalThis.globalSub = globalThis.globalSub || new LittlePubSub({verbose: true});
2287
-
2456
+ globalThis.globalSub = globalThis.globalSub || new LittlePubSub(true);
2288
2457
  /**
2289
2458
  * @access public
2290
2459
  * @example
2291
2460
  * const peernet = new Peernet();
2292
2461
  */
2293
2462
  class Peernet {
2294
- /**
2295
- * @access public
2296
- * @param {Object} options
2297
- * @param {String} options.network - desired network
2298
- * @param {String} options.stars - star list for selected network (these should match, don't mix networks)
2299
- * @param {String} options.root - path to root directory
2300
- * @param {String} options.storePrefix - prefix for datatores (lfc)
2301
- *
2302
- * @return {Promise} instance of Peernet
2303
- *
2304
- * @example
2305
- * const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
2306
- */
2307
- constructor(options = {}) {
2308
- this._discovered = [];
2309
- /**
2310
- * @property {String} network - current network
2311
- */
2312
- this.network = options.network || 'leofcoin';
2313
- this.stars = options.stars;
2314
- const parts = this.network.split(':');
2315
- this.networkVersion = options.networkVersion || parts.length > 1 ? parts[1] : 'mainnet';
2316
-
2317
- if (!options.storePrefix) options.storePrefix = 'lfc';
2318
- if (!options.port) options.port = 2000;
2319
- if (!options.root) {
2320
- parts[1] ? options.root = `.${parts[0]}/${parts[1]}` : options.root = `.${this.network}`;
2321
- }
2322
-
2323
- globalThis.peernet = this;
2324
- this.bw = {
2325
- up: 0,
2326
- down: 0,
2327
- };
2328
- return this._init(options)
2329
- }
2330
-
2331
- get defaultStores() {
2332
- return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message']
2333
- }
2334
-
2335
- addProto(name, proto) {
2336
- if (!globalThis.peernet.protos[name]) globalThis.peernet.protos[name] = proto;
2337
- }
2338
-
2339
- addCodec(name, codec) {
2340
- if (!this.codecs[name]) this.codecs[name] = codec;
2341
- }
2342
-
2343
- async addStore(name, prefix, root, isPrivate = true) {
2344
- if (name === 'block' || name === 'transaction' || name === 'chain' ||
2345
- name === 'data' || name === 'message') isPrivate = false;
2346
-
2347
- let Storage;
2348
-
2349
- this.hasDaemon ? Storage = LeofcoinStorageClient : Storage = LeofcoinStorage;
2350
-
2351
- if (!globalThis[`${name}Store`]) {
2352
- globalThis[`${name}Store`] = new Storage(name, root);
2353
- await globalThis[`${name}Store`].init();
2354
- }
2355
-
2356
- globalThis[`${name}Store`].private = isPrivate;
2357
- if (!isPrivate) this.stores.push(name);
2358
- }
2359
-
2360
-
2361
- /**
2362
- * @see MessageHandler
2363
- */
2364
- prepareMessage(data) {
2365
- return this._messageHandler.prepareMessage(data)
2366
- }
2367
-
2368
- /**
2369
- * @access public
2370
- *
2371
- * @return {Array} peerId
2372
- */
2373
- get peers() {
2374
- return Object.keys(this.client.connections)
2375
- }
2376
-
2377
- get connections() {
2378
- return Object.values(this.client.connections)
2379
- }
2380
-
2381
- get peerEntries() {
2382
- return Object.entries(this.client.connections)
2383
- }
2384
-
2385
- /**
2386
- * @return {String} id - peerId
2387
- */
2388
- getConnection(id) {
2389
- return this.client.connections[id]
2390
- }
2391
-
2392
- /**
2393
- * @private
2394
- *
2395
- * @param {Object} options
2396
- * @param {String} options.root - path to root directory
2397
- *
2398
- * @return {Promise} instance of Peernet
2399
- */
2400
- async _init(options) {
2401
- // peernetDHT aka closesPeer by coordinates
2463
+ stores = [];
2402
2464
  /**
2403
2465
  * @type {Object}
2404
2466
  * @property {Object} peer Instance of Peer
2405
2467
  */
2406
- this.dht = new DhtEarth();
2468
+ dht = new DhtEarth();
2469
+ /** @leofcoin/peernet-swarm/client */
2470
+ client;
2471
+ network;
2472
+ stars;
2473
+ networkVersion;
2474
+ bw;
2407
2475
  /**
2408
- * @type {Map}
2409
- * @property {Object} peer Instance of Peer
2476
+ * @access public
2477
+ * @param {Object} options
2478
+ * @param {String} options.network - desired network
2479
+ * @param {String} options.stars - star list for selected network (these should match, don't mix networks)
2480
+ * @param {String} options.root - path to root directory
2481
+ * @param {String} options.storePrefix - prefix for datatores (lfc)
2482
+ *
2483
+ * @return {Promise} instance of Peernet
2484
+ *
2485
+ * @example
2486
+ * const peernet = new Peernet({network: 'leofcoin', root: '.leofcoin'});
2410
2487
  */
2411
- this.stores = [];
2412
- this.codecs = {...codecs$1};
2413
- this.requestProtos = {};
2414
- this.storePrefix = options.storePrefix;
2415
- this.root = options.root;
2416
-
2417
- const {
2418
- RequestMessage,
2419
- ResponseMessage,
2420
- PeerMessage,
2421
- PeerMessageResponse,
2422
- PeernetMessage,
2423
- DHTMessage,
2424
- DHTMessageResponse,
2425
- DataMessage,
2426
- DataMessageResponse,
2427
- PsMessage,
2428
- ChatMessage,
2429
- PeernetFile
2430
- // FolderMessageResponse
2431
- } = await import(/* webpackChunkName: "messages" */ './messages-bb950ed7.js');
2432
-
2488
+ constructor(options) {
2489
+ /**
2490
+ * @property {String} network - current network
2491
+ */
2492
+ this.network = options.network || 'leofcoin';
2493
+ this.stars = options.stars;
2494
+ const parts = this.network.split(':');
2495
+ this.networkVersion = options.networkVersion || parts.length > 1 ? parts[1] : 'mainnet';
2496
+ if (!options.storePrefix)
2497
+ options.storePrefix = 'lfc';
2498
+ if (!options.port)
2499
+ options.port = 2000;
2500
+ if (!options.root) {
2501
+ parts[1] ? options.root = `.${parts[0]}/${parts[1]}` : options.root = `.${this.network}`;
2502
+ }
2503
+ globalThis.peernet = this;
2504
+ this.bw = {
2505
+ up: 0,
2506
+ down: 0,
2507
+ };
2508
+ return this._init(options);
2509
+ }
2510
+ get defaultStores() {
2511
+ return ['account', 'wallet', 'block', 'transaction', 'chain', 'data', 'message'];
2512
+ }
2513
+ addProto(name, proto) {
2514
+ if (!globalThis.peernet.protos[name])
2515
+ globalThis.peernet.protos[name] = proto;
2516
+ }
2517
+ addCodec(codec) {
2518
+ return utils.addCodec(codec);
2519
+ }
2520
+ async addStore(name, prefix, root, isPrivate = true) {
2521
+ if (name === 'block' || name === 'transaction' || name === 'chain' ||
2522
+ name === 'data' || name === 'message')
2523
+ isPrivate = false;
2524
+ let Storage;
2525
+ this.hasDaemon ? Storage = LeofcoinStorageClient : Storage = LeofcoinStorage;
2526
+ if (!globalThis[`${name}Store`]) {
2527
+ globalThis[`${name}Store`] = new Storage(name, root);
2528
+ await globalThis[`${name}Store`].init();
2529
+ }
2530
+ globalThis[`${name}Store`].private = isPrivate;
2531
+ if (!isPrivate)
2532
+ this.stores.push(name);
2533
+ }
2433
2534
  /**
2434
- * proto Object containing protos
2435
- * @type {Object}
2436
- * @property {PeernetMessage} protos[peernet-message] messageNode
2437
- * @property {DHTMessage} protos[peernet-dht] messageNode
2438
- * @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
2439
- * @property {DataMessage} protos[peernet-data] messageNode
2440
- * @property {DataMessageResponse} protos[peernet-data-response] messageNode
2535
+ * @see MessageHandler
2441
2536
  */
2442
-
2443
- globalThis.peernet.protos = {
2444
- 'peernet-request': RequestMessage,
2445
- 'peernet-response': ResponseMessage,
2446
- 'peernet-peer': PeerMessage,
2447
- 'peernet-peer-response': PeerMessageResponse,
2448
- 'peernet-message': PeernetMessage,
2449
- 'peernet-dht': DHTMessage,
2450
- 'peernet-dht-response': DHTMessageResponse,
2451
- 'peernet-data': DataMessage,
2452
- 'peernet-data-response': DataMessageResponse,
2453
- 'peernet-ps': PsMessage,
2454
- 'chat-message': ChatMessage,
2455
- 'peernet-file': PeernetFile
2456
- };
2457
-
2458
- this._messageHandler = new MessageHandler(this.network);
2459
-
2460
- const {daemon, environment} = await target();
2461
- this.hasDaemon = daemon;
2462
-
2463
- for (const store of this.defaultStores) {
2464
- await this.addStore(store, options.storePrefix, options.root);
2537
+ prepareMessage(data) {
2538
+ return this._messageHandler.prepareMessage(data);
2465
2539
  }
2466
-
2467
- const accountExists = await accountStore.has('public');
2468
- if (accountExists) {
2469
- const pub = await accountStore.get('public');
2470
- this.id = JSON.parse(new TextDecoder().decode(pub)).walletId;
2471
- let accounts = await walletStore.get('accounts');
2472
- accounts = new TextDecoder().decode(accounts);
2473
- const selected = await walletStore.get('selected-account');
2474
- globalThis.peernet.selectedAccount = new TextDecoder().decode(selected);
2475
-
2476
- // fixing account issue (string while needs to be a JSON)
2477
- // TODO: remove when on mainnet
2478
- try {
2479
- this.accounts = JSON.parse(accounts);
2480
- } catch {
2481
- this.accounts = [accounts.split(',')];
2482
- }
2483
- } else {
2484
- const importee = await import(/* webpackChunkName: "generate-account" */ './index-73b8d9b9.js');
2485
- const generateAccount = importee.default;
2486
- const {identity, accounts, config} = await generateAccount(this.network);
2487
- // await accountStore.put('config', JSON.stringify(config));
2488
- await accountStore.put('public', JSON.stringify({walletId: identity.walletId}));
2489
-
2490
- await walletStore.put('version', String(1));
2491
- await walletStore.put('accounts', JSON.stringify(accounts));
2492
- await walletStore.put('selected-account', accounts[0][1]);
2493
- await walletStore.put('identity', JSON.stringify(identity));
2494
-
2495
- globalThis.peernet.selectedAccount = accounts[0][1];
2496
- this.id = identity.walletId;
2540
+ /**
2541
+ * @access public
2542
+ *
2543
+ * @return {Array} peerId
2544
+ */
2545
+ get peers() {
2546
+ return Object.keys(this.client.connections);
2547
+ }
2548
+ get connections() {
2549
+ return Object.values(this.client.connections);
2550
+ }
2551
+ get peerEntries() {
2552
+ return Object.entries(this.client.connections);
2497
2553
  }
2498
- this._peerHandler = new PeerDiscovery(this.id);
2499
- this.peerId = this.id;
2500
-
2501
- pubsub.subscribe('peer:connected', async (peer) => {
2502
- // console.log(peer);
2503
- // console.log({connected: peer.id, as: this._getPeerId(peer.id) });
2504
- // peer.on('peernet.data', async (message) => {
2505
- // const id = message.id
2506
- // message = new PeernetMessage(Buffer.from(message.data.data))
2507
- // const proto = protoFor(message.decoded.data)
2508
- // this._protoHandler({id, proto}, peer)
2509
- // })
2510
- });
2511
-
2512
2554
  /**
2513
- * converts data -> message -> proto
2514
- * @see DataHandler
2555
+ * @return {String} id - peerId
2515
2556
  */
2516
- pubsub.subscribe('peer:data', dataHandler);
2517
-
2518
-
2519
- const importee = await import(/* webpackChunkName: "peernet-swarm" */ './client-13d9b3de.js');
2557
+ getConnection(id) {
2558
+ return this.client.connections[id];
2559
+ }
2520
2560
  /**
2521
- * @access public
2522
- * @type {PeernetClient}
2561
+ * @private
2562
+ *
2563
+ * @param {Object} options
2564
+ * @param {String} options.root - path to root directory
2565
+ *
2566
+ * @return {Promise} instance of Peernet
2523
2567
  */
2524
- this.client = new importee.default(this.id, this.networkVersion, this.stars);
2525
- if (globalThis.navigator) {
2526
- globalThis.addEventListener('beforeunload', async () => this.client.close());
2527
- } else {
2528
- process.on('SIGTERM', async () => {
2529
- process.stdin.resume();
2530
- await this.client.close();
2531
- process.exit();
2532
- });
2568
+ async _init(options) {
2569
+ this.requestProtos = {};
2570
+ this.storePrefix = options.storePrefix;
2571
+ this.root = options.root;
2572
+ const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
2573
+ // FolderMessageResponse
2574
+ } = await import(/* webpackChunkName: "messages" */ './messages-6db1f01d.js');
2575
+ /**
2576
+ * proto Object containing protos
2577
+ * @type {Object}
2578
+ * @property {PeernetMessage} protos[peernet-message] messageNode
2579
+ * @property {DHTMessage} protos[peernet-dht] messageNode
2580
+ * @property {DHTMessageResponse} protos[peernet-dht-response] messageNode
2581
+ * @property {DataMessage} protos[peernet-data] messageNode
2582
+ * @property {DataMessageResponse} protos[peernet-data-response] messageNode
2583
+ */
2584
+ globalThis.peernet.protos = {
2585
+ 'peernet-request': RequestMessage,
2586
+ 'peernet-response': ResponseMessage,
2587
+ 'peernet-peer': PeerMessage,
2588
+ 'peernet-peer-response': PeerMessageResponse,
2589
+ 'peernet-message': PeernetMessage,
2590
+ 'peernet-dht': DHTMessage,
2591
+ 'peernet-dht-response': DHTMessageResponse,
2592
+ 'peernet-data': DataMessage,
2593
+ 'peernet-data-response': DataMessageResponse,
2594
+ 'peernet-ps': PsMessage,
2595
+ 'chat-message': ChatMessage,
2596
+ 'peernet-file': PeernetFile
2597
+ };
2598
+ this._messageHandler = new MessageHandler(this.network);
2599
+ const { daemon, environment } = await target();
2600
+ this.hasDaemon = daemon;
2601
+ for (const store of this.defaultStores) {
2602
+ await this.addStore(store, options.storePrefix, options.root);
2603
+ }
2604
+ const accountExists = await accountStore.has('public');
2605
+ if (accountExists) {
2606
+ const pub = await accountStore.get('public');
2607
+ this.id = JSON.parse(new TextDecoder().decode(pub)).walletId;
2608
+ let accounts = await walletStore.get('accounts');
2609
+ accounts = new TextDecoder().decode(accounts);
2610
+ const selected = await walletStore.get('selected-account');
2611
+ globalThis.peernet.selectedAccount = new TextDecoder().decode(selected);
2612
+ // fixing account issue (string while needs to be a JSON)
2613
+ // TODO: remove when on mainnet
2614
+ try {
2615
+ this.accounts = JSON.parse(accounts);
2616
+ }
2617
+ catch {
2618
+ this.accounts = [accounts.split(',')];
2619
+ }
2620
+ }
2621
+ else {
2622
+ const importee = await import(/* webpackChunkName: "generate-account" */ './index-639f2260.js');
2623
+ const generateAccount = importee.default;
2624
+ const { identity, accounts, config } = await generateAccount(this.network);
2625
+ // await accountStore.put('config', JSON.stringify(config));
2626
+ await accountStore.put('public', JSON.stringify({ walletId: identity.walletId }));
2627
+ await walletStore.put('version', String(1));
2628
+ await walletStore.put('accounts', JSON.stringify(accounts));
2629
+ await walletStore.put('selected-account', accounts[0][1]);
2630
+ await walletStore.put('identity', JSON.stringify(identity));
2631
+ globalThis.peernet.selectedAccount = accounts[0][1];
2632
+ this.id = identity.walletId;
2633
+ }
2634
+ this._peerHandler = new PeerDiscovery(this.id);
2635
+ this.peerId = this.id;
2636
+ pubsub.subscribe('peer:connected', async (peer) => {
2637
+ // console.log(peer);
2638
+ // console.log({connected: peer.id, as: this._getPeerId(peer.id) });
2639
+ // peer.on('peernet.data', async (message) => {
2640
+ // const id = message.id
2641
+ // message = new PeernetMessage(Buffer.from(message.data.data))
2642
+ // const proto = protoFor(message.decoded.data)
2643
+ // this._protoHandler({id, proto}, peer)
2644
+ // })
2645
+ });
2646
+ /**
2647
+ * converts data -> message -> proto
2648
+ * @see DataHandler
2649
+ */
2650
+ pubsub.subscribe('peer:data', dataHandler);
2651
+ const importee = await import('./client-1c52a169.js');
2652
+ /**
2653
+ * @access public
2654
+ * @type {PeernetClient}
2655
+ */
2656
+ this.client = new importee.default(this.id, this.networkVersion, this.stars);
2657
+ if (globalThis.navigator) {
2658
+ globalThis.addEventListener('beforeunload', async () => this.client.close());
2659
+ }
2660
+ else {
2661
+ process.on('SIGTERM', async () => {
2662
+ process.stdin.resume();
2663
+ await this.client.close();
2664
+ process.exit();
2665
+ });
2666
+ }
2667
+ return this;
2533
2668
  }
2534
- return this
2535
- }
2536
-
2537
- addRequestHandler(name, method) {
2538
- this.requestProtos[name] = method;
2539
- }
2540
-
2541
- sendMessage(peer, id, data) {
2542
- if (peer.readyState === 'open') {
2543
- peer.send(data, id);
2544
- this.bw.up += data.length;
2545
- } else if (peer.readyState === 'closed') ;
2546
-
2547
- }
2548
-
2549
- async handleDHT(peer, id, proto) {
2550
- let { hash, store } = proto.decoded;
2551
- let has;
2552
-
2553
- if (store) {
2554
- store = globalThis[`${store}Store`];
2555
- has = store.private ? false : await store.has(hash);
2556
- } else {
2557
- has = await this.has(hash);
2669
+ addRequestHandler(name, method) {
2670
+ this.requestProtos[name] = method;
2558
2671
  }
2559
-
2560
- const data = await new globalThis.peernet.protos['peernet-dht-response']({hash, has});
2561
- const node = await this.prepareMessage(data);
2562
-
2563
- this.sendMessage(peer, id, node.encoded);
2564
- }
2565
-
2566
- async handleData(peer, id, proto) {
2567
- let { hash, store } = proto.decoded;
2568
- let data;
2569
- store = globalThis[`${store}Store`] || await this.whichStore([...this.stores], hash);
2570
-
2571
- if (store && !store.private) {
2572
- data = await store.get(hash);
2573
-
2574
- if (data) {
2575
- data = await new globalThis.peernet.protos['peernet-data-response']({hash, data});
2576
-
2672
+ sendMessage(peer, id, data) {
2673
+ if (peer.readyState === 'open') {
2674
+ peer.send(data, id);
2675
+ this.bw.up += data.length;
2676
+ }
2677
+ else if (peer.readyState === 'closed') ;
2678
+ }
2679
+ async handleDHT(peer, id, proto) {
2680
+ let { hash, store } = proto.decoded;
2681
+ let has;
2682
+ if (store) {
2683
+ store = globalThis[`${store}Store`];
2684
+ has = store.private ? false : await store.has(hash);
2685
+ }
2686
+ else {
2687
+ has = await this.has(hash);
2688
+ }
2689
+ const data = await new globalThis.peernet.protos['peernet-dht-response']({ hash, has });
2577
2690
  const node = await this.prepareMessage(data);
2578
2691
  this.sendMessage(peer, id, node.encoded);
2579
- }
2580
2692
  }
2581
- }
2582
-
2583
- async handleRequest(peer, id, proto) {
2584
- const method = this.requestProtos[proto.decoded.request];
2585
- if (method) {
2586
- const data = await method();
2587
- const node = await this.prepareMessage(data);
2588
- this.sendMessage(peer, id, node.encoded);
2693
+ async handleData(peer, id, proto) {
2694
+ let { hash, store } = proto.decoded;
2695
+ let data;
2696
+ store = globalThis[`${store}Store`] || await this.whichStore([...this.stores], hash);
2697
+ if (store && !store.private) {
2698
+ data = await store.get(hash);
2699
+ if (data) {
2700
+ data = await new globalThis.peernet.protos['peernet-data-response']({ hash, data });
2701
+ const node = await this.prepareMessage(data);
2702
+ this.sendMessage(peer, id, node.encoded);
2703
+ }
2704
+ }
2589
2705
  }
2590
- }
2591
-
2592
- /**
2593
- * @private
2594
- *
2595
- * @param {Buffer} message - peernet message
2596
- * @param {PeernetPeer} peer - peernet peer
2597
- */
2598
- async _protoHandler(message, peer, from) {
2599
- const {id, proto} = message;
2600
- this.bw.down += proto.encoded.length;
2601
- switch(proto.name) {
2602
- case 'peernet-dht': {
2603
- this.handleDHT(peer, id, proto);
2604
- break
2605
- }
2606
- case 'peenet-data': {
2607
- this.handleData(peer, id, proto);
2608
- break
2609
- }
2610
- case 'peernet-request': {
2611
- this.handleRequest(peer, id, proto);
2612
- }
2613
-
2614
- case 'peernet-ps': {
2615
- if (peer.peerId !== this.id) globalSub.publish(proto.decoded.topic, proto.decoded.data);
2616
- }
2706
+ async handleRequest(peer, id, proto) {
2707
+ const method = this.requestProtos[proto.decoded.request];
2708
+ if (method) {
2709
+ const data = await method();
2710
+ const node = await this.prepareMessage(data);
2711
+ this.sendMessage(peer, id, node.encoded);
2712
+ }
2617
2713
  }
2618
- }
2619
-
2620
- /**
2621
- * performs a walk and resolves first encounter
2622
- *
2623
- * @param {String} hash
2624
- */
2625
- async walk(hash) {
2626
- if (!hash) throw new Error('hash expected, received undefined')
2627
- const data = await new globalThis.peernet.protos['peernet-dht']({hash});
2628
- this.client.id;
2629
- const walk = async peer => {
2630
- const node = await this.prepareMessage(data);
2631
- let result = await peer.request(node.encoded);
2632
- result = new Uint8Array(Object.values(result));
2633
- const proto = await protoFor(result);
2634
- if (proto.name !== 'peernet-dht-response') throw dhtError(proto.name)
2635
-
2636
- // TODO: give ip and port (just used for location)
2637
- if (!peer.connection.remoteAddress || !peer.connection.localAddress) {
2638
- peer.connection.remoteFamily = 'ipv4';
2639
- peer.connection.remoteAddress = '127.0.0.1';
2640
- peer.connection.remotePort = '0000';
2641
- }
2642
-
2643
- const peerInfo = {
2644
- family: peer.connection.remoteFamily || peer.connection.localFamily,
2645
- address: peer.connection.remoteAddress || peer.connection.localAddress,
2646
- port: peer.connection.remotePort || peer.connection.localPort,
2647
- id: peer.peerId,
2648
- };
2649
-
2650
- if (proto.decoded.has) this.dht.addProvider(peerInfo, proto.decoded.hash);
2651
- };
2652
- let walks = [];
2653
- for (const peer of this.connections) {
2654
- if (peer.peerId !== this.id) {
2655
- walks.push(walk(peer));
2656
- }
2714
+ /**
2715
+ * @private
2716
+ *
2717
+ * @param {Buffer} message - peernet message
2718
+ * @param {PeernetPeer} peer - peernet peer
2719
+ */
2720
+ async _protoHandler(message, peer, from) {
2721
+ const { id, proto } = message;
2722
+ this.bw.down += proto.encoded.length;
2723
+ switch (proto.name) {
2724
+ case 'peernet-dht': {
2725
+ this.handleDHT(peer, id, proto);
2726
+ break;
2727
+ }
2728
+ case 'peenet-data': {
2729
+ this.handleData(peer, id, proto);
2730
+ break;
2731
+ }
2732
+ case 'peernet-request': {
2733
+ this.handleRequest(peer, id, proto);
2734
+ }
2735
+ case 'peernet-ps': {
2736
+ if (peer.peerId !== this.id)
2737
+ globalSub.publish(proto.decoded.topic, proto.decoded.data);
2738
+ }
2739
+ }
2657
2740
  }
2658
- return Promise.all(walks)
2659
- }
2660
-
2661
- /**
2662
- * Override DHT behavior, try's finding the content three times
2663
- *
2664
- * @param {String} hash
2665
- */
2666
- async providersFor(hash) {
2667
- let providers = await this.dht.providersFor(hash);
2668
- // walk the network to find a provider
2669
- if (!providers || providers.length === 0) {
2670
- await this.walk(hash);
2671
- providers = await this.dht.providersFor(hash);
2672
- // second walk the network to find a provider
2673
- if (!providers || providers.length === 0) {
2674
- await this.walk(hash);
2675
- providers = await this.dht.providersFor(hash);
2676
- }
2677
- // last walk
2678
- if (!providers || providers.length === 0) {
2679
- await this.walk(hash);
2680
- providers = await this.dht.providersFor(hash);
2681
- }
2682
- }
2683
- // undefined if no providers given
2684
- return providers
2685
- }
2686
-
2687
- get block() {
2688
- return {
2689
- get: async (hash) => {
2690
- const data = await blockStore.has(hash);
2691
- if (data) return blockStore.get(hash)
2692
- return this.requestData(hash, 'block')
2693
- },
2694
- put: async (hash, data) => {
2695
- if (await blockStore.has(hash)) return
2696
- return await blockStore.put(hash, data)
2697
- },
2698
- has: async (hash) => await blockStore.has(hash, 'block'),
2741
+ /**
2742
+ * performs a walk and resolves first encounter
2743
+ *
2744
+ * @param {String} hash
2745
+ */
2746
+ async walk(hash) {
2747
+ if (!hash)
2748
+ throw new Error('hash expected, received undefined');
2749
+ const data = await new globalThis.peernet.protos['peernet-dht']({ hash });
2750
+ this.client.id;
2751
+ const walk = async (peer) => {
2752
+ const node = await this.prepareMessage(data);
2753
+ let result = await peer.request(node.encoded);
2754
+ result = new Uint8Array(Object.values(result));
2755
+ const proto = await protoFor(result);
2756
+ if (proto.name !== 'peernet-dht-response')
2757
+ throw dhtError(proto.name);
2758
+ // TODO: give ip and port (just used for location)
2759
+ if (!peer.connection.remoteAddress || !peer.connection.localAddress) {
2760
+ peer.connection.remoteFamily = 'ipv4';
2761
+ peer.connection.remoteAddress = '127.0.0.1';
2762
+ peer.connection.remotePort = '0000';
2763
+ }
2764
+ const peerInfo = {
2765
+ family: peer.connection.remoteFamily || peer.connection.localFamily,
2766
+ address: peer.connection.remoteAddress || peer.connection.localAddress,
2767
+ port: peer.connection.remotePort || peer.connection.localPort,
2768
+ id: peer.peerId,
2769
+ };
2770
+ if (proto.decoded.has)
2771
+ this.dht.addProvider(peerInfo, proto.decoded.hash);
2772
+ };
2773
+ let walks = [];
2774
+ for (const peer of this.connections) {
2775
+ if (peer.peerId !== this.id) {
2776
+ walks.push(walk(peer));
2777
+ }
2778
+ }
2779
+ return Promise.all(walks);
2699
2780
  }
2700
- }
2701
-
2702
- get transaction() {
2703
- return {
2704
- get: async (hash) => {
2705
- const data = await transactionStore.has(hash);
2706
- if (data) return await transactionStore.get(hash)
2707
- return this.requestData(hash, 'transaction')
2708
- },
2709
- put: async (hash, data) => {
2710
- if (await transactionStore.has(hash)) return
2711
- return await transactionStore.put(hash, data)
2712
- },
2713
- has: async (hash) => await transactionStore.has(hash),
2781
+ /**
2782
+ * Override DHT behavior, try's finding the content three times
2783
+ *
2784
+ * @param {String} hash
2785
+ */
2786
+ async providersFor(hash) {
2787
+ let providers = await this.dht.providersFor(hash);
2788
+ // walk the network to find a provider
2789
+ if (!providers || providers.length === 0) {
2790
+ await this.walk(hash);
2791
+ providers = await this.dht.providersFor(hash);
2792
+ // second walk the network to find a provider
2793
+ if (!providers || providers.length === 0) {
2794
+ await this.walk(hash);
2795
+ providers = await this.dht.providersFor(hash);
2796
+ }
2797
+ // last walk
2798
+ if (!providers || providers.length === 0) {
2799
+ await this.walk(hash);
2800
+ providers = await this.dht.providersFor(hash);
2801
+ }
2802
+ }
2803
+ // undefined if no providers given
2804
+ return providers;
2714
2805
  }
2715
- }
2716
-
2717
- async requestData(hash, store) {
2718
- const providers = await this.providersFor(hash);
2719
- if (!providers || providers.size === 0) throw nothingFoundError(hash)
2720
- debug(`found ${providers.size} provider(s) for ${hash}`);
2721
- // get closest peer on earth
2722
- const closestPeer = await this.dht.closestPeer(providers);
2723
- // get peer instance by id
2724
- if (!closestPeer || !closestPeer.id) return this.requestData(hash, store?.name || store)
2725
-
2726
- const id = closestPeer.id;
2727
- if (this.connections) {
2728
- let closest = this.connections.filter((peer) => {
2729
- if (peer.peerId === id) return peer
2730
- });
2731
-
2732
- let data = await new globalThis.peernet.protos['peernet-data']({hash, store: store?.name || store});
2733
-
2734
- const node = await this.prepareMessage(data);
2735
- if (closest[0]) data = await closest[0].request(node.encoded);
2736
- else {
2737
- closest = this.connections.filter((peer) => {
2738
- if (peer.peerId === id) return peer
2739
- });
2740
- if (closest[0]) data = await closest[0].request(node.encoded);
2741
- }
2742
- data = new Uint8Array(Object.values(data));
2743
- const proto = await protoFor(data);
2744
- // TODO: store data automaticly or not
2745
- return BufferToUint8Array(proto.decoded.data)
2746
-
2747
- // this.put(hash, proto.decoded.data)
2806
+ get block() {
2807
+ return {
2808
+ get: async (hash) => {
2809
+ const data = await blockStore.has(hash);
2810
+ if (data)
2811
+ return blockStore.get(hash);
2812
+ return this.requestData(hash, 'block');
2813
+ },
2814
+ put: async (hash, data) => {
2815
+ if (await blockStore.has(hash))
2816
+ return;
2817
+ return await blockStore.put(hash, data);
2818
+ },
2819
+ has: async (hash) => await blockStore.has(hash, 'block'),
2820
+ };
2748
2821
  }
2749
- return
2750
- }
2751
-
2752
-
2753
- get message() {
2754
- return {
2755
- /**
2756
- * Get content for given message hash
2757
- *
2758
- * @param {String} hash
2759
- */
2760
- get: async (hash) => {
2761
- debug(`get message ${hash}`);
2762
- const message = await messageStore.has(hash);
2763
- if (message) return await messageStore.get(hash)
2764
- return this.requestData(hash, 'message')
2765
- },
2766
- /**
2767
- * put message content
2768
- *
2769
- * @param {String} hash
2770
- * @param {Buffer} message
2771
- */
2772
- put: async (hash, message) => await messageStore.put(hash, message),
2773
- /**
2774
- * @param {String} hash
2775
- * @return {Boolean}
2776
- */
2777
- has: async (hash) => await messageStore.has(hash),
2822
+ get transaction() {
2823
+ return {
2824
+ get: async (hash) => {
2825
+ const data = await transactionStore.has(hash);
2826
+ if (data)
2827
+ return await transactionStore.get(hash);
2828
+ return this.requestData(hash, 'transaction');
2829
+ },
2830
+ put: async (hash, data) => {
2831
+ if (await transactionStore.has(hash))
2832
+ return;
2833
+ return await transactionStore.put(hash, data);
2834
+ },
2835
+ has: async (hash) => await transactionStore.has(hash),
2836
+ };
2778
2837
  }
2779
- }
2780
-
2781
- get data() {
2782
- return {
2783
- /**
2784
- * Get content for given data hash
2785
- *
2786
- * @param {String} hash
2787
- */
2788
- get: async (hash) => {
2789
- debug(`get data ${hash}`);
2790
- const data = await dataStore.has(hash);
2791
- if (data) return await dataStore.get(hash)
2792
- return this.requestData(hash, 'data')
2793
- },
2794
- /**
2795
- * put data content
2796
- *
2797
- * @param {String} hash
2798
- * @param {Buffer} data
2799
- */
2800
- put: async (hash, data) => await dataStore.put(hash, data),
2801
- /**
2802
- * @param {String} hash
2803
- * @return {Boolean}
2804
- */
2805
- has: async (hash) => await dataStore.has(hash),
2838
+ async requestData(hash, store) {
2839
+ const providers = await this.providersFor(hash);
2840
+ if (!providers || providers.size === 0)
2841
+ throw nothingFoundError(hash);
2842
+ debug(`found ${providers.size} provider(s) for ${hash}`);
2843
+ // get closest peer on earth
2844
+ const closestPeer = await this.dht.closestPeer(providers);
2845
+ // get peer instance by id
2846
+ if (!closestPeer || !closestPeer.id)
2847
+ return this.requestData(hash, store?.name || store);
2848
+ const id = closestPeer.id;
2849
+ if (this.connections) {
2850
+ let closest = this.connections.filter((peer) => {
2851
+ if (peer.peerId === id)
2852
+ return peer;
2853
+ });
2854
+ let data = await new globalThis.peernet.protos['peernet-data']({ hash, store: store?.name || store });
2855
+ const node = await this.prepareMessage(data);
2856
+ if (closest[0])
2857
+ data = await closest[0].request(node.encoded);
2858
+ else {
2859
+ closest = this.connections.filter((peer) => {
2860
+ if (peer.peerId === id)
2861
+ return peer;
2862
+ });
2863
+ if (closest[0])
2864
+ data = await closest[0].request(node.encoded);
2865
+ }
2866
+ data = new Uint8Array(Object.values(data));
2867
+ const proto = await protoFor(data);
2868
+ // TODO: store data automaticly or not
2869
+ return BufferToUint8Array(proto.decoded.data);
2870
+ // this.put(hash, proto.decoded.data)
2871
+ }
2872
+ return;
2806
2873
  }
2807
- }
2808
-
2809
- get folder() {
2810
- return {
2811
- /**
2812
- * Get content for given data hash
2813
- *
2814
- * @param {String} hash
2815
- */
2816
- get: async (hash) => {
2817
- debug(`get data ${hash}`);
2818
- const data = await dataStore.has(hash);
2819
- if (data) return await dataStore.get(hash)
2820
- return this.requestData(hash, 'data')
2821
- },
2822
- /**
2823
- * put data content
2824
- *
2825
- * @param {String} hash
2826
- * @param {Buffer} data
2827
- */
2828
- put: async (hash, data) => await dataStore.put(hash, data),
2829
- /**
2830
- * @param {String} hash
2831
- * @return {Boolean}
2832
- */
2833
- has: async (hash) => await dataStore.has(hash),
2874
+ get message() {
2875
+ return {
2876
+ /**
2877
+ * Get content for given message hash
2878
+ *
2879
+ * @param {String} hash
2880
+ */
2881
+ get: async (hash) => {
2882
+ debug(`get message ${hash}`);
2883
+ const message = await messageStore.has(hash);
2884
+ if (message)
2885
+ return await messageStore.get(hash);
2886
+ return this.requestData(hash, 'message');
2887
+ },
2888
+ /**
2889
+ * put message content
2890
+ *
2891
+ * @param {String} hash
2892
+ * @param {Buffer} message
2893
+ */
2894
+ put: async (hash, message) => await messageStore.put(hash, message),
2895
+ /**
2896
+ * @param {String} hash
2897
+ * @return {Boolean}
2898
+ */
2899
+ has: async (hash) => await messageStore.has(hash),
2900
+ };
2834
2901
  }
2835
- }
2836
-
2837
- async addFolder(files) {
2838
- const links = [];
2839
- for (const file of files) {
2840
- const fileNode = await new globalThis.peernet.protos['peernet-file'](file);
2841
- const hash = await fileNode.hash;
2842
- await dataStore.put(hash, fileNode.encoded);
2843
- links.push({hash, path: file.path});
2844
- }
2845
- const node = await new globalThis.peernet.protos['peernet-file']({path: '/', links});
2846
- const hash = await node.hash;
2847
- await dataStore.put(hash, node.encoded);
2848
-
2849
- return hash
2850
- }
2851
-
2852
- async ls(hash, options) {
2853
- let data;
2854
- const has = await dataStore.has(hash);
2855
- data = has ? await dataStore.get(hash) : await this.requestData(hash, 'data');
2856
-
2857
- const node = await new peernet.protos['peernet-file'](data);
2858
- await node.decode();
2859
- console.log(data);
2860
- const paths = [];
2861
- if (node.decoded?.links.length === 0) throw new Error(`${hash} is a file`)
2862
- for (const {path, hash} of node.decoded.links) {
2863
- paths.push({path, hash});
2864
- }
2865
- if (options?.pin) await dataStore.put(hash, node.encoded);
2866
- return paths
2867
- }
2868
-
2869
- async cat(hash, options) {
2870
- let data;
2871
- const has = await dataStore.has(hash);
2872
- data = has ? await dataStore.get(hash) : await this.requestData(hash, 'data');
2873
- const node = await new peernet.protos['peernet-file'](data);
2874
-
2875
- if (node.decoded?.links.length > 0) throw new Error(`${hash} is a directory`)
2876
- if (options?.pin) await dataStore.put(hash, node.encoded);
2877
- return node.decoded.content
2878
- }
2879
-
2880
- /**
2881
- * goes trough given stores and tries to find data for given hash
2882
- * @param {Array} stores
2883
- * @param {string} hash
2884
- */
2885
- async whichStore(stores, hash) {
2886
- let store = stores.pop();
2887
- store = globalThis[`${store}Store`];
2888
- if (store) {
2889
- const has = await store.has(hash);
2890
- if (has) return store
2891
- if (stores.length > 0) return this.whichStore(stores, hash)
2892
- } else return
2893
- }
2894
-
2895
- /**
2896
- * Get content for given hash
2897
- *
2898
- * @param {String} hash - the hash of the wanted data
2899
- * @param {String} store - storeName to access
2900
- */
2901
- async get(hash, store) {
2902
- debug(`get ${hash}`);
2903
- let data;
2904
- if (store) store = globalThis[`${store}Store`];
2905
- if (!store) store = await this.whichStore([...this.stores], hash);
2906
- if (store && await store.has(hash)) data = await store.get(hash);
2907
- if (data) return data
2908
-
2909
- return this.requestData(hash, store?.name || store)
2910
- }
2911
-
2912
- /**
2913
- * put content
2914
- *
2915
- * @param {String} hash
2916
- * @param {Buffer} data
2917
- * @param {String} store - storeName to access
2918
- */
2919
- async put(hash, data, store = 'data') {
2920
- store = globalThis[`${store}Store`];
2921
- return store.put(hash, data)
2922
- }
2923
-
2924
- /**
2925
- * @param {String} hash
2926
- * @return {Boolean}
2927
- */
2928
- async has(hash) {
2929
- const store = await this.whichStore([...this.stores], hash);
2930
- if (store) {
2931
- return store.private ? false : true
2902
+ get data() {
2903
+ return {
2904
+ /**
2905
+ * Get content for given data hash
2906
+ *
2907
+ * @param {String} hash
2908
+ */
2909
+ get: async (hash) => {
2910
+ debug(`get data ${hash}`);
2911
+ const data = await dataStore.has(hash);
2912
+ if (data)
2913
+ return await dataStore.get(hash);
2914
+ return this.requestData(hash, 'data');
2915
+ },
2916
+ /**
2917
+ * put data content
2918
+ *
2919
+ * @param {String} hash
2920
+ * @param {Buffer} data
2921
+ */
2922
+ put: async (hash, data) => await dataStore.put(hash, data),
2923
+ /**
2924
+ * @param {String} hash
2925
+ * @return {Boolean}
2926
+ */
2927
+ has: async (hash) => await dataStore.has(hash),
2928
+ };
2932
2929
  }
2933
- return false
2934
- }
2935
-
2936
- /**
2937
- *
2938
- * @param {String} topic
2939
- * @param {String|Object|Array|Boolean|Buffer} data
2940
- */
2941
- async publish(topic, data) {
2942
- // globalSub.publish(topic, data)
2943
- const id = Math.random().toString(36).slice(-12);
2944
- data = await new globalThis.peernet.protos['peernet-ps']({data, topic});
2945
- for (const peer of this.connections) {
2946
- if (peer.peerId !== this.peerId) {
2947
- const node = await this.prepareMessage(data);
2948
- this.sendMessage(peer, id, node.encoded);
2949
- }
2950
- // TODO: if peer subscribed
2930
+ get folder() {
2931
+ return {
2932
+ /**
2933
+ * Get content for given data hash
2934
+ *
2935
+ * @param {String} hash
2936
+ */
2937
+ get: async (hash) => {
2938
+ debug(`get data ${hash}`);
2939
+ const data = await dataStore.has(hash);
2940
+ if (data)
2941
+ return await dataStore.get(hash);
2942
+ return this.requestData(hash, 'data');
2943
+ },
2944
+ /**
2945
+ * put data content
2946
+ *
2947
+ * @param {String} hash
2948
+ * @param {Buffer} data
2949
+ */
2950
+ put: async (hash, data) => await dataStore.put(hash, data),
2951
+ /**
2952
+ * @param {String} hash
2953
+ * @return {Boolean}
2954
+ */
2955
+ has: async (hash) => await dataStore.has(hash),
2956
+ };
2957
+ }
2958
+ async addFolder(files) {
2959
+ const links = [];
2960
+ for (const file of files) {
2961
+ const fileNode = await new globalThis.peernet.protos['peernet-file'](file);
2962
+ const hash = await fileNode.hash;
2963
+ await dataStore.put(hash, fileNode.encoded);
2964
+ links.push({ hash, path: file.path });
2965
+ }
2966
+ const node = await new globalThis.peernet.protos['peernet-file']({ path: '/', links });
2967
+ const hash = await node.hash;
2968
+ await dataStore.put(hash, node.encoded);
2969
+ return hash;
2970
+ }
2971
+ async ls(hash, options) {
2972
+ let data;
2973
+ const has = await dataStore.has(hash);
2974
+ data = has ? await dataStore.get(hash) : await this.requestData(hash, 'data');
2975
+ const node = await new peernet.protos['peernet-file'](data);
2976
+ await node.decode();
2977
+ console.log(data);
2978
+ const paths = [];
2979
+ if (node.decoded?.links.length === 0)
2980
+ throw new Error(`${hash} is a file`);
2981
+ for (const { path, hash } of node.decoded.links) {
2982
+ paths.push({ path, hash });
2983
+ }
2984
+ if (options?.pin)
2985
+ await dataStore.put(hash, node.encoded);
2986
+ return paths;
2987
+ }
2988
+ async cat(hash, options) {
2989
+ let data;
2990
+ const has = await dataStore.has(hash);
2991
+ data = has ? await dataStore.get(hash) : await this.requestData(hash, 'data');
2992
+ const node = await new peernet.protos['peernet-file'](data);
2993
+ if (node.decoded?.links.length > 0)
2994
+ throw new Error(`${hash} is a directory`);
2995
+ if (options?.pin)
2996
+ await dataStore.put(hash, node.encoded);
2997
+ return node.decoded.content;
2998
+ }
2999
+ /**
3000
+ * goes trough given stores and tries to find data for given hash
3001
+ * @param {Array} stores
3002
+ * @param {string} hash
3003
+ */
3004
+ async whichStore(stores, hash) {
3005
+ let store = stores.pop();
3006
+ store = globalThis[`${store}Store`];
3007
+ if (store) {
3008
+ const has = await store.has(hash);
3009
+ if (has)
3010
+ return store;
3011
+ if (stores.length > 0)
3012
+ return this.whichStore(stores, hash);
3013
+ }
3014
+ else
3015
+ return;
3016
+ }
3017
+ /**
3018
+ * Get content for given hash
3019
+ *
3020
+ * @param {String} hash - the hash of the wanted data
3021
+ * @param {String} store - storeName to access
3022
+ */
3023
+ async get(hash, store) {
3024
+ debug(`get ${hash}`);
3025
+ let data;
3026
+ if (store)
3027
+ store = globalThis[`${store}Store`];
3028
+ if (!store)
3029
+ store = await this.whichStore([...this.stores], hash);
3030
+ if (store && await store.has(hash))
3031
+ data = await store.get(hash);
3032
+ if (data)
3033
+ return data;
3034
+ return this.requestData(hash, store?.name || store);
3035
+ }
3036
+ /**
3037
+ * put content
3038
+ *
3039
+ * @param {String} hash
3040
+ * @param {Buffer} data
3041
+ * @param {String} store - storeName to access
3042
+ */
3043
+ async put(hash, data, store = 'data') {
3044
+ store = globalThis[`${store}Store`];
3045
+ return store.put(hash, data);
3046
+ }
3047
+ /**
3048
+ * @param {String} hash
3049
+ * @return {Boolean}
3050
+ */
3051
+ async has(hash) {
3052
+ const store = await this.whichStore([...this.stores], hash);
3053
+ if (store) {
3054
+ return store.private ? false : true;
3055
+ }
3056
+ return false;
3057
+ }
3058
+ /**
3059
+ *
3060
+ * @param {String} topic
3061
+ * @param {String|Object|Array|Boolean|Buffer} data
3062
+ */
3063
+ async publish(topic, data) {
3064
+ // globalSub.publish(topic, data)
3065
+ const id = Math.random().toString(36).slice(-12);
3066
+ data = await new globalThis.peernet.protos['peernet-ps']({ data, topic });
3067
+ for (const peer of this.connections) {
3068
+ if (peer.peerId !== this.peerId) {
3069
+ const node = await this.prepareMessage(data);
3070
+ this.sendMessage(peer, id, node.encoded);
3071
+ }
3072
+ // TODO: if peer subscribed
3073
+ }
3074
+ }
3075
+ createHash(data, name) {
3076
+ return new CodeHash(data, { name });
3077
+ }
3078
+ /**
3079
+ *
3080
+ * @param {String} topic
3081
+ * @param {Method} cb
3082
+ */
3083
+ async subscribe(topic, callback) {
3084
+ // TODO: if peer subscribed
3085
+ globalSub.subscribe(topic, callback);
3086
+ }
3087
+ async removePeer(peer) {
3088
+ return this.client.removePeer(peer);
3089
+ }
3090
+ get Buffer() {
3091
+ return Buffer;
2951
3092
  }
2952
- }
2953
-
2954
- createHash(data, name) {
2955
- return new CodeHash(data, {name})
2956
- }
2957
-
2958
- /**
2959
- *
2960
- * @param {String} topic
2961
- * @param {Method} cb
2962
- */
2963
- async subscribe(topic, callback) {
2964
- // TODO: if peer subscribed
2965
- globalSub.subscribe(topic, callback);
2966
- }
2967
-
2968
- async removePeer(peer) {
2969
- return this.client.removePeer(peer)
2970
- }
2971
-
2972
- get Buffer() {
2973
- return Buffer
2974
- }
2975
3093
  }
2976
3094
  globalThis.Peernet = Peernet;
2977
3095