shogun-core 3.2.1 β†’ 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('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;
@@ -99462,11 +99466,15 @@ class SHIP_01 {
99462
99466
  const receivedMessages = new Set();
99463
99467
  // Ascolta messaggi in tempo reale su GunDB
99464
99468
  this.shogun.db.gun
99465
- .get(`messages`)
99469
+ .get(SHIP_01.NODES.MESSAGES)
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,38 +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('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
- const isSentToTarget = msgData.from === userPub && msgData.to === withUsername;
99573
- const isReceivedFromTarget = msgData.to === username && msgData.from === otherUserPub;
99574
- console.log(`[SHIP-01] Message ${messageId} match:`, {
99575
- isSentToTarget,
99576
- isReceivedFromTarget,
99577
- fromMatch: msgData.from === userPub,
99578
- toMatch: msgData.to === withUsername,
99579
- receivedToMatch: msgData.to === username,
99580
- receivedFromMatch: msgData.from === otherUserPub
99581
- });
99576
+ // Fixed: Handle both username and userPub in matching
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;
99582
99581
  if (isSentToTarget || isReceivedFromTarget) {
99583
99582
  // Decrypt message
99584
99583
  const decryptedContent = await this.decryptMessage(msgData.content, msgData.from);
@@ -99586,18 +99585,16 @@ class SHIP_01 {
99586
99585
  from: msgData.from,
99587
99586
  to: msgData.to,
99588
99587
  content: decryptedContent,
99589
- timestamp: parseInt(msgData.timestamp)
99588
+ timestamp: parseInt(msgData.timestamp),
99590
99589
  });
99591
- console.log(`[SHIP-01] βœ… Decrypted message from ${msgData.from.substring(0, 20)}...`);
99592
99590
  }
99593
99591
  }
99594
99592
  catch (error) {
99595
- console.error(`[SHIP-01] ❌ Error processing message ${messageId}:`, error);
99593
+ // Silent error - message couldn't be decrypted
99596
99594
  }
99597
99595
  });
99598
99596
  // Wait a bit for GunDB to return all messages, then resolve
99599
99597
  setTimeout(() => {
99600
- console.log(`[SHIP-01] Found ${messages.length} messages out of ${messageCount} total`);
99601
99598
  const sorted = messages.sort((a, b) => a.timestamp - b.timestamp);
99602
99599
  resolve(sorted);
99603
99600
  }, 2000);
@@ -99627,7 +99624,7 @@ class SHIP_01 {
99627
99624
  const derived = await (0, derive_1.default)(seaPair.priv, null, {
99628
99625
  includeSecp256k1Ethereum: true,
99629
99626
  includeP256: false,
99630
- includeSecp256k1Bitcoin: false
99627
+ includeSecp256k1Bitcoin: false,
99631
99628
  });
99632
99629
  return derived.secp256k1Ethereum.address;
99633
99630
  }
@@ -99636,7 +99633,7 @@ class SHIP_01 {
99636
99633
  // Fallback: hash della chiave pubblica
99637
99634
  const fallbackKey = publicKey || "unknown";
99638
99635
  const hash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(fallbackKey));
99639
- return ethers_1.ethers.getAddress('0x' + hash.slice(-40));
99636
+ return ethers_1.ethers.getAddress("0x" + hash.slice(-40));
99640
99637
  }
99641
99638
  }
99642
99639
  /**
@@ -99647,181 +99644,12 @@ class SHIP_01 {
99647
99644
  }
99648
99645
  }
99649
99646
  exports.SHIP_01 = SHIP_01;
99650
- // ============================================================================
99651
- // 8. ESEMPIO D'USO COMPLETO
99652
- // ============================================================================
99653
- // async function main() {
99654
- // console.log("πŸš€ Secure Messaging App - Shogun Core + GunDB\n");
99655
- // // 1. Inizializza il sistema
99656
- // const app = new SHIP_01({
99657
- // gunOptions: {
99658
- // peers: ["https://relay.shogun-eco.xyz/gun","https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun","https://peer.wallie.io/gun"],
99659
- // radisk: false,
99660
- // localStorage:false,
99661
- // }
99662
- // });
99663
- // // 2. Signup (prima volta)
99664
- // console.log("πŸ“ Registrazione nuovo utente...");
99665
- // const signupResult = await app.signup("alice", "password123");
99666
- // if (!signupResult.success) {
99667
- // console.log("ℹ️ Utente giΓ  esistente, procedo con login");
99668
- // } else {
99669
- // console.log("βœ… Utente registrato!");
99670
- // console.log(` Username: alice`);
99671
- // console.log(` Public Key: ${signupResult.userPub}`);
99672
- // console.log(` Derived Address: ${signupResult.derivedAddress}\n`);
99673
- // }
99674
- // // 3. Login
99675
- // console.log("πŸ” Login...");
99676
- // const loginResult = await app.login("alice", "password123");
99677
- // if (!loginResult.success) {
99678
- // console.error("❌ Login fallito:", loginResult.error);
99679
- // return;
99680
- // }
99681
- // console.log("βœ… Login effettuato!");
99682
- // console.log(` - Autenticazione: Shogun Core (Username/Password)`);
99683
- // console.log(` - Storage: GunDB decentralizzato P2P\n`);
99684
- // // 4. Pubblica chiave pubblica
99685
- // console.log("πŸ“’ Pubblicazione chiave pubblica...");
99686
- // await app.publishPublicKey();
99687
- // // 5. Ascolta messaggi in arrivo
99688
- // console.log("\nπŸ‘‚ In ascolto di messaggi...\n");
99689
- // await app.listenForMessages((message) => {
99690
- // console.log(`πŸ“¨ Nuovo messaggio da ${message.from.substring(0, 10)}...:`);
99691
- // console.log(` Contenuto: ${message.content}`);
99692
- // console.log(` Timestamp: ${new Date(message.timestamp).toLocaleString()}\n`);
99693
- // });
99694
- // // 6. Invia un messaggio
99695
- // const recipientUsername = "bob";
99696
- // console.log(`πŸ“€ Invio messaggio a ${recipientUsername}...`);
99697
- // const result = await app.sendMessage(
99698
- // recipientUsername,
99699
- // "Hello Bob! This is a secure message using Shogun Core"
99700
- // );
99701
- // if (result.success) {
99702
- // console.log("βœ… Messaggio inviato!");
99703
- // console.log(` Message ID: ${result.messageId}`);
99704
- // console.log(` Storage: GunDB P2P (gratis!)`);
99705
- // }
99706
- // // 7. Recupera storico conversazione
99707
- // console.log("\nπŸ“š Recupero storico messaggi...");
99708
- // const history = await app.getMessageHistory(recipientUsername);
99709
- // console.log(`\nπŸ’¬ Conversazione con ${recipientUsername} (${history.length} messaggi):`);
99710
- // history.forEach((msg, i) => {
99711
- // const isMe = msg.from === loginResult.userPub;
99712
- // console.log(`${i + 1}. ${isMe ? 'Tu' : 'Loro'}: ${msg.content}`);
99713
- // });
99714
- // }
99715
- // ============================================================================
99716
- // 9. VANTAGGI DELL'ARCHITETTURA
99717
- // ============================================================================
99718
- /**
99719
- * VANTAGGI DI QUESTA ARCHITETTURA:
99720
- *
99721
- * 1. SEMPLICITΓ€:
99722
- * - Solo username/password (nessun wallet necessario)
99723
- * - Nessun gas fee o transazioni blockchain
99724
- * - Setup in pochi secondi
99725
- *
99726
- * 2. DECENTRALIZZAZIONE COMPLETA:
99727
- * - Storage P2P su GunDB
99728
- * - Nessun server centrale
99729
- * - Censorship resistant
99730
- * - User sovereignty
99731
- *
99732
- * 3. COSTI ZERO:
99733
- * - Nessun costo per messaggi
99734
- * - Nessun costo per storage
99735
- * - Completamente gratis
99736
- *
99737
- * 4. END-TO-END ENCRYPTION:
99738
- * - Messaggi crittografati con ECDH (Elliptic Curve Diffie-Hellman)
99739
- * - SEA.secret deriva shared secret da epub (encryption public key)
99740
- * - SEA.encrypt cripta con AES-GCM
99741
- * - Solo mittente e destinatario possono leggere i messaggi
99742
- * - Nessun server o relay puΓ² leggere il contenuto
99743
- *
99744
- * 5. IDENTITΓ€ DECENTRALIZZATA:
99745
- * - Chiave pubblica GunDB come identitΓ 
99746
- * - PuΓ² essere derivata in address Ethereum se necessario
99747
- * - Portabile tra diverse applicazioni
99748
- *
99749
- * 6. REAL-TIME:
99750
- * - Messaggi in tempo reale
99751
- * - Sincronizzazione automatica
99752
- * - Listener reattivi
99753
- *
99754
- * 7. OFFLINE-FIRST:
99755
- * - Funziona anche offline
99756
- * - Sincronizzazione automatica al riconnect
99757
- * - GunDB gestisce conflitti automaticamente
99758
- *
99759
- * COME FUNZIONA LA CRITTOGRAFIA:
99760
- *
99761
- * 1. SETUP - Ogni utente ha un SEA pair:
99762
- * - pub: chiave pubblica di signing
99763
- * - priv: chiave privata di signing
99764
- * - epub: chiave pubblica di encryption (per ECDH)
99765
- * - epriv: chiave privata di encryption (per ECDH)
99766
- *
99767
- * 2. PUBBLICAZIONE CHIAVI:
99768
- * - Ogni utente pubblica il suo epub su GunDB
99769
- * - Altri possono trovarlo per criptare messaggi
99770
- *
99771
- * 3. INVIO MESSAGGIO (Alice β†’ Bob):
99772
- * a) Alice ottiene l'epub di Bob da GunDB
99773
- * b) SEA.secret(bob.epub, alice.pair) β†’ shared_secret (ECDH)
99774
- * c) SEA.encrypt(message, shared_secret) β†’ encrypted_message
99775
- * d) Alice salva encrypted_message su GunDB
99776
- *
99777
- * 4. RICEZIONE MESSAGGIO (Bob riceve):
99778
- * a) Bob legge encrypted_message da GunDB
99779
- * b) Bob ottiene l'epub di Alice
99780
- * c) SEA.secret(alice.epub, bob.pair) β†’ shared_secret (stesso!)
99781
- * d) SEA.decrypt(encrypted_message, shared_secret) β†’ message
99782
- *
99783
- * 5. SICUREZZA:
99784
- * - Shared secret derivato con ECDH (mai trasmesso)
99785
- * - Solo Alice e Bob possono derivare lo stesso secret
99786
- * - Messaggi crittografati con AES-256-GCM
99787
- * - Forward secrecy se chiavi sono ruotate
99788
- *
99789
- * Esempio tecnico:
99790
- * Alice.epub + Bob.epriv β†’ shared_secret_AB
99791
- * Bob.epub + Alice.epriv β†’ shared_secret_AB (stesso!)
99792
- *
99793
- * Vantaggi:
99794
- * βœ… End-to-end encryption
99795
- * βœ… Perfect forward secrecy (con key rotation)
99796
- * βœ… Nessun server puΓ² leggere i messaggi
99797
- * βœ… Standard crittografico (ECDH + AES-GCM)
99798
- * βœ… Una sola chiave privata da gestire
99799
- * βœ… Address Ethereum derivabile (interoperabilitΓ )
99800
- */
99801
- // ============================================================================
99802
- // 10. TEST COMPLETO: Alice e Bob si scambiano messaggi
99803
- // ============================================================================
99804
- /**
99805
- * Test completo che simula Alice e Bob che si scambiano messaggi CRITTOGRAFATI
99806
- *
99807
- * CRITTOGRAFIA END-TO-END:
99808
- * - Ogni messaggio Γ¨ crittografato con ECDH (Elliptic Curve Diffie-Hellman)
99809
- * - Solo mittente e destinatario possono leggere i messaggi
99810
- * - I relay GunDB vedono solo dati crittografati
99811
- *
99812
- * FLOW:
99813
- * 1. Alice e Bob pubblicano le loro chiavi pubbliche (epub)
99814
- * 2. Alice vuole inviare a Bob:
99815
- * - Ottiene bob.epub da GunDB
99816
- * - SEA.secret(bob.epub, alice.pair) β†’ shared_secret
99817
- * - SEA.encrypt(message, shared_secret) β†’ encrypted
99818
- * - Salva encrypted su GunDB
99819
- * 3. Bob riceve:
99820
- * - Legge encrypted da GunDB
99821
- * - Ottiene alice.epub
99822
- * - SEA.secret(alice.epub, bob.pair) β†’ shared_secret (stesso!)
99823
- * - SEA.decrypt(encrypted, shared_secret) β†’ message
99824
- */
99647
+ // GunDB Node Names - Constants for clarity
99648
+ SHIP_01.NODES = {
99649
+ MESSAGES: "messages",
99650
+ USERS: "users",
99651
+ PUBLIC_KEYS: "publicKeys",
99652
+ };
99825
99653
  async function testAliceAndBob() {
99826
99654
  console.log("πŸ§ͺ TEST: Alice e Bob - Conversazione Crittografata E2E\n");
99827
99655
  console.log("=".repeat(60));
@@ -99843,14 +99671,14 @@ async function testAliceAndBob() {
99843
99671
  }
99844
99672
  await alice.publishPublicKey();
99845
99673
  // Aspetta che la chiave sia sincronizzata
99846
- await new Promise(resolve => setTimeout(resolve, 1000));
99674
+ await new Promise((resolve) => setTimeout(resolve, 1000));
99847
99675
  // Setup Bob
99848
99676
  console.log("\nπŸ‘¨ BOB - Setup");
99849
99677
  console.log("-".repeat(60));
99850
99678
  const bob = new SHIP_01({
99851
99679
  gunOptions: {
99852
99680
  peers: ["https://peer.wallie.io/gun"],
99853
- radisk: true
99681
+ radisk: true,
99854
99682
  },
99855
99683
  });
99856
99684
  // Bob signup/login
@@ -99862,7 +99690,7 @@ async function testAliceAndBob() {
99862
99690
  }
99863
99691
  await bob.publishPublicKey();
99864
99692
  // Aspetta che la chiave sia sincronizzata
99865
- await new Promise(resolve => setTimeout(resolve, 1000));
99693
+ await new Promise((resolve) => setTimeout(resolve, 1000));
99866
99694
  console.log("\n" + "=".repeat(60));
99867
99695
  console.log("πŸ’¬ CONVERSAZIONE");
99868
99696
  console.log("=".repeat(60));
@@ -99884,31 +99712,31 @@ async function testAliceAndBob() {
99884
99712
  console.log(` Timestamp: ${new Date(msg.timestamp).toLocaleTimeString()}`);
99885
99713
  });
99886
99714
  // Aspetta che i listener siano pronti
99887
- await new Promise(resolve => setTimeout(resolve, 2000));
99715
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99888
99716
  // Alice invia messaggio a Bob
99889
99717
  console.log("\n[Alice invia] πŸ“€");
99890
99718
  const msg1 = await alice.sendMessage("bob", "Ciao Bob! Come stai? πŸ‘‹");
99891
99719
  console.log(` βœ… Inviato: "${msg1.messageId}"`);
99892
99720
  // Aspetta che Bob riceva
99893
- await new Promise(resolve => setTimeout(resolve, 2000));
99721
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99894
99722
  // Bob risponde ad Alice
99895
99723
  console.log("\n[Bob invia] πŸ“€");
99896
99724
  const msg2 = await bob.sendMessage("alice", "Ciao Alice! Tutto bene, grazie! Tu? 😊");
99897
99725
  console.log(` βœ… Inviato: "${msg2.messageId}"`);
99898
99726
  // Aspetta che Alice riceva
99899
- await new Promise(resolve => setTimeout(resolve, 2000));
99727
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99900
99728
  // Alice risponde
99901
99729
  console.log("\n[Alice invia] πŸ“€");
99902
99730
  const msg3 = await alice.sendMessage("bob", "Anch'io benissimo! Questo sistema di messaggistica Γ¨ fantastico! πŸš€");
99903
99731
  console.log(` βœ… Inviato: "${msg3.messageId}"`);
99904
99732
  // Aspetta che Bob riceva
99905
- await new Promise(resolve => setTimeout(resolve, 2000));
99733
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99906
99734
  // Bob conclude
99907
99735
  console.log("\n[Bob invia] πŸ“€");
99908
99736
  const msg4 = await bob.sendMessage("alice", "Vero! Zero costi, decentralizzato e veloce! πŸ’ͺ");
99909
99737
  console.log(` βœ… Inviato: "${msg4.messageId}"`);
99910
99738
  // Aspetta finale
99911
- await new Promise(resolve => setTimeout(resolve, 3000));
99739
+ await new Promise((resolve) => setTimeout(resolve, 3000));
99912
99740
  // Mostra statistiche
99913
99741
  console.log("\n" + "=".repeat(60));
99914
99742
  console.log("πŸ“Š STATISTICHE FINALI");
@@ -99954,8 +99782,6 @@ async function testAliceAndBob() {
99954
99782
  }
99955
99783
  // Esegui esempio o test
99956
99784
  if (__webpack_require__.c[__webpack_require__.s] === module) {
99957
- // Scegli quale eseguire decommentando una delle due righe:
99958
- // main().catch(console.error); // Esempio singolo utente
99959
99785
  testAliceAndBob().catch(console.error); // Test completo Alice & Bob
99960
99786
  }
99961
99787