shogun-core 3.2.2 → 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 +108133 -43791
  3. package/dist/browser/shogun-core.js.map +1 -1
  4. package/dist/ship/examples/messenger-cli.js +173 -60
  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 +300 -695
  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 +47 -76
  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 +23 -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,23 +42,23 @@ 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: [
56
+ "https://peer.wallie.io/gun",
52
57
  "https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun",
53
58
  "https://relay.shogun-eco.xyz/gun",
54
- "https://peer.wallie.io/gun",
55
59
  ],
56
- radisk: false,
60
+ radisk: true,
57
61
  localStorage: false,
58
- multicast: false, // Disabilita multicast per evitare blocchi
59
- wire: false,
60
- axe: false,
61
62
  },
62
63
  });
63
64
  // Don't initialize readline in browser environment
@@ -118,19 +119,19 @@ class MessengerCLI {
118
119
  process.stdout.write(c("gray", "."));
119
120
  }, 500);
120
121
  try {
121
- // Prova login con timeout
122
- 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");
123
124
  clearInterval(loadingInterval);
124
125
  console.log(""); // Nuova linea dopo i dots
125
- // Se fallisce, prova signup
126
+ // Se fallisce, prova signup (SHIP-00)
126
127
  if (!result.success) {
127
128
  console.log(c("yellow", "📝 Utente non trovato, creazione in corso..."));
128
- const signupResult = await this.app.signup(username, password);
129
+ const signupResult = await this.identity.signup(username, password);
129
130
  if (signupResult.success) {
130
131
  // Aspetta un momento per evitare race condition
131
132
  await new Promise((resolve) => setTimeout(resolve, 1000));
132
133
  // Riprova login
133
- result = await this.app.login(username, password);
134
+ result = await this.identity.login(username, password);
134
135
  }
135
136
  else {
136
137
  console.log(c("red", `❌ Signup fallito: ${signupResult.error}`));
@@ -148,13 +149,16 @@ class MessengerCLI {
148
149
  console.log(c("gray", ` Derived Address: ${c("cyan", result.derivedAddress || "")}`));
149
150
  console.log("");
150
151
  console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
151
- await this.app.publishPublicKey();
152
+ await this.identity.publishPublicKey();
152
153
  // Aspetta che la chiave sia sincronizzata
153
154
  await new Promise((resolve) => setTimeout(resolve, 1000));
154
155
  console.log(c("green", "✅ Chiave pubblicata su GunDB"));
155
156
  console.log("");
156
- // Ascolta messaggi
157
- 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) => {
158
162
  this.onMessageReceived(msg);
159
163
  });
160
164
  console.log(c("cyan", "💬 Chat pronta! Scrivi /help per i comandi disponibili"));
@@ -180,25 +184,44 @@ class MessengerCLI {
180
184
  // MESSAGING
181
185
  // ========================================================================
182
186
  async sendMessage(content) {
183
- if (!this.isAuthenticated) {
187
+ if (!this.isAuthenticated || !this.messaging) {
184
188
  console.log(c("red", "❌ Non autenticato. Usa /login"));
185
189
  return;
186
190
  }
187
- if (!this.recipient) {
188
- console.log(c("yellow", "⚠️ Nessun destinatario. Usa /to <username>"));
189
- return;
190
- }
191
191
  try {
192
- const result = await this.app.sendMessage(this.recipient, content);
193
- if (result.success) {
194
- const time = new Date().toLocaleTimeString();
195
- console.log(c("gray", `[${time}]`) +
196
- " " +
197
- c("green", `${this.currentUser}:`) +
198
- " " +
199
- 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
+ }
200
219
  }
201
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) {
202
225
  console.log(c("red", `❌ Errore invio: ${result.error}`));
203
226
  }
204
227
  }
@@ -219,27 +242,36 @@ class MessengerCLI {
219
242
  console.log("");
220
243
  this.rl.prompt();
221
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
+ }
222
258
  // ========================================================================
223
259
  // KEY PAIR MANAGEMENT
224
260
  // ========================================================================
225
261
  async exportKeyPair() {
226
262
  try {
227
- // Ottieni il SEA pair completo
228
- const seaPair = this.app["shogun"].db.gun.user()?._?.sea;
263
+ // Ottieni il SEA pair completo da SHIP-00
264
+ const seaPair = this.identity.exportKeyPair();
229
265
  if (!seaPair) {
230
266
  console.log(c("red", "❌ Impossibile accedere al SEA pair"));
231
267
  return;
232
268
  }
233
- // Crea export object
269
+ // Converti in base64 per facilità di copia
234
270
  const exportData = {
235
- pub: seaPair.pub,
236
- priv: seaPair.priv,
237
- epub: seaPair.epub,
238
- epriv: seaPair.epriv,
271
+ ...seaPair,
239
272
  alias: this.currentUser,
240
273
  exportedAt: Date.now()
241
274
  };
242
- // Converti in base64 per facilità di copia
243
275
  const jsonString = JSON.stringify(exportData);
244
276
  const base64 = Buffer.from(jsonString).toString('base64');
245
277
  console.log("");
@@ -314,13 +346,13 @@ class MessengerCLI {
314
346
  epub: keyPairData.epub,
315
347
  epriv: keyPairData.epriv
316
348
  };
317
- // Login con pair
318
- 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");
319
351
  clearInterval(loadingInterval);
320
352
  console.log("");
321
353
  if (result.success) {
322
354
  this.currentUser = keyPairData.alias || result.username || 'unknown';
323
- this.derivedAddress = await this.app.deriveEthereumAddress(seaPair.pub);
355
+ this.derivedAddress = await this.identity.deriveEthereumAddress(seaPair.pub);
324
356
  this.isAuthenticated = true;
325
357
  console.log("");
326
358
  console.log(c("green", "✅ Login con key pair effettuato!"));
@@ -329,12 +361,14 @@ class MessengerCLI {
329
361
  console.log(c("gray", ` Derived Address: ${c("cyan", this.derivedAddress)}`));
330
362
  console.log("");
331
363
  console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
332
- await this.app.publishPublicKey();
364
+ await this.identity.publishPublicKey();
333
365
  await new Promise((resolve) => setTimeout(resolve, 1000));
334
366
  console.log(c("green", "✅ Chiave pubblicata su GunDB"));
335
367
  console.log("");
368
+ // Inizializza messaging (SHIP-01)
369
+ this.messaging = new SHIP_01_1.SHIP_01(this.identity);
336
370
  // Ascolta messaggi
337
- await this.app.listenForMessages((msg) => {
371
+ await this.messaging.listenForMessages((msg) => {
338
372
  this.onMessageReceived(msg);
339
373
  });
340
374
  console.log(c("cyan", "💬 Chat pronta!"));
@@ -363,14 +397,20 @@ class MessengerCLI {
363
397
  this.rl.question(c("red", "Sei sicuro? Scrivi 'CONFERMA' per procedere: "), (answer) => {
364
398
  if (answer.trim() === "CONFERMA") {
365
399
  console.log(c("yellow", "🗑️ Cancellazione messaggi in corso..."));
366
- // Ottieni tutti i messaggi
367
- this.app["shogun"].db.gun.get("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) => {
368
408
  if (allMessages && typeof allMessages === 'object') {
369
409
  let count = 0;
370
410
  // Cancella ogni messaggio
371
411
  for (const [messageId, data] of Object.entries(allMessages)) {
372
412
  if (typeof data === "object" && data !== null && messageId !== '_') {
373
- this.app["shogun"].db.gun.get("messages").get(messageId).put(null);
413
+ gun.get(SHIP_01_1.SHIP_01.NODES.MESSAGES).get(messageId).put(null);
374
414
  count++;
375
415
  }
376
416
  }
@@ -417,8 +457,12 @@ class MessengerCLI {
417
457
  if (args[0]) {
418
458
  this.recipient = args[0];
419
459
  console.log(c("cyan", `💬 Chattando con ${c("bold", this.recipient)}`));
420
- // Carica storico
421
- 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);
422
466
  if (history.length > 0) {
423
467
  console.log(c("gray", `\n📚 Storico conversazione (${history.length} messaggi):\n`));
424
468
  history.forEach((msg, i) => {
@@ -451,7 +495,8 @@ class MessengerCLI {
451
495
  this.showStatus();
452
496
  break;
453
497
  case "/logout":
454
- this.app.logout();
498
+ this.identity.logout();
499
+ this.messaging = null;
455
500
  this.isAuthenticated = false;
456
501
  this.currentUser = "";
457
502
  this.recipient = "";
@@ -491,6 +536,23 @@ class MessengerCLI {
491
536
  }
492
537
  await this.wipeAllMessages();
493
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;
494
556
  case "/exit":
495
557
  case "/quit":
496
558
  this.rl.close();
@@ -500,6 +562,32 @@ class MessengerCLI {
500
562
  console.log(c("gray", " Scrivi /help per aiuto"));
501
563
  }
502
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
+ }
503
591
  showHelp() {
504
592
  console.log("");
505
593
  console.log(c("bold", c("cyan", "📖 COMANDI DISPONIBILI")));
@@ -509,7 +597,9 @@ class MessengerCLI {
509
597
  console.log(" " + c("bold", "/login-pair <keypair>") + " - Login con SEA key pair");
510
598
  console.log("");
511
599
  console.log(c("bold", "MESSAGGISTICA:"));
512
- 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");
513
603
  console.log("");
514
604
  console.log(c("bold", "KEY MANAGEMENT:"));
515
605
  console.log(" " + c("bold", "/export") + " - Esporta il tuo key pair (backup)");
@@ -526,6 +616,7 @@ class MessengerCLI {
526
616
  console.log(c("bold", c("green", "🔐 SICUREZZA")));
527
617
  console.log("");
528
618
  console.log(" ✅ Crittografia end-to-end (ECDH + AES-GCM)");
619
+ console.log(" ✅ Canali con token condiviso (AES-256)");
529
620
  console.log(" ✅ Storage decentralizzato P2P (GunDB)");
530
621
  console.log(" ✅ Nessun server può leggere i messaggi");
531
622
  console.log(" ✅ Key pair portabile (export/import)");
@@ -536,26 +627,41 @@ class MessengerCLI {
536
627
  console.log(" " + c("gray", "# Login normale"));
537
628
  console.log(" " + c("gray", "/login alice password123"));
538
629
  console.log("");
539
- console.log(" " + c("gray", "# Export key pair (backup)"));
540
- console.log(" " + c("gray", "/export"));
541
- console.log("");
542
- console.log(" " + c("gray", "# Login con key pair (no password)"));
543
- console.log(" " + c("gray", "/login-pair eyJwdWIiOiIuLi4ifQ=="));
544
- console.log("");
545
- console.log(" " + c("gray", "# Chattare"));
630
+ console.log(" " + c("gray", "# Chat diretta (ECDH)"));
546
631
  console.log(" " + c("gray", "/to bob"));
547
632
  console.log(" " + c("gray", "Ciao Bob! Come stai?"));
548
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("");
549
641
  }
550
642
  showStatus() {
551
643
  console.log("");
552
644
  console.log(c("bold", c("cyan", "📊 STATO SISTEMA")));
553
645
  console.log("");
554
646
  console.log(" " + c("gray", "Utente:") + " " + c("green", this.currentUser));
555
- console.log(" " +
556
- c("gray", "Destinatario:") +
557
- " " +
558
- 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
+ }
559
665
  console.log(" " + c("gray", "Address:") + " " + c("cyan", this.derivedAddress));
560
666
  console.log(" " +
561
667
  c("gray", "Autenticato:") +
@@ -575,7 +681,14 @@ class MessengerCLI {
575
681
  }
576
682
  updatePrompt() {
577
683
  let prompt = "";
578
- 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) {
579
692
  prompt =
580
693
  c("green", `[${this.currentUser}]`) +
581
694
  c("white", " → ") +