shogun-core 3.1.0 → 3.2.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/dist/browser/_e6ae.shogun-core.js +14 -0
- package/dist/browser/_e6ae.shogun-core.js.map +1 -0
- package/dist/browser/shogun-core.js +1685 -6
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/ship/examples/messenger-cli.js +632 -0
- package/dist/ship/implementation/SHIP_01.js +803 -0
- package/dist/ship/interfaces/ISHIP_01.js +71 -0
- package/dist/{gundb → src/gundb}/db.js +2 -2
- package/dist/{index.js → src/index.js} +7 -2
- package/dist/types/ship/examples/messenger-cli.d.ts +31 -0
- package/dist/types/ship/implementation/SHIP_01.d.ts +108 -0
- package/dist/types/ship/interfaces/ISHIP_01.d.ts +305 -0
- package/dist/types/{index.d.ts → src/index.d.ts} +4 -1
- package/package.json +2 -1
- /package/dist/{config → src/config}/simplified-config.js +0 -0
- /package/dist/{core.js → src/core.js} +0 -0
- /package/dist/{examples → src/examples}/api-test.js +0 -0
- /package/dist/{examples → src/examples}/simple-api-test.js +0 -0
- /package/dist/{gundb → src/gundb}/api.js +0 -0
- /package/dist/{gundb → src/gundb}/crypto.js +0 -0
- /package/dist/{gundb → src/gundb}/derive.js +0 -0
- /package/dist/{gundb → src/gundb}/errors.js +0 -0
- /package/dist/{gundb → src/gundb}/index.js +0 -0
- /package/dist/{gundb → src/gundb}/rxjs.js +0 -0
- /package/dist/{gundb → src/gundb}/types.js +0 -0
- /package/dist/{interfaces → src/interfaces}/common.js +0 -0
- /package/dist/{interfaces → src/interfaces}/events.js +0 -0
- /package/dist/{interfaces → src/interfaces}/plugin.js +0 -0
- /package/dist/{interfaces → src/interfaces}/shogun.js +0 -0
- /package/dist/{managers → src/managers}/AuthManager.js +0 -0
- /package/dist/{managers → src/managers}/CoreInitializer.js +0 -0
- /package/dist/{managers → src/managers}/EventManager.js +0 -0
- /package/dist/{managers → src/managers}/PluginManager.js +0 -0
- /package/dist/{migration-test.js → src/migration-test.js} +0 -0
- /package/dist/{plugins → src/plugins}/base.js +0 -0
- /package/dist/{plugins → src/plugins}/index.js +0 -0
- /package/dist/{plugins → src/plugins}/nostr/index.js +0 -0
- /package/dist/{plugins → src/plugins}/nostr/nostrConnector.js +0 -0
- /package/dist/{plugins → src/plugins}/nostr/nostrConnectorPlugin.js +0 -0
- /package/dist/{plugins → src/plugins}/nostr/nostrSigner.js +0 -0
- /package/dist/{plugins → src/plugins}/nostr/types.js +0 -0
- /package/dist/{plugins → src/plugins}/oauth/index.js +0 -0
- /package/dist/{plugins → src/plugins}/oauth/oauthConnector.js +0 -0
- /package/dist/{plugins → src/plugins}/oauth/oauthPlugin.js +0 -0
- /package/dist/{plugins → src/plugins}/oauth/types.js +0 -0
- /package/dist/{plugins → src/plugins}/web3/index.js +0 -0
- /package/dist/{plugins → src/plugins}/web3/types.js +0 -0
- /package/dist/{plugins → src/plugins}/web3/web3Connector.js +0 -0
- /package/dist/{plugins → src/plugins}/web3/web3ConnectorPlugin.js +0 -0
- /package/dist/{plugins → src/plugins}/web3/web3Signer.js +0 -0
- /package/dist/{plugins → src/plugins}/webauthn/index.js +0 -0
- /package/dist/{plugins → src/plugins}/webauthn/types.js +0 -0
- /package/dist/{plugins → src/plugins}/webauthn/webauthn.js +0 -0
- /package/dist/{plugins → src/plugins}/webauthn/webauthnPlugin.js +0 -0
- /package/dist/{plugins → src/plugins}/webauthn/webauthnSigner.js +0 -0
- /package/dist/{storage → src/storage}/storage.js +0 -0
- /package/dist/{types → src/types}/events.js +0 -0
- /package/dist/{types → src/types}/shogun.js +0 -0
- /package/dist/{utils → src/utils}/errorHandler.js +0 -0
- /package/dist/{utils → src/utils}/eventEmitter.js +0 -0
- /package/dist/{utils → src/utils}/validation.js +0 -0
- /package/dist/types/{config → src/config}/simplified-config.d.ts +0 -0
- /package/dist/types/{core.d.ts → src/core.d.ts} +0 -0
- /package/dist/types/{examples → src/examples}/api-test.d.ts +0 -0
- /package/dist/types/{examples → src/examples}/simple-api-test.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/api.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/crypto.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/db.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/derive.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/errors.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/index.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/rxjs.d.ts +0 -0
- /package/dist/types/{gundb → src/gundb}/types.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/common.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/events.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/plugin.d.ts +0 -0
- /package/dist/types/{interfaces → src/interfaces}/shogun.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/AuthManager.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/CoreInitializer.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/EventManager.d.ts +0 -0
- /package/dist/types/{managers → src/managers}/PluginManager.d.ts +0 -0
- /package/dist/types/{migration-test.d.ts → src/migration-test.d.ts} +0 -0
- /package/dist/types/{plugins → src/plugins}/base.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrConnector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrConnectorPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/nostrSigner.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/nostr/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/oauth/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/oauth/oauthConnector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/oauth/oauthPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/oauth/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3Connector.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3ConnectorPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/web3/web3Signer.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/index.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/types.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthn.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthnPlugin.d.ts +0 -0
- /package/dist/types/{plugins → src/plugins}/webauthn/webauthnSigner.d.ts +0 -0
- /package/dist/types/{storage → src/storage}/storage.d.ts +0 -0
- /package/dist/types/{types → src/types}/events.d.ts +0 -0
- /package/dist/types/{types → src/types}/shogun.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/errorHandler.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/eventEmitter.d.ts +0 -0
- /package/dist/types/{utils → src/utils}/validation.d.ts +0 -0
|
@@ -98485,6 +98485,1463 @@ module.exports = function whichTypedArray(value) {
|
|
|
98485
98485
|
};
|
|
98486
98486
|
|
|
98487
98487
|
|
|
98488
|
+
/***/ }),
|
|
98489
|
+
|
|
98490
|
+
/***/ "./ship/examples/messenger-cli.ts":
|
|
98491
|
+
/*!****************************************!*\
|
|
98492
|
+
!*** ./ship/examples/messenger-cli.ts ***!
|
|
98493
|
+
\****************************************/
|
|
98494
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
98495
|
+
|
|
98496
|
+
"use strict";
|
|
98497
|
+
/* provided dependency */ var process = __webpack_require__(/*! process/browser */ "./node_modules/process/browser.js");
|
|
98498
|
+
/* provided dependency */ var Buffer = __webpack_require__(/*! buffer */ "./node_modules/buffer/index.js")["Buffer"];
|
|
98499
|
+
//#!/usr/bin/env node
|
|
98500
|
+
|
|
98501
|
+
/**
|
|
98502
|
+
* Shogun Chat - CLI Interface
|
|
98503
|
+
*
|
|
98504
|
+
* End-to-end encrypted decentralized chat
|
|
98505
|
+
* Simple and functional CLI interface
|
|
98506
|
+
*/
|
|
98507
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
98508
|
+
exports.MessengerCLI = void 0;
|
|
98509
|
+
const SHIP_01_1 = __webpack_require__(/*! ../implementation/SHIP_01 */ "./ship/implementation/SHIP_01.ts");
|
|
98510
|
+
// Only import readline in Node.js environment
|
|
98511
|
+
let readline;
|
|
98512
|
+
try {
|
|
98513
|
+
if (false) // removed by dead control flow
|
|
98514
|
+
{}
|
|
98515
|
+
}
|
|
98516
|
+
catch (e) {
|
|
98517
|
+
// Browser environment - readline not available
|
|
98518
|
+
}
|
|
98519
|
+
// ============================================================================
|
|
98520
|
+
// COLORS
|
|
98521
|
+
// ============================================================================
|
|
98522
|
+
const colors = {
|
|
98523
|
+
reset: "\x1b[0m",
|
|
98524
|
+
bold: "\x1b[1m",
|
|
98525
|
+
dim: "\x1b[2m",
|
|
98526
|
+
red: "\x1b[31m",
|
|
98527
|
+
green: "\x1b[32m",
|
|
98528
|
+
yellow: "\x1b[33m",
|
|
98529
|
+
blue: "\x1b[34m",
|
|
98530
|
+
magenta: "\x1b[35m",
|
|
98531
|
+
cyan: "\x1b[36m",
|
|
98532
|
+
white: "\x1b[37m",
|
|
98533
|
+
gray: "\x1b[90m",
|
|
98534
|
+
};
|
|
98535
|
+
const c = (color, text) => `${colors[color]}${text}${colors.reset}`;
|
|
98536
|
+
// ============================================================================
|
|
98537
|
+
// CHAT CLI
|
|
98538
|
+
// ============================================================================
|
|
98539
|
+
class MessengerCLI {
|
|
98540
|
+
constructor() {
|
|
98541
|
+
this.currentUser = "";
|
|
98542
|
+
this.recipient = "";
|
|
98543
|
+
this.derivedAddress = "";
|
|
98544
|
+
this.isAuthenticated = false;
|
|
98545
|
+
// Initialize app in all environments (needed for TypeScript)
|
|
98546
|
+
this.app = new SHIP_01_1.SHIP_01({
|
|
98547
|
+
gunOptions: {
|
|
98548
|
+
peers: [
|
|
98549
|
+
"https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun",
|
|
98550
|
+
"https://relay.shogun-eco.xyz/gun",
|
|
98551
|
+
"https://peer.wallie.io/gun",
|
|
98552
|
+
],
|
|
98553
|
+
radisk: false,
|
|
98554
|
+
localStorage: false,
|
|
98555
|
+
multicast: false, // Disabilita multicast per evitare blocchi
|
|
98556
|
+
wire: false,
|
|
98557
|
+
axe: false,
|
|
98558
|
+
},
|
|
98559
|
+
});
|
|
98560
|
+
// Don't initialize readline in browser environment
|
|
98561
|
+
if (true) {
|
|
98562
|
+
console.warn('MessengerCLI is designed for Node.js CLI usage only');
|
|
98563
|
+
return;
|
|
98564
|
+
}
|
|
98565
|
+
// removed by dead control flow
|
|
98566
|
+
|
|
98567
|
+
// removed by dead control flow
|
|
98568
|
+
|
|
98569
|
+
}
|
|
98570
|
+
// ========================================================================
|
|
98571
|
+
// SETUP
|
|
98572
|
+
// ========================================================================
|
|
98573
|
+
setupHandlers() {
|
|
98574
|
+
this.rl.on("line", async (line) => {
|
|
98575
|
+
const input = line.trim();
|
|
98576
|
+
if (!input) {
|
|
98577
|
+
this.rl.prompt();
|
|
98578
|
+
return;
|
|
98579
|
+
}
|
|
98580
|
+
if (input.startsWith("/")) {
|
|
98581
|
+
await this.handleCommand(input);
|
|
98582
|
+
}
|
|
98583
|
+
else {
|
|
98584
|
+
await this.sendMessage(input);
|
|
98585
|
+
}
|
|
98586
|
+
this.rl.prompt();
|
|
98587
|
+
});
|
|
98588
|
+
this.rl.on("close", () => {
|
|
98589
|
+
console.log("\n" + c("yellow", "👋 Arrivederci!"));
|
|
98590
|
+
process.exit(0);
|
|
98591
|
+
});
|
|
98592
|
+
// Ctrl+C handler
|
|
98593
|
+
process.on("SIGINT", () => {
|
|
98594
|
+
this.rl.close();
|
|
98595
|
+
});
|
|
98596
|
+
}
|
|
98597
|
+
// ========================================================================
|
|
98598
|
+
// UTILITIES
|
|
98599
|
+
// ========================================================================
|
|
98600
|
+
async withTimeout(promise, timeoutMs, errorMessage) {
|
|
98601
|
+
return Promise.race([
|
|
98602
|
+
promise,
|
|
98603
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(errorMessage)), timeoutMs)),
|
|
98604
|
+
]);
|
|
98605
|
+
}
|
|
98606
|
+
// ========================================================================
|
|
98607
|
+
// AUTH
|
|
98608
|
+
// ========================================================================
|
|
98609
|
+
async login(username, password) {
|
|
98610
|
+
console.log(c("cyan", "🔐 Login in corso..."));
|
|
98611
|
+
// Loading indicator
|
|
98612
|
+
const loadingInterval = setInterval(() => {
|
|
98613
|
+
process.stdout.write(c("gray", "."));
|
|
98614
|
+
}, 500);
|
|
98615
|
+
try {
|
|
98616
|
+
// Prova login con timeout
|
|
98617
|
+
let result = await this.withTimeout(this.app.login(username, password), 15000, "Login timeout - verifica connessione ai peers");
|
|
98618
|
+
clearInterval(loadingInterval);
|
|
98619
|
+
console.log(""); // Nuova linea dopo i dots
|
|
98620
|
+
// Se fallisce, prova signup
|
|
98621
|
+
if (!result.success) {
|
|
98622
|
+
console.log(c("yellow", "📝 Utente non trovato, creazione in corso..."));
|
|
98623
|
+
const signupResult = await this.app.signup(username, password);
|
|
98624
|
+
if (signupResult.success) {
|
|
98625
|
+
// Aspetta un momento per evitare race condition
|
|
98626
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
98627
|
+
// Riprova login
|
|
98628
|
+
result = await this.app.login(username, password);
|
|
98629
|
+
}
|
|
98630
|
+
else {
|
|
98631
|
+
console.log(c("red", `❌ Signup fallito: ${signupResult.error}`));
|
|
98632
|
+
return false;
|
|
98633
|
+
}
|
|
98634
|
+
}
|
|
98635
|
+
if (result.success) {
|
|
98636
|
+
this.currentUser = username;
|
|
98637
|
+
this.derivedAddress = result.derivedAddress || "";
|
|
98638
|
+
this.isAuthenticated = true;
|
|
98639
|
+
console.log("");
|
|
98640
|
+
console.log(c("green", "✅ Login effettuato!"));
|
|
98641
|
+
console.log(c("gray", ` Username: ${c("bold", username)}`));
|
|
98642
|
+
console.log(c("gray", ` Public Key: ${result.userPub?.substring(0, 40)}...`));
|
|
98643
|
+
console.log(c("gray", ` Derived Address: ${c("cyan", result.derivedAddress || "")}`));
|
|
98644
|
+
console.log("");
|
|
98645
|
+
console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
|
|
98646
|
+
await this.app.publishPublicKey();
|
|
98647
|
+
// Aspetta che la chiave sia sincronizzata
|
|
98648
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
98649
|
+
console.log(c("green", "✅ Chiave pubblicata su GunDB"));
|
|
98650
|
+
console.log("");
|
|
98651
|
+
// Ascolta messaggi
|
|
98652
|
+
await this.app.listenForMessages((msg) => {
|
|
98653
|
+
this.onMessageReceived(msg);
|
|
98654
|
+
});
|
|
98655
|
+
console.log(c("cyan", "💬 Chat pronta! Scrivi /help per i comandi disponibili"));
|
|
98656
|
+
console.log("");
|
|
98657
|
+
return true;
|
|
98658
|
+
}
|
|
98659
|
+
else {
|
|
98660
|
+
console.log(c("red", `❌ Login fallito: ${result.error}`));
|
|
98661
|
+
return false;
|
|
98662
|
+
}
|
|
98663
|
+
}
|
|
98664
|
+
catch (error) {
|
|
98665
|
+
clearInterval(loadingInterval);
|
|
98666
|
+
console.log("");
|
|
98667
|
+
console.log(c("red", `❌ Errore: ${error.message}`));
|
|
98668
|
+
return false;
|
|
98669
|
+
}
|
|
98670
|
+
finally {
|
|
98671
|
+
clearInterval(loadingInterval);
|
|
98672
|
+
}
|
|
98673
|
+
}
|
|
98674
|
+
// ========================================================================
|
|
98675
|
+
// MESSAGING
|
|
98676
|
+
// ========================================================================
|
|
98677
|
+
async sendMessage(content) {
|
|
98678
|
+
if (!this.isAuthenticated) {
|
|
98679
|
+
console.log(c("red", "❌ Non autenticato. Usa /login"));
|
|
98680
|
+
return;
|
|
98681
|
+
}
|
|
98682
|
+
if (!this.recipient) {
|
|
98683
|
+
console.log(c("yellow", "⚠️ Nessun destinatario. Usa /to <username>"));
|
|
98684
|
+
return;
|
|
98685
|
+
}
|
|
98686
|
+
try {
|
|
98687
|
+
const result = await this.app.sendMessage(this.recipient, content);
|
|
98688
|
+
if (result.success) {
|
|
98689
|
+
const time = new Date().toLocaleTimeString();
|
|
98690
|
+
console.log(c("gray", `[${time}]`) +
|
|
98691
|
+
" " +
|
|
98692
|
+
c("green", `${this.currentUser}:`) +
|
|
98693
|
+
" " +
|
|
98694
|
+
content);
|
|
98695
|
+
}
|
|
98696
|
+
else {
|
|
98697
|
+
console.log(c("red", `❌ Errore invio: ${result.error}`));
|
|
98698
|
+
}
|
|
98699
|
+
}
|
|
98700
|
+
catch (error) {
|
|
98701
|
+
console.log(c("red", `❌ Errore: ${error.message}`));
|
|
98702
|
+
}
|
|
98703
|
+
}
|
|
98704
|
+
onMessageReceived(message) {
|
|
98705
|
+
const time = new Date(message.timestamp).toLocaleTimeString();
|
|
98706
|
+
const fromUser = message.from.substring(0, 10) + "...";
|
|
98707
|
+
console.log("");
|
|
98708
|
+
console.log(c("cyan", "📨 Nuovo messaggio!"));
|
|
98709
|
+
console.log(c("gray", `[${time}]`) +
|
|
98710
|
+
" " +
|
|
98711
|
+
c("cyan", `${fromUser}:`) +
|
|
98712
|
+
" " +
|
|
98713
|
+
message.content);
|
|
98714
|
+
console.log("");
|
|
98715
|
+
this.rl.prompt();
|
|
98716
|
+
}
|
|
98717
|
+
// ========================================================================
|
|
98718
|
+
// KEY PAIR MANAGEMENT
|
|
98719
|
+
// ========================================================================
|
|
98720
|
+
async exportKeyPair() {
|
|
98721
|
+
try {
|
|
98722
|
+
// Ottieni il SEA pair completo
|
|
98723
|
+
const seaPair = this.app["shogun"].db.gun.user()?._?.sea;
|
|
98724
|
+
if (!seaPair) {
|
|
98725
|
+
console.log(c("red", "❌ Impossibile accedere al SEA pair"));
|
|
98726
|
+
return;
|
|
98727
|
+
}
|
|
98728
|
+
// Crea export object
|
|
98729
|
+
const exportData = {
|
|
98730
|
+
pub: seaPair.pub,
|
|
98731
|
+
priv: seaPair.priv,
|
|
98732
|
+
epub: seaPair.epub,
|
|
98733
|
+
epriv: seaPair.epriv,
|
|
98734
|
+
alias: this.currentUser,
|
|
98735
|
+
exportedAt: Date.now()
|
|
98736
|
+
};
|
|
98737
|
+
// Converti in base64 per facilità di copia
|
|
98738
|
+
const jsonString = JSON.stringify(exportData);
|
|
98739
|
+
const base64 = Buffer.from(jsonString).toString('base64');
|
|
98740
|
+
console.log("");
|
|
98741
|
+
console.log(c("green", "✅ KEY PAIR ESPORTATO"));
|
|
98742
|
+
console.log(c("yellow", "═".repeat(60)));
|
|
98743
|
+
console.log("");
|
|
98744
|
+
console.log(c("bold", "🔑 SEA PAIR (Base64):"));
|
|
98745
|
+
console.log("");
|
|
98746
|
+
console.log(c("cyan", base64));
|
|
98747
|
+
console.log("");
|
|
98748
|
+
console.log(c("yellow", "═".repeat(60)));
|
|
98749
|
+
console.log("");
|
|
98750
|
+
console.log(c("gray", "💾 SALVA QUESTO KEY PAIR IN UN LUOGO SICURO!"));
|
|
98751
|
+
console.log(c("gray", " Puoi usarlo per:"));
|
|
98752
|
+
console.log(c("gray", " - Fare login: /login-pair <keypair>"));
|
|
98753
|
+
console.log(c("gray", " - Importare: /import <keypair>"));
|
|
98754
|
+
console.log(c("gray", " - Backup della tua identità"));
|
|
98755
|
+
console.log("");
|
|
98756
|
+
console.log(c("red", "⚠️ NON CONDIVIDERE MAI QUESTO KEY PAIR!"));
|
|
98757
|
+
console.log(c("red", " Contiene le tue chiavi private!"));
|
|
98758
|
+
console.log("");
|
|
98759
|
+
// Salva anche su file (opzionale)
|
|
98760
|
+
const fs = await __webpack_require__.e(/*! import() */ "_e6ae").then(__webpack_require__.t.bind(__webpack_require__, /*! fs */ "?e6ae", 23));
|
|
98761
|
+
const filename = `shogun-keypair-${this.currentUser}-${Date.now()}.txt`;
|
|
98762
|
+
fs.writeFileSync(filename, base64);
|
|
98763
|
+
console.log(c("green", `💾 Key pair salvato anche in: ${filename}`));
|
|
98764
|
+
console.log("");
|
|
98765
|
+
}
|
|
98766
|
+
catch (error) {
|
|
98767
|
+
console.log(c("red", `❌ Errore export: ${error.message}`));
|
|
98768
|
+
}
|
|
98769
|
+
}
|
|
98770
|
+
async importKeyPair(base64KeyPair) {
|
|
98771
|
+
try {
|
|
98772
|
+
// Decodifica da base64
|
|
98773
|
+
const jsonString = Buffer.from(base64KeyPair, 'base64').toString('utf-8');
|
|
98774
|
+
const keyPairData = JSON.parse(jsonString);
|
|
98775
|
+
// Verifica che abbia tutti i campi necessari
|
|
98776
|
+
if (!keyPairData.pub || !keyPairData.priv || !keyPairData.epub || !keyPairData.epriv) {
|
|
98777
|
+
console.log(c("red", "❌ Key pair invalido. Mancano campi obbligatori."));
|
|
98778
|
+
return;
|
|
98779
|
+
}
|
|
98780
|
+
console.log(c("cyan", "📥 Key pair importato con successo!"));
|
|
98781
|
+
console.log(c("gray", ` Utente: ${keyPairData.alias || 'unknown'}`));
|
|
98782
|
+
console.log(c("gray", ` Public Key: ${keyPairData.pub.substring(0, 30)}...`));
|
|
98783
|
+
console.log("");
|
|
98784
|
+
console.log(c("yellow", "💡 Usa /login-pair <keypair> per fare login"));
|
|
98785
|
+
console.log("");
|
|
98786
|
+
}
|
|
98787
|
+
catch (error) {
|
|
98788
|
+
console.log(c("red", `❌ Errore import: ${error.message}`));
|
|
98789
|
+
console.log(c("gray", " Verifica che il key pair sia valido"));
|
|
98790
|
+
}
|
|
98791
|
+
}
|
|
98792
|
+
async loginWithPair(base64KeyPair) {
|
|
98793
|
+
console.log(c("cyan", "🔐 Login con key pair..."));
|
|
98794
|
+
const loadingInterval = setInterval(() => {
|
|
98795
|
+
process.stdout.write(c("gray", "."));
|
|
98796
|
+
}, 500);
|
|
98797
|
+
try {
|
|
98798
|
+
// Decodifica key pair
|
|
98799
|
+
const jsonString = Buffer.from(base64KeyPair, 'base64').toString('utf-8');
|
|
98800
|
+
const keyPairData = JSON.parse(jsonString);
|
|
98801
|
+
// Verifica validità
|
|
98802
|
+
if (!keyPairData.pub || !keyPairData.priv || !keyPairData.epub || !keyPairData.epriv) {
|
|
98803
|
+
throw new Error("Key pair invalido");
|
|
98804
|
+
}
|
|
98805
|
+
// Crea SEA pair object
|
|
98806
|
+
const seaPair = {
|
|
98807
|
+
pub: keyPairData.pub,
|
|
98808
|
+
priv: keyPairData.priv,
|
|
98809
|
+
epub: keyPairData.epub,
|
|
98810
|
+
epriv: keyPairData.epriv
|
|
98811
|
+
};
|
|
98812
|
+
// Login con pair
|
|
98813
|
+
const result = await this.withTimeout(this.app["shogun"].loginWithPair(seaPair), 15000, "Login timeout");
|
|
98814
|
+
clearInterval(loadingInterval);
|
|
98815
|
+
console.log("");
|
|
98816
|
+
if (result.success) {
|
|
98817
|
+
this.currentUser = keyPairData.alias || result.username || 'unknown';
|
|
98818
|
+
this.derivedAddress = await this.app.deriveEthereumAddress(seaPair.pub);
|
|
98819
|
+
this.isAuthenticated = true;
|
|
98820
|
+
console.log("");
|
|
98821
|
+
console.log(c("green", "✅ Login con key pair effettuato!"));
|
|
98822
|
+
console.log(c("gray", ` Username: ${c("bold", this.currentUser)}`));
|
|
98823
|
+
console.log(c("gray", ` Public Key: ${seaPair.pub.substring(0, 40)}...`));
|
|
98824
|
+
console.log(c("gray", ` Derived Address: ${c("cyan", this.derivedAddress)}`));
|
|
98825
|
+
console.log("");
|
|
98826
|
+
console.log(c("yellow", "📢 Pubblicazione chiave pubblica..."));
|
|
98827
|
+
await this.app.publishPublicKey();
|
|
98828
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
98829
|
+
console.log(c("green", "✅ Chiave pubblicata su GunDB"));
|
|
98830
|
+
console.log("");
|
|
98831
|
+
// Ascolta messaggi
|
|
98832
|
+
await this.app.listenForMessages((msg) => {
|
|
98833
|
+
this.onMessageReceived(msg);
|
|
98834
|
+
});
|
|
98835
|
+
console.log(c("cyan", "💬 Chat pronta!"));
|
|
98836
|
+
console.log("");
|
|
98837
|
+
this.updatePrompt();
|
|
98838
|
+
}
|
|
98839
|
+
else {
|
|
98840
|
+
console.log(c("red", `❌ Login fallito: ${result.error}`));
|
|
98841
|
+
}
|
|
98842
|
+
}
|
|
98843
|
+
catch (error) {
|
|
98844
|
+
clearInterval(loadingInterval);
|
|
98845
|
+
console.log("");
|
|
98846
|
+
console.log(c("red", `❌ Errore: ${error.message}`));
|
|
98847
|
+
}
|
|
98848
|
+
finally {
|
|
98849
|
+
clearInterval(loadingInterval);
|
|
98850
|
+
}
|
|
98851
|
+
}
|
|
98852
|
+
async wipeAllMessages() {
|
|
98853
|
+
console.log("");
|
|
98854
|
+
console.log(c("yellow", "⚠️ ATTENZIONE: Stai per cancellare TUTTI i messaggi dal nodo GunDB"));
|
|
98855
|
+
console.log(c("yellow", " Questa operazione è IRREVERSIBILE!"));
|
|
98856
|
+
console.log("");
|
|
98857
|
+
// Conferma
|
|
98858
|
+
this.rl.question(c("red", "Sei sicuro? Scrivi 'CONFERMA' per procedere: "), (answer) => {
|
|
98859
|
+
if (answer.trim() === "CONFERMA") {
|
|
98860
|
+
console.log(c("yellow", "🗑️ Cancellazione messaggi in corso..."));
|
|
98861
|
+
// Ottieni tutti i messaggi
|
|
98862
|
+
this.app["shogun"].db.gun.get("messages").once((allMessages) => {
|
|
98863
|
+
if (allMessages && typeof allMessages === 'object') {
|
|
98864
|
+
let count = 0;
|
|
98865
|
+
// Cancella ogni messaggio
|
|
98866
|
+
for (const [messageId, data] of Object.entries(allMessages)) {
|
|
98867
|
+
if (typeof data === "object" && data !== null && messageId !== '_') {
|
|
98868
|
+
this.app["shogun"].db.gun.get("messages").get(messageId).put(null);
|
|
98869
|
+
count++;
|
|
98870
|
+
}
|
|
98871
|
+
}
|
|
98872
|
+
console.log(c("green", `✅ ${count} messaggi cancellati dal nodo GunDB`));
|
|
98873
|
+
}
|
|
98874
|
+
else {
|
|
98875
|
+
console.log(c("gray", "ℹ️ Nessun messaggio da cancellare"));
|
|
98876
|
+
}
|
|
98877
|
+
console.log("");
|
|
98878
|
+
this.rl.prompt();
|
|
98879
|
+
});
|
|
98880
|
+
}
|
|
98881
|
+
else {
|
|
98882
|
+
console.log(c("gray", "❌ Cancellazione annullata"));
|
|
98883
|
+
console.log("");
|
|
98884
|
+
this.rl.prompt();
|
|
98885
|
+
}
|
|
98886
|
+
});
|
|
98887
|
+
}
|
|
98888
|
+
// ========================================================================
|
|
98889
|
+
// COMMANDS
|
|
98890
|
+
// ========================================================================
|
|
98891
|
+
async handleCommand(cmd) {
|
|
98892
|
+
const parts = cmd.split(" ");
|
|
98893
|
+
const command = parts[0].toLowerCase();
|
|
98894
|
+
const args = parts.slice(1);
|
|
98895
|
+
switch (command) {
|
|
98896
|
+
case "/login":
|
|
98897
|
+
if (args.length >= 2) {
|
|
98898
|
+
const [username, password] = args;
|
|
98899
|
+
await this.login(username, password);
|
|
98900
|
+
this.updatePrompt();
|
|
98901
|
+
}
|
|
98902
|
+
else {
|
|
98903
|
+
console.log(c("yellow", "⚠️ Uso: /login <username> <password>"));
|
|
98904
|
+
}
|
|
98905
|
+
break;
|
|
98906
|
+
case "/to":
|
|
98907
|
+
case "/chat":
|
|
98908
|
+
if (!this.isAuthenticated) {
|
|
98909
|
+
console.log(c("red", "❌ Prima fai login: /login <username> <password>"));
|
|
98910
|
+
break;
|
|
98911
|
+
}
|
|
98912
|
+
if (args[0]) {
|
|
98913
|
+
this.recipient = args[0];
|
|
98914
|
+
console.log(c("cyan", `💬 Chattando con ${c("bold", this.recipient)}`));
|
|
98915
|
+
// Carica storico
|
|
98916
|
+
const history = await this.app.getMessageHistory(this.recipient);
|
|
98917
|
+
if (history.length > 0) {
|
|
98918
|
+
console.log(c("gray", `\n📚 Storico conversazione (${history.length} messaggi):\n`));
|
|
98919
|
+
history.forEach((msg, i) => {
|
|
98920
|
+
const time = new Date(msg.timestamp).toLocaleTimeString();
|
|
98921
|
+
const isMe = msg.from === this.currentUser;
|
|
98922
|
+
const from = isMe ? this.currentUser : this.recipient;
|
|
98923
|
+
const color = isMe ? "green" : "cyan";
|
|
98924
|
+
console.log(c("gray", `[${time}]`) +
|
|
98925
|
+
" " +
|
|
98926
|
+
c(color, `${from}:`) +
|
|
98927
|
+
" " +
|
|
98928
|
+
msg.content);
|
|
98929
|
+
});
|
|
98930
|
+
console.log("");
|
|
98931
|
+
}
|
|
98932
|
+
this.updatePrompt();
|
|
98933
|
+
}
|
|
98934
|
+
else {
|
|
98935
|
+
console.log(c("yellow", "⚠️ Uso: /to <username>"));
|
|
98936
|
+
}
|
|
98937
|
+
break;
|
|
98938
|
+
case "/help":
|
|
98939
|
+
this.showHelp();
|
|
98940
|
+
break;
|
|
98941
|
+
case "/clear":
|
|
98942
|
+
console.clear();
|
|
98943
|
+
this.showHeader();
|
|
98944
|
+
break;
|
|
98945
|
+
case "/status":
|
|
98946
|
+
this.showStatus();
|
|
98947
|
+
break;
|
|
98948
|
+
case "/logout":
|
|
98949
|
+
this.app.logout();
|
|
98950
|
+
this.isAuthenticated = false;
|
|
98951
|
+
this.currentUser = "";
|
|
98952
|
+
this.recipient = "";
|
|
98953
|
+
console.log(c("yellow", "👋 Disconnesso"));
|
|
98954
|
+
this.updatePrompt();
|
|
98955
|
+
break;
|
|
98956
|
+
case "/export":
|
|
98957
|
+
case "/backup":
|
|
98958
|
+
if (!this.isAuthenticated) {
|
|
98959
|
+
console.log(c("red", "❌ Prima fai login"));
|
|
98960
|
+
break;
|
|
98961
|
+
}
|
|
98962
|
+
await this.exportKeyPair();
|
|
98963
|
+
break;
|
|
98964
|
+
case "/import":
|
|
98965
|
+
case "/restore":
|
|
98966
|
+
if (args[0]) {
|
|
98967
|
+
await this.importKeyPair(args[0]);
|
|
98968
|
+
}
|
|
98969
|
+
else {
|
|
98970
|
+
console.log(c("yellow", "⚠️ Uso: /import <keypair-json-base64>"));
|
|
98971
|
+
}
|
|
98972
|
+
break;
|
|
98973
|
+
case "/login-pair":
|
|
98974
|
+
if (args[0]) {
|
|
98975
|
+
await this.loginWithPair(args[0]);
|
|
98976
|
+
}
|
|
98977
|
+
else {
|
|
98978
|
+
console.log(c("yellow", "⚠️ Uso: /login-pair <keypair-json-base64>"));
|
|
98979
|
+
}
|
|
98980
|
+
break;
|
|
98981
|
+
case "/wipe":
|
|
98982
|
+
case "/delete-all":
|
|
98983
|
+
if (!this.isAuthenticated) {
|
|
98984
|
+
console.log(c("red", "❌ Prima fai login"));
|
|
98985
|
+
break;
|
|
98986
|
+
}
|
|
98987
|
+
await this.wipeAllMessages();
|
|
98988
|
+
break;
|
|
98989
|
+
case "/exit":
|
|
98990
|
+
case "/quit":
|
|
98991
|
+
this.rl.close();
|
|
98992
|
+
break;
|
|
98993
|
+
default:
|
|
98994
|
+
console.log(c("red", `❌ Comando sconosciuto: ${command}`));
|
|
98995
|
+
console.log(c("gray", " Scrivi /help per aiuto"));
|
|
98996
|
+
}
|
|
98997
|
+
}
|
|
98998
|
+
showHelp() {
|
|
98999
|
+
console.log("");
|
|
99000
|
+
console.log(c("bold", c("cyan", "📖 COMANDI DISPONIBILI")));
|
|
99001
|
+
console.log("");
|
|
99002
|
+
console.log(c("bold", "AUTENTICAZIONE:"));
|
|
99003
|
+
console.log(" " + c("bold", "/login <user> <pass>") + " - Login/Signup con password");
|
|
99004
|
+
console.log(" " + c("bold", "/login-pair <keypair>") + " - Login con SEA key pair");
|
|
99005
|
+
console.log("");
|
|
99006
|
+
console.log(c("bold", "MESSAGGISTICA:"));
|
|
99007
|
+
console.log(" " + c("bold", "/to <username>") + " - Inizia chat con un utente");
|
|
99008
|
+
console.log("");
|
|
99009
|
+
console.log(c("bold", "KEY MANAGEMENT:"));
|
|
99010
|
+
console.log(" " + c("bold", "/export") + " - Esporta il tuo key pair (backup)");
|
|
99011
|
+
console.log(" " + c("bold", "/import <keypair>") + " - Mostra info su key pair");
|
|
99012
|
+
console.log("");
|
|
99013
|
+
console.log(c("bold", "UTILITÀ:"));
|
|
99014
|
+
console.log(" " + c("bold", "/help") + " - Mostra questo aiuto");
|
|
99015
|
+
console.log(" " + c("bold", "/status") + " - Mostra stato connessione");
|
|
99016
|
+
console.log(" " + c("bold", "/clear") + " - Pulisci schermo");
|
|
99017
|
+
console.log(" " + c("bold", "/wipe") + " - Cancella TUTTI i messaggi (⚠️)");
|
|
99018
|
+
console.log(" " + c("bold", "/logout") + " - Disconnetti");
|
|
99019
|
+
console.log(" " + c("bold", "/exit") + " - Esci dall'app");
|
|
99020
|
+
console.log("");
|
|
99021
|
+
console.log(c("bold", c("green", "🔐 SICUREZZA")));
|
|
99022
|
+
console.log("");
|
|
99023
|
+
console.log(" ✅ Crittografia end-to-end (ECDH + AES-GCM)");
|
|
99024
|
+
console.log(" ✅ Storage decentralizzato P2P (GunDB)");
|
|
99025
|
+
console.log(" ✅ Nessun server può leggere i messaggi");
|
|
99026
|
+
console.log(" ✅ Key pair portabile (export/import)");
|
|
99027
|
+
console.log(" ✅ Zero costi, completamente gratis");
|
|
99028
|
+
console.log("");
|
|
99029
|
+
console.log(c("bold", c("yellow", "💡 ESEMPI")));
|
|
99030
|
+
console.log("");
|
|
99031
|
+
console.log(" " + c("gray", "# Login normale"));
|
|
99032
|
+
console.log(" " + c("gray", "/login alice password123"));
|
|
99033
|
+
console.log("");
|
|
99034
|
+
console.log(" " + c("gray", "# Export key pair (backup)"));
|
|
99035
|
+
console.log(" " + c("gray", "/export"));
|
|
99036
|
+
console.log("");
|
|
99037
|
+
console.log(" " + c("gray", "# Login con key pair (no password)"));
|
|
99038
|
+
console.log(" " + c("gray", "/login-pair eyJwdWIiOiIuLi4ifQ=="));
|
|
99039
|
+
console.log("");
|
|
99040
|
+
console.log(" " + c("gray", "# Chattare"));
|
|
99041
|
+
console.log(" " + c("gray", "/to bob"));
|
|
99042
|
+
console.log(" " + c("gray", "Ciao Bob! Come stai?"));
|
|
99043
|
+
console.log("");
|
|
99044
|
+
}
|
|
99045
|
+
showStatus() {
|
|
99046
|
+
console.log("");
|
|
99047
|
+
console.log(c("bold", c("cyan", "📊 STATO SISTEMA")));
|
|
99048
|
+
console.log("");
|
|
99049
|
+
console.log(" " + c("gray", "Utente:") + " " + c("green", this.currentUser));
|
|
99050
|
+
console.log(" " +
|
|
99051
|
+
c("gray", "Destinatario:") +
|
|
99052
|
+
" " +
|
|
99053
|
+
c("yellow", this.recipient || "(nessuno)"));
|
|
99054
|
+
console.log(" " + c("gray", "Address:") + " " + c("cyan", this.derivedAddress));
|
|
99055
|
+
console.log(" " +
|
|
99056
|
+
c("gray", "Autenticato:") +
|
|
99057
|
+
" " +
|
|
99058
|
+
(this.isAuthenticated ? c("green", "✅ Sì") : c("red", "❌ No")));
|
|
99059
|
+
console.log("");
|
|
99060
|
+
}
|
|
99061
|
+
showHeader() {
|
|
99062
|
+
console.log("");
|
|
99063
|
+
console.log(c("bold", c("cyan", "═══════════════════════════════════════════════════════")));
|
|
99064
|
+
console.log(c("bold", c("cyan", " 🗡️ SHOGUN CHAT - Decentralized E2E Messaging")));
|
|
99065
|
+
console.log(c("bold", c("cyan", "═══════════════════════════════════════════════════════")));
|
|
99066
|
+
console.log("");
|
|
99067
|
+
console.log(c("gray", " Powered by Shogun Core + GunDB"));
|
|
99068
|
+
console.log(c("gray", " Zero-cost encrypted messaging over P2P network"));
|
|
99069
|
+
console.log("");
|
|
99070
|
+
}
|
|
99071
|
+
updatePrompt() {
|
|
99072
|
+
let prompt = "";
|
|
99073
|
+
if (this.recipient) {
|
|
99074
|
+
prompt =
|
|
99075
|
+
c("green", `[${this.currentUser}]`) +
|
|
99076
|
+
c("white", " → ") +
|
|
99077
|
+
c("yellow", this.recipient) +
|
|
99078
|
+
c("green", " ➤ ");
|
|
99079
|
+
}
|
|
99080
|
+
else if (this.currentUser) {
|
|
99081
|
+
prompt = c("green", `[${this.currentUser}]`) + c("green", " ➤ ");
|
|
99082
|
+
}
|
|
99083
|
+
else {
|
|
99084
|
+
prompt = c("gray", "➤ ");
|
|
99085
|
+
}
|
|
99086
|
+
this.rl.setPrompt(prompt);
|
|
99087
|
+
}
|
|
99088
|
+
// ========================================================================
|
|
99089
|
+
// START
|
|
99090
|
+
// ========================================================================
|
|
99091
|
+
async start() {
|
|
99092
|
+
this.showHeader();
|
|
99093
|
+
const args = process.argv.slice(2);
|
|
99094
|
+
if (args.length >= 2) {
|
|
99095
|
+
// Auto-login
|
|
99096
|
+
const [username, password] = args;
|
|
99097
|
+
const success = await this.login(username, password);
|
|
99098
|
+
if (success) {
|
|
99099
|
+
this.updatePrompt();
|
|
99100
|
+
this.rl.prompt();
|
|
99101
|
+
}
|
|
99102
|
+
else {
|
|
99103
|
+
console.log(c("red", "❌ Auto-login fallito"));
|
|
99104
|
+
this.rl.close();
|
|
99105
|
+
}
|
|
99106
|
+
}
|
|
99107
|
+
else {
|
|
99108
|
+
// Login manuale
|
|
99109
|
+
console.log(c("cyan", "💡 Comandi disponibili:"));
|
|
99110
|
+
console.log(c("yellow", " /login <username> <password>") +
|
|
99111
|
+
c("gray", " - Login o crea account"));
|
|
99112
|
+
console.log(c("yellow", " /help") +
|
|
99113
|
+
c("gray", " - Mostra tutti i comandi"));
|
|
99114
|
+
console.log("");
|
|
99115
|
+
console.log(c("gray", " Oppure avvia con: yarn chat <username> <password>"));
|
|
99116
|
+
console.log("");
|
|
99117
|
+
this.updatePrompt();
|
|
99118
|
+
this.rl.prompt();
|
|
99119
|
+
}
|
|
99120
|
+
}
|
|
99121
|
+
}
|
|
99122
|
+
exports.MessengerCLI = MessengerCLI;
|
|
99123
|
+
// ============================================================================
|
|
99124
|
+
// MAIN
|
|
99125
|
+
// ============================================================================
|
|
99126
|
+
const cli = new MessengerCLI();
|
|
99127
|
+
cli.start().catch(console.error);
|
|
99128
|
+
|
|
99129
|
+
|
|
99130
|
+
/***/ }),
|
|
99131
|
+
|
|
99132
|
+
/***/ "./ship/implementation/SHIP_01.ts":
|
|
99133
|
+
/*!****************************************!*\
|
|
99134
|
+
!*** ./ship/implementation/SHIP_01.ts ***!
|
|
99135
|
+
\****************************************/
|
|
99136
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
99137
|
+
|
|
99138
|
+
"use strict";
|
|
99139
|
+
/* module decorator */ module = __webpack_require__.nmd(module);
|
|
99140
|
+
|
|
99141
|
+
/**
|
|
99142
|
+
* Esempio Pratico: Messaggistica Decentralizzata con Shogun Core
|
|
99143
|
+
*
|
|
99144
|
+
* Questo esempio mostra come creare un sistema di messaggistica sicuro usando:
|
|
99145
|
+
* - Shogun Core per autenticazione (username/password)
|
|
99146
|
+
* - GunDB per storage decentralizzato P2P
|
|
99147
|
+
* - SEA (Security, Encryption, Authorization) per crittografia
|
|
99148
|
+
*
|
|
99149
|
+
* Vantaggi:
|
|
99150
|
+
* ✅ Completamente decentralizzato (no server centrale)
|
|
99151
|
+
* ✅ Zero costi (no blockchain, no gas fees)
|
|
99152
|
+
* ✅ Real-time messaging
|
|
99153
|
+
* ✅ Offline-first
|
|
99154
|
+
* ✅ End-to-end encryption
|
|
99155
|
+
*
|
|
99156
|
+
* Note sull'ERC7627:
|
|
99157
|
+
* L'EIP era un template concettuale. Questo esempio implementa
|
|
99158
|
+
* solo la parte GunDB/Shogun Core senza interazione blockchain.
|
|
99159
|
+
* La funzione deriveEthereumAddress() rimane come utility per derivare
|
|
99160
|
+
* un address Ethereum dalla chiave GunDB se necessario in futuro.
|
|
99161
|
+
*/
|
|
99162
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
99163
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
99164
|
+
};
|
|
99165
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
99166
|
+
exports.SHIP_01 = void 0;
|
|
99167
|
+
const core_1 = __webpack_require__(/*! ../../src/core */ "./src/core.ts");
|
|
99168
|
+
const ethers_1 = __webpack_require__(/*! ethers */ "./node_modules/ethers/lib.commonjs/index.js");
|
|
99169
|
+
const derive_1 = __importDefault(__webpack_require__(/*! ../../src/gundb/derive */ "./src/gundb/derive.ts"));
|
|
99170
|
+
// ============================================================================
|
|
99171
|
+
// 1. SETUP: Inizializzazione del Sistema Completo
|
|
99172
|
+
// ============================================================================
|
|
99173
|
+
/**
|
|
99174
|
+
* Classe per messaggistica sicura con Shogun Core
|
|
99175
|
+
* Implementa l'interfaccia ISHIP_01
|
|
99176
|
+
* Usa solo GunDB per storage decentralizzato (no blockchain)
|
|
99177
|
+
*/
|
|
99178
|
+
class SHIP_01 {
|
|
99179
|
+
constructor(shogunConfig) {
|
|
99180
|
+
// Inizializza Shogun Core
|
|
99181
|
+
this.shogun = new core_1.ShogunCore(shogunConfig);
|
|
99182
|
+
}
|
|
99183
|
+
// ========================================================================
|
|
99184
|
+
// 2. AUTENTICAZIONE: Username e Password
|
|
99185
|
+
// ========================================================================
|
|
99186
|
+
/**
|
|
99187
|
+
* Registra un nuovo utente
|
|
99188
|
+
*/
|
|
99189
|
+
async signup(username, password) {
|
|
99190
|
+
try {
|
|
99191
|
+
// Registra con Shogun Core (crea SEA pair automaticamente)
|
|
99192
|
+
const signupResult = await this.shogun.signUp(username, password);
|
|
99193
|
+
if (!signupResult.success) {
|
|
99194
|
+
return {
|
|
99195
|
+
success: false,
|
|
99196
|
+
error: signupResult.error || "Signup failed"
|
|
99197
|
+
};
|
|
99198
|
+
}
|
|
99199
|
+
console.log("✅ Utente registrato");
|
|
99200
|
+
console.log(` Username: ${username}`);
|
|
99201
|
+
console.log(` GunDB Public Key: ${signupResult.pub}`);
|
|
99202
|
+
// Opzionale: deriva address Ethereum dalla chiave GunDB
|
|
99203
|
+
const derivedAddress = signupResult.pub
|
|
99204
|
+
? await this.deriveEthereumAddress(signupResult.pub)
|
|
99205
|
+
: undefined;
|
|
99206
|
+
if (derivedAddress) {
|
|
99207
|
+
console.log(` Derived Address: ${derivedAddress}`);
|
|
99208
|
+
}
|
|
99209
|
+
return {
|
|
99210
|
+
success: true,
|
|
99211
|
+
userPub: signupResult.pub,
|
|
99212
|
+
derivedAddress
|
|
99213
|
+
};
|
|
99214
|
+
}
|
|
99215
|
+
catch (error) {
|
|
99216
|
+
return {
|
|
99217
|
+
success: false,
|
|
99218
|
+
error: error.message
|
|
99219
|
+
};
|
|
99220
|
+
}
|
|
99221
|
+
}
|
|
99222
|
+
/**
|
|
99223
|
+
* Login con username e password
|
|
99224
|
+
*/
|
|
99225
|
+
async login(username, password) {
|
|
99226
|
+
try {
|
|
99227
|
+
// Login con Shogun Core
|
|
99228
|
+
const loginResult = await this.shogun.login(username, password);
|
|
99229
|
+
if (!loginResult.success) {
|
|
99230
|
+
return {
|
|
99231
|
+
success: false,
|
|
99232
|
+
error: loginResult.error || "Login failed"
|
|
99233
|
+
};
|
|
99234
|
+
}
|
|
99235
|
+
console.log("✅ Login effettuato");
|
|
99236
|
+
console.log(` Username: ${username}`);
|
|
99237
|
+
console.log(` GunDB Public Key: ${loginResult.userPub}`);
|
|
99238
|
+
// Opzionale: deriva address Ethereum dalla chiave GunDB
|
|
99239
|
+
const derivedAddress = loginResult.userPub
|
|
99240
|
+
? await this.deriveEthereumAddress(loginResult.userPub)
|
|
99241
|
+
: undefined;
|
|
99242
|
+
if (derivedAddress) {
|
|
99243
|
+
console.log(` Derived Address: ${derivedAddress}`);
|
|
99244
|
+
}
|
|
99245
|
+
return {
|
|
99246
|
+
success: true,
|
|
99247
|
+
userPub: loginResult.userPub,
|
|
99248
|
+
derivedAddress
|
|
99249
|
+
};
|
|
99250
|
+
}
|
|
99251
|
+
catch (error) {
|
|
99252
|
+
return {
|
|
99253
|
+
success: false,
|
|
99254
|
+
error: error.message
|
|
99255
|
+
};
|
|
99256
|
+
}
|
|
99257
|
+
}
|
|
99258
|
+
/**
|
|
99259
|
+
* Login con SEA Key Pair
|
|
99260
|
+
*
|
|
99261
|
+
* Autenticazione diretta usando un key pair esportato.
|
|
99262
|
+
* Utile per:
|
|
99263
|
+
* - Recupero account senza password
|
|
99264
|
+
* - Portabilità tra dispositivi
|
|
99265
|
+
* - Backup dell'identità
|
|
99266
|
+
*/
|
|
99267
|
+
async loginWithPair(seaPair) {
|
|
99268
|
+
try {
|
|
99269
|
+
console.log("🔐 Login con key pair...");
|
|
99270
|
+
// Autentica con GunDB usando il pair
|
|
99271
|
+
const authResult = await new Promise((resolve) => {
|
|
99272
|
+
this.shogun.db.gun.user().auth(seaPair, (ack) => {
|
|
99273
|
+
if (ack.err) {
|
|
99274
|
+
resolve({
|
|
99275
|
+
success: false,
|
|
99276
|
+
error: ack.err,
|
|
99277
|
+
});
|
|
99278
|
+
}
|
|
99279
|
+
else {
|
|
99280
|
+
resolve({
|
|
99281
|
+
success: true,
|
|
99282
|
+
userPub: seaPair.pub,
|
|
99283
|
+
});
|
|
99284
|
+
}
|
|
99285
|
+
});
|
|
99286
|
+
});
|
|
99287
|
+
if (!authResult.success) {
|
|
99288
|
+
console.log("❌ Login fallito:", authResult.error);
|
|
99289
|
+
return authResult;
|
|
99290
|
+
}
|
|
99291
|
+
// Opzionale: deriva address Ethereum dalla chiave GunDB
|
|
99292
|
+
const derivedAddress = await this.deriveEthereumAddress(seaPair.pub);
|
|
99293
|
+
console.log("✅ Login effettuato");
|
|
99294
|
+
console.log(` GunDB Public Key: ${seaPair.pub}`);
|
|
99295
|
+
console.log(` Derived Address: ${derivedAddress}`);
|
|
99296
|
+
return {
|
|
99297
|
+
success: true,
|
|
99298
|
+
userPub: authResult.userPub,
|
|
99299
|
+
derivedAddress
|
|
99300
|
+
};
|
|
99301
|
+
}
|
|
99302
|
+
catch (error) {
|
|
99303
|
+
console.error("❌ Errore login con pair:", error);
|
|
99304
|
+
return {
|
|
99305
|
+
success: false,
|
|
99306
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
99307
|
+
};
|
|
99308
|
+
}
|
|
99309
|
+
}
|
|
99310
|
+
/**
|
|
99311
|
+
* Logout
|
|
99312
|
+
*/
|
|
99313
|
+
logout() {
|
|
99314
|
+
this.shogun.logout();
|
|
99315
|
+
console.log("👋 Logout effettuato");
|
|
99316
|
+
}
|
|
99317
|
+
/**
|
|
99318
|
+
* Verifica se l'utente è autenticato
|
|
99319
|
+
*/
|
|
99320
|
+
isLoggedIn() {
|
|
99321
|
+
return this.shogun.isLoggedIn();
|
|
99322
|
+
}
|
|
99323
|
+
// ========================================================================
|
|
99324
|
+
// 3. GESTIONE CHIAVI PUBBLICHE: Salva su GunDB
|
|
99325
|
+
// ========================================================================
|
|
99326
|
+
/**
|
|
99327
|
+
* Salva la chiave pubblica dell'utente su GunDB
|
|
99328
|
+
* Questo permette ad altri di trovare la tua chiave per criptare messaggi
|
|
99329
|
+
*/
|
|
99330
|
+
async publishPublicKey() {
|
|
99331
|
+
try {
|
|
99332
|
+
if (!this.isLoggedIn()) {
|
|
99333
|
+
return { success: false, error: "Not logged in" };
|
|
99334
|
+
}
|
|
99335
|
+
// Ottieni il SEA pair dell'utente corrente
|
|
99336
|
+
const currentUser = this.shogun.db.user;
|
|
99337
|
+
if (!currentUser || !currentUser.is) {
|
|
99338
|
+
return { success: false, error: "No user session" };
|
|
99339
|
+
}
|
|
99340
|
+
// Salva chiave pubblica sul nodo globale usando il userPub come chiave
|
|
99341
|
+
// Questo permette ad altri di trovarla facilmente
|
|
99342
|
+
const userPub = currentUser.is.pub;
|
|
99343
|
+
await this.shogun.db.gun.get(userPub).put({
|
|
99344
|
+
pub: currentUser.is.pub,
|
|
99345
|
+
epub: currentUser.is.epub,
|
|
99346
|
+
algorithm: "ECDSA",
|
|
99347
|
+
timestamp: Date.now().toString()
|
|
99348
|
+
}).then();
|
|
99349
|
+
console.log(`📝 Chiave pubblica pubblicata su GunDB`);
|
|
99350
|
+
return { success: true };
|
|
99351
|
+
}
|
|
99352
|
+
catch (error) {
|
|
99353
|
+
console.error("❌ Errore pubblicazione chiave:", error);
|
|
99354
|
+
return { success: false, error: error.message };
|
|
99355
|
+
}
|
|
99356
|
+
}
|
|
99357
|
+
// ========================================================================
|
|
99358
|
+
// 4. INVIO MESSAGGI: Solo GunDB
|
|
99359
|
+
// ========================================================================
|
|
99360
|
+
/**
|
|
99361
|
+
* Invia un messaggio crittografato a un altro utente
|
|
99362
|
+
*/
|
|
99363
|
+
async sendMessage(recipientUsername, message) {
|
|
99364
|
+
try {
|
|
99365
|
+
if (!this.isLoggedIn()) {
|
|
99366
|
+
return { success: false, error: "Not logged in" };
|
|
99367
|
+
}
|
|
99368
|
+
const currentUser = this.shogun.db.user;
|
|
99369
|
+
if (!currentUser || !currentUser.is) {
|
|
99370
|
+
return { success: false, error: "No user session" };
|
|
99371
|
+
}
|
|
99372
|
+
// 1. Ottieni la chiave pubblica del destinatario
|
|
99373
|
+
const recipientKey = await this.getRecipientPublicKey(recipientUsername);
|
|
99374
|
+
if (!recipientKey) {
|
|
99375
|
+
return {
|
|
99376
|
+
success: false,
|
|
99377
|
+
error: `Recipient ${recipientUsername} has not published their public key`
|
|
99378
|
+
};
|
|
99379
|
+
}
|
|
99380
|
+
// 2. Ottieni il SEA pair completo (include chiavi private)
|
|
99381
|
+
const senderPair = this.shogun.db.gun.user()?._?.sea;
|
|
99382
|
+
if (!senderPair) {
|
|
99383
|
+
return { success: false, error: "Cannot access SEA pair" };
|
|
99384
|
+
}
|
|
99385
|
+
// 3. Cripta il messaggio usando SEA.secret + SEA.encrypt (ECDH)
|
|
99386
|
+
const encryptedMessage = await this.shogun.db.crypto.encFor(message, senderPair, // sender pair completo
|
|
99387
|
+
{ epub: recipientKey.epub } // recipient public encryption key
|
|
99388
|
+
);
|
|
99389
|
+
// 4. Genera ID messaggio
|
|
99390
|
+
const messageId = this.generateMessageId();
|
|
99391
|
+
const senderPub = currentUser.is.pub;
|
|
99392
|
+
// 5. Salva messaggio crittografato su GunDB
|
|
99393
|
+
const messageData = {
|
|
99394
|
+
from: senderPub,
|
|
99395
|
+
to: recipientUsername,
|
|
99396
|
+
content: encryptedMessage, // Contenuto crittografato!
|
|
99397
|
+
timestamp: Date.now().toString(),
|
|
99398
|
+
messageId: messageId
|
|
99399
|
+
};
|
|
99400
|
+
// Salva sul nodo globale 'messages' per permettere il listener
|
|
99401
|
+
await this.shogun.db.gun.get('messages').get(messageId).put(messageData).then();
|
|
99402
|
+
console.log(`✅ Messaggio salvato: ${messageId}`);
|
|
99403
|
+
return {
|
|
99404
|
+
success: true,
|
|
99405
|
+
messageId: messageId
|
|
99406
|
+
};
|
|
99407
|
+
}
|
|
99408
|
+
catch (error) {
|
|
99409
|
+
return {
|
|
99410
|
+
success: false,
|
|
99411
|
+
error: error.message
|
|
99412
|
+
};
|
|
99413
|
+
}
|
|
99414
|
+
}
|
|
99415
|
+
/**
|
|
99416
|
+
* Ottiene la chiave pubblica di un utente da GunDB
|
|
99417
|
+
*/
|
|
99418
|
+
async getRecipientPublicKey(username) {
|
|
99419
|
+
try {
|
|
99420
|
+
// Prima trova l'utente dal username
|
|
99421
|
+
const userData = await this.shogun.db.getUserByAlias(username);
|
|
99422
|
+
if (!userData || !userData.userPub) {
|
|
99423
|
+
console.error(`❌ User ${username} not found`);
|
|
99424
|
+
return null;
|
|
99425
|
+
}
|
|
99426
|
+
const userPub = userData.userPub;
|
|
99427
|
+
// Le chiavi sono salvate direttamente sul nodo userPub
|
|
99428
|
+
const publicKeyData = await this.shogun.db.gun.get(userPub).then();
|
|
99429
|
+
if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
|
|
99430
|
+
return {
|
|
99431
|
+
pub: publicKeyData.pub,
|
|
99432
|
+
epub: publicKeyData.epub
|
|
99433
|
+
};
|
|
99434
|
+
}
|
|
99435
|
+
return null;
|
|
99436
|
+
}
|
|
99437
|
+
catch (error) {
|
|
99438
|
+
console.error("❌ Errore recupero chiave pubblica:", error);
|
|
99439
|
+
return null;
|
|
99440
|
+
}
|
|
99441
|
+
}
|
|
99442
|
+
// ========================================================================
|
|
99443
|
+
// 5. RICEZIONE MESSAGGI: Ascolta GunDB in real-time
|
|
99444
|
+
// ========================================================================
|
|
99445
|
+
/**
|
|
99446
|
+
* Ascolta messaggi crittografati in arrivo su GunDB
|
|
99447
|
+
*/
|
|
99448
|
+
async listenForMessages(onMessage) {
|
|
99449
|
+
if (!this.isLoggedIn()) {
|
|
99450
|
+
console.error("❌ Non autenticato");
|
|
99451
|
+
return;
|
|
99452
|
+
}
|
|
99453
|
+
const currentUser = this.shogun.db.user;
|
|
99454
|
+
if (!currentUser || !currentUser.is) {
|
|
99455
|
+
console.error("❌ Nessuna sessione utente");
|
|
99456
|
+
return;
|
|
99457
|
+
}
|
|
99458
|
+
const userPub = currentUser.is.pub;
|
|
99459
|
+
// Ottieni username dell'utente corrente
|
|
99460
|
+
const username = currentUser.is.alias;
|
|
99461
|
+
// Set per tracciare messaggi già ricevuti (evita duplicati)
|
|
99462
|
+
const receivedMessages = new Set();
|
|
99463
|
+
// Ascolta messaggi in tempo reale su GunDB
|
|
99464
|
+
this.shogun.db.gun
|
|
99465
|
+
.get(`messages`)
|
|
99466
|
+
.map()
|
|
99467
|
+
.on(async (data, key) => {
|
|
99468
|
+
// Filtra solo i messaggi destinati a questo utente (per username)
|
|
99469
|
+
if (data && data.to === username && data.from && data.content && data.messageId) {
|
|
99470
|
+
// Evita duplicati (GunDB può emettere più volte)
|
|
99471
|
+
if (receivedMessages.has(data.messageId)) {
|
|
99472
|
+
return;
|
|
99473
|
+
}
|
|
99474
|
+
receivedMessages.add(data.messageId);
|
|
99475
|
+
try {
|
|
99476
|
+
// Decripta il messaggio
|
|
99477
|
+
const decryptedContent = await this.decryptMessage(data.content, data.from);
|
|
99478
|
+
onMessage({
|
|
99479
|
+
from: data.from,
|
|
99480
|
+
content: decryptedContent,
|
|
99481
|
+
timestamp: parseInt(data.timestamp)
|
|
99482
|
+
});
|
|
99483
|
+
}
|
|
99484
|
+
catch (error) {
|
|
99485
|
+
console.error("❌ Errore decrittazione messaggio:", error);
|
|
99486
|
+
}
|
|
99487
|
+
}
|
|
99488
|
+
});
|
|
99489
|
+
console.log(`👂 In ascolto di messaggi per ${username} (${userPub.substring(0, 10)}...)`);
|
|
99490
|
+
}
|
|
99491
|
+
/**
|
|
99492
|
+
* Decripta un messaggio usando SEA.secret + SEA.decrypt (ECDH)
|
|
99493
|
+
*/
|
|
99494
|
+
async decryptMessage(encryptedContent, senderPub) {
|
|
99495
|
+
// Ottieni il SEA pair completo del destinatario (noi)
|
|
99496
|
+
const receiverPair = this.shogun.db.gun.user()?._?.sea;
|
|
99497
|
+
if (!receiverPair) {
|
|
99498
|
+
throw new Error("Cannot access SEA pair");
|
|
99499
|
+
}
|
|
99500
|
+
// Ottieni epub del mittente
|
|
99501
|
+
const senderKey = await this.getPublicKeyByPub(senderPub);
|
|
99502
|
+
if (!senderKey) {
|
|
99503
|
+
throw new Error("Sender public key not found");
|
|
99504
|
+
}
|
|
99505
|
+
// Decripta usando SEA.secret + SEA.decrypt (ECDH)
|
|
99506
|
+
const decrypted = await this.shogun.db.crypto.decFrom(encryptedContent, { epub: senderKey.epub }, // sender's public encryption key
|
|
99507
|
+
receiverPair // receiver's pair completo
|
|
99508
|
+
);
|
|
99509
|
+
return decrypted;
|
|
99510
|
+
}
|
|
99511
|
+
/**
|
|
99512
|
+
* Ottiene la chiave pubblica di un utente dalla sua pub key
|
|
99513
|
+
*/
|
|
99514
|
+
async getPublicKeyByPub(userPub) {
|
|
99515
|
+
try {
|
|
99516
|
+
// Le chiavi sono salvate direttamente sul nodo userPub
|
|
99517
|
+
const publicKeyData = await this.shogun.db.gun.get(userPub).then();
|
|
99518
|
+
if (publicKeyData && publicKeyData.epub && publicKeyData.pub) {
|
|
99519
|
+
return {
|
|
99520
|
+
pub: publicKeyData.pub,
|
|
99521
|
+
epub: publicKeyData.epub
|
|
99522
|
+
};
|
|
99523
|
+
}
|
|
99524
|
+
return null;
|
|
99525
|
+
}
|
|
99526
|
+
catch (error) {
|
|
99527
|
+
console.error("❌ Errore recupero chiave:", error);
|
|
99528
|
+
return null;
|
|
99529
|
+
}
|
|
99530
|
+
}
|
|
99531
|
+
// ========================================================================
|
|
99532
|
+
// 6. RECUPERO STORICO: Query messaggi passati
|
|
99533
|
+
// ========================================================================
|
|
99534
|
+
/**
|
|
99535
|
+
* Recupera lo storico dei messaggi crittografati con un utente
|
|
99536
|
+
*/
|
|
99537
|
+
async getMessageHistory(withUsername) {
|
|
99538
|
+
if (!this.isLoggedIn()) {
|
|
99539
|
+
console.error("❌ Non autenticato");
|
|
99540
|
+
return [];
|
|
99541
|
+
}
|
|
99542
|
+
const currentUser = this.shogun.db.user;
|
|
99543
|
+
if (!currentUser || !currentUser.is) {
|
|
99544
|
+
console.error("❌ Nessuna sessione utente");
|
|
99545
|
+
return [];
|
|
99546
|
+
}
|
|
99547
|
+
const userPub = currentUser.is.pub;
|
|
99548
|
+
const username = currentUser.is.alias;
|
|
99549
|
+
const allMessages = [];
|
|
99550
|
+
// Ottieni il userPub dell'altro utente
|
|
99551
|
+
const otherUserData = await this.shogun.db.getUserByAlias(withUsername);
|
|
99552
|
+
const otherUserPub = otherUserData?.userPub;
|
|
99553
|
+
// Recupera tutti i messaggi dal nodo 'messages' e filtra
|
|
99554
|
+
const allMessagesNode = await this.shogun.db.gun.get('messages').then();
|
|
99555
|
+
if (allMessagesNode) {
|
|
99556
|
+
for (const [messageId, data] of Object.entries(allMessagesNode)) {
|
|
99557
|
+
if (typeof data === 'object' && data !== null) {
|
|
99558
|
+
const msgData = data;
|
|
99559
|
+
// Filtra messaggi tra questo utente e withUsername
|
|
99560
|
+
// Messaggi inviati da me a loro
|
|
99561
|
+
const isSentToTarget = msgData.from === userPub && msgData.to === withUsername;
|
|
99562
|
+
// Messaggi ricevuti da loro
|
|
99563
|
+
const isReceivedFromTarget = msgData.to === username &&
|
|
99564
|
+
(msgData.from === otherUserPub ||
|
|
99565
|
+
msgData.from);
|
|
99566
|
+
if ((isSentToTarget || isReceivedFromTarget) && msgData.content && msgData.messageId) {
|
|
99567
|
+
try {
|
|
99568
|
+
// Decripta ogni messaggio
|
|
99569
|
+
const decryptedContent = await this.decryptMessage(msgData.content, msgData.from);
|
|
99570
|
+
allMessages.push({
|
|
99571
|
+
from: msgData.from,
|
|
99572
|
+
to: msgData.to,
|
|
99573
|
+
content: decryptedContent,
|
|
99574
|
+
timestamp: parseInt(msgData.timestamp)
|
|
99575
|
+
});
|
|
99576
|
+
}
|
|
99577
|
+
catch (error) {
|
|
99578
|
+
console.error(`❌ Errore decrittazione messaggio ${messageId}:`, error);
|
|
99579
|
+
// Salta messaggi che non possono essere decriptati
|
|
99580
|
+
}
|
|
99581
|
+
}
|
|
99582
|
+
}
|
|
99583
|
+
}
|
|
99584
|
+
}
|
|
99585
|
+
// Ordina per timestamp
|
|
99586
|
+
return allMessages.sort((a, b) => a.timestamp - b.timestamp);
|
|
99587
|
+
}
|
|
99588
|
+
// ========================================================================
|
|
99589
|
+
// 7. UTILITY FUNCTIONS
|
|
99590
|
+
// ========================================================================
|
|
99591
|
+
/**
|
|
99592
|
+
* Converte la chiave pubblica di GunDB in address Ethereum
|
|
99593
|
+
* Usa la chiave privata SEA come seed per derivazione deterministica
|
|
99594
|
+
*
|
|
99595
|
+
* Questo garantisce che:
|
|
99596
|
+
* - Stesso SEA pair → stesso address Ethereum
|
|
99597
|
+
* - Derivazione cryptografica sicura
|
|
99598
|
+
* - Identità unificata tra GunDB e blockchain
|
|
99599
|
+
*/
|
|
99600
|
+
async deriveEthereumAddress(publicKey) {
|
|
99601
|
+
try {
|
|
99602
|
+
// Ottieni il SEA pair completo
|
|
99603
|
+
const seaPair = this.shogun.db.gun.user()?._?.sea;
|
|
99604
|
+
if (!seaPair || !seaPair.priv) {
|
|
99605
|
+
throw new Error("Cannot access SEA pair");
|
|
99606
|
+
}
|
|
99607
|
+
// Usa la chiave privata SEA come seed per derive
|
|
99608
|
+
// Questo è MOLTO più sicuro e deterministico del username!
|
|
99609
|
+
const derived = await (0, derive_1.default)(seaPair.priv, null, {
|
|
99610
|
+
includeSecp256k1Ethereum: true,
|
|
99611
|
+
includeP256: false,
|
|
99612
|
+
includeSecp256k1Bitcoin: false
|
|
99613
|
+
});
|
|
99614
|
+
return derived.secp256k1Ethereum.address;
|
|
99615
|
+
}
|
|
99616
|
+
catch (error) {
|
|
99617
|
+
console.error("❌ Errore derivazione address:", error);
|
|
99618
|
+
// Fallback: hash della chiave pubblica
|
|
99619
|
+
const fallbackKey = publicKey || "unknown";
|
|
99620
|
+
const hash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(fallbackKey));
|
|
99621
|
+
return ethers_1.ethers.getAddress('0x' + hash.slice(-40));
|
|
99622
|
+
}
|
|
99623
|
+
}
|
|
99624
|
+
/**
|
|
99625
|
+
* Genera ID messaggio univoco
|
|
99626
|
+
*/
|
|
99627
|
+
generateMessageId() {
|
|
99628
|
+
return ethers_1.ethers.hexlify(ethers_1.ethers.randomBytes(16));
|
|
99629
|
+
}
|
|
99630
|
+
}
|
|
99631
|
+
exports.SHIP_01 = SHIP_01;
|
|
99632
|
+
// ============================================================================
|
|
99633
|
+
// 8. ESEMPIO D'USO COMPLETO
|
|
99634
|
+
// ============================================================================
|
|
99635
|
+
// async function main() {
|
|
99636
|
+
// console.log("🚀 Secure Messaging App - Shogun Core + GunDB\n");
|
|
99637
|
+
// // 1. Inizializza il sistema
|
|
99638
|
+
// const app = new SHIP_01({
|
|
99639
|
+
// gunOptions: {
|
|
99640
|
+
// peers: ["https://relay.shogun-eco.xyz/gun","https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun","https://peer.wallie.io/gun"],
|
|
99641
|
+
// radisk: false,
|
|
99642
|
+
// localStorage:false,
|
|
99643
|
+
// }
|
|
99644
|
+
// });
|
|
99645
|
+
// // 2. Signup (prima volta)
|
|
99646
|
+
// console.log("📝 Registrazione nuovo utente...");
|
|
99647
|
+
// const signupResult = await app.signup("alice", "password123");
|
|
99648
|
+
// if (!signupResult.success) {
|
|
99649
|
+
// console.log("ℹ️ Utente già esistente, procedo con login");
|
|
99650
|
+
// } else {
|
|
99651
|
+
// console.log("✅ Utente registrato!");
|
|
99652
|
+
// console.log(` Username: alice`);
|
|
99653
|
+
// console.log(` Public Key: ${signupResult.userPub}`);
|
|
99654
|
+
// console.log(` Derived Address: ${signupResult.derivedAddress}\n`);
|
|
99655
|
+
// }
|
|
99656
|
+
// // 3. Login
|
|
99657
|
+
// console.log("🔐 Login...");
|
|
99658
|
+
// const loginResult = await app.login("alice", "password123");
|
|
99659
|
+
// if (!loginResult.success) {
|
|
99660
|
+
// console.error("❌ Login fallito:", loginResult.error);
|
|
99661
|
+
// return;
|
|
99662
|
+
// }
|
|
99663
|
+
// console.log("✅ Login effettuato!");
|
|
99664
|
+
// console.log(` - Autenticazione: Shogun Core (Username/Password)`);
|
|
99665
|
+
// console.log(` - Storage: GunDB decentralizzato P2P\n`);
|
|
99666
|
+
// // 4. Pubblica chiave pubblica
|
|
99667
|
+
// console.log("📢 Pubblicazione chiave pubblica...");
|
|
99668
|
+
// await app.publishPublicKey();
|
|
99669
|
+
// // 5. Ascolta messaggi in arrivo
|
|
99670
|
+
// console.log("\n👂 In ascolto di messaggi...\n");
|
|
99671
|
+
// await app.listenForMessages((message) => {
|
|
99672
|
+
// console.log(`📨 Nuovo messaggio da ${message.from.substring(0, 10)}...:`);
|
|
99673
|
+
// console.log(` Contenuto: ${message.content}`);
|
|
99674
|
+
// console.log(` Timestamp: ${new Date(message.timestamp).toLocaleString()}\n`);
|
|
99675
|
+
// });
|
|
99676
|
+
// // 6. Invia un messaggio
|
|
99677
|
+
// const recipientUsername = "bob";
|
|
99678
|
+
// console.log(`📤 Invio messaggio a ${recipientUsername}...`);
|
|
99679
|
+
// const result = await app.sendMessage(
|
|
99680
|
+
// recipientUsername,
|
|
99681
|
+
// "Hello Bob! This is a secure message using Shogun Core"
|
|
99682
|
+
// );
|
|
99683
|
+
// if (result.success) {
|
|
99684
|
+
// console.log("✅ Messaggio inviato!");
|
|
99685
|
+
// console.log(` Message ID: ${result.messageId}`);
|
|
99686
|
+
// console.log(` Storage: GunDB P2P (gratis!)`);
|
|
99687
|
+
// }
|
|
99688
|
+
// // 7. Recupera storico conversazione
|
|
99689
|
+
// console.log("\n📚 Recupero storico messaggi...");
|
|
99690
|
+
// const history = await app.getMessageHistory(recipientUsername);
|
|
99691
|
+
// console.log(`\n💬 Conversazione con ${recipientUsername} (${history.length} messaggi):`);
|
|
99692
|
+
// history.forEach((msg, i) => {
|
|
99693
|
+
// const isMe = msg.from === loginResult.userPub;
|
|
99694
|
+
// console.log(`${i + 1}. ${isMe ? 'Tu' : 'Loro'}: ${msg.content}`);
|
|
99695
|
+
// });
|
|
99696
|
+
// }
|
|
99697
|
+
// ============================================================================
|
|
99698
|
+
// 9. VANTAGGI DELL'ARCHITETTURA
|
|
99699
|
+
// ============================================================================
|
|
99700
|
+
/**
|
|
99701
|
+
* VANTAGGI DI QUESTA ARCHITETTURA:
|
|
99702
|
+
*
|
|
99703
|
+
* 1. SEMPLICITÀ:
|
|
99704
|
+
* - Solo username/password (nessun wallet necessario)
|
|
99705
|
+
* - Nessun gas fee o transazioni blockchain
|
|
99706
|
+
* - Setup in pochi secondi
|
|
99707
|
+
*
|
|
99708
|
+
* 2. DECENTRALIZZAZIONE COMPLETA:
|
|
99709
|
+
* - Storage P2P su GunDB
|
|
99710
|
+
* - Nessun server centrale
|
|
99711
|
+
* - Censorship resistant
|
|
99712
|
+
* - User sovereignty
|
|
99713
|
+
*
|
|
99714
|
+
* 3. COSTI ZERO:
|
|
99715
|
+
* - Nessun costo per messaggi
|
|
99716
|
+
* - Nessun costo per storage
|
|
99717
|
+
* - Completamente gratis
|
|
99718
|
+
*
|
|
99719
|
+
* 4. END-TO-END ENCRYPTION:
|
|
99720
|
+
* - Messaggi crittografati con ECDH (Elliptic Curve Diffie-Hellman)
|
|
99721
|
+
* - SEA.secret deriva shared secret da epub (encryption public key)
|
|
99722
|
+
* - SEA.encrypt cripta con AES-GCM
|
|
99723
|
+
* - Solo mittente e destinatario possono leggere i messaggi
|
|
99724
|
+
* - Nessun server o relay può leggere il contenuto
|
|
99725
|
+
*
|
|
99726
|
+
* 5. IDENTITÀ DECENTRALIZZATA:
|
|
99727
|
+
* - Chiave pubblica GunDB come identità
|
|
99728
|
+
* - Può essere derivata in address Ethereum se necessario
|
|
99729
|
+
* - Portabile tra diverse applicazioni
|
|
99730
|
+
*
|
|
99731
|
+
* 6. REAL-TIME:
|
|
99732
|
+
* - Messaggi in tempo reale
|
|
99733
|
+
* - Sincronizzazione automatica
|
|
99734
|
+
* - Listener reattivi
|
|
99735
|
+
*
|
|
99736
|
+
* 7. OFFLINE-FIRST:
|
|
99737
|
+
* - Funziona anche offline
|
|
99738
|
+
* - Sincronizzazione automatica al riconnect
|
|
99739
|
+
* - GunDB gestisce conflitti automaticamente
|
|
99740
|
+
*
|
|
99741
|
+
* COME FUNZIONA LA CRITTOGRAFIA:
|
|
99742
|
+
*
|
|
99743
|
+
* 1. SETUP - Ogni utente ha un SEA pair:
|
|
99744
|
+
* - pub: chiave pubblica di signing
|
|
99745
|
+
* - priv: chiave privata di signing
|
|
99746
|
+
* - epub: chiave pubblica di encryption (per ECDH)
|
|
99747
|
+
* - epriv: chiave privata di encryption (per ECDH)
|
|
99748
|
+
*
|
|
99749
|
+
* 2. PUBBLICAZIONE CHIAVI:
|
|
99750
|
+
* - Ogni utente pubblica il suo epub su GunDB
|
|
99751
|
+
* - Altri possono trovarlo per criptare messaggi
|
|
99752
|
+
*
|
|
99753
|
+
* 3. INVIO MESSAGGIO (Alice → Bob):
|
|
99754
|
+
* a) Alice ottiene l'epub di Bob da GunDB
|
|
99755
|
+
* b) SEA.secret(bob.epub, alice.pair) → shared_secret (ECDH)
|
|
99756
|
+
* c) SEA.encrypt(message, shared_secret) → encrypted_message
|
|
99757
|
+
* d) Alice salva encrypted_message su GunDB
|
|
99758
|
+
*
|
|
99759
|
+
* 4. RICEZIONE MESSAGGIO (Bob riceve):
|
|
99760
|
+
* a) Bob legge encrypted_message da GunDB
|
|
99761
|
+
* b) Bob ottiene l'epub di Alice
|
|
99762
|
+
* c) SEA.secret(alice.epub, bob.pair) → shared_secret (stesso!)
|
|
99763
|
+
* d) SEA.decrypt(encrypted_message, shared_secret) → message
|
|
99764
|
+
*
|
|
99765
|
+
* 5. SICUREZZA:
|
|
99766
|
+
* - Shared secret derivato con ECDH (mai trasmesso)
|
|
99767
|
+
* - Solo Alice e Bob possono derivare lo stesso secret
|
|
99768
|
+
* - Messaggi crittografati con AES-256-GCM
|
|
99769
|
+
* - Forward secrecy se chiavi sono ruotate
|
|
99770
|
+
*
|
|
99771
|
+
* Esempio tecnico:
|
|
99772
|
+
* Alice.epub + Bob.epriv → shared_secret_AB
|
|
99773
|
+
* Bob.epub + Alice.epriv → shared_secret_AB (stesso!)
|
|
99774
|
+
*
|
|
99775
|
+
* Vantaggi:
|
|
99776
|
+
* ✅ End-to-end encryption
|
|
99777
|
+
* ✅ Perfect forward secrecy (con key rotation)
|
|
99778
|
+
* ✅ Nessun server può leggere i messaggi
|
|
99779
|
+
* ✅ Standard crittografico (ECDH + AES-GCM)
|
|
99780
|
+
* ✅ Una sola chiave privata da gestire
|
|
99781
|
+
* ✅ Address Ethereum derivabile (interoperabilità)
|
|
99782
|
+
*/
|
|
99783
|
+
// ============================================================================
|
|
99784
|
+
// 10. TEST COMPLETO: Alice e Bob si scambiano messaggi
|
|
99785
|
+
// ============================================================================
|
|
99786
|
+
/**
|
|
99787
|
+
* Test completo che simula Alice e Bob che si scambiano messaggi CRITTOGRAFATI
|
|
99788
|
+
*
|
|
99789
|
+
* CRITTOGRAFIA END-TO-END:
|
|
99790
|
+
* - Ogni messaggio è crittografato con ECDH (Elliptic Curve Diffie-Hellman)
|
|
99791
|
+
* - Solo mittente e destinatario possono leggere i messaggi
|
|
99792
|
+
* - I relay GunDB vedono solo dati crittografati
|
|
99793
|
+
*
|
|
99794
|
+
* FLOW:
|
|
99795
|
+
* 1. Alice e Bob pubblicano le loro chiavi pubbliche (epub)
|
|
99796
|
+
* 2. Alice vuole inviare a Bob:
|
|
99797
|
+
* - Ottiene bob.epub da GunDB
|
|
99798
|
+
* - SEA.secret(bob.epub, alice.pair) → shared_secret
|
|
99799
|
+
* - SEA.encrypt(message, shared_secret) → encrypted
|
|
99800
|
+
* - Salva encrypted su GunDB
|
|
99801
|
+
* 3. Bob riceve:
|
|
99802
|
+
* - Legge encrypted da GunDB
|
|
99803
|
+
* - Ottiene alice.epub
|
|
99804
|
+
* - SEA.secret(alice.epub, bob.pair) → shared_secret (stesso!)
|
|
99805
|
+
* - SEA.decrypt(encrypted, shared_secret) → message
|
|
99806
|
+
*/
|
|
99807
|
+
async function testAliceAndBob() {
|
|
99808
|
+
console.log("🧪 TEST: Alice e Bob - Conversazione Crittografata E2E\n");
|
|
99809
|
+
console.log("=".repeat(60));
|
|
99810
|
+
// Setup Alice
|
|
99811
|
+
console.log("\n👩 ALICE - Setup");
|
|
99812
|
+
console.log("-".repeat(60));
|
|
99813
|
+
const alice = new SHIP_01({
|
|
99814
|
+
gunOptions: {
|
|
99815
|
+
peers: ["https://peer.wallie.io/gun"],
|
|
99816
|
+
radisk: true,
|
|
99817
|
+
},
|
|
99818
|
+
});
|
|
99819
|
+
// Alice signup/login
|
|
99820
|
+
await alice.signup("alice", "password123");
|
|
99821
|
+
const aliceLogin = await alice.login("alice", "password123");
|
|
99822
|
+
if (!aliceLogin.success) {
|
|
99823
|
+
console.error("❌ Alice login failed");
|
|
99824
|
+
return;
|
|
99825
|
+
}
|
|
99826
|
+
await alice.publishPublicKey();
|
|
99827
|
+
// Aspetta che la chiave sia sincronizzata
|
|
99828
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
99829
|
+
// Setup Bob
|
|
99830
|
+
console.log("\n👨 BOB - Setup");
|
|
99831
|
+
console.log("-".repeat(60));
|
|
99832
|
+
const bob = new SHIP_01({
|
|
99833
|
+
gunOptions: {
|
|
99834
|
+
peers: ["https://peer.wallie.io/gun"],
|
|
99835
|
+
radisk: true
|
|
99836
|
+
},
|
|
99837
|
+
});
|
|
99838
|
+
// Bob signup/login
|
|
99839
|
+
await bob.signup("bob", "password456");
|
|
99840
|
+
const bobLogin = await bob.login("bob", "password456");
|
|
99841
|
+
if (!bobLogin.success) {
|
|
99842
|
+
console.error("❌ Bob login failed");
|
|
99843
|
+
return;
|
|
99844
|
+
}
|
|
99845
|
+
await bob.publishPublicKey();
|
|
99846
|
+
// Aspetta che la chiave sia sincronizzata
|
|
99847
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
99848
|
+
console.log("\n" + "=".repeat(60));
|
|
99849
|
+
console.log("💬 CONVERSAZIONE");
|
|
99850
|
+
console.log("=".repeat(60));
|
|
99851
|
+
// Alice e Bob ascoltano messaggi
|
|
99852
|
+
let aliceMessages = [];
|
|
99853
|
+
let bobMessages = [];
|
|
99854
|
+
await alice.listenForMessages((msg) => {
|
|
99855
|
+
aliceMessages.push(msg);
|
|
99856
|
+
console.log(`\n[Alice riceve] 📨`);
|
|
99857
|
+
console.log(` Da: ${msg.from.substring(0, 10)}...`);
|
|
99858
|
+
console.log(` Messaggio: "${msg.content}"`);
|
|
99859
|
+
console.log(` Timestamp: ${new Date(msg.timestamp).toLocaleTimeString()}`);
|
|
99860
|
+
});
|
|
99861
|
+
await bob.listenForMessages((msg) => {
|
|
99862
|
+
bobMessages.push(msg);
|
|
99863
|
+
console.log(`\n[Bob riceve] 📨`);
|
|
99864
|
+
console.log(` Da: ${msg.from.substring(0, 10)}...`);
|
|
99865
|
+
console.log(` Messaggio: "${msg.content}"`);
|
|
99866
|
+
console.log(` Timestamp: ${new Date(msg.timestamp).toLocaleTimeString()}`);
|
|
99867
|
+
});
|
|
99868
|
+
// Aspetta che i listener siano pronti
|
|
99869
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99870
|
+
// Alice invia messaggio a Bob
|
|
99871
|
+
console.log("\n[Alice invia] 📤");
|
|
99872
|
+
const msg1 = await alice.sendMessage("bob", "Ciao Bob! Come stai? 👋");
|
|
99873
|
+
console.log(` ✅ Inviato: "${msg1.messageId}"`);
|
|
99874
|
+
// Aspetta che Bob riceva
|
|
99875
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99876
|
+
// Bob risponde ad Alice
|
|
99877
|
+
console.log("\n[Bob invia] 📤");
|
|
99878
|
+
const msg2 = await bob.sendMessage("alice", "Ciao Alice! Tutto bene, grazie! Tu? 😊");
|
|
99879
|
+
console.log(` ✅ Inviato: "${msg2.messageId}"`);
|
|
99880
|
+
// Aspetta che Alice riceva
|
|
99881
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99882
|
+
// Alice risponde
|
|
99883
|
+
console.log("\n[Alice invia] 📤");
|
|
99884
|
+
const msg3 = await alice.sendMessage("bob", "Anch'io benissimo! Questo sistema di messaggistica è fantastico! 🚀");
|
|
99885
|
+
console.log(` ✅ Inviato: "${msg3.messageId}"`);
|
|
99886
|
+
// Aspetta che Bob riceva
|
|
99887
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
99888
|
+
// Bob conclude
|
|
99889
|
+
console.log("\n[Bob invia] 📤");
|
|
99890
|
+
const msg4 = await bob.sendMessage("alice", "Vero! Zero costi, decentralizzato e veloce! 💪");
|
|
99891
|
+
console.log(` ✅ Inviato: "${msg4.messageId}"`);
|
|
99892
|
+
// Aspetta finale
|
|
99893
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
99894
|
+
// Mostra statistiche
|
|
99895
|
+
console.log("\n" + "=".repeat(60));
|
|
99896
|
+
console.log("📊 STATISTICHE FINALI");
|
|
99897
|
+
console.log("=".repeat(60));
|
|
99898
|
+
console.log(`\n👩 Alice:`);
|
|
99899
|
+
console.log(` - Messaggi inviati: 2`);
|
|
99900
|
+
console.log(` - Messaggi ricevuti: ${aliceMessages.length}`);
|
|
99901
|
+
console.log(` - Public Key: ${aliceLogin.userPub?.substring(0, 20)}...`);
|
|
99902
|
+
console.log(` - Derived Address: ${aliceLogin.derivedAddress}`);
|
|
99903
|
+
console.log(`\n👨 Bob:`);
|
|
99904
|
+
console.log(` - Messaggi inviati: 2`);
|
|
99905
|
+
console.log(` - Messaggi ricevuti: ${bobMessages.length}`);
|
|
99906
|
+
console.log(` - Public Key: ${bobLogin.userPub?.substring(0, 20)}...`);
|
|
99907
|
+
console.log(` - Derived Address: ${bobLogin.derivedAddress}`);
|
|
99908
|
+
// Recupera storico
|
|
99909
|
+
console.log("\n" + "=".repeat(60));
|
|
99910
|
+
console.log("📚 STORICO CONVERSAZIONE");
|
|
99911
|
+
console.log("=".repeat(60));
|
|
99912
|
+
const aliceHistory = await alice.getMessageHistory("bob");
|
|
99913
|
+
console.log(`\n👩 Storico di Alice con Bob (${aliceHistory.length} messaggi):`);
|
|
99914
|
+
aliceHistory.forEach((msg, i) => {
|
|
99915
|
+
const sender = msg.from === aliceLogin.userPub ? "Alice" : "Bob";
|
|
99916
|
+
console.log(` ${i + 1}. [${sender}]: ${msg.content}`);
|
|
99917
|
+
});
|
|
99918
|
+
const bobHistory = await bob.getMessageHistory("alice");
|
|
99919
|
+
console.log(`\n👨 Storico di Bob con Alice (${bobHistory.length} messaggi):`);
|
|
99920
|
+
bobHistory.forEach((msg, i) => {
|
|
99921
|
+
const sender = msg.from === bobLogin.userPub ? "Bob" : "Alice";
|
|
99922
|
+
console.log(` ${i + 1}. [${sender}]: ${msg.content}`);
|
|
99923
|
+
});
|
|
99924
|
+
// Riepilogo finale
|
|
99925
|
+
console.log("\n" + "=".repeat(60));
|
|
99926
|
+
console.log("✅ TEST COMPLETATO CON SUCCESSO!");
|
|
99927
|
+
console.log("=".repeat(60));
|
|
99928
|
+
console.log("\n📝 Riepilogo:");
|
|
99929
|
+
console.log(" ✅ 2 utenti registrati (Alice, Bob)");
|
|
99930
|
+
console.log(" ✅ 4 messaggi scambiati");
|
|
99931
|
+
console.log(" ✅ Messaggi ricevuti in real-time");
|
|
99932
|
+
console.log(" ✅ Storico recuperato correttamente");
|
|
99933
|
+
console.log(" ✅ Storage: GunDB P2P (gratis!)");
|
|
99934
|
+
console.log(" ✅ Costi: $0.00");
|
|
99935
|
+
console.log("\n🎉 Sistema di messaggistica decentralizzato funzionante!\n");
|
|
99936
|
+
}
|
|
99937
|
+
// Esegui esempio o test
|
|
99938
|
+
if (__webpack_require__.c[__webpack_require__.s] === module) {
|
|
99939
|
+
// Scegli quale eseguire decommentando una delle due righe:
|
|
99940
|
+
// main().catch(console.error); // Esempio singolo utente
|
|
99941
|
+
testAliceAndBob().catch(console.error); // Test completo Alice & Bob
|
|
99942
|
+
}
|
|
99943
|
+
|
|
99944
|
+
|
|
98488
99945
|
/***/ }),
|
|
98489
99946
|
|
|
98490
99947
|
/***/ "./src/config/simplified-config.ts":
|
|
@@ -101230,8 +102687,8 @@ class DataBase {
|
|
|
101230
102687
|
username: username,
|
|
101231
102688
|
userPub: userPub,
|
|
101232
102689
|
epub: epub,
|
|
101233
|
-
registeredAt: Date.now(),
|
|
101234
|
-
lastSeen: Date.now(),
|
|
102690
|
+
registeredAt: Date.now().toString(),
|
|
102691
|
+
lastSeen: Date.now().toString(),
|
|
101235
102692
|
};
|
|
101236
102693
|
const ack = await this.node
|
|
101237
102694
|
.get("users")
|
|
@@ -102820,7 +104277,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
102820
104277
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
102821
104278
|
};
|
|
102822
104279
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
102823
|
-
exports.autoQuickStart = exports.AutoQuickStart = exports.createSimpleAPI = exports.quickStart = exports.QuickStart = exports.SimpleGunAPI = exports.DataBase = exports.GunErrors = exports.derive = exports.crypto = exports.RxJS = exports.SEA = exports.ShogunCore = exports.Gun = void 0;
|
|
104280
|
+
exports.autoQuickStart = exports.AutoQuickStart = exports.createSimpleAPI = exports.quickStart = exports.QuickStart = exports.SimpleGunAPI = exports.DataBase = exports.GunErrors = exports.derive = exports.crypto = exports.RxJS = exports.SEA = exports.ShogunCore = exports.Gun = exports.MessengerCLI = exports.SHIP_01 = void 0;
|
|
102824
104281
|
const core_1 = __webpack_require__(/*! ./core */ "./src/core.ts");
|
|
102825
104282
|
Object.defineProperty(exports, "ShogunCore", ({ enumerable: true, get: function () { return core_1.ShogunCore; } }));
|
|
102826
104283
|
const db_1 = __webpack_require__(/*! ./gundb/db */ "./src/gundb/db.ts");
|
|
@@ -102844,8 +104301,13 @@ exports.Gun = db_3.default;
|
|
|
102844
104301
|
__exportStar(__webpack_require__(/*! ./utils/errorHandler */ "./src/utils/errorHandler.ts"), exports);
|
|
102845
104302
|
__exportStar(__webpack_require__(/*! ./plugins */ "./src/plugins/index.ts"), exports);
|
|
102846
104303
|
__exportStar(__webpack_require__(/*! ./interfaces/shogun */ "./src/interfaces/shogun.ts"), exports);
|
|
102847
|
-
// Export simplified configuration
|
|
102848
104304
|
__exportStar(__webpack_require__(/*! ./config/simplified-config */ "./src/config/simplified-config.ts"), exports);
|
|
104305
|
+
var SHIP_01_1 = __webpack_require__(/*! ../ship/implementation/SHIP_01 */ "./ship/implementation/SHIP_01.ts");
|
|
104306
|
+
Object.defineProperty(exports, "SHIP_01", ({ enumerable: true, get: function () { return SHIP_01_1.SHIP_01; } }));
|
|
104307
|
+
// Export MessengerCLI only in Node.js environment (not browser)
|
|
104308
|
+
// This prevents "readline is not a function" errors in browser builds
|
|
104309
|
+
var messenger_cli_1 = __webpack_require__(/*! ../ship/examples/messenger-cli */ "./ship/examples/messenger-cli.ts");
|
|
104310
|
+
Object.defineProperty(exports, "MessengerCLI", ({ enumerable: true, get: function () { return messenger_cli_1.MessengerCLI; } }));
|
|
102849
104311
|
|
|
102850
104312
|
|
|
102851
104313
|
/***/ }),
|
|
@@ -109640,7 +111102,43 @@ function generateDeterministicPassword(salt) {
|
|
|
109640
111102
|
/******/ return module.exports;
|
|
109641
111103
|
/******/ }
|
|
109642
111104
|
/******/
|
|
111105
|
+
/******/ // expose the modules object (__webpack_modules__)
|
|
111106
|
+
/******/ __webpack_require__.m = __webpack_modules__;
|
|
111107
|
+
/******/
|
|
111108
|
+
/******/ // expose the module cache
|
|
111109
|
+
/******/ __webpack_require__.c = __webpack_module_cache__;
|
|
111110
|
+
/******/
|
|
109643
111111
|
/************************************************************************/
|
|
111112
|
+
/******/ /* webpack/runtime/create fake namespace object */
|
|
111113
|
+
/******/ (() => {
|
|
111114
|
+
/******/ var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);
|
|
111115
|
+
/******/ var leafPrototypes;
|
|
111116
|
+
/******/ // create a fake namespace object
|
|
111117
|
+
/******/ // mode & 1: value is a module id, require it
|
|
111118
|
+
/******/ // mode & 2: merge all properties of value into the ns
|
|
111119
|
+
/******/ // mode & 4: return value when already ns object
|
|
111120
|
+
/******/ // mode & 16: return value when it's Promise-like
|
|
111121
|
+
/******/ // mode & 8|1: behave like require
|
|
111122
|
+
/******/ __webpack_require__.t = function(value, mode) {
|
|
111123
|
+
/******/ if(mode & 1) value = this(value);
|
|
111124
|
+
/******/ if(mode & 8) return value;
|
|
111125
|
+
/******/ if(typeof value === 'object' && value) {
|
|
111126
|
+
/******/ if((mode & 4) && value.__esModule) return value;
|
|
111127
|
+
/******/ if((mode & 16) && typeof value.then === 'function') return value;
|
|
111128
|
+
/******/ }
|
|
111129
|
+
/******/ var ns = Object.create(null);
|
|
111130
|
+
/******/ __webpack_require__.r(ns);
|
|
111131
|
+
/******/ var def = {};
|
|
111132
|
+
/******/ leafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];
|
|
111133
|
+
/******/ for(var current = mode & 2 && value; (typeof current == 'object' || typeof current == 'function') && !~leafPrototypes.indexOf(current); current = getProto(current)) {
|
|
111134
|
+
/******/ Object.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));
|
|
111135
|
+
/******/ }
|
|
111136
|
+
/******/ def['default'] = () => (value);
|
|
111137
|
+
/******/ __webpack_require__.d(ns, def);
|
|
111138
|
+
/******/ return ns;
|
|
111139
|
+
/******/ };
|
|
111140
|
+
/******/ })();
|
|
111141
|
+
/******/
|
|
109644
111142
|
/******/ /* webpack/runtime/define property getters */
|
|
109645
111143
|
/******/ (() => {
|
|
109646
111144
|
/******/ // define getter functions for harmony exports
|
|
@@ -109653,6 +111151,28 @@ function generateDeterministicPassword(salt) {
|
|
|
109653
111151
|
/******/ };
|
|
109654
111152
|
/******/ })();
|
|
109655
111153
|
/******/
|
|
111154
|
+
/******/ /* webpack/runtime/ensure chunk */
|
|
111155
|
+
/******/ (() => {
|
|
111156
|
+
/******/ __webpack_require__.f = {};
|
|
111157
|
+
/******/ // This file contains only the entry chunk.
|
|
111158
|
+
/******/ // The chunk loading function for additional chunks
|
|
111159
|
+
/******/ __webpack_require__.e = (chunkId) => {
|
|
111160
|
+
/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {
|
|
111161
|
+
/******/ __webpack_require__.f[key](chunkId, promises);
|
|
111162
|
+
/******/ return promises;
|
|
111163
|
+
/******/ }, []));
|
|
111164
|
+
/******/ };
|
|
111165
|
+
/******/ })();
|
|
111166
|
+
/******/
|
|
111167
|
+
/******/ /* webpack/runtime/get javascript chunk filename */
|
|
111168
|
+
/******/ (() => {
|
|
111169
|
+
/******/ // This function allow to reference async chunks
|
|
111170
|
+
/******/ __webpack_require__.u = (chunkId) => {
|
|
111171
|
+
/******/ // return url for filenames based on template
|
|
111172
|
+
/******/ return "" + chunkId + ".shogun-core.js";
|
|
111173
|
+
/******/ };
|
|
111174
|
+
/******/ })();
|
|
111175
|
+
/******/
|
|
109656
111176
|
/******/ /* webpack/runtime/global */
|
|
109657
111177
|
/******/ (() => {
|
|
109658
111178
|
/******/ __webpack_require__.g = (function() {
|
|
@@ -109670,6 +111190,52 @@ function generateDeterministicPassword(salt) {
|
|
|
109670
111190
|
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
109671
111191
|
/******/ })();
|
|
109672
111192
|
/******/
|
|
111193
|
+
/******/ /* webpack/runtime/load script */
|
|
111194
|
+
/******/ (() => {
|
|
111195
|
+
/******/ var inProgress = {};
|
|
111196
|
+
/******/ var dataWebpackPrefix = "ShogunCore:";
|
|
111197
|
+
/******/ // loadScript function to load a script via script tag
|
|
111198
|
+
/******/ __webpack_require__.l = (url, done, key, chunkId) => {
|
|
111199
|
+
/******/ if(inProgress[url]) { inProgress[url].push(done); return; }
|
|
111200
|
+
/******/ var script, needAttach;
|
|
111201
|
+
/******/ if(key !== undefined) {
|
|
111202
|
+
/******/ var scripts = document.getElementsByTagName("script");
|
|
111203
|
+
/******/ for(var i = 0; i < scripts.length; i++) {
|
|
111204
|
+
/******/ var s = scripts[i];
|
|
111205
|
+
/******/ if(s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) { script = s; break; }
|
|
111206
|
+
/******/ }
|
|
111207
|
+
/******/ }
|
|
111208
|
+
/******/ if(!script) {
|
|
111209
|
+
/******/ needAttach = true;
|
|
111210
|
+
/******/ script = document.createElement('script');
|
|
111211
|
+
/******/
|
|
111212
|
+
/******/ script.charset = 'utf-8';
|
|
111213
|
+
/******/ script.timeout = 120;
|
|
111214
|
+
/******/ if (__webpack_require__.nc) {
|
|
111215
|
+
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
|
111216
|
+
/******/ }
|
|
111217
|
+
/******/ script.setAttribute("data-webpack", dataWebpackPrefix + key);
|
|
111218
|
+
/******/
|
|
111219
|
+
/******/ script.src = url;
|
|
111220
|
+
/******/ }
|
|
111221
|
+
/******/ inProgress[url] = [done];
|
|
111222
|
+
/******/ var onScriptComplete = (prev, event) => {
|
|
111223
|
+
/******/ // avoid mem leaks in IE.
|
|
111224
|
+
/******/ script.onerror = script.onload = null;
|
|
111225
|
+
/******/ clearTimeout(timeout);
|
|
111226
|
+
/******/ var doneFns = inProgress[url];
|
|
111227
|
+
/******/ delete inProgress[url];
|
|
111228
|
+
/******/ script.parentNode && script.parentNode.removeChild(script);
|
|
111229
|
+
/******/ doneFns && doneFns.forEach((fn) => (fn(event)));
|
|
111230
|
+
/******/ if(prev) return prev(event);
|
|
111231
|
+
/******/ }
|
|
111232
|
+
/******/ var timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);
|
|
111233
|
+
/******/ script.onerror = onScriptComplete.bind(null, script.onerror);
|
|
111234
|
+
/******/ script.onload = onScriptComplete.bind(null, script.onload);
|
|
111235
|
+
/******/ needAttach && document.head.appendChild(script);
|
|
111236
|
+
/******/ };
|
|
111237
|
+
/******/ })();
|
|
111238
|
+
/******/
|
|
109673
111239
|
/******/ /* webpack/runtime/make namespace object */
|
|
109674
111240
|
/******/ (() => {
|
|
109675
111241
|
/******/ // define __esModule on exports
|
|
@@ -109690,12 +111256,125 @@ function generateDeterministicPassword(salt) {
|
|
|
109690
111256
|
/******/ };
|
|
109691
111257
|
/******/ })();
|
|
109692
111258
|
/******/
|
|
111259
|
+
/******/ /* webpack/runtime/publicPath */
|
|
111260
|
+
/******/ (() => {
|
|
111261
|
+
/******/ var scriptUrl;
|
|
111262
|
+
/******/ if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
|
|
111263
|
+
/******/ var document = __webpack_require__.g.document;
|
|
111264
|
+
/******/ if (!scriptUrl && document) {
|
|
111265
|
+
/******/ if (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')
|
|
111266
|
+
/******/ scriptUrl = document.currentScript.src;
|
|
111267
|
+
/******/ if (!scriptUrl) {
|
|
111268
|
+
/******/ var scripts = document.getElementsByTagName("script");
|
|
111269
|
+
/******/ if(scripts.length) {
|
|
111270
|
+
/******/ var i = scripts.length - 1;
|
|
111271
|
+
/******/ while (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;
|
|
111272
|
+
/******/ }
|
|
111273
|
+
/******/ }
|
|
111274
|
+
/******/ }
|
|
111275
|
+
/******/ // When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration
|
|
111276
|
+
/******/ // or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.
|
|
111277
|
+
/******/ if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
|
|
111278
|
+
/******/ scriptUrl = scriptUrl.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
|
|
111279
|
+
/******/ __webpack_require__.p = scriptUrl;
|
|
111280
|
+
/******/ })();
|
|
111281
|
+
/******/
|
|
111282
|
+
/******/ /* webpack/runtime/jsonp chunk loading */
|
|
111283
|
+
/******/ (() => {
|
|
111284
|
+
/******/ // no baseURI
|
|
111285
|
+
/******/
|
|
111286
|
+
/******/ // object to store loaded and loading chunks
|
|
111287
|
+
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
111288
|
+
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
|
|
111289
|
+
/******/ var installedChunks = {
|
|
111290
|
+
/******/ "main": 0
|
|
111291
|
+
/******/ };
|
|
111292
|
+
/******/
|
|
111293
|
+
/******/ __webpack_require__.f.j = (chunkId, promises) => {
|
|
111294
|
+
/******/ // JSONP chunk loading for javascript
|
|
111295
|
+
/******/ var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
|
|
111296
|
+
/******/ if(installedChunkData !== 0) { // 0 means "already installed".
|
|
111297
|
+
/******/
|
|
111298
|
+
/******/ // a Promise means "currently loading".
|
|
111299
|
+
/******/ if(installedChunkData) {
|
|
111300
|
+
/******/ promises.push(installedChunkData[2]);
|
|
111301
|
+
/******/ } else {
|
|
111302
|
+
/******/ if(true) { // all chunks have JS
|
|
111303
|
+
/******/ // setup Promise in chunk cache
|
|
111304
|
+
/******/ var promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));
|
|
111305
|
+
/******/ promises.push(installedChunkData[2] = promise);
|
|
111306
|
+
/******/
|
|
111307
|
+
/******/ // start chunk loading
|
|
111308
|
+
/******/ var url = __webpack_require__.p + __webpack_require__.u(chunkId);
|
|
111309
|
+
/******/ // create error before stack unwound to get useful stacktrace later
|
|
111310
|
+
/******/ var error = new Error();
|
|
111311
|
+
/******/ var loadingEnded = (event) => {
|
|
111312
|
+
/******/ if(__webpack_require__.o(installedChunks, chunkId)) {
|
|
111313
|
+
/******/ installedChunkData = installedChunks[chunkId];
|
|
111314
|
+
/******/ if(installedChunkData !== 0) installedChunks[chunkId] = undefined;
|
|
111315
|
+
/******/ if(installedChunkData) {
|
|
111316
|
+
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
|
|
111317
|
+
/******/ var realSrc = event && event.target && event.target.src;
|
|
111318
|
+
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
|
|
111319
|
+
/******/ error.name = 'ChunkLoadError';
|
|
111320
|
+
/******/ error.type = errorType;
|
|
111321
|
+
/******/ error.request = realSrc;
|
|
111322
|
+
/******/ installedChunkData[1](error);
|
|
111323
|
+
/******/ }
|
|
111324
|
+
/******/ }
|
|
111325
|
+
/******/ };
|
|
111326
|
+
/******/ __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
|
|
111327
|
+
/******/ }
|
|
111328
|
+
/******/ }
|
|
111329
|
+
/******/ }
|
|
111330
|
+
/******/ };
|
|
111331
|
+
/******/
|
|
111332
|
+
/******/ // no prefetching
|
|
111333
|
+
/******/
|
|
111334
|
+
/******/ // no preloaded
|
|
111335
|
+
/******/
|
|
111336
|
+
/******/ // no HMR
|
|
111337
|
+
/******/
|
|
111338
|
+
/******/ // no HMR manifest
|
|
111339
|
+
/******/
|
|
111340
|
+
/******/ // no on chunks loaded
|
|
111341
|
+
/******/
|
|
111342
|
+
/******/ // install a JSONP callback for chunk loading
|
|
111343
|
+
/******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
|
|
111344
|
+
/******/ var [chunkIds, moreModules, runtime] = data;
|
|
111345
|
+
/******/ // add "moreModules" to the modules object,
|
|
111346
|
+
/******/ // then flag all "chunkIds" as loaded and fire callback
|
|
111347
|
+
/******/ var moduleId, chunkId, i = 0;
|
|
111348
|
+
/******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) {
|
|
111349
|
+
/******/ for(moduleId in moreModules) {
|
|
111350
|
+
/******/ if(__webpack_require__.o(moreModules, moduleId)) {
|
|
111351
|
+
/******/ __webpack_require__.m[moduleId] = moreModules[moduleId];
|
|
111352
|
+
/******/ }
|
|
111353
|
+
/******/ }
|
|
111354
|
+
/******/ if(runtime) var result = runtime(__webpack_require__);
|
|
111355
|
+
/******/ }
|
|
111356
|
+
/******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);
|
|
111357
|
+
/******/ for(;i < chunkIds.length; i++) {
|
|
111358
|
+
/******/ chunkId = chunkIds[i];
|
|
111359
|
+
/******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
|
|
111360
|
+
/******/ installedChunks[chunkId][0]();
|
|
111361
|
+
/******/ }
|
|
111362
|
+
/******/ installedChunks[chunkId] = 0;
|
|
111363
|
+
/******/ }
|
|
111364
|
+
/******/
|
|
111365
|
+
/******/ }
|
|
111366
|
+
/******/
|
|
111367
|
+
/******/ var chunkLoadingGlobal = this["webpackChunkShogunCore"] = this["webpackChunkShogunCore"] || [];
|
|
111368
|
+
/******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
|
|
111369
|
+
/******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
|
|
111370
|
+
/******/ })();
|
|
111371
|
+
/******/
|
|
109693
111372
|
/************************************************************************/
|
|
109694
111373
|
/******/
|
|
111374
|
+
/******/ // module cache are used so entry inlining is disabled
|
|
109695
111375
|
/******/ // startup
|
|
109696
111376
|
/******/ // Load entry module and return exports
|
|
109697
|
-
/******/
|
|
109698
|
-
/******/ var __webpack_exports__ = __webpack_require__("./src/index.ts");
|
|
111377
|
+
/******/ var __webpack_exports__ = __webpack_require__(__webpack_require__.s = "./src/index.ts");
|
|
109699
111378
|
/******/
|
|
109700
111379
|
/******/ return __webpack_exports__;
|
|
109701
111380
|
/******/ })()
|