@leofcoin/chain 1.10.13 → 1.10.15

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 (33) hide show
  1. package/exports/beacon-envelope.js +2 -2
  2. package/exports/beacon-epoch.js +1 -1
  3. package/exports/beacon-lifecycle.js +2 -2
  4. package/exports/beacon-round.js +1 -1
  5. package/exports/beacon.js +1 -1
  6. package/exports/browser/beacon-envelope.js +79 -3
  7. package/exports/browser/beacon-epoch.js +2 -1
  8. package/exports/browser/beacon-lifecycle.js +3 -2
  9. package/exports/browser/beacon-round.js +2 -1
  10. package/exports/browser/beacon-wire.js +3 -3
  11. package/exports/browser/beacon.js +3 -2
  12. package/exports/browser/{browser-DvU1xNFS-sdlKNCJc.js → browser-DvU1xNFS-DmmNUdE-.js} +4 -4
  13. package/exports/browser/{proposal.proto-BcUgd885.js → browser-crypto-B9N9KlL4.js} +35 -6
  14. package/exports/browser/chain.js +16 -295
  15. package/exports/browser/{client-B-jyclOB-CsNYfj4Z.js → client-DDC8C510-3uaB70KL.js} +36 -12
  16. package/exports/browser/connection-monitor-GPztgSSJ.js +454 -0
  17. package/exports/browser/hkdf-CnZvwpZ9.js +222 -0
  18. package/exports/browser/{index-Bxr5Iztg-C6xBk0rK.js → index-Bxr5Iztg-WbFIosyf.js} +4 -4
  19. package/exports/browser/{index-CFBGfpG1.js → index-Ccn5sExe.js} +1 -2
  20. package/exports/browser/{messages-FMRAS8QX-CvlZBzy5.js → messages-DH0tgNM9-C2CtyLsf.js} +4 -4
  21. package/exports/browser/{node-browser-xlqSBOaN.js → node-browser-BYi7D_oa.js} +6 -6
  22. package/exports/browser/node-browser.js +4 -4
  23. package/exports/browser/sha2-piimb6xL.js +614 -0
  24. package/exports/browser/{weierstrass-C-jX_jly.js → weierstrass-Q0QND1ZT.js} +1 -1
  25. package/exports/browser/workers/machine-worker.js +412 -135
  26. package/exports/chain.js +13 -291
  27. package/exports/connection-monitor.js +324 -0
  28. package/exports/node.js +7 -0
  29. package/exports/workers/machine-worker.js +412 -135
  30. package/package.json +8 -4
  31. package/exports/browser/browser-CWeoyGUw-BabtHowB.js +0 -57
  32. package/exports/browser/constants-Cv0p224A.js +0 -130
  33. package/exports/browser/hkdf-DhdhLAAv.js +0 -147
@@ -1,8 +1,8 @@
1
- import { i as inflate_1, c as createDebugger, d as deflate_1, L as LittlePubSub } from './node-browser-xlqSBOaN.js';
2
- import 'crypto';
3
- import './constants-Cv0p224A.js';
4
- import './proposal.proto-BcUgd885.js';
1
+ import { i as inflate_1, c as createDebugger, d as deflate_1, L as LittlePubSub } from './node-browser-BYi7D_oa.js';
2
+ import './browser-crypto-B9N9KlL4.js';
3
+ import './connection-monitor-GPztgSSJ.js';
5
4
  import './index-CvKt4UDE.js';
5
+ import './sha2-piimb6xL.js';
6
6
 
7
7
  class Api {
8
8
  _pubsub;
@@ -233,7 +233,7 @@ class SocketRequestClient {
233
233
  const init = async () => {
234
234
  // @ts-ignore
235
235
  if (!globalThis.WebSocket && !this.#experimentalWebsocket)
236
- globalThis.WebSocket = (await import('./browser-DvU1xNFS-sdlKNCJc.js').then(function (n) { return n.b; })).default.w3cwebsocket;
236
+ globalThis.WebSocket = (await import('./browser-DvU1xNFS-DmmNUdE-.js').then(function (n) { return n.b; })).default.w3cwebsocket;
237
237
  const client = new WebSocket(this.#url, this.#protocol);
238
238
  if (this.#experimentalWebsocket) {
239
239
  client.addEventListener('error', this.onerror);
@@ -1155,6 +1155,7 @@ class Client {
1155
1155
  #connectEvent = 'peer:connected';
1156
1156
  #supportedTransports = new Set(['webrtc']);
1157
1157
  #preferredTransportKind = 'webrtc';
1158
+ #wrtcBackend = 'vandeurenglenn';
1158
1159
  #fallbackTransportOrder = [];
1159
1160
  #enableCircuitFallback = true;
1160
1161
  #transportConnectTimeoutMs = 10_000;
@@ -1212,6 +1213,13 @@ class Client {
1212
1213
  ? 'webrtc'
1213
1214
  : 'webtransport';
1214
1215
  this.#webTransportUrlTemplate = options.transport?.webtransport?.urlTemplate;
1216
+ const wrtcBackend = options.transport?.webrtc?.backend ||
1217
+ globalThis.process?.env?.NETPEER_SWARM_WRTC_BACKEND ||
1218
+ 'vandeurenglenn';
1219
+ if (wrtcBackend !== 'vandeurenglenn' && wrtcBackend !== 'koush') {
1220
+ throw new Error(`Unsupported WebRTC backend: ${wrtcBackend}`);
1221
+ }
1222
+ this.#wrtcBackend = wrtcBackend;
1215
1223
  this.#enableCircuitFallback = options.transport?.fallback?.enabled ?? true;
1216
1224
  if (typeof options.transport?.fallback?.connectTimeoutMs === 'number' &&
1217
1225
  options.transport.fallback.connectTimeoutMs > 0) {
@@ -1297,7 +1305,8 @@ class Client {
1297
1305
  throw lastErr;
1298
1306
  }
1299
1307
  async _init() {
1300
- if (!globalThis.RTCPeerConnection &&
1308
+ if (this.#supportedTransports.has('webrtc') &&
1309
+ !globalThis.RTCPeerConnection &&
1301
1310
  !globalThis.wrtc) {
1302
1311
  const { backend, implementation } = await this.#loadNodeWebrtcImplementation();
1303
1312
  globalThis.wrtc = implementation;
@@ -1325,13 +1334,28 @@ class Client {
1325
1334
  }
1326
1335
  }
1327
1336
  async #loadNodeWebrtcImplementation() {
1328
- const koushWrtcModule = await import('./browser-CWeoyGUw-BabtHowB.js').then(function (n) { return n.b; });
1329
- const koushWrtc = koushWrtcModule.default;
1330
- if (!isWrtcImplementation(koushWrtc)) {
1331
- throw new Error('@koush/wrtc does not match required wrtc contract');
1337
+ let wrtcModule;
1338
+ if (this.#wrtcBackend === 'koush') {
1339
+ try {
1340
+ wrtcModule = await import('@koush/wrtc');
1341
+ }
1342
+ catch (error) {
1343
+ throw new Error('The koush WebRTC backend is opt-in; install @koush/wrtc to use it', { cause: error });
1344
+ }
1332
1345
  }
1333
- debug('using @koush/wrtc as wrtc implementation');
1334
- return { backend: 'koush', implementation: koushWrtc };
1346
+ else {
1347
+ wrtcModule = await import('@vandeurenglenn/wrtc');
1348
+ }
1349
+ const moduleCandidate = wrtcModule;
1350
+ const implementation = isWrtcImplementation(moduleCandidate.default)
1351
+ ? moduleCandidate.default
1352
+ : wrtcModule;
1353
+ if (!isWrtcImplementation(implementation)) {
1354
+ const packageName = this.#wrtcBackend === 'koush' ? '@koush/wrtc' : '@vandeurenglenn/wrtc';
1355
+ throw new Error(`${packageName} does not match required wrtc contract`);
1356
+ }
1357
+ debug(`using ${this.#wrtcBackend} as wrtc implementation`);
1358
+ return { backend: this.#wrtcBackend, implementation };
1335
1359
  }
1336
1360
  setupStarListeners(starConnection, starId) {
1337
1361
  // create stable references to handlers so we can unsubscribe later
@@ -0,0 +1,454 @@
1
+ import { F as FormatInterface, o as proto$2, q as proto$3, i as index, f as index$1, r as proto$4 } from './browser-crypto-B9N9KlL4.js';
2
+
3
+ class ValidatorMessage extends FormatInterface {
4
+ get messageName() {
5
+ return "ValidatorMessage";
6
+ }
7
+ constructor(buffer) {
8
+ if (buffer instanceof ValidatorMessage)
9
+ return buffer;
10
+ const name = "validator-message";
11
+ super(buffer, proto$2, { name });
12
+ }
13
+ }
14
+
15
+ class BlockMessage extends FormatInterface {
16
+ get messageName() {
17
+ return "BlockMessage";
18
+ }
19
+ constructor(buffer) {
20
+ if (buffer instanceof BlockMessage)
21
+ return buffer;
22
+ const name = "block-message";
23
+ super(buffer, proto$3, { name });
24
+ }
25
+ encode(decoded) {
26
+ decoded = decoded || this.decoded;
27
+ const validators = [];
28
+ for (const validator of decoded.validators) {
29
+ if (validator instanceof ValidatorMessage)
30
+ validators.push(validator.encode());
31
+ else
32
+ validators.push(new ValidatorMessage(validator).encode());
33
+ }
34
+ return super.encode({
35
+ ...decoded,
36
+ validators: index(validators)
37
+ });
38
+ }
39
+ decode(encoded) {
40
+ encoded = encoded || this.encoded;
41
+ super.decode(encoded);
42
+ this.decoded.validators = index$1(this.decoded.validators).map((validator) => new ValidatorMessage(validator).decoded);
43
+ return this.decoded;
44
+ }
45
+ }
46
+
47
+ var proto$1 = {
48
+ up: Number(),
49
+ down: Number()
50
+ };
51
+
52
+ class BWMessage extends FormatInterface {
53
+ get messageName() {
54
+ return "BWMessage";
55
+ }
56
+ constructor(buffer) {
57
+ if (buffer instanceof BWMessage)
58
+ return buffer;
59
+ const name = "bw-message";
60
+ super(buffer, proto$1, { name });
61
+ }
62
+ }
63
+
64
+ class LastBlockMessage extends FormatInterface {
65
+ get messageName() {
66
+ return "LastBlockMessage";
67
+ }
68
+ constructor(buffer) {
69
+ if (buffer instanceof LastBlockMessage)
70
+ return buffer;
71
+ const name = "last-block-message";
72
+ super(buffer, proto$4, { name });
73
+ }
74
+ }
75
+
76
+ var proto = {
77
+ lastblock: Object(),
78
+ values: Object()
79
+ };
80
+
81
+ class StateMessage extends FormatInterface {
82
+ get messageName() {
83
+ return "StateMessage";
84
+ }
85
+ constructor(buffer) {
86
+ if (buffer instanceof StateMessage)
87
+ return buffer;
88
+ const name = "state-message";
89
+ super(buffer, proto, { name });
90
+ }
91
+ }
92
+
93
+ var networks = {
94
+ leofcoin: {
95
+ mainnet: {
96
+ // ports don't really matter since it is favorable to have it begind a ngninx proxy but if we change something to the proto it's easier maybe?
97
+ port: 44444,
98
+ // todo a versionhash would be nice to have as a double check?
99
+ versionHash: "0",
100
+ // a short description identifying the version
101
+ description: "Main net current version",
102
+ stars: ["wss://star.leofcoin.org"]
103
+ // todo webrtc and bittorent stars
104
+ },
105
+ peach: {
106
+ faucet: "https://remote.leofcoin.org/faucet",
107
+ port: 44444,
108
+ description: "Main testnet: latest step before merging into main",
109
+ versionHash: "1",
110
+ stars: ["wss://star.leofcoin.org"]
111
+ // todo webrtc and bittorent stars
112
+ }
113
+ }
114
+ };
115
+
116
+ var networks$1 = /*#__PURE__*/Object.freeze({
117
+ __proto__: null,
118
+ default: networks
119
+ });
120
+
121
+ const PROTOCOL_VERSION = "0.3.0";
122
+ const REACHED_ONE_ZERO_ZERO = false;
123
+ const DEFAULT_NODE_OPTIONS = {
124
+ autoStart: false,
125
+ network: "leofcoin:peach",
126
+ networkVersion: "peach",
127
+ version: PROTOCOL_VERSION,
128
+ stars: networks.leofcoin.peach.stars
129
+ };
130
+
131
+ const INITIAL_RECONNECT_DELAY = 5e3;
132
+ const MAX_RECONNECT_DELAY = 3e4;
133
+ const isSendablePeer = (peer) => {
134
+ if (!peer || typeof peer !== "object") return false;
135
+ const candidate = peer;
136
+ if (typeof candidate.send !== "function") return false;
137
+ if (candidate.connected === true) return true;
138
+ return typeof candidate.once === "function" && typeof candidate.removeListener === "function";
139
+ };
140
+ const guardPeerMessages = (peernet) => {
141
+ const sendMessage = peernet.sendMessage.bind(peernet);
142
+ peernet.sendMessage = (peer, ...args) => {
143
+ if (isSendablePeer(peer)) return sendMessage(peer, ...args);
144
+ for (const [peerId, connection] of Object.entries(peernet.connections || {})) {
145
+ if (connection === peer) delete peernet.connections[peerId];
146
+ }
147
+ return Promise.resolve(void 0);
148
+ };
149
+ };
150
+ class ConnectionMonitor {
151
+ #isMonitoring = false;
152
+ #checkInterval = null;
153
+ #reconnectDelay = INITIAL_RECONNECT_DELAY;
154
+ #reconnectTimer = null;
155
+ #healthCheckInterval = 6e4;
156
+ #version;
157
+ #lastHealthCheckAt = 0;
158
+ #reconnecting = false;
159
+ // event handlers to remove later
160
+ #onOnline = null;
161
+ #onVisibilityChange = null;
162
+ #onSigcont = null;
163
+ #onPeerConnected = null;
164
+ get isMonitoring() {
165
+ return this.#isMonitoring;
166
+ }
167
+ get connectedPeers() {
168
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => peer.connected);
169
+ }
170
+ get compatiblePeers() {
171
+ return this.connectedPeers.filter((peer) => {
172
+ if (!peer.version || !this.#version) return false;
173
+ const [peerMajor, peerMinor] = peer.version.split(".");
174
+ const [localMajor, localMinor] = this.#version.split(".");
175
+ return peerMajor === localMajor && peerMinor === localMinor;
176
+ });
177
+ }
178
+ get disconnectedPeers() {
179
+ return Object.values(globalThis.peernet?.connections || {}).filter((peer) => !peer.connected);
180
+ }
181
+ #pruneInvalidConnections() {
182
+ const connections = globalThis.peernet?.connections;
183
+ if (!connections) return;
184
+ for (const [peerId, peer] of Object.entries(connections)) {
185
+ if (!isSendablePeer(peer)) {
186
+ delete connections[peerId];
187
+ console.warn(`Removed invalid peer connection: ${peerId}`);
188
+ }
189
+ }
190
+ }
191
+ start(version) {
192
+ this.#version = version;
193
+ console.log(`\u{1F517} Connection Monitor initialized for version: ${this.#version}`);
194
+ if (this.#isMonitoring) return;
195
+ this.#isMonitoring = true;
196
+ console.log("\u{1F504} Starting connection monitor...");
197
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
198
+ this.#onOnline = () => {
199
+ console.log("\u{1F310} Network online \u2014 attempting restore");
200
+ void this.#restoreNetwork();
201
+ };
202
+ window.addEventListener("online", this.#onOnline);
203
+ this.#onVisibilityChange = () => {
204
+ if (document.visibilityState === "visible") {
205
+ console.log("\u{1F4A1} Visibility regained");
206
+ if (this.connectedPeers.length === 0) {
207
+ console.log("\u{1F4A1} Visibility regained \u2014 attempting restore");
208
+ void this.#restoreNetwork();
209
+ }
210
+ }
211
+ };
212
+ document.addEventListener("visibilitychange", this.#onVisibilityChange);
213
+ }
214
+ if (typeof process !== "undefined" && typeof process.on === "function") {
215
+ this.#onSigcont = () => {
216
+ console.log("\u{1F514} Process resumed (SIGCONT) \u2014 attempting restore");
217
+ void this.#restoreNetwork();
218
+ };
219
+ try {
220
+ process.on("SIGCONT", this.#onSigcont);
221
+ } catch (e) {
222
+ }
223
+ }
224
+ this.#lastHealthCheckAt = Date.now();
225
+ this.#checkInterval = setInterval(() => {
226
+ this.#healthCheck();
227
+ }, this.#healthCheckInterval);
228
+ this.#onPeerConnected = () => {
229
+ if (this.#reconnectTimer) {
230
+ clearTimeout(this.#reconnectTimer);
231
+ this.#reconnectTimer = null;
232
+ }
233
+ this.#reconnecting = false;
234
+ this.#reconnectDelay = INITIAL_RECONNECT_DELAY;
235
+ };
236
+ globalThis.pubsub?.subscribe("peer:connected", this.#onPeerConnected);
237
+ }
238
+ stop() {
239
+ if (!this.#isMonitoring) return;
240
+ this.#isMonitoring = false;
241
+ if (this.#checkInterval) {
242
+ clearInterval(this.#checkInterval);
243
+ this.#checkInterval = null;
244
+ }
245
+ if (typeof window !== "undefined") {
246
+ if (this.#onOnline) {
247
+ window.removeEventListener("online", this.#onOnline);
248
+ this.#onOnline = null;
249
+ }
250
+ if (this.#onVisibilityChange) {
251
+ document.removeEventListener("visibilitychange", this.#onVisibilityChange);
252
+ this.#onVisibilityChange = null;
253
+ }
254
+ }
255
+ if (typeof process !== "undefined" && typeof process.removeListener === "function" && this.#onSigcont) {
256
+ try {
257
+ process.removeListener("SIGCONT", this.#onSigcont);
258
+ } catch (e) {
259
+ }
260
+ this.#onSigcont = null;
261
+ }
262
+ if (this.#onPeerConnected) {
263
+ globalThis.pubsub?.unsubscribe("peer:connected", this.#onPeerConnected);
264
+ this.#onPeerConnected = null;
265
+ }
266
+ if (this.#reconnectTimer) {
267
+ clearTimeout(this.#reconnectTimer);
268
+ this.#reconnectTimer = null;
269
+ }
270
+ console.log("\u23F9\uFE0F Connection monitor stopped");
271
+ }
272
+ async #healthCheck() {
273
+ this.#pruneInvalidConnections();
274
+ const now = Date.now();
275
+ const expectedNext = this.#lastHealthCheckAt + this.#healthCheckInterval;
276
+ const drift = now - expectedNext;
277
+ this.#lastHealthCheckAt = now;
278
+ if (drift > 5e3) {
279
+ console.log(`\u23F0 Detected timer drift of ${drift}ms (likely system sleep) \u2014 attempting restore`);
280
+ void this.#restoreNetwork();
281
+ }
282
+ const connectedPeers = this.connectedPeers;
283
+ const compatiblePeers = this.compatiblePeers;
284
+ const disconnectedPeers = this.disconnectedPeers;
285
+ console.log(
286
+ `\u{1F50D} Health check: ${connectedPeers.length} connected, ${compatiblePeers.length} compatible, ${disconnectedPeers.length} negotiating`
287
+ );
288
+ if (connectedPeers.length === 0 && disconnectedPeers.length === 0 && !this.#reconnectTimer) {
289
+ console.warn("\u26A0\uFE0F No peer connections detected \u2014 attempting reconnection");
290
+ await this.#attemptReconnection();
291
+ } else if (compatiblePeers.length === 0 && connectedPeers.length > 0 && !this.#reconnectTimer) {
292
+ console.warn("\u26A0\uFE0F No compatible peers found \u2014 attempting reconnection");
293
+ await this.#attemptReconnection();
294
+ }
295
+ globalThis.pubsub?.publish("connection-status", {
296
+ connected: connectedPeers.length,
297
+ compatible: compatiblePeers.length,
298
+ healthy: compatiblePeers.length > 0
299
+ });
300
+ }
301
+ // lightweight TCP probe to detect internet connectivity in Node.js
302
+ async #isOnLine(timeout = 1500) {
303
+ if (navigator?.onLine !== void 0) {
304
+ return navigator.onLine;
305
+ }
306
+ return new Promise(async (resolve) => {
307
+ try {
308
+ const net = await import('net');
309
+ const socket = new net.Socket();
310
+ let finished = false;
311
+ const finish = (val) => {
312
+ if (finished) return;
313
+ finished = true;
314
+ try {
315
+ socket.destroy();
316
+ } catch (e) {
317
+ }
318
+ resolve(val);
319
+ };
320
+ socket.setTimeout(timeout);
321
+ socket.once("connect", () => finish(true));
322
+ socket.once("error", () => finish(false));
323
+ socket.once("timeout", () => finish(false));
324
+ socket.connect(53, "1.1.1.1");
325
+ } catch (e) {
326
+ resolve(false);
327
+ }
328
+ });
329
+ }
330
+ // Called on visibility/online/resume events
331
+ async #restoreNetwork() {
332
+ if (this.#reconnecting) {
333
+ console.log("\u{1F501} Reconnection already in progress, skipping");
334
+ return;
335
+ }
336
+ this.#reconnecting = true;
337
+ if (this.connectedPeers.length > 0) {
338
+ console.log("\u2705 Already connected to peers, skipping restoration");
339
+ this.#reconnecting = false;
340
+ return;
341
+ }
342
+ console.log("\u{1F501} Restoring network");
343
+ try {
344
+ const online = await this.#isOnLine(1500);
345
+ if (!online) {
346
+ console.warn("\u26A0\uFE0F No internet detected, skipping restore");
347
+ this.#reconnecting = false;
348
+ return;
349
+ }
350
+ } catch (e) {
351
+ console.warn("\u26A0\uFE0F Online probe failed, proceeding with restore", e?.message || e);
352
+ }
353
+ try {
354
+ console.log("\u{1F504} Attempting network restoration...");
355
+ if (globalThis.peernet?.client?.reinit) {
356
+ console.log(" \u2192 Trying client.reinit()");
357
+ try {
358
+ await globalThis.peernet.client.reinit();
359
+ console.log(" \u2705 client.reinit() succeeded");
360
+ } catch (e) {
361
+ console.warn(" \u26A0\uFE0F client.reinit() failed:", e?.message || e);
362
+ }
363
+ }
364
+ if (globalThis.peernet?.start) {
365
+ console.log(" \u2192 Trying peernet.start()");
366
+ try {
367
+ await globalThis.peernet.start();
368
+ console.log(" \u2705 peernet.start() succeeded");
369
+ } catch (e) {
370
+ console.warn(" \u26A0\uFE0F peernet.start() failed:", e?.message || e);
371
+ }
372
+ }
373
+ try {
374
+ const networkName = globalThis.peernet?.network;
375
+ if (networkName && typeof networkName === "string") {
376
+ const { default: networks } = await Promise.resolve().then(function () { return networks$1; });
377
+ const [mainKey, subKey] = networkName.split(":");
378
+ const networkConfig = networks?.[mainKey]?.[subKey];
379
+ if (networkConfig?.stars && Array.isArray(networkConfig.stars)) {
380
+ console.log(" \u2192 Attempting to dial star servers:", networkConfig.stars.join(", "));
381
+ for (const star of networkConfig.stars) {
382
+ try {
383
+ if (globalThis.peernet?.client && "dial" in globalThis.peernet.client) {
384
+ await globalThis.peernet.client.dial(star);
385
+ console.log(` \u2705 Connected to star server: ${star}`);
386
+ }
387
+ } catch (e) {
388
+ console.warn(` \u26A0\uFE0F Failed to dial ${star}:`, e?.message || e);
389
+ }
390
+ }
391
+ }
392
+ }
393
+ } catch (e) {
394
+ console.warn(" \u26A0\uFE0F Could not load or dial star servers:", e?.message || e);
395
+ }
396
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
397
+ this.#pruneInvalidConnections();
398
+ const connectedAfter = this.connectedPeers.length;
399
+ console.log(`\u{1F504} Restoration complete. Connected peers: ${connectedAfter}`);
400
+ } catch (error) {
401
+ console.error("\u274C Network restoration failed:", error?.message || error);
402
+ } finally {
403
+ this.#reconnecting = false;
404
+ }
405
+ }
406
+ async waitForPeers(timeoutMs = 3e4) {
407
+ return new Promise((resolve) => {
408
+ const startTime = Date.now();
409
+ const checkPeers = () => {
410
+ if (this.compatiblePeers.length > 0) {
411
+ resolve(true);
412
+ return;
413
+ }
414
+ if (Date.now() - startTime >= timeoutMs) {
415
+ resolve(false);
416
+ return;
417
+ }
418
+ setTimeout(checkPeers, 1e3);
419
+ };
420
+ checkPeers();
421
+ });
422
+ }
423
+ async #attemptReconnection() {
424
+ try {
425
+ await this.#restoreNetwork();
426
+ const hasConnections = this.connectedPeers.length > 0 || this.disconnectedPeers.length > 0;
427
+ if (hasConnections) {
428
+ console.log("\u2705 Reconnection successful, resetting backoff delay");
429
+ this.#reconnectDelay = INITIAL_RECONNECT_DELAY;
430
+ } else {
431
+ console.warn("\u26A0\uFE0F Reconnection attempt completed but no peers connected");
432
+ this.#scheduleReconnect();
433
+ }
434
+ } catch (error) {
435
+ console.error("\u274C Reconnection failed:", error?.message || error);
436
+ this.#scheduleReconnect();
437
+ }
438
+ }
439
+ #scheduleReconnect() {
440
+ if (!this.#isMonitoring || this.#reconnectTimer) return;
441
+ if (this.#reconnectDelay >= MAX_RECONNECT_DELAY) {
442
+ console.warn("\u26A0\uFE0F No peers available; automatic retries paused until the next health check or network event");
443
+ return;
444
+ }
445
+ this.#reconnectDelay = Math.min(this.#reconnectDelay * 1.5, MAX_RECONNECT_DELAY);
446
+ console.warn(`\u26A0\uFE0F Increasing reconnection delay to ${this.#reconnectDelay} ms`);
447
+ this.#reconnectTimer = setTimeout(() => {
448
+ this.#reconnectTimer = null;
449
+ void this.#attemptReconnection();
450
+ }, this.#reconnectDelay);
451
+ }
452
+ }
453
+
454
+ export { BlockMessage as B, ConnectionMonitor as C, DEFAULT_NODE_OPTIONS as D, LastBlockMessage as L, PROTOCOL_VERSION as P, REACHED_ONE_ZERO_ZERO as R, StateMessage as S, ValidatorMessage as V, BWMessage as a, guardPeerMessages as g };