shogun-core 3.2.2 β†’ 3.2.3

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.
@@ -98546,15 +98546,12 @@ class MessengerCLI {
98546
98546
  this.app = new SHIP_01_1.SHIP_01({
98547
98547
  gunOptions: {
98548
98548
  peers: [
98549
+ "https://peer.wallie.io/gun",
98549
98550
  "https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun",
98550
98551
  "https://relay.shogun-eco.xyz/gun",
98551
- "https://peer.wallie.io/gun",
98552
98552
  ],
98553
- radisk: false,
98553
+ radisk: true,
98554
98554
  localStorage: false,
98555
- multicast: false, // Disabilita multicast per evitare blocchi
98556
- wire: false,
98557
- axe: false,
98558
98555
  },
98559
98556
  });
98560
98557
  // Don't initialize readline in browser environment
@@ -98859,13 +98856,13 @@ class MessengerCLI {
98859
98856
  if (answer.trim() === "CONFERMA") {
98860
98857
  console.log(c("yellow", "πŸ—‘οΈ Cancellazione messaggi in corso..."));
98861
98858
  // Ottieni tutti i messaggi
98862
- this.app["shogun"].db.gun.get("messages").once((allMessages) => {
98859
+ this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).once((allMessages) => {
98863
98860
  if (allMessages && typeof allMessages === 'object') {
98864
98861
  let count = 0;
98865
98862
  // Cancella ogni messaggio
98866
98863
  for (const [messageId, data] of Object.entries(allMessages)) {
98867
98864
  if (typeof data === "object" && data !== null && messageId !== '_') {
98868
- this.app["shogun"].db.gun.get("messages").get(messageId).put(null);
98865
+ this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).get(messageId).put(null);
98869
98866
  count++;
98870
98867
  }
98871
98868
  }
@@ -99193,7 +99190,7 @@ class SHIP_01 {
99193
99190
  if (!signupResult.success) {
99194
99191
  return {
99195
99192
  success: false,
99196
- error: signupResult.error || "Signup failed"
99193
+ error: signupResult.error || "Signup failed",
99197
99194
  };
99198
99195
  }
99199
99196
  console.log("βœ… Utente registrato");
@@ -99209,13 +99206,13 @@ class SHIP_01 {
99209
99206
  return {
99210
99207
  success: true,
99211
99208
  userPub: signupResult.pub,
99212
- derivedAddress
99209
+ derivedAddress,
99213
99210
  };
99214
99211
  }
99215
99212
  catch (error) {
99216
99213
  return {
99217
99214
  success: false,
99218
- error: error.message
99215
+ error: error.message,
99219
99216
  };
99220
99217
  }
99221
99218
  }
@@ -99229,7 +99226,7 @@ class SHIP_01 {
99229
99226
  if (!loginResult.success) {
99230
99227
  return {
99231
99228
  success: false,
99232
- error: loginResult.error || "Login failed"
99229
+ error: loginResult.error || "Login failed",
99233
99230
  };
99234
99231
  }
99235
99232
  console.log("βœ… Login effettuato");
@@ -99245,13 +99242,13 @@ class SHIP_01 {
99245
99242
  return {
99246
99243
  success: true,
99247
99244
  userPub: loginResult.userPub,
99248
- derivedAddress
99245
+ derivedAddress,
99249
99246
  };
99250
99247
  }
99251
99248
  catch (error) {
99252
99249
  return {
99253
99250
  success: false,
99254
- error: error.message
99251
+ error: error.message,
99255
99252
  };
99256
99253
  }
99257
99254
  }
@@ -99296,7 +99293,7 @@ class SHIP_01 {
99296
99293
  return {
99297
99294
  success: true,
99298
99295
  userPub: authResult.userPub,
99299
- derivedAddress
99296
+ derivedAddress,
99300
99297
  };
99301
99298
  }
99302
99299
  catch (error) {
@@ -99340,12 +99337,15 @@ class SHIP_01 {
99340
99337
  // Salva chiave pubblica sul nodo globale usando il userPub come chiave
99341
99338
  // Questo permette ad altri di trovarla facilmente
99342
99339
  const userPub = currentUser.is.pub;
99343
- await this.shogun.db.gun.get(userPub).put({
99340
+ await this.shogun.db.gun
99341
+ .get(userPub)
99342
+ .put({
99344
99343
  pub: currentUser.is.pub,
99345
99344
  epub: currentUser.is.epub,
99346
99345
  algorithm: "ECDSA",
99347
- timestamp: Date.now().toString()
99348
- }).then();
99346
+ timestamp: Date.now().toString(),
99347
+ })
99348
+ .then();
99349
99349
  console.log(`πŸ“ Chiave pubblica pubblicata su GunDB`);
99350
99350
  return { success: true };
99351
99351
  }
@@ -99374,7 +99374,7 @@ class SHIP_01 {
99374
99374
  if (!recipientKey) {
99375
99375
  return {
99376
99376
  success: false,
99377
- error: `Recipient ${recipientUsername} has not published their public key`
99377
+ error: `Recipient ${recipientUsername} has not published their public key`,
99378
99378
  };
99379
99379
  }
99380
99380
  // 2. Ottieni il SEA pair completo (include chiavi private)
@@ -99395,20 +99395,24 @@ class SHIP_01 {
99395
99395
  to: recipientUsername,
99396
99396
  content: encryptedMessage, // Contenuto crittografato!
99397
99397
  timestamp: Date.now().toString(),
99398
- messageId: messageId
99398
+ messageId: messageId,
99399
99399
  };
99400
99400
  // Salva sul nodo globale 'messages' per permettere il listener
99401
- await this.shogun.db.gun.get(SHIP_01.NODES.MESSAGES).get(messageId).put(messageData).then();
99401
+ await this.shogun.db.gun
99402
+ .get(SHIP_01.NODES.MESSAGES)
99403
+ .get(messageId)
99404
+ .put(messageData)
99405
+ .then();
99402
99406
  console.log(`βœ… Messaggio salvato: ${messageId}`);
99403
99407
  return {
99404
99408
  success: true,
99405
- messageId: messageId
99409
+ messageId: messageId,
99406
99410
  };
99407
99411
  }
99408
99412
  catch (error) {
99409
99413
  return {
99410
99414
  success: false,
99411
- error: error.message
99415
+ error: error.message,
99412
99416
  };
99413
99417
  }
99414
99418
  }
@@ -99429,7 +99433,7 @@ class SHIP_01 {
99429
99433
  if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
99430
99434
  return {
99431
99435
  pub: publicKeyData.pub,
99432
- epub: publicKeyData.epub
99436
+ epub: publicKeyData.epub,
99433
99437
  };
99434
99438
  }
99435
99439
  return null;
@@ -99466,7 +99470,11 @@ class SHIP_01 {
99466
99470
  .map()
99467
99471
  .on(async (data, key) => {
99468
99472
  // Filtra solo i messaggi destinati a questo utente (per username)
99469
- if (data && data.to === username && data.from && data.content && data.messageId) {
99473
+ if (data &&
99474
+ data.to === username &&
99475
+ data.from &&
99476
+ data.content &&
99477
+ data.messageId) {
99470
99478
  // Evita duplicati (GunDB puΓ² emettere piΓΉ volte)
99471
99479
  if (receivedMessages.has(data.messageId)) {
99472
99480
  return;
@@ -99478,7 +99486,7 @@ class SHIP_01 {
99478
99486
  onMessage({
99479
99487
  from: data.from,
99480
99488
  content: decryptedContent,
99481
- timestamp: parseInt(data.timestamp)
99489
+ timestamp: parseInt(data.timestamp),
99482
99490
  });
99483
99491
  }
99484
99492
  catch (error) {
@@ -99518,7 +99526,7 @@ class SHIP_01 {
99518
99526
  if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
99519
99527
  return {
99520
99528
  pub: publicKeyData.pub,
99521
- epub: publicKeyData.epub
99529
+ epub: publicKeyData.epub,
99522
99530
  };
99523
99531
  }
99524
99532
  return null;
@@ -99547,39 +99555,29 @@ class SHIP_01 {
99547
99555
  const userPub = currentUser.is.pub;
99548
99556
  const username = currentUser.is.alias;
99549
99557
  const allMessages = [];
99550
- console.log(`[SHIP-01] Getting history between ${username} (${userPub.substring(0, 20)}...) and ${withUsername}`);
99551
99558
  // Ottieni il userPub dell'altro utente
99552
99559
  const otherUserData = await this.shogun.db.getUserByAlias(withUsername);
99553
99560
  const otherUserPub = otherUserData?.userPub;
99554
- console.log(`[SHIP-01] Other user pub: ${otherUserPub?.substring(0, 20) || 'not found'}...`);
99555
99561
  // Use .map() instead of .then() to iterate all messages
99556
99562
  return new Promise((resolve) => {
99557
99563
  const messages = [];
99558
99564
  let messageCount = 0;
99559
- this.shogun.db.gun.get(SHIP_01.NODES.MESSAGES).map().once(async (msgData, messageId) => {
99565
+ this.shogun.db.gun
99566
+ .get(SHIP_01.NODES.MESSAGES)
99567
+ .map()
99568
+ .once(async (msgData, messageId) => {
99560
99569
  // Skip metadata fields
99561
- if (!msgData || typeof msgData !== 'object' || messageId === '_') {
99570
+ if (!msgData || typeof msgData !== "object" || messageId === "_") {
99562
99571
  return;
99563
99572
  }
99564
99573
  messageCount++;
99565
- console.log(`[SHIP-01] Checking message ${messageId}:`, {
99566
- from: msgData.from?.substring(0, 20),
99567
- to: msgData.to,
99568
- hasContent: !!msgData.content
99569
- });
99570
99574
  try {
99571
99575
  // Check if message is part of this conversation
99572
99576
  // Fixed: Handle both username and userPub in matching
99573
- const isSentToTarget = msgData.from === userPub && (msgData.to === withUsername || msgData.to === otherUserPub);
99574
- const isReceivedFromTarget = (msgData.to === username || msgData.to === userPub) && msgData.from === otherUserPub;
99575
- console.log(`[SHIP-01] Message ${messageId} match:`, {
99576
- isSentToTarget,
99577
- isReceivedFromTarget,
99578
- fromMatch: msgData.from === userPub,
99579
- toMatch: msgData.to === withUsername,
99580
- receivedToMatch: msgData.to === username,
99581
- receivedFromMatch: msgData.from === otherUserPub
99582
- });
99577
+ const isSentToTarget = msgData.from === userPub &&
99578
+ (msgData.to === withUsername || msgData.to === otherUserPub);
99579
+ const isReceivedFromTarget = (msgData.to === username || msgData.to === userPub) &&
99580
+ msgData.from === otherUserPub;
99583
99581
  if (isSentToTarget || isReceivedFromTarget) {
99584
99582
  // Decrypt message
99585
99583
  const decryptedContent = await this.decryptMessage(msgData.content, msgData.from);
@@ -99587,18 +99585,16 @@ class SHIP_01 {
99587
99585
  from: msgData.from,
99588
99586
  to: msgData.to,
99589
99587
  content: decryptedContent,
99590
- timestamp: parseInt(msgData.timestamp)
99588
+ timestamp: parseInt(msgData.timestamp),
99591
99589
  });
99592
- console.log(`[SHIP-01] βœ… Decrypted message from ${msgData.from.substring(0, 20)}...`);
99593
99590
  }
99594
99591
  }
99595
99592
  catch (error) {
99596
- console.error(`[SHIP-01] ❌ Error processing message ${messageId}:`, error);
99593
+ // Silent error - message couldn't be decrypted
99597
99594
  }
99598
99595
  });
99599
99596
  // Wait a bit for GunDB to return all messages, then resolve
99600
99597
  setTimeout(() => {
99601
- console.log(`[SHIP-01] Found ${messages.length} messages out of ${messageCount} total`);
99602
99598
  const sorted = messages.sort((a, b) => a.timestamp - b.timestamp);
99603
99599
  resolve(sorted);
99604
99600
  }, 2000);
@@ -99628,7 +99624,7 @@ class SHIP_01 {
99628
99624
  const derived = await (0, derive_1.default)(seaPair.priv, null, {
99629
99625
  includeSecp256k1Ethereum: true,
99630
99626
  includeP256: false,
99631
- includeSecp256k1Bitcoin: false
99627
+ includeSecp256k1Bitcoin: false,
99632
99628
  });
99633
99629
  return derived.secp256k1Ethereum.address;
99634
99630
  }
@@ -99637,7 +99633,7 @@ class SHIP_01 {
99637
99633
  // Fallback: hash della chiave pubblica
99638
99634
  const fallbackKey = publicKey || "unknown";
99639
99635
  const hash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(fallbackKey));
99640
- return ethers_1.ethers.getAddress('0x' + hash.slice(-40));
99636
+ return ethers_1.ethers.getAddress("0x" + hash.slice(-40));
99641
99637
  }
99642
99638
  }
99643
99639
  /**
@@ -99650,185 +99646,10 @@ class SHIP_01 {
99650
99646
  exports.SHIP_01 = SHIP_01;
99651
99647
  // GunDB Node Names - Constants for clarity
99652
99648
  SHIP_01.NODES = {
99653
- MESSAGES: 'messages',
99654
- USERS: 'users',
99655
- PUBLIC_KEYS: 'publicKeys'
99649
+ MESSAGES: "messages",
99650
+ USERS: "users",
99651
+ PUBLIC_KEYS: "publicKeys",
99656
99652
  };
99657
- // ============================================================================
99658
- // 8. ESEMPIO D'USO COMPLETO
99659
- // ============================================================================
99660
- // async function main() {
99661
- // console.log("πŸš€ Secure Messaging App - Shogun Core + GunDB\n");
99662
- // // 1. Inizializza il sistema
99663
- // const app = new SHIP_01({
99664
- // gunOptions: {
99665
- // peers: ["https://relay.shogun-eco.xyz/gun","https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun","https://peer.wallie.io/gun"],
99666
- // radisk: false,
99667
- // localStorage:false,
99668
- // }
99669
- // });
99670
- // // 2. Signup (prima volta)
99671
- // console.log("πŸ“ Registrazione nuovo utente...");
99672
- // const signupResult = await app.signup("alice", "password123");
99673
- // if (!signupResult.success) {
99674
- // console.log("ℹ️ Utente giΓ  esistente, procedo con login");
99675
- // } else {
99676
- // console.log("βœ… Utente registrato!");
99677
- // console.log(` Username: alice`);
99678
- // console.log(` Public Key: ${signupResult.userPub}`);
99679
- // console.log(` Derived Address: ${signupResult.derivedAddress}\n`);
99680
- // }
99681
- // // 3. Login
99682
- // console.log("πŸ” Login...");
99683
- // const loginResult = await app.login("alice", "password123");
99684
- // if (!loginResult.success) {
99685
- // console.error("❌ Login fallito:", loginResult.error);
99686
- // return;
99687
- // }
99688
- // console.log("βœ… Login effettuato!");
99689
- // console.log(` - Autenticazione: Shogun Core (Username/Password)`);
99690
- // console.log(` - Storage: GunDB decentralizzato P2P\n`);
99691
- // // 4. Pubblica chiave pubblica
99692
- // console.log("πŸ“’ Pubblicazione chiave pubblica...");
99693
- // await app.publishPublicKey();
99694
- // // 5. Ascolta messaggi in arrivo
99695
- // console.log("\nπŸ‘‚ In ascolto di messaggi...\n");
99696
- // await app.listenForMessages((message) => {
99697
- // console.log(`πŸ“¨ Nuovo messaggio da ${message.from.substring(0, 10)}...:`);
99698
- // console.log(` Contenuto: ${message.content}`);
99699
- // console.log(` Timestamp: ${new Date(message.timestamp).toLocaleString()}\n`);
99700
- // });
99701
- // // 6. Invia un messaggio
99702
- // const recipientUsername = "bob";
99703
- // console.log(`πŸ“€ Invio messaggio a ${recipientUsername}...`);
99704
- // const result = await app.sendMessage(
99705
- // recipientUsername,
99706
- // "Hello Bob! This is a secure message using Shogun Core"
99707
- // );
99708
- // if (result.success) {
99709
- // console.log("βœ… Messaggio inviato!");
99710
- // console.log(` Message ID: ${result.messageId}`);
99711
- // console.log(` Storage: GunDB P2P (gratis!)`);
99712
- // }
99713
- // // 7. Recupera storico conversazione
99714
- // console.log("\nπŸ“š Recupero storico messaggi...");
99715
- // const history = await app.getMessageHistory(recipientUsername);
99716
- // console.log(`\nπŸ’¬ Conversazione con ${recipientUsername} (${history.length} messaggi):`);
99717
- // history.forEach((msg, i) => {
99718
- // const isMe = msg.from === loginResult.userPub;
99719
- // console.log(`${i + 1}. ${isMe ? 'Tu' : 'Loro'}: ${msg.content}`);
99720
- // });
99721
- // }
99722
- // ============================================================================
99723
- // 9. VANTAGGI DELL'ARCHITETTURA
99724
- // ============================================================================
99725
- /**
99726
- * VANTAGGI DI QUESTA ARCHITETTURA:
99727
- *
99728
- * 1. SEMPLICITΓ€:
99729
- * - Solo username/password (nessun wallet necessario)
99730
- * - Nessun gas fee o transazioni blockchain
99731
- * - Setup in pochi secondi
99732
- *
99733
- * 2. DECENTRALIZZAZIONE COMPLETA:
99734
- * - Storage P2P su GunDB
99735
- * - Nessun server centrale
99736
- * - Censorship resistant
99737
- * - User sovereignty
99738
- *
99739
- * 3. COSTI ZERO:
99740
- * - Nessun costo per messaggi
99741
- * - Nessun costo per storage
99742
- * - Completamente gratis
99743
- *
99744
- * 4. END-TO-END ENCRYPTION:
99745
- * - Messaggi crittografati con ECDH (Elliptic Curve Diffie-Hellman)
99746
- * - SEA.secret deriva shared secret da epub (encryption public key)
99747
- * - SEA.encrypt cripta con AES-GCM
99748
- * - Solo mittente e destinatario possono leggere i messaggi
99749
- * - Nessun server o relay puΓ² leggere il contenuto
99750
- *
99751
- * 5. IDENTITΓ€ DECENTRALIZZATA:
99752
- * - Chiave pubblica GunDB come identitΓ 
99753
- * - PuΓ² essere derivata in address Ethereum se necessario
99754
- * - Portabile tra diverse applicazioni
99755
- *
99756
- * 6. REAL-TIME:
99757
- * - Messaggi in tempo reale
99758
- * - Sincronizzazione automatica
99759
- * - Listener reattivi
99760
- *
99761
- * 7. OFFLINE-FIRST:
99762
- * - Funziona anche offline
99763
- * - Sincronizzazione automatica al riconnect
99764
- * - GunDB gestisce conflitti automaticamente
99765
- *
99766
- * COME FUNZIONA LA CRITTOGRAFIA:
99767
- *
99768
- * 1. SETUP - Ogni utente ha un SEA pair:
99769
- * - pub: chiave pubblica di signing
99770
- * - priv: chiave privata di signing
99771
- * - epub: chiave pubblica di encryption (per ECDH)
99772
- * - epriv: chiave privata di encryption (per ECDH)
99773
- *
99774
- * 2. PUBBLICAZIONE CHIAVI:
99775
- * - Ogni utente pubblica il suo epub su GunDB
99776
- * - Altri possono trovarlo per criptare messaggi
99777
- *
99778
- * 3. INVIO MESSAGGIO (Alice β†’ Bob):
99779
- * a) Alice ottiene l'epub di Bob da GunDB
99780
- * b) SEA.secret(bob.epub, alice.pair) β†’ shared_secret (ECDH)
99781
- * c) SEA.encrypt(message, shared_secret) β†’ encrypted_message
99782
- * d) Alice salva encrypted_message su GunDB
99783
- *
99784
- * 4. RICEZIONE MESSAGGIO (Bob riceve):
99785
- * a) Bob legge encrypted_message da GunDB
99786
- * b) Bob ottiene l'epub di Alice
99787
- * c) SEA.secret(alice.epub, bob.pair) β†’ shared_secret (stesso!)
99788
- * d) SEA.decrypt(encrypted_message, shared_secret) β†’ message
99789
- *
99790
- * 5. SICUREZZA:
99791
- * - Shared secret derivato con ECDH (mai trasmesso)
99792
- * - Solo Alice e Bob possono derivare lo stesso secret
99793
- * - Messaggi crittografati con AES-256-GCM
99794
- * - Forward secrecy se chiavi sono ruotate
99795
- *
99796
- * Esempio tecnico:
99797
- * Alice.epub + Bob.epriv β†’ shared_secret_AB
99798
- * Bob.epub + Alice.epriv β†’ shared_secret_AB (stesso!)
99799
- *
99800
- * Vantaggi:
99801
- * βœ… End-to-end encryption
99802
- * βœ… Perfect forward secrecy (con key rotation)
99803
- * βœ… Nessun server puΓ² leggere i messaggi
99804
- * βœ… Standard crittografico (ECDH + AES-GCM)
99805
- * βœ… Una sola chiave privata da gestire
99806
- * βœ… Address Ethereum derivabile (interoperabilitΓ )
99807
- */
99808
- // ============================================================================
99809
- // 10. TEST COMPLETO: Alice e Bob si scambiano messaggi
99810
- // ============================================================================
99811
- /**
99812
- * Test completo che simula Alice e Bob che si scambiano messaggi CRITTOGRAFATI
99813
- *
99814
- * CRITTOGRAFIA END-TO-END:
99815
- * - Ogni messaggio Γ¨ crittografato con ECDH (Elliptic Curve Diffie-Hellman)
99816
- * - Solo mittente e destinatario possono leggere i messaggi
99817
- * - I relay GunDB vedono solo dati crittografati
99818
- *
99819
- * FLOW:
99820
- * 1. Alice e Bob pubblicano le loro chiavi pubbliche (epub)
99821
- * 2. Alice vuole inviare a Bob:
99822
- * - Ottiene bob.epub da GunDB
99823
- * - SEA.secret(bob.epub, alice.pair) β†’ shared_secret
99824
- * - SEA.encrypt(message, shared_secret) β†’ encrypted
99825
- * - Salva encrypted su GunDB
99826
- * 3. Bob riceve:
99827
- * - Legge encrypted da GunDB
99828
- * - Ottiene alice.epub
99829
- * - SEA.secret(alice.epub, bob.pair) β†’ shared_secret (stesso!)
99830
- * - SEA.decrypt(encrypted, shared_secret) β†’ message
99831
- */
99832
99653
  async function testAliceAndBob() {
99833
99654
  console.log("πŸ§ͺ TEST: Alice e Bob - Conversazione Crittografata E2E\n");
99834
99655
  console.log("=".repeat(60));
@@ -99850,14 +99671,14 @@ async function testAliceAndBob() {
99850
99671
  }
99851
99672
  await alice.publishPublicKey();
99852
99673
  // Aspetta che la chiave sia sincronizzata
99853
- await new Promise(resolve => setTimeout(resolve, 1000));
99674
+ await new Promise((resolve) => setTimeout(resolve, 1000));
99854
99675
  // Setup Bob
99855
99676
  console.log("\nπŸ‘¨ BOB - Setup");
99856
99677
  console.log("-".repeat(60));
99857
99678
  const bob = new SHIP_01({
99858
99679
  gunOptions: {
99859
99680
  peers: ["https://peer.wallie.io/gun"],
99860
- radisk: true
99681
+ radisk: true,
99861
99682
  },
99862
99683
  });
99863
99684
  // Bob signup/login
@@ -99869,7 +99690,7 @@ async function testAliceAndBob() {
99869
99690
  }
99870
99691
  await bob.publishPublicKey();
99871
99692
  // Aspetta che la chiave sia sincronizzata
99872
- await new Promise(resolve => setTimeout(resolve, 1000));
99693
+ await new Promise((resolve) => setTimeout(resolve, 1000));
99873
99694
  console.log("\n" + "=".repeat(60));
99874
99695
  console.log("πŸ’¬ CONVERSAZIONE");
99875
99696
  console.log("=".repeat(60));
@@ -99891,31 +99712,31 @@ async function testAliceAndBob() {
99891
99712
  console.log(` Timestamp: ${new Date(msg.timestamp).toLocaleTimeString()}`);
99892
99713
  });
99893
99714
  // Aspetta che i listener siano pronti
99894
- await new Promise(resolve => setTimeout(resolve, 2000));
99715
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99895
99716
  // Alice invia messaggio a Bob
99896
99717
  console.log("\n[Alice invia] πŸ“€");
99897
99718
  const msg1 = await alice.sendMessage("bob", "Ciao Bob! Come stai? πŸ‘‹");
99898
99719
  console.log(` βœ… Inviato: "${msg1.messageId}"`);
99899
99720
  // Aspetta che Bob riceva
99900
- await new Promise(resolve => setTimeout(resolve, 2000));
99721
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99901
99722
  // Bob risponde ad Alice
99902
99723
  console.log("\n[Bob invia] πŸ“€");
99903
99724
  const msg2 = await bob.sendMessage("alice", "Ciao Alice! Tutto bene, grazie! Tu? 😊");
99904
99725
  console.log(` βœ… Inviato: "${msg2.messageId}"`);
99905
99726
  // Aspetta che Alice riceva
99906
- await new Promise(resolve => setTimeout(resolve, 2000));
99727
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99907
99728
  // Alice risponde
99908
99729
  console.log("\n[Alice invia] πŸ“€");
99909
99730
  const msg3 = await alice.sendMessage("bob", "Anch'io benissimo! Questo sistema di messaggistica Γ¨ fantastico! πŸš€");
99910
99731
  console.log(` βœ… Inviato: "${msg3.messageId}"`);
99911
99732
  // Aspetta che Bob riceva
99912
- await new Promise(resolve => setTimeout(resolve, 2000));
99733
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99913
99734
  // Bob conclude
99914
99735
  console.log("\n[Bob invia] πŸ“€");
99915
99736
  const msg4 = await bob.sendMessage("alice", "Vero! Zero costi, decentralizzato e veloce! πŸ’ͺ");
99916
99737
  console.log(` βœ… Inviato: "${msg4.messageId}"`);
99917
99738
  // Aspetta finale
99918
- await new Promise(resolve => setTimeout(resolve, 3000));
99739
+ await new Promise((resolve) => setTimeout(resolve, 3000));
99919
99740
  // Mostra statistiche
99920
99741
  console.log("\n" + "=".repeat(60));
99921
99742
  console.log("πŸ“Š STATISTICHE FINALI");
@@ -99961,8 +99782,6 @@ async function testAliceAndBob() {
99961
99782
  }
99962
99783
  // Esegui esempio o test
99963
99784
  if (__webpack_require__.c[__webpack_require__.s] === module) {
99964
- // Scegli quale eseguire decommentando una delle due righe:
99965
- // main().catch(console.error); // Esempio singolo utente
99966
99785
  testAliceAndBob().catch(console.error); // Test completo Alice & Bob
99967
99786
  }
99968
99787