@leofcoin/chain 1.7.73 → 1.7.75

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.
@@ -5201,6 +5201,12 @@ class State extends Contract {
5201
5201
  get shouldSync() {
5202
5202
  if (this.#chainSyncing)
5203
5203
  return false;
5204
+ // Check if we have any connected peers with the same version
5205
+ const compatiblePeers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
5206
+ if (compatiblePeers.length === 0) {
5207
+ debug$1('No compatible peers available for sync');
5208
+ return false;
5209
+ }
5204
5210
  if (!this.#chainSyncing ||
5205
5211
  this.#resolveErrored ||
5206
5212
  this.#syncState === 'errored' ||
@@ -5209,6 +5215,25 @@ class State extends Contract {
5209
5215
  return true;
5210
5216
  return false;
5211
5217
  }
5218
+ async #waitForPeers(timeoutMs = 30000) {
5219
+ return new Promise((resolve) => {
5220
+ const checkPeers = () => {
5221
+ const peers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
5222
+ if (peers.length > 0) {
5223
+ resolve(true);
5224
+ }
5225
+ };
5226
+ // Check immediately
5227
+ checkPeers();
5228
+ // Set up interval to check periodically
5229
+ const interval = setInterval(checkPeers, 1000);
5230
+ // Set timeout
5231
+ setTimeout(() => {
5232
+ clearInterval(interval);
5233
+ resolve(false);
5234
+ }, timeoutMs);
5235
+ });
5236
+ }
5212
5237
  async triggerSync() {
5213
5238
  const latest = await this.#getLatestBlock();
5214
5239
  return this.syncChain(latest);
@@ -5268,6 +5293,114 @@ class VersionControl extends State {
5268
5293
  }
5269
5294
  }
5270
5295
 
5296
+ /**
5297
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
5298
+ */
5299
+ class ConnectionMonitor {
5300
+ #isMonitoring = false;
5301
+ #checkInterval = null;
5302
+ #reconnectAttempts = 0;
5303
+ #maxReconnectAttempts = 10;
5304
+ #reconnectDelay = 5000;
5305
+ #healthCheckInterval = 10000;
5306
+ #version;
5307
+ get isMonitoring() {
5308
+ return this.#isMonitoring;
5309
+ }
5310
+ get connectedPeers() {
5311
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
5312
+ }
5313
+ get compatiblePeers() {
5314
+ return this.connectedPeers.filter((peer) => peer.version === this.#version);
5315
+ }
5316
+ constructor(version) {
5317
+ this.#version = version;
5318
+ console.log(`🔗 Connection Monitor initialized for version: ${this.#version}`);
5319
+ }
5320
+ start() {
5321
+ if (this.#isMonitoring)
5322
+ return;
5323
+ this.#isMonitoring = true;
5324
+ console.log('🔄 Starting connection monitor...');
5325
+ this.#checkInterval = setInterval(() => {
5326
+ this.#healthCheck();
5327
+ }, this.#healthCheckInterval);
5328
+ // Initial health check
5329
+ this.#healthCheck();
5330
+ }
5331
+ stop() {
5332
+ if (!this.#isMonitoring)
5333
+ return;
5334
+ this.#isMonitoring = false;
5335
+ if (this.#checkInterval) {
5336
+ clearInterval(this.#checkInterval);
5337
+ this.#checkInterval = null;
5338
+ }
5339
+ console.log('⏹️ Connection monitor stopped');
5340
+ }
5341
+ async #healthCheck() {
5342
+ const connectedPeers = this.connectedPeers;
5343
+ const compatiblePeers = this.compatiblePeers;
5344
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
5345
+ if (connectedPeers.length === 0) {
5346
+ console.warn('⚠️ No peer connections detected');
5347
+ await this.#attemptReconnection();
5348
+ }
5349
+ else if (compatiblePeers.length === 0) {
5350
+ console.warn('⚠️ No compatible peers found');
5351
+ // Could attempt to find compatible peers or trigger version negotiation
5352
+ }
5353
+ else {
5354
+ // Reset reconnect attempts on successful connection
5355
+ this.#reconnectAttempts = 0;
5356
+ }
5357
+ // Publish connection status
5358
+ globalThis.pubsub?.publish('connection-status', {
5359
+ connected: connectedPeers.length,
5360
+ compatible: compatiblePeers.length,
5361
+ healthy: compatiblePeers.length > 0
5362
+ });
5363
+ }
5364
+ async #attemptReconnection() {
5365
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
5366
+ console.error('❌ Max reconnection attempts reached');
5367
+ return;
5368
+ }
5369
+ this.#reconnectAttempts++;
5370
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
5371
+ try {
5372
+ // Try to restart the network
5373
+ if (globalThis.peernet?.start) {
5374
+ await globalThis.peernet.start();
5375
+ }
5376
+ // Wait a bit before next check
5377
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
5378
+ }
5379
+ catch (error) {
5380
+ console.error('❌ Reconnection failed:', error.message);
5381
+ // Exponential backoff
5382
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
5383
+ }
5384
+ }
5385
+ async waitForPeers(timeoutMs = 30000) {
5386
+ return new Promise((resolve) => {
5387
+ const startTime = Date.now();
5388
+ const checkPeers = () => {
5389
+ if (this.compatiblePeers.length > 0) {
5390
+ resolve(true);
5391
+ return;
5392
+ }
5393
+ if (Date.now() - startTime >= timeoutMs) {
5394
+ resolve(false);
5395
+ return;
5396
+ }
5397
+ setTimeout(checkPeers, 1000);
5398
+ };
5399
+ checkPeers();
5400
+ });
5401
+ }
5402
+ }
5403
+
5271
5404
  const debug = globalThis.createDebugger('leofcoin/chain');
5272
5405
  // check if browser or local
5273
5406
  class Chain extends VersionControl {
@@ -5280,6 +5413,10 @@ class Chain extends VersionControl {
5280
5413
  #participants;
5281
5414
  #participating;
5282
5415
  #jail;
5416
+ #peerConnectionRetries;
5417
+ #maxPeerRetries;
5418
+ #peerRetryDelay;
5419
+ #connectionMonitor;
5283
5420
  constructor(config) {
5284
5421
  super(config);
5285
5422
  this.#slotTime = 10000;
@@ -5291,6 +5428,9 @@ class Chain extends VersionControl {
5291
5428
  this.#participants = [];
5292
5429
  this.#participating = false;
5293
5430
  this.#jail = [];
5431
+ this.#peerConnectionRetries = new Map();
5432
+ this.#maxPeerRetries = 5;
5433
+ this.#peerRetryDelay = 5000;
5294
5434
  this.#addTransaction = async (message) => {
5295
5435
  const transaction = new TransactionMessage(message);
5296
5436
  const hash = await transaction.hash();
@@ -5365,6 +5505,7 @@ class Chain extends VersionControl {
5365
5505
  // this.node = await new Node()
5366
5506
  this.#participants = [];
5367
5507
  this.#participating = false;
5508
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
5368
5509
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
5369
5510
  if (!initialized)
5370
5511
  await this.#setup();
@@ -5372,8 +5513,11 @@ class Chain extends VersionControl {
5372
5513
  // this.#state = new State()
5373
5514
  // todo some functions rely on state
5374
5515
  await super.init();
5516
+ // Start connection monitoring
5517
+ this.#connectionMonitor.start();
5375
5518
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
5376
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
5519
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
5520
+ return new BWMessage(bw);
5377
5521
  });
5378
5522
  // await globalThis.peernet.addRequestHandler('peerId', () => {
5379
5523
  // let node =
@@ -5454,7 +5598,7 @@ class Chain extends VersionControl {
5454
5598
  }
5455
5599
  }
5456
5600
  if (this.wantList.length > 0) {
5457
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
5601
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
5458
5602
  for (let i = 0; i < promises.length; i++) {
5459
5603
  const result = promises[i];
5460
5604
  if (result.status === 'fulfilled')
@@ -5781,7 +5925,7 @@ class Chain extends VersionControl {
5781
5925
  * @returns
5782
5926
  */
5783
5927
  internalCall(sender, contract, method, parameters) {
5784
- globalThis.msg = this.#createMessage(sender, contract);
5928
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
5785
5929
  return this.machine.execute(contract, method, parameters);
5786
5930
  }
5787
5931
  /**
@@ -5792,11 +5936,11 @@ class Chain extends VersionControl {
5792
5936
  * @returns
5793
5937
  */
5794
5938
  call(contract, method, parameters) {
5795
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5939
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5796
5940
  return this.machine.execute(contract, method, parameters);
5797
5941
  }
5798
5942
  staticCall(contract, method, parameters) {
5799
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5943
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5800
5944
  return this.machine.get(contract, method, parameters);
5801
5945
  }
5802
5946
  mint(to, amount) {
@@ -5826,6 +5970,27 @@ class Chain extends VersionControl {
5826
5970
  lookup(name) {
5827
5971
  return this.call(addresses.nameService, 'lookup', [name]);
5828
5972
  }
5973
+ #monitorPeerConnections() {
5974
+ setInterval(() => {
5975
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
5976
+ debug(`Connected peers: ${connectedPeers.length}`);
5977
+ if (connectedPeers.length === 0) {
5978
+ debug('No peers connected, attempting to reconnect...');
5979
+ this.#attemptPeerReconnection();
5980
+ }
5981
+ }, 10000); // Check every 10 seconds
5982
+ }
5983
+ async #attemptPeerReconnection() {
5984
+ try {
5985
+ // Try to reconnect to star servers
5986
+ if (globalThis.peernet && globalThis.peernet.start) {
5987
+ await globalThis.peernet.start();
5988
+ }
5989
+ }
5990
+ catch (error) {
5991
+ console.warn('Failed to reconnect to peers:', error.message);
5992
+ }
5993
+ }
5829
5994
  }
5830
5995
 
5831
5996
  export { Chain as default };
@@ -1,4 +1,4 @@
1
- import { L as LittlePubSub } from './node-browser-BvxzAdLe.js';
1
+ import { L as LittlePubSub } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
4
4
 
@@ -1,4 +1,4 @@
1
- import { F as FormatInterface } from './node-browser-BvxzAdLe.js';
1
+ import { F as FormatInterface } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
4
4
 
@@ -8495,7 +8495,7 @@ class Peernet {
8495
8495
  this.root = options.root;
8496
8496
  const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
8497
8497
  // FolderMessageResponse
8498
- } = await import(/* webpackChunkName: "messages" */ './messages-CW17jRdc-c9cSXiiQ.js');
8498
+ } = await import(/* webpackChunkName: "messages" */ './messages-CW17jRdc-Dtrj-vba.js');
8499
8499
  /**
8500
8500
  * proto Object containing protos
8501
8501
  * @type {Object}
@@ -8589,7 +8589,7 @@ class Peernet {
8589
8589
  if (this.#starting || this.#started)
8590
8590
  return;
8591
8591
  this.#starting = true;
8592
- const importee = await import('./client-DD7vhDK_-UAymLS2i.js');
8592
+ const importee = await import('./client-DD7vhDK_-BdNAdRzV.js');
8593
8593
  /**
8594
8594
  * @access public
8595
8595
  * @type {PeernetClient}
@@ -9078,7 +9078,7 @@ globalThis.Peernet = Peernet;
9078
9078
  var networks = {
9079
9079
  leofcoin: {
9080
9080
  peach: {
9081
- stars: ['wss://star.leofcoin.org'] // todo webrtc and bittorent stars
9081
+ stars: ['wss://star-testnet.leofcoin.org', 'wss://star.leofcoin.org'] // Separate testnet stars
9082
9082
  }
9083
9083
  }
9084
9084
  };
@@ -1,3 +1,3 @@
1
- export { N as default } from './node-browser-BvxzAdLe.js';
1
+ export { N as default } from './node-browser-DMmrhyQS.js';
2
2
  import './identity--VAIVSMm-DTWL357I.js';
3
3
  import './index-DUfUgiQY.js';
package/exports/chain.js CHANGED
@@ -1347,6 +1347,12 @@ class State extends Contract {
1347
1347
  get shouldSync() {
1348
1348
  if (this.#chainSyncing)
1349
1349
  return false;
1350
+ // Check if we have any connected peers with the same version
1351
+ const compatiblePeers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
1352
+ if (compatiblePeers.length === 0) {
1353
+ debug$1('No compatible peers available for sync');
1354
+ return false;
1355
+ }
1350
1356
  if (!this.#chainSyncing ||
1351
1357
  this.#resolveErrored ||
1352
1358
  this.#syncState === 'errored' ||
@@ -1355,6 +1361,25 @@ class State extends Contract {
1355
1361
  return true;
1356
1362
  return false;
1357
1363
  }
1364
+ async #waitForPeers(timeoutMs = 30000) {
1365
+ return new Promise((resolve) => {
1366
+ const checkPeers = () => {
1367
+ const peers = Object.values(globalThis.peernet.connections || {}).filter((peer) => peer.connected && peer.version === this.version);
1368
+ if (peers.length > 0) {
1369
+ resolve(true);
1370
+ }
1371
+ };
1372
+ // Check immediately
1373
+ checkPeers();
1374
+ // Set up interval to check periodically
1375
+ const interval = setInterval(checkPeers, 1000);
1376
+ // Set timeout
1377
+ setTimeout(() => {
1378
+ clearInterval(interval);
1379
+ resolve(false);
1380
+ }, timeoutMs);
1381
+ });
1382
+ }
1358
1383
  async triggerSync() {
1359
1384
  const latest = await this.#getLatestBlock();
1360
1385
  return this.syncChain(latest);
@@ -1414,6 +1439,114 @@ class VersionControl extends State {
1414
1439
  }
1415
1440
  }
1416
1441
 
1442
+ /**
1443
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
1444
+ */
1445
+ class ConnectionMonitor {
1446
+ #isMonitoring = false;
1447
+ #checkInterval = null;
1448
+ #reconnectAttempts = 0;
1449
+ #maxReconnectAttempts = 10;
1450
+ #reconnectDelay = 5000;
1451
+ #healthCheckInterval = 10000;
1452
+ #version;
1453
+ get isMonitoring() {
1454
+ return this.#isMonitoring;
1455
+ }
1456
+ get connectedPeers() {
1457
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
1458
+ }
1459
+ get compatiblePeers() {
1460
+ return this.connectedPeers.filter((peer) => peer.version === this.#version);
1461
+ }
1462
+ constructor(version) {
1463
+ this.#version = version;
1464
+ console.log(`🔗 Connection Monitor initialized for version: ${this.#version}`);
1465
+ }
1466
+ start() {
1467
+ if (this.#isMonitoring)
1468
+ return;
1469
+ this.#isMonitoring = true;
1470
+ console.log('🔄 Starting connection monitor...');
1471
+ this.#checkInterval = setInterval(() => {
1472
+ this.#healthCheck();
1473
+ }, this.#healthCheckInterval);
1474
+ // Initial health check
1475
+ this.#healthCheck();
1476
+ }
1477
+ stop() {
1478
+ if (!this.#isMonitoring)
1479
+ return;
1480
+ this.#isMonitoring = false;
1481
+ if (this.#checkInterval) {
1482
+ clearInterval(this.#checkInterval);
1483
+ this.#checkInterval = null;
1484
+ }
1485
+ console.log('⏹️ Connection monitor stopped');
1486
+ }
1487
+ async #healthCheck() {
1488
+ const connectedPeers = this.connectedPeers;
1489
+ const compatiblePeers = this.compatiblePeers;
1490
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
1491
+ if (connectedPeers.length === 0) {
1492
+ console.warn('⚠️ No peer connections detected');
1493
+ await this.#attemptReconnection();
1494
+ }
1495
+ else if (compatiblePeers.length === 0) {
1496
+ console.warn('⚠️ No compatible peers found');
1497
+ // Could attempt to find compatible peers or trigger version negotiation
1498
+ }
1499
+ else {
1500
+ // Reset reconnect attempts on successful connection
1501
+ this.#reconnectAttempts = 0;
1502
+ }
1503
+ // Publish connection status
1504
+ globalThis.pubsub?.publish('connection-status', {
1505
+ connected: connectedPeers.length,
1506
+ compatible: compatiblePeers.length,
1507
+ healthy: compatiblePeers.length > 0
1508
+ });
1509
+ }
1510
+ async #attemptReconnection() {
1511
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
1512
+ console.error('❌ Max reconnection attempts reached');
1513
+ return;
1514
+ }
1515
+ this.#reconnectAttempts++;
1516
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
1517
+ try {
1518
+ // Try to restart the network
1519
+ if (globalThis.peernet?.start) {
1520
+ await globalThis.peernet.start();
1521
+ }
1522
+ // Wait a bit before next check
1523
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
1524
+ }
1525
+ catch (error) {
1526
+ console.error('❌ Reconnection failed:', error.message);
1527
+ // Exponential backoff
1528
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
1529
+ }
1530
+ }
1531
+ async waitForPeers(timeoutMs = 30000) {
1532
+ return new Promise((resolve) => {
1533
+ const startTime = Date.now();
1534
+ const checkPeers = () => {
1535
+ if (this.compatiblePeers.length > 0) {
1536
+ resolve(true);
1537
+ return;
1538
+ }
1539
+ if (Date.now() - startTime >= timeoutMs) {
1540
+ resolve(false);
1541
+ return;
1542
+ }
1543
+ setTimeout(checkPeers, 1000);
1544
+ };
1545
+ checkPeers();
1546
+ });
1547
+ }
1548
+ }
1549
+
1417
1550
  const debug = globalThis.createDebugger('leofcoin/chain');
1418
1551
  // check if browser or local
1419
1552
  class Chain extends VersionControl {
@@ -1426,6 +1559,10 @@ class Chain extends VersionControl {
1426
1559
  #participants;
1427
1560
  #participating;
1428
1561
  #jail;
1562
+ #peerConnectionRetries;
1563
+ #maxPeerRetries;
1564
+ #peerRetryDelay;
1565
+ #connectionMonitor;
1429
1566
  constructor(config) {
1430
1567
  super(config);
1431
1568
  this.#slotTime = 10000;
@@ -1437,6 +1574,9 @@ class Chain extends VersionControl {
1437
1574
  this.#participants = [];
1438
1575
  this.#participating = false;
1439
1576
  this.#jail = [];
1577
+ this.#peerConnectionRetries = new Map();
1578
+ this.#maxPeerRetries = 5;
1579
+ this.#peerRetryDelay = 5000;
1440
1580
  this.#addTransaction = async (message) => {
1441
1581
  const transaction = new TransactionMessage(message);
1442
1582
  const hash = await transaction.hash();
@@ -1511,6 +1651,7 @@ class Chain extends VersionControl {
1511
1651
  // this.node = await new Node()
1512
1652
  this.#participants = [];
1513
1653
  this.#participating = false;
1654
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
1514
1655
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
1515
1656
  if (!initialized)
1516
1657
  await this.#setup();
@@ -1518,8 +1659,11 @@ class Chain extends VersionControl {
1518
1659
  // this.#state = new State()
1519
1660
  // todo some functions rely on state
1520
1661
  await super.init();
1662
+ // Start connection monitoring
1663
+ this.#connectionMonitor.start();
1521
1664
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
1522
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
1665
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
1666
+ return new BWMessage(bw);
1523
1667
  });
1524
1668
  // await globalThis.peernet.addRequestHandler('peerId', () => {
1525
1669
  // let node =
@@ -1600,7 +1744,7 @@ class Chain extends VersionControl {
1600
1744
  }
1601
1745
  }
1602
1746
  if (this.wantList.length > 0) {
1603
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
1747
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
1604
1748
  for (let i = 0; i < promises.length; i++) {
1605
1749
  const result = promises[i];
1606
1750
  if (result.status === 'fulfilled')
@@ -1927,7 +2071,7 @@ class Chain extends VersionControl {
1927
2071
  * @returns
1928
2072
  */
1929
2073
  internalCall(sender, contract, method, parameters) {
1930
- globalThis.msg = this.#createMessage(sender, contract);
2074
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
1931
2075
  return this.machine.execute(contract, method, parameters);
1932
2076
  }
1933
2077
  /**
@@ -1938,11 +2082,11 @@ class Chain extends VersionControl {
1938
2082
  * @returns
1939
2083
  */
1940
2084
  call(contract, method, parameters) {
1941
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2085
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1942
2086
  return this.machine.execute(contract, method, parameters);
1943
2087
  }
1944
2088
  staticCall(contract, method, parameters) {
1945
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2089
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1946
2090
  return this.machine.get(contract, method, parameters);
1947
2091
  }
1948
2092
  mint(to, amount) {
@@ -1972,6 +2116,27 @@ class Chain extends VersionControl {
1972
2116
  lookup(name) {
1973
2117
  return this.call(addresses.nameService, 'lookup', [name]);
1974
2118
  }
2119
+ #monitorPeerConnections() {
2120
+ setInterval(() => {
2121
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
2122
+ debug(`Connected peers: ${connectedPeers.length}`);
2123
+ if (connectedPeers.length === 0) {
2124
+ debug('No peers connected, attempting to reconnect...');
2125
+ this.#attemptPeerReconnection();
2126
+ }
2127
+ }, 10000); // Check every 10 seconds
2128
+ }
2129
+ async #attemptPeerReconnection() {
2130
+ try {
2131
+ // Try to reconnect to star servers
2132
+ if (globalThis.peernet && globalThis.peernet.start) {
2133
+ await globalThis.peernet.start();
2134
+ }
2135
+ }
2136
+ catch (error) {
2137
+ console.warn('Failed to reconnect to peers:', error.message);
2138
+ }
2139
+ }
1975
2140
  }
1976
2141
 
1977
2142
  export { Chain as default };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
3
+ */
4
+ export default class ConnectionMonitor {
5
+ #private;
6
+ get isMonitoring(): boolean;
7
+ get connectedPeers(): import("@netpeer/swarm/peer").default[];
8
+ get compatiblePeers(): import("@netpeer/swarm/peer").default[];
9
+ constructor(version: string);
10
+ start(): void;
11
+ stop(): void;
12
+ waitForPeers(timeoutMs?: number): Promise<boolean>;
13
+ }
@@ -7,7 +7,8 @@ export default class SyncController {
7
7
  get fullyLoaded(): boolean;
8
8
  constructor();
9
9
  /**
10
- * Resolves/rejects a promise or rejects on timeout
10
+ * Resolves/rejects a promise or rejects on timeout with retry logic
11
11
  */
12
- resolve(): void;
12
+ resolve(operation: () => Promise<any>, timeoutMs?: number): Promise<any>;
13
+ stop(): void;
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/chain",
3
- "version": "1.7.73",
3
+ "version": "1.7.75",
4
4
  "description": "Official javascript implementation",
5
5
  "private": false,
6
6
  "exports": {