shogun-core 3.2.3 → 3.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.
Files changed (32) hide show
  1. package/README.md +12 -0
  2. package/dist/browser/shogun-core.js +108102 -43579
  3. package/dist/browser/shogun-core.js.map +1 -1
  4. package/dist/ship/examples/messenger-cli.js +171 -55
  5. package/dist/ship/examples/wallet-cli.js +767 -0
  6. package/dist/ship/implementation/SHIP_00.js +478 -0
  7. package/dist/ship/implementation/SHIP_01.js +275 -492
  8. package/dist/ship/implementation/SHIP_02.js +1366 -0
  9. package/dist/ship/implementation/SHIP_03.js +855 -0
  10. package/dist/ship/interfaces/ISHIP_00.js +135 -0
  11. package/dist/ship/interfaces/ISHIP_01.js +81 -24
  12. package/dist/ship/interfaces/ISHIP_02.js +57 -0
  13. package/dist/ship/interfaces/ISHIP_03.js +61 -0
  14. package/dist/src/gundb/db.js +55 -11
  15. package/dist/src/index.js +10 -2
  16. package/dist/src/managers/CoreInitializer.js +41 -13
  17. package/dist/src/storage/storage.js +22 -9
  18. package/dist/types/ship/examples/messenger-cli.d.ts +7 -1
  19. package/dist/types/ship/examples/wallet-cli.d.ts +131 -0
  20. package/dist/types/ship/implementation/SHIP_00.d.ts +113 -0
  21. package/dist/types/ship/implementation/SHIP_01.d.ts +44 -77
  22. package/dist/types/ship/implementation/SHIP_02.d.ts +297 -0
  23. package/dist/types/ship/implementation/SHIP_03.d.ts +127 -0
  24. package/dist/types/ship/interfaces/ISHIP_00.d.ts +410 -0
  25. package/dist/types/ship/interfaces/ISHIP_01.d.ts +157 -119
  26. package/dist/types/ship/interfaces/ISHIP_02.d.ts +470 -0
  27. package/dist/types/ship/interfaces/ISHIP_03.d.ts +295 -0
  28. package/dist/types/src/gundb/db.d.ts +10 -3
  29. package/dist/types/src/index.d.ts +7 -0
  30. package/dist/types/src/interfaces/shogun.d.ts +2 -0
  31. package/dist/types/src/storage/storage.d.ts +2 -1
  32. package/package.json +22 -9
@@ -8,6 +8,7 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.MessengerCLI = void 0;
11
+ const SHIP_00_1 = require("../implementation/SHIP_00");
11
12
  const SHIP_01_1 = require("../implementation/SHIP_01");
12
13
  // Only import readline in Node.js environment
13
14
  let readline;
@@ -41,12 +42,15 @@ const c = (color, text) => `${colors[color]}${text}${colors.reset}`;
41
42
  // ============================================================================
42
43
  class MessengerCLI {
43
44
  constructor() {
45
+ this.messaging = null;
44
46
  this.currentUser = "";
45
47
  this.recipient = "";
46
48
  this.derivedAddress = "";
47
49
  this.isAuthenticated = false;
48
- // Initialize app in all environments (needed for TypeScript)
49
- this.app = new SHIP_01_1.SHIP_01({
50
+ this.channelToken = ""; // Token for channel messages
51
+ this.currentChannel = ""; // Current channel name
52
+ // Initialize identity layer (SHIP-00)
53
+ this.identity = new SHIP_00_1.SHIP_00({
50
54
  gunOptions: {
51
55
  peers: [
52
56
  "https://peer.wallie.io/gun",
@@ -115,19 +119,19 @@ class MessengerCLI {
115
119
  process.stdout.write(c("gray", "."));
116
120
  }, 500);
117
121
  try {
118
- // Prova login con timeout
119
- let result = await this.withTimeout(this.app.login(username, password), 15000, "Login timeout - verifica connessione ai peers");
122
+ // Prova login con timeout (SHIP-00)
123
+ let result = await this.withTimeout(this.identity.login(username, password), 15000, "Login timeout - verifica connessione ai peers");
120
124
  clearInterval(loadingInterval);
121
125
  console.log(""); // Nuova linea dopo i dots
122
- // Se fallisce, prova signup
126
+ // Se fallisce, prova signup (SHIP-00)
123
127
  if (!result.success) {
124
128
  console.log(c("yellow", "📝 Utente non trovato, creazione in corso..."));
125
- const signupResult = await this.app.signup(username, password);
129
+ const signupResult = await this.identity.signup(username, password);
126
130
  if (signupResult.success) {
127
131
  // Aspetta un momento per evitare race condition
128
132
  await new Promise((resolve) => setTimeout(resolve, 1000));
129
133
  // Riprova login
130
- result = await this.app.login(username, password);
134
+ result = await this.identity.login(username, password);
131
135
  }
132
136
  else {
133
137
  console.log(c("red", `❌ Signup fallito: ${signupResult.error}`));
@@ -145,13 +149,16 @@ class MessengerCLI {
145
149
  console.log(c("gray", ` Derived Address: ${c("cyan", result.derivedAddress || "")}`));
146
150
  console.log("");
147
151
  console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
148
- await this.app.publishPublicKey();
152
+ await this.identity.publishPublicKey();
149
153
  // Aspetta che la chiave sia sincronizzata
150
154
  await new Promise((resolve) => setTimeout(resolve, 1000));
151
155
  console.log(c("green", "✅ Chiave pubblicata su GunDB"));
152
156
  console.log("");
153
- // Ascolta messaggi
154
- await this.app.listenForMessages((msg) => {
157
+ // Inizializza messaging layer (SHIP-01)
158
+ this.messaging = new SHIP_01_1.SHIP_01(this.identity);
159
+ console.log(c("green", "✅ Messaging inizializzato"));
160
+ // Ascolta messaggi (SHIP-01)
161
+ await this.messaging.listenForMessages((msg) => {
155
162
  this.onMessageReceived(msg);
156
163
  });
157
164
  console.log(c("cyan", "💬 Chat pronta! Scrivi /help per i comandi disponibili"));
@@ -177,25 +184,44 @@ class MessengerCLI {
177
184
  // MESSAGING
178
185
  // ========================================================================
179
186
  async sendMessage(content) {
180
- if (!this.isAuthenticated) {
187
+ if (!this.isAuthenticated || !this.messaging) {
181
188
  console.log(c("red", "❌ Non autenticato. Usa /login"));
182
189
  return;
183
190
  }
184
- if (!this.recipient) {
185
- console.log(c("yellow", "⚠️ Nessun destinatario. Usa /to <username>"));
186
- return;
187
- }
188
191
  try {
189
- const result = await this.app.sendMessage(this.recipient, content);
190
- if (result.success) {
191
- const time = new Date().toLocaleTimeString();
192
- console.log(c("gray", `[${time}]`) +
193
- " " +
194
- c("green", `${this.currentUser}:`) +
195
- " " +
196
- content);
192
+ let result;
193
+ // Check if in channel mode or direct message mode
194
+ if (this.currentChannel && this.channelToken) {
195
+ // Send to channel with token encryption
196
+ result = await this.messaging.sendMessageWithToken(this.channelToken, content, this.currentChannel);
197
+ if (result.success) {
198
+ const time = new Date().toLocaleTimeString();
199
+ console.log(c("gray", `[${time}]`) +
200
+ " " +
201
+ c("magenta", `#${this.currentChannel}`) +
202
+ " " +
203
+ c("green", `${this.currentUser}:`) +
204
+ " " +
205
+ content);
206
+ }
207
+ }
208
+ else if (this.recipient) {
209
+ // Send direct message with ECDH encryption
210
+ result = await this.messaging.sendMessage(this.recipient, content);
211
+ if (result.success) {
212
+ const time = new Date().toLocaleTimeString();
213
+ console.log(c("gray", `[${time}]`) +
214
+ " " +
215
+ c("green", `${this.currentUser}:`) +
216
+ " " +
217
+ content);
218
+ }
197
219
  }
198
220
  else {
221
+ console.log(c("yellow", "⚠️ Usa /to <username> per messaggi diretti o /channel <nome> <token> per canali"));
222
+ return;
223
+ }
224
+ if (!result.success) {
199
225
  console.log(c("red", `❌ Errore invio: ${result.error}`));
200
226
  }
201
227
  }
@@ -216,27 +242,36 @@ class MessengerCLI {
216
242
  console.log("");
217
243
  this.rl.prompt();
218
244
  }
245
+ onChannelMessageReceived(message) {
246
+ const time = new Date(message.timestamp).toLocaleTimeString();
247
+ const fromUser = message.from.substring(0, 10) + "...";
248
+ console.log("");
249
+ console.log(c("magenta", `📡 #${message.channel}`));
250
+ console.log(c("gray", `[${time}]`) +
251
+ " " +
252
+ c("cyan", `${fromUser}:`) +
253
+ " " +
254
+ message.content);
255
+ console.log("");
256
+ this.rl.prompt();
257
+ }
219
258
  // ========================================================================
220
259
  // KEY PAIR MANAGEMENT
221
260
  // ========================================================================
222
261
  async exportKeyPair() {
223
262
  try {
224
- // Ottieni il SEA pair completo
225
- const seaPair = this.app["shogun"].db.gun.user()?._?.sea;
263
+ // Ottieni il SEA pair completo da SHIP-00
264
+ const seaPair = this.identity.exportKeyPair();
226
265
  if (!seaPair) {
227
266
  console.log(c("red", "❌ Impossibile accedere al SEA pair"));
228
267
  return;
229
268
  }
230
- // Crea export object
269
+ // Converti in base64 per facilità di copia
231
270
  const exportData = {
232
- pub: seaPair.pub,
233
- priv: seaPair.priv,
234
- epub: seaPair.epub,
235
- epriv: seaPair.epriv,
271
+ ...seaPair,
236
272
  alias: this.currentUser,
237
273
  exportedAt: Date.now()
238
274
  };
239
- // Converti in base64 per facilità di copia
240
275
  const jsonString = JSON.stringify(exportData);
241
276
  const base64 = Buffer.from(jsonString).toString('base64');
242
277
  console.log("");
@@ -311,13 +346,13 @@ class MessengerCLI {
311
346
  epub: keyPairData.epub,
312
347
  epriv: keyPairData.epriv
313
348
  };
314
- // Login con pair
315
- const result = await this.withTimeout(this.app["shogun"].loginWithPair(seaPair), 15000, "Login timeout");
349
+ // Login con pair (SHIP-00)
350
+ const result = await this.withTimeout(this.identity.loginWithPair(seaPair), 15000, "Login timeout");
316
351
  clearInterval(loadingInterval);
317
352
  console.log("");
318
353
  if (result.success) {
319
354
  this.currentUser = keyPairData.alias || result.username || 'unknown';
320
- this.derivedAddress = await this.app.deriveEthereumAddress(seaPair.pub);
355
+ this.derivedAddress = await this.identity.deriveEthereumAddress(seaPair.pub);
321
356
  this.isAuthenticated = true;
322
357
  console.log("");
323
358
  console.log(c("green", "✅ Login con key pair effettuato!"));
@@ -326,12 +361,14 @@ class MessengerCLI {
326
361
  console.log(c("gray", ` Derived Address: ${c("cyan", this.derivedAddress)}`));
327
362
  console.log("");
328
363
  console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
329
- await this.app.publishPublicKey();
364
+ await this.identity.publishPublicKey();
330
365
  await new Promise((resolve) => setTimeout(resolve, 1000));
331
366
  console.log(c("green", "✅ Chiave pubblicata su GunDB"));
332
367
  console.log("");
368
+ // Inizializza messaging (SHIP-01)
369
+ this.messaging = new SHIP_01_1.SHIP_01(this.identity);
333
370
  // Ascolta messaggi
334
- await this.app.listenForMessages((msg) => {
371
+ await this.messaging.listenForMessages((msg) => {
335
372
  this.onMessageReceived(msg);
336
373
  });
337
374
  console.log(c("cyan", "💬 Chat pronta!"));
@@ -360,14 +397,20 @@ class MessengerCLI {
360
397
  this.rl.question(c("red", "Sei sicuro? Scrivi 'CONFERMA' per procedere: "), (answer) => {
361
398
  if (answer.trim() === "CONFERMA") {
362
399
  console.log(c("yellow", "🗑️ Cancellazione messaggi in corso..."));
363
- // Ottieni tutti i messaggi
364
- this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).once((allMessages) => {
400
+ // Ottieni tutti i messaggi (access GunDB through identity)
401
+ const gun = this.identity.shogun?.db?.gun;
402
+ if (!gun) {
403
+ console.log(c("red", "❌ Impossibile accedere a GunDB"));
404
+ this.rl.prompt();
405
+ return;
406
+ }
407
+ gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).once((allMessages) => {
365
408
  if (allMessages && typeof allMessages === 'object') {
366
409
  let count = 0;
367
410
  // Cancella ogni messaggio
368
411
  for (const [messageId, data] of Object.entries(allMessages)) {
369
412
  if (typeof data === "object" && data !== null && messageId !== '_') {
370
- this.app["shogun"].db.gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).get(messageId).put(null);
413
+ gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).get(messageId).put(null);
371
414
  count++;
372
415
  }
373
416
  }
@@ -414,8 +457,12 @@ class MessengerCLI {
414
457
  if (args[0]) {
415
458
  this.recipient = args[0];
416
459
  console.log(c("cyan", `💬 Chattando con ${c("bold", this.recipient)}`));
417
- // Carica storico
418
- const history = await this.app.getMessageHistory(this.recipient);
460
+ // Carica storico (SHIP-01)
461
+ if (!this.messaging) {
462
+ console.log(c("red", "❌ Messaging non inizializzato"));
463
+ break;
464
+ }
465
+ const history = await this.messaging.getMessageHistory(this.recipient);
419
466
  if (history.length > 0) {
420
467
  console.log(c("gray", `\n📚 Storico conversazione (${history.length} messaggi):\n`));
421
468
  history.forEach((msg, i) => {
@@ -448,7 +495,8 @@ class MessengerCLI {
448
495
  this.showStatus();
449
496
  break;
450
497
  case "/logout":
451
- this.app.logout();
498
+ this.identity.logout();
499
+ this.messaging = null;
452
500
  this.isAuthenticated = false;
453
501
  this.currentUser = "";
454
502
  this.recipient = "";
@@ -488,6 +536,23 @@ class MessengerCLI {
488
536
  }
489
537
  await this.wipeAllMessages();
490
538
  break;
539
+ case "/channel":
540
+ case "/join":
541
+ if (!this.isAuthenticated) {
542
+ console.log(c("red", "❌ Prima fai login"));
543
+ break;
544
+ }
545
+ if (args.length >= 2) {
546
+ const [channelName, token] = args;
547
+ await this.joinChannel(channelName, token);
548
+ }
549
+ else {
550
+ console.log(c("yellow", "⚠️ Uso: /channel <nome> <token>"));
551
+ }
552
+ break;
553
+ case "/leave":
554
+ this.leaveChannel();
555
+ break;
491
556
  case "/exit":
492
557
  case "/quit":
493
558
  this.rl.close();
@@ -497,6 +562,32 @@ class MessengerCLI {
497
562
  console.log(c("gray", " Scrivi /help per aiuto"));
498
563
  }
499
564
  }
565
+ async joinChannel(channelName, token) {
566
+ if (!this.messaging) {
567
+ console.log(c("red", "❌ Messaging non inizializzato"));
568
+ return;
569
+ }
570
+ this.currentChannel = channelName;
571
+ this.channelToken = token;
572
+ this.recipient = ""; // Clear direct message recipient
573
+ console.log("");
574
+ console.log(c("magenta", `📡 Connesso al canale #${channelName}`));
575
+ console.log(c("gray", " Token: " + "*".repeat(token.length)));
576
+ console.log("");
577
+ // Listen for channel messages
578
+ await this.messaging.listenForTokenMessages(token, (msg) => this.onChannelMessageReceived(msg), channelName);
579
+ this.updatePrompt();
580
+ }
581
+ leaveChannel() {
582
+ if (!this.currentChannel) {
583
+ console.log(c("yellow", "⚠️ Non sei in un canale"));
584
+ return;
585
+ }
586
+ console.log(c("yellow", `👋 Uscito dal canale #${this.currentChannel}`));
587
+ this.currentChannel = "";
588
+ this.channelToken = "";
589
+ this.updatePrompt();
590
+ }
500
591
  showHelp() {
501
592
  console.log("");
502
593
  console.log(c("bold", c("cyan", "📖 COMANDI DISPONIBILI")));
@@ -506,7 +597,9 @@ class MessengerCLI {
506
597
  console.log(" " + c("bold", "/login-pair <keypair>") + " - Login con SEA key pair");
507
598
  console.log("");
508
599
  console.log(c("bold", "MESSAGGISTICA:"));
509
- console.log(" " + c("bold", "/to <username>") + " - Inizia chat con un utente");
600
+ console.log(" " + c("bold", "/to <username>") + " - Chat diretta con utente");
601
+ console.log(" " + c("bold", "/channel <nome> <token>") + " - Entra in canale criptato");
602
+ console.log(" " + c("bold", "/leave") + " - Esci dal canale");
510
603
  console.log("");
511
604
  console.log(c("bold", "KEY MANAGEMENT:"));
512
605
  console.log(" " + c("bold", "/export") + " - Esporta il tuo key pair (backup)");
@@ -523,6 +616,7 @@ class MessengerCLI {
523
616
  console.log(c("bold", c("green", "🔐 SICUREZZA")));
524
617
  console.log("");
525
618
  console.log(" ✅ Crittografia end-to-end (ECDH + AES-GCM)");
619
+ console.log(" ✅ Canali con token condiviso (AES-256)");
526
620
  console.log(" ✅ Storage decentralizzato P2P (GunDB)");
527
621
  console.log(" ✅ Nessun server può leggere i messaggi");
528
622
  console.log(" ✅ Key pair portabile (export/import)");
@@ -533,26 +627,41 @@ class MessengerCLI {
533
627
  console.log(" " + c("gray", "# Login normale"));
534
628
  console.log(" " + c("gray", "/login alice password123"));
535
629
  console.log("");
536
- console.log(" " + c("gray", "# Export key pair (backup)"));
537
- console.log(" " + c("gray", "/export"));
538
- console.log("");
539
- console.log(" " + c("gray", "# Login con key pair (no password)"));
540
- console.log(" " + c("gray", "/login-pair eyJwdWIiOiIuLi4ifQ=="));
541
- console.log("");
542
- console.log(" " + c("gray", "# Chattare"));
630
+ console.log(" " + c("gray", "# Chat diretta (ECDH)"));
543
631
  console.log(" " + c("gray", "/to bob"));
544
632
  console.log(" " + c("gray", "Ciao Bob! Come stai?"));
545
633
  console.log("");
634
+ console.log(" " + c("gray", "# Canale criptato (token)"));
635
+ console.log(" " + c("gray", "/channel dev-team mySecretToken123"));
636
+ console.log(" " + c("gray", "Messaggio nel canale #dev-team"));
637
+ console.log("");
638
+ console.log(" " + c("gray", "# Export key pair (backup)"));
639
+ console.log(" " + c("gray", "/export"));
640
+ console.log("");
546
641
  }
547
642
  showStatus() {
548
643
  console.log("");
549
644
  console.log(c("bold", c("cyan", "📊 STATO SISTEMA")));
550
645
  console.log("");
551
646
  console.log(" " + c("gray", "Utente:") + " " + c("green", this.currentUser));
552
- console.log(" " +
553
- c("gray", "Destinatario:") +
554
- " " +
555
- c("yellow", this.recipient || "(nessuno)"));
647
+ if (this.currentChannel) {
648
+ console.log(" " +
649
+ c("gray", "Canale:") +
650
+ " " +
651
+ c("magenta", `#${this.currentChannel}`));
652
+ }
653
+ else if (this.recipient) {
654
+ console.log(" " +
655
+ c("gray", "Chat con:") +
656
+ " " +
657
+ c("yellow", this.recipient));
658
+ }
659
+ else {
660
+ console.log(" " +
661
+ c("gray", "Destinatario:") +
662
+ " " +
663
+ c("gray", "(nessuno)"));
664
+ }
556
665
  console.log(" " + c("gray", "Address:") + " " + c("cyan", this.derivedAddress));
557
666
  console.log(" " +
558
667
  c("gray", "Autenticato:") +
@@ -572,7 +681,14 @@ class MessengerCLI {
572
681
  }
573
682
  updatePrompt() {
574
683
  let prompt = "";
575
- if (this.recipient) {
684
+ if (this.currentChannel) {
685
+ prompt =
686
+ c("green", `[${this.currentUser}]`) +
687
+ c("white", " → ") +
688
+ c("magenta", `#${this.currentChannel}`) +
689
+ c("green", " ➤ ");
690
+ }
691
+ else if (this.recipient) {
576
692
  prompt =
577
693
  c("green", `[${this.currentUser}]`) +
578
694
  c("white", " → ") +