magnetk 2.2.5 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/client.js CHANGED
@@ -62,19 +62,30 @@ DISCOVERY_PRIORITY=dht,relay,direct
62
62
 
63
63
  # ===== Chunking =====
64
64
  CHUNK_SIZE_MB=1
65
+ ADAPTIVE_CHUNKING=true
65
66
  MAX_PARALLEL_CHUNKS=10
67
+
68
+ # ===== Connection Strategy =====
69
+ # RELAY_ASSISTED: auto | true | false
70
+ # auto = try direct P2P first, fall back to relay if unreachable
71
+ # true = always route data through relay (privacy mode)
72
+ # false = direct P2P only, fail if unreachable
73
+ RELAY_ASSISTED=auto
74
+ # HOLE_PUNCH: Enable NAT traversal via STUN + libp2p hole punching
75
+ HOLE_PUNCH=true
76
+ # RELAY_TIMEOUT_MS: How long to wait for direct connection before relay fallback
77
+ RELAY_TIMEOUT_MS=5000
66
78
  `;
67
79
 
68
80
  export class MagnetkClient extends EventEmitter {
69
81
  constructor(config = {}) {
70
82
  super();
71
83
  this.config = {
72
- // Relay settings (supports multiple relays for failover)
84
+ // Relay settings (supports multiple relays for failover/scaling)
73
85
  relayUrl: '69.169.109.243',
74
86
  relayPort: 4003,
75
87
  relays: [], // Array of {host, port} for multi-relay failover
76
88
  seedPort: 4002,
77
- enableSTUN: true,
78
89
  seederPath: null,
79
90
  configPath: null,
80
91
 
@@ -83,6 +94,13 @@ export class MagnetkClient extends EventEmitter {
83
94
  dhtBootstrapPeers: [], // Custom bootstrap peer multiaddrs
84
95
  discoveryPriority: ['dht', 'relay', 'direct'], // Discovery order
85
96
 
97
+ // Connection strategy
98
+ stunServers: ['stun:stun.l.google.com:19302'], // STUN servers for NAT traversal
99
+ holePunch: true, // Enable NAT hole punching (STUN first, relay fallback)
100
+ relayAssisted: 'auto', // 'auto' | true | false — relay-assisted data transfer
101
+ enableRelayFallback: true, // Fall back to relay if direct P2P fails
102
+ relayTimeout: 5000, // ms to wait for direct connection before relay fallback
103
+
86
104
  // Auto-config: create settings.conf if missing
87
105
  autoConfig: true,
88
106
  ...config
@@ -307,6 +325,23 @@ export class MagnetkClient extends EventEmitter {
307
325
  args.push('-bootstrap', this.config.dhtBootstrapPeers.join(','));
308
326
  }
309
327
 
328
+ // Connection strategy flags
329
+ if (this.config.holePunch) {
330
+ args.push('-holepunch');
331
+ }
332
+ if (this.config.relayAssisted !== undefined) {
333
+ const mode = this.config.relayAssisted === true ? 'true'
334
+ : this.config.relayAssisted === false ? 'false'
335
+ : this.config.relayAssisted;
336
+ args.push('-relay-assisted', mode);
337
+ }
338
+
339
+ // Multi-relay: pass additional relay addresses
340
+ if (this.config.relays && this.config.relays.length > 0) {
341
+ const relayAddrs = this.config.relays.map(r => `${r.host}:${r.port}`).join(',');
342
+ args.push('-relay-addresses', relayAddrs);
343
+ }
344
+
310
345
  console.log(`[Magnetk-JS] Spawning seeder: ${binPath} ${args.join(' ')}`);
311
346
 
312
347
  return new Promise((resolve, reject) => {
@@ -391,21 +426,68 @@ export class MagnetkClient extends EventEmitter {
391
426
  }
392
427
 
393
428
  const addressesToTry = [];
429
+
430
+ // Helper: filter out non-routable addresses
431
+ const isRoutable = (host) => {
432
+ if (!host) return false;
433
+ // 0.0.0.0 is a bind-all address, not valid for connecting
434
+ if (host === '0.0.0.0') return false;
435
+ // Link-local, loopback handled separately
436
+ if (host.startsWith('169.254.')) return false;
437
+ return true;
438
+ };
439
+
394
440
  if (lookupResult && lookupResult.found && lookupResult.seeds.length > 0) {
395
441
  const seed = lookupResult.seeds[0];
396
- if (seed.transport_addr) addressesToTry.push(seed.transport_addr);
442
+ console.log(`[Magnetk-JS] Relay returned seed: peer_id=${seed.peer_id}, transport_addr=${seed.transport_addr}, addresses=${JSON.stringify(seed.addresses)}`);
443
+
444
+ // Add transport_addr if routable
445
+ if (seed.transport_addr) {
446
+ const [h] = seed.transport_addr.split(':');
447
+ if (isRoutable(h)) {
448
+ addressesToTry.push(seed.transport_addr);
449
+ } else {
450
+ console.log(`[Magnetk-JS] Skipping non-routable transport_addr: ${seed.transport_addr}`);
451
+ }
452
+ }
453
+
454
+ // Parse multiaddr addresses
397
455
  if (seed.addresses) {
398
456
  seed.addresses.forEach(addr => {
399
457
  const parts = addr.split('/');
400
458
  if (parts.length >= 5 && parts[1] === 'ip4' && parts[3] === 'tcp') {
401
- addressesToTry.push(`${parts[2]}:${parts[4]}`);
459
+ const ip = parts[2];
460
+ if (isRoutable(ip)) {
461
+ addressesToTry.push(`${ip}:${parts[4]}`);
462
+ } else {
463
+ console.log(`[Magnetk-JS] Skipping non-routable address: ${addr}`);
464
+ }
402
465
  }
403
466
  });
404
467
  }
468
+ } else {
469
+ console.log(`[Magnetk-JS] Relay lookup: no seeds found for this file hash`);
405
470
  }
471
+
472
+ // Fallback: extract seed IP from magnet link relay addr
473
+ // If the magnet link contains the relay multiaddr, the seed's IP might be known
474
+ // from the relay's host (when seed is on same VPS as relay)
475
+ if (addressesToTry.length === 0 && ml.relayAddr) {
476
+ // Try to parse /ip4/HOST/tcp/PORT from relay multiaddr
477
+ const parts = ml.relayAddr.split('/');
478
+ if (parts.length >= 3 && parts[1] === 'ip4') {
479
+ const seedAddr = `${parts[2]}:${this.config.seedPort}`;
480
+ console.log(`[Magnetk-JS] No routable seeds from relay, trying relay host as seed: ${seedAddr}`);
481
+ addressesToTry.push(seedAddr);
482
+ }
483
+ }
484
+
485
+ // Local fallback (same machine)
406
486
  addressesToTry.push(`127.0.0.1:${this.config.seedPort}`);
407
487
 
408
488
  const uniqueAddrs = [...new Set(addressesToTry)];
489
+ console.log(`[Magnetk-JS] Connection attempts: ${uniqueAddrs.join(', ')}`);
490
+
409
491
  let socket;
410
492
  let connectionType = CONNECTION_TYPE.UNKNOWN;
411
493
  let finalAddr = null;
@@ -415,7 +497,11 @@ export class MagnetkClient extends EventEmitter {
415
497
  const port = parseInt(portStr, 10) || 4002;
416
498
 
417
499
  try {
418
- socket = await this.connect(host, port);
500
+ // Use configurable timeout for connection attempts
501
+ socket = await Promise.race([
502
+ this.connect(host, port),
503
+ new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), this.config.relayTimeout || 5000))
504
+ ]);
419
505
  finalAddr = addr;
420
506
  if (host === '127.0.0.1' || host === 'localhost') connectionType = CONNECTION_TYPE.LOCAL;
421
507
  else if (host === relayHost) connectionType = CONNECTION_TYPE.RELAYED;
package/download.js CHANGED
@@ -19,7 +19,7 @@ async function download() {
19
19
  dhtEnabled: true, // Enable DHT discovery
20
20
  relayUrl: '69.169.109.243',
21
21
  relayPort: 4003,
22
- seedPort: 4005
22
+ seedPort: 4002
23
23
  });
24
24
 
25
25
  // Extract filename from URI roughly to show intention
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magnetk",
3
- "version": "2.2.5",
3
+ "version": "2.3.0",
4
4
  "description": "JavaScript SDK for Magnetk P2P File Transfer System",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -34,4 +34,4 @@
34
34
  ],
35
35
  "author": "Magnetk Contributors",
36
36
  "license": "MIT"
37
- }
37
+ }
package/share.js CHANGED
@@ -1,6 +1,6 @@
1
- import { MagnetkClient } from 'magnetk';
1
+ import { MagnetkClient } from './client.js';
2
2
  import path from 'path';
3
- import 'dotenv/config';
3
+ // import 'dotenv/config';
4
4
 
5
5
  const filePath = "./app.txt";
6
6
 
@@ -8,8 +8,8 @@ async function share() {
8
8
  const client = new MagnetkClient({
9
9
  relayUrl: '69.169.109.243', // Default to local for dev, change to public IPs for prod
10
10
  relayPort: 4003,
11
- seederPath: process.env.MAGNETK_SEEDER_PATH,
12
- seedPort: 4005 // Default seed port
11
+ // seederPath: process.env.MAGNETK_SEEDER_PATH || "~root/Desktop/Magnetk/magnetk/bin/seed",
12
+ seedPort: 4002 // Data transfer port (must not conflict with relay 4003)
13
13
  });
14
14
 
15
15
  console.log(`[Share] Preparing to share: ${filePath}`);