@leofcoin/chain 1.7.72 → 1.7.74

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.
@@ -4219,7 +4219,10 @@ class Machine {
4219
4219
  }
4220
4220
  }
4221
4221
  else if (data.question === 'peers') {
4222
- this.worker.postMessage({ id: data.id, input: peernet.connections ? peernet.peers : [] });
4222
+ this.worker.postMessage({
4223
+ id: data.id,
4224
+ input: peernet.connections ? Object.entries(peernet.connections).map(([id, peer]) => peer.toJSON()) : []
4225
+ });
4223
4226
  }
4224
4227
  else {
4225
4228
  this.worker.postMessage({ id: data.id, input: data.input });
@@ -5198,6 +5201,12 @@ class State extends Contract {
5198
5201
  get shouldSync() {
5199
5202
  if (this.#chainSyncing)
5200
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
+ }
5201
5210
  if (!this.#chainSyncing ||
5202
5211
  this.#resolveErrored ||
5203
5212
  this.#syncState === 'errored' ||
@@ -5206,6 +5215,25 @@ class State extends Contract {
5206
5215
  return true;
5207
5216
  return false;
5208
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
+ }
5209
5237
  async triggerSync() {
5210
5238
  const latest = await this.#getLatestBlock();
5211
5239
  return this.syncChain(latest);
@@ -5265,6 +5293,112 @@ class VersionControl extends State {
5265
5293
  }
5266
5294
  }
5267
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
+ get isMonitoring() {
5307
+ return this.#isMonitoring;
5308
+ }
5309
+ get connectedPeers() {
5310
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
5311
+ }
5312
+ get compatiblePeers() {
5313
+ return this.connectedPeers.filter((peer) => peer.version === this.version);
5314
+ }
5315
+ constructor(version) {
5316
+ this.version = version;
5317
+ }
5318
+ start() {
5319
+ if (this.#isMonitoring)
5320
+ return;
5321
+ this.#isMonitoring = true;
5322
+ console.log('🔄 Starting connection monitor...');
5323
+ this.#checkInterval = setInterval(() => {
5324
+ this.#healthCheck();
5325
+ }, this.#healthCheckInterval);
5326
+ // Initial health check
5327
+ this.#healthCheck();
5328
+ }
5329
+ stop() {
5330
+ if (!this.#isMonitoring)
5331
+ return;
5332
+ this.#isMonitoring = false;
5333
+ if (this.#checkInterval) {
5334
+ clearInterval(this.#checkInterval);
5335
+ this.#checkInterval = null;
5336
+ }
5337
+ console.log('⏹️ Connection monitor stopped');
5338
+ }
5339
+ async #healthCheck() {
5340
+ const connectedPeers = this.connectedPeers;
5341
+ const compatiblePeers = this.compatiblePeers;
5342
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
5343
+ if (connectedPeers.length === 0) {
5344
+ console.warn('⚠️ No peer connections detected');
5345
+ await this.#attemptReconnection();
5346
+ }
5347
+ else if (compatiblePeers.length === 0) {
5348
+ console.warn('⚠️ No compatible peers found');
5349
+ // Could attempt to find compatible peers or trigger version negotiation
5350
+ }
5351
+ else {
5352
+ // Reset reconnect attempts on successful connection
5353
+ this.#reconnectAttempts = 0;
5354
+ }
5355
+ // Publish connection status
5356
+ globalThis.pubsub?.publish('connection-status', {
5357
+ connected: connectedPeers.length,
5358
+ compatible: compatiblePeers.length,
5359
+ healthy: compatiblePeers.length > 0
5360
+ });
5361
+ }
5362
+ async #attemptReconnection() {
5363
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
5364
+ console.error('❌ Max reconnection attempts reached');
5365
+ return;
5366
+ }
5367
+ this.#reconnectAttempts++;
5368
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
5369
+ try {
5370
+ // Try to restart the network
5371
+ if (globalThis.peernet?.start) {
5372
+ await globalThis.peernet.start();
5373
+ }
5374
+ // Wait a bit before next check
5375
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
5376
+ }
5377
+ catch (error) {
5378
+ console.error('❌ Reconnection failed:', error.message);
5379
+ // Exponential backoff
5380
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
5381
+ }
5382
+ }
5383
+ async waitForPeers(timeoutMs = 30000) {
5384
+ return new Promise((resolve) => {
5385
+ const startTime = Date.now();
5386
+ const checkPeers = () => {
5387
+ if (this.compatiblePeers.length > 0) {
5388
+ resolve(true);
5389
+ return;
5390
+ }
5391
+ if (Date.now() - startTime >= timeoutMs) {
5392
+ resolve(false);
5393
+ return;
5394
+ }
5395
+ setTimeout(checkPeers, 1000);
5396
+ };
5397
+ checkPeers();
5398
+ });
5399
+ }
5400
+ }
5401
+
5268
5402
  const debug = globalThis.createDebugger('leofcoin/chain');
5269
5403
  // check if browser or local
5270
5404
  class Chain extends VersionControl {
@@ -5277,6 +5411,10 @@ class Chain extends VersionControl {
5277
5411
  #participants;
5278
5412
  #participating;
5279
5413
  #jail;
5414
+ #peerConnectionRetries;
5415
+ #maxPeerRetries;
5416
+ #peerRetryDelay;
5417
+ #connectionMonitor;
5280
5418
  constructor(config) {
5281
5419
  super(config);
5282
5420
  this.#slotTime = 10000;
@@ -5288,6 +5426,9 @@ class Chain extends VersionControl {
5288
5426
  this.#participants = [];
5289
5427
  this.#participating = false;
5290
5428
  this.#jail = [];
5429
+ this.#peerConnectionRetries = new Map();
5430
+ this.#maxPeerRetries = 5;
5431
+ this.#peerRetryDelay = 5000;
5291
5432
  this.#addTransaction = async (message) => {
5292
5433
  const transaction = new TransactionMessage(message);
5293
5434
  const hash = await transaction.hash();
@@ -5362,6 +5503,7 @@ class Chain extends VersionControl {
5362
5503
  // this.node = await new Node()
5363
5504
  this.#participants = [];
5364
5505
  this.#participating = false;
5506
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
5365
5507
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
5366
5508
  if (!initialized)
5367
5509
  await this.#setup();
@@ -5369,8 +5511,11 @@ class Chain extends VersionControl {
5369
5511
  // this.#state = new State()
5370
5512
  // todo some functions rely on state
5371
5513
  await super.init();
5514
+ // Start connection monitoring
5515
+ this.#connectionMonitor.start();
5372
5516
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
5373
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
5517
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
5518
+ return new BWMessage(bw);
5374
5519
  });
5375
5520
  // await globalThis.peernet.addRequestHandler('peerId', () => {
5376
5521
  // let node =
@@ -5451,7 +5596,7 @@ class Chain extends VersionControl {
5451
5596
  }
5452
5597
  }
5453
5598
  if (this.wantList.length > 0) {
5454
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
5599
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
5455
5600
  for (let i = 0; i < promises.length; i++) {
5456
5601
  const result = promises[i];
5457
5602
  if (result.status === 'fulfilled')
@@ -5778,7 +5923,7 @@ class Chain extends VersionControl {
5778
5923
  * @returns
5779
5924
  */
5780
5925
  internalCall(sender, contract, method, parameters) {
5781
- globalThis.msg = this.#createMessage(sender, contract);
5926
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
5782
5927
  return this.machine.execute(contract, method, parameters);
5783
5928
  }
5784
5929
  /**
@@ -5789,11 +5934,11 @@ class Chain extends VersionControl {
5789
5934
  * @returns
5790
5935
  */
5791
5936
  call(contract, method, parameters) {
5792
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5937
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5793
5938
  return this.machine.execute(contract, method, parameters);
5794
5939
  }
5795
5940
  staticCall(contract, method, parameters) {
5796
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
5941
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
5797
5942
  return this.machine.get(contract, method, parameters);
5798
5943
  }
5799
5944
  mint(to, amount) {
@@ -5823,6 +5968,27 @@ class Chain extends VersionControl {
5823
5968
  lookup(name) {
5824
5969
  return this.call(addresses.nameService, 'lookup', [name]);
5825
5970
  }
5971
+ #monitorPeerConnections() {
5972
+ setInterval(() => {
5973
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
5974
+ debug(`Connected peers: ${connectedPeers.length}`);
5975
+ if (connectedPeers.length === 0) {
5976
+ debug('No peers connected, attempting to reconnect...');
5977
+ this.#attemptPeerReconnection();
5978
+ }
5979
+ }, 10000); // Check every 10 seconds
5980
+ }
5981
+ async #attemptPeerReconnection() {
5982
+ try {
5983
+ // Try to reconnect to star servers
5984
+ if (globalThis.peernet && globalThis.peernet.start) {
5985
+ await globalThis.peernet.start();
5986
+ }
5987
+ }
5988
+ catch (error) {
5989
+ console.warn('Failed to reconnect to peers:', error.message);
5990
+ }
5991
+ }
5826
5992
  }
5827
5993
 
5828
5994
  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
@@ -365,7 +365,10 @@ class Machine {
365
365
  }
366
366
  }
367
367
  else if (data.question === 'peers') {
368
- this.worker.postMessage({ id: data.id, input: peernet.connections ? peernet.peers : [] });
368
+ this.worker.postMessage({
369
+ id: data.id,
370
+ input: peernet.connections ? Object.entries(peernet.connections).map(([id, peer]) => peer.toJSON()) : []
371
+ });
369
372
  }
370
373
  else {
371
374
  this.worker.postMessage({ id: data.id, input: data.input });
@@ -1344,6 +1347,12 @@ class State extends Contract {
1344
1347
  get shouldSync() {
1345
1348
  if (this.#chainSyncing)
1346
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
+ }
1347
1356
  if (!this.#chainSyncing ||
1348
1357
  this.#resolveErrored ||
1349
1358
  this.#syncState === 'errored' ||
@@ -1352,6 +1361,25 @@ class State extends Contract {
1352
1361
  return true;
1353
1362
  return false;
1354
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
+ }
1355
1383
  async triggerSync() {
1356
1384
  const latest = await this.#getLatestBlock();
1357
1385
  return this.syncChain(latest);
@@ -1411,6 +1439,112 @@ class VersionControl extends State {
1411
1439
  }
1412
1440
  }
1413
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
+ get isMonitoring() {
1453
+ return this.#isMonitoring;
1454
+ }
1455
+ get connectedPeers() {
1456
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
1457
+ }
1458
+ get compatiblePeers() {
1459
+ return this.connectedPeers.filter((peer) => peer.version === this.version);
1460
+ }
1461
+ constructor(version) {
1462
+ this.version = version;
1463
+ }
1464
+ start() {
1465
+ if (this.#isMonitoring)
1466
+ return;
1467
+ this.#isMonitoring = true;
1468
+ console.log('🔄 Starting connection monitor...');
1469
+ this.#checkInterval = setInterval(() => {
1470
+ this.#healthCheck();
1471
+ }, this.#healthCheckInterval);
1472
+ // Initial health check
1473
+ this.#healthCheck();
1474
+ }
1475
+ stop() {
1476
+ if (!this.#isMonitoring)
1477
+ return;
1478
+ this.#isMonitoring = false;
1479
+ if (this.#checkInterval) {
1480
+ clearInterval(this.#checkInterval);
1481
+ this.#checkInterval = null;
1482
+ }
1483
+ console.log('⏹️ Connection monitor stopped');
1484
+ }
1485
+ async #healthCheck() {
1486
+ const connectedPeers = this.connectedPeers;
1487
+ const compatiblePeers = this.compatiblePeers;
1488
+ console.log(`🔍 Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible`);
1489
+ if (connectedPeers.length === 0) {
1490
+ console.warn('⚠️ No peer connections detected');
1491
+ await this.#attemptReconnection();
1492
+ }
1493
+ else if (compatiblePeers.length === 0) {
1494
+ console.warn('⚠️ No compatible peers found');
1495
+ // Could attempt to find compatible peers or trigger version negotiation
1496
+ }
1497
+ else {
1498
+ // Reset reconnect attempts on successful connection
1499
+ this.#reconnectAttempts = 0;
1500
+ }
1501
+ // Publish connection status
1502
+ globalThis.pubsub?.publish('connection-status', {
1503
+ connected: connectedPeers.length,
1504
+ compatible: compatiblePeers.length,
1505
+ healthy: compatiblePeers.length > 0
1506
+ });
1507
+ }
1508
+ async #attemptReconnection() {
1509
+ if (this.#reconnectAttempts >= this.#maxReconnectAttempts) {
1510
+ console.error('❌ Max reconnection attempts reached');
1511
+ return;
1512
+ }
1513
+ this.#reconnectAttempts++;
1514
+ console.log(`🔄 Attempting reconnection ${this.#reconnectAttempts}/${this.#maxReconnectAttempts}`);
1515
+ try {
1516
+ // Try to restart the network
1517
+ if (globalThis.peernet?.start) {
1518
+ await globalThis.peernet.start();
1519
+ }
1520
+ // Wait a bit before next check
1521
+ await new Promise((resolve) => setTimeout(resolve, this.#reconnectDelay));
1522
+ }
1523
+ catch (error) {
1524
+ console.error('❌ Reconnection failed:', error.message);
1525
+ // Exponential backoff
1526
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, 30000);
1527
+ }
1528
+ }
1529
+ async waitForPeers(timeoutMs = 30000) {
1530
+ return new Promise((resolve) => {
1531
+ const startTime = Date.now();
1532
+ const checkPeers = () => {
1533
+ if (this.compatiblePeers.length > 0) {
1534
+ resolve(true);
1535
+ return;
1536
+ }
1537
+ if (Date.now() - startTime >= timeoutMs) {
1538
+ resolve(false);
1539
+ return;
1540
+ }
1541
+ setTimeout(checkPeers, 1000);
1542
+ };
1543
+ checkPeers();
1544
+ });
1545
+ }
1546
+ }
1547
+
1414
1548
  const debug = globalThis.createDebugger('leofcoin/chain');
1415
1549
  // check if browser or local
1416
1550
  class Chain extends VersionControl {
@@ -1423,6 +1557,10 @@ class Chain extends VersionControl {
1423
1557
  #participants;
1424
1558
  #participating;
1425
1559
  #jail;
1560
+ #peerConnectionRetries;
1561
+ #maxPeerRetries;
1562
+ #peerRetryDelay;
1563
+ #connectionMonitor;
1426
1564
  constructor(config) {
1427
1565
  super(config);
1428
1566
  this.#slotTime = 10000;
@@ -1434,6 +1572,9 @@ class Chain extends VersionControl {
1434
1572
  this.#participants = [];
1435
1573
  this.#participating = false;
1436
1574
  this.#jail = [];
1575
+ this.#peerConnectionRetries = new Map();
1576
+ this.#maxPeerRetries = 5;
1577
+ this.#peerRetryDelay = 5000;
1437
1578
  this.#addTransaction = async (message) => {
1438
1579
  const transaction = new TransactionMessage(message);
1439
1580
  const hash = await transaction.hash();
@@ -1508,6 +1649,7 @@ class Chain extends VersionControl {
1508
1649
  // this.node = await new Node()
1509
1650
  this.#participants = [];
1510
1651
  this.#participating = false;
1652
+ this.#connectionMonitor = new ConnectionMonitor(this.version);
1511
1653
  const initialized = await globalThis.contractStore.has(addresses.contractFactory);
1512
1654
  if (!initialized)
1513
1655
  await this.#setup();
@@ -1515,8 +1657,11 @@ class Chain extends VersionControl {
1515
1657
  // this.#state = new State()
1516
1658
  // todo some functions rely on state
1517
1659
  await super.init();
1660
+ // Start connection monitoring
1661
+ this.#connectionMonitor.start();
1518
1662
  await globalThis.peernet.addRequestHandler('bw-request-message', () => {
1519
- return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
1663
+ const bw = globalThis.peernet.client?.bw || { up: 0, down: 0 };
1664
+ return new BWMessage(bw);
1520
1665
  });
1521
1666
  // await globalThis.peernet.addRequestHandler('peerId', () => {
1522
1667
  // let node =
@@ -1597,7 +1742,7 @@ class Chain extends VersionControl {
1597
1742
  }
1598
1743
  }
1599
1744
  if (this.wantList.length > 0) {
1600
- const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash)));
1745
+ const promises = await Promise.allSettled(this.wantList.map((hash) => peernet.get(hash, 'block')));
1601
1746
  for (let i = 0; i < promises.length; i++) {
1602
1747
  const result = promises[i];
1603
1748
  if (result.status === 'fulfilled')
@@ -1924,7 +2069,7 @@ class Chain extends VersionControl {
1924
2069
  * @returns
1925
2070
  */
1926
2071
  internalCall(sender, contract, method, parameters) {
1927
- globalThis.msg = this.#createMessage(sender, contract);
2072
+ // globalThis.msg = this.#createMessage(sender, contract) // Debug line removed
1928
2073
  return this.machine.execute(contract, method, parameters);
1929
2074
  }
1930
2075
  /**
@@ -1935,11 +2080,11 @@ class Chain extends VersionControl {
1935
2080
  * @returns
1936
2081
  */
1937
2082
  call(contract, method, parameters) {
1938
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2083
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1939
2084
  return this.machine.execute(contract, method, parameters);
1940
2085
  }
1941
2086
  staticCall(contract, method, parameters) {
1942
- globalThis.msg = this.#createMessage(peernet.selectedAccount, contract);
2087
+ // globalThis.msg = this.#createMessage(peernet.selectedAccount, contract) // Debug line removed
1943
2088
  return this.machine.get(contract, method, parameters);
1944
2089
  }
1945
2090
  mint(to, amount) {
@@ -1969,6 +2114,27 @@ class Chain extends VersionControl {
1969
2114
  lookup(name) {
1970
2115
  return this.call(addresses.nameService, 'lookup', [name]);
1971
2116
  }
2117
+ #monitorPeerConnections() {
2118
+ setInterval(() => {
2119
+ const connectedPeers = Object.values(globalThis.peernet.connections).filter((peer) => peer.connected);
2120
+ debug(`Connected peers: ${connectedPeers.length}`);
2121
+ if (connectedPeers.length === 0) {
2122
+ debug('No peers connected, attempting to reconnect...');
2123
+ this.#attemptPeerReconnection();
2124
+ }
2125
+ }, 10000); // Check every 10 seconds
2126
+ }
2127
+ async #attemptPeerReconnection() {
2128
+ try {
2129
+ // Try to reconnect to star servers
2130
+ if (globalThis.peernet && globalThis.peernet.start) {
2131
+ await globalThis.peernet.start();
2132
+ }
2133
+ }
2134
+ catch (error) {
2135
+ console.warn('Failed to reconnect to peers:', error.message);
2136
+ }
2137
+ }
1972
2138
  }
1973
2139
 
1974
2140
  export { Chain as default };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Connection Monitor - Monitors peer connections and handles reconnection logic
3
+ */
4
+ export default class ConnectionMonitor {
5
+ #private;
6
+ private version;
7
+ get isMonitoring(): boolean;
8
+ get connectedPeers(): import("@netpeer/swarm/peer").default[];
9
+ get compatiblePeers(): import("@netpeer/swarm/peer").default[];
10
+ constructor(version: string);
11
+ start(): void;
12
+ stop(): void;
13
+ waitForPeers(timeoutMs?: number): Promise<boolean>;
14
+ }
@@ -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.72",
3
+ "version": "1.7.74",
4
4
  "description": "Official javascript implementation",
5
5
  "private": false,
6
6
  "exports": {
@@ -69,7 +69,7 @@
69
69
  "@leofcoin/messages": "^1.4.40",
70
70
  "@leofcoin/multi-wallet": "^3.1.8",
71
71
  "@leofcoin/networks": "^1.1.25",
72
- "@leofcoin/peernet": "^1.1.83",
72
+ "@leofcoin/peernet": "^1.1.84",
73
73
  "@leofcoin/storage": "^3.5.38",
74
74
  "@leofcoin/utils": "^1.1.39",
75
75
  "@leofcoin/workers": "^1.5.23",