shogun-core 3.3.0 → 3.3.2

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 (36) hide show
  1. package/dist/browser/shogun-core.js +83301 -148719
  2. package/dist/browser/shogun-core.js.map +1 -1
  3. package/dist/ship/examples/ephemeral-cli.js +234 -0
  4. package/dist/ship/examples/identity-cli.js +503 -0
  5. package/dist/ship/examples/stealth-cli.js +433 -0
  6. package/dist/ship/examples/storage-cli.js +615 -0
  7. package/dist/ship/examples/vault-cli.js +444 -0
  8. package/dist/ship/implementation/SHIP_04.js +589 -0
  9. package/dist/ship/implementation/SHIP_05.js +1064 -0
  10. package/dist/ship/implementation/SHIP_06.js +350 -0
  11. package/dist/ship/implementation/SHIP_07.js +635 -0
  12. package/dist/ship/index.js +17 -0
  13. package/dist/ship/interfaces/ISHIP_04.js +62 -0
  14. package/dist/ship/interfaces/ISHIP_05.js +59 -0
  15. package/dist/ship/interfaces/ISHIP_06.js +144 -0
  16. package/dist/ship/interfaces/ISHIP_07.js +194 -0
  17. package/dist/src/index.js +1 -15
  18. package/dist/types/ship/examples/ephemeral-cli.d.ts +13 -0
  19. package/dist/types/ship/examples/identity-cli.d.ts +40 -0
  20. package/dist/types/ship/examples/stealth-cli.d.ts +31 -0
  21. package/dist/types/ship/examples/storage-cli.d.ts +48 -0
  22. package/dist/types/ship/examples/vault-cli.d.ts +13 -0
  23. package/dist/types/ship/implementation/SHIP_04.d.ts +76 -0
  24. package/dist/types/ship/implementation/SHIP_05.d.ts +70 -0
  25. package/dist/types/ship/implementation/SHIP_06.d.ts +66 -0
  26. package/dist/types/ship/implementation/SHIP_07.d.ts +101 -0
  27. package/dist/types/ship/index.d.ts +14 -0
  28. package/dist/types/ship/interfaces/ISHIP_04.d.ts +245 -0
  29. package/dist/types/ship/interfaces/ISHIP_05.d.ts +234 -0
  30. package/dist/types/ship/interfaces/ISHIP_06.d.ts +370 -0
  31. package/dist/types/ship/interfaces/ISHIP_07.d.ts +522 -0
  32. package/dist/types/src/index.d.ts +0 -10
  33. package/dist/types/src/types/shogun.d.ts +2 -0
  34. package/package.json +1 -1
  35. package/dist/browser/_e6ae.shogun-core.js +0 -14
  36. package/dist/browser/_e6ae.shogun-core.js.map +0 -1
@@ -0,0 +1,503 @@
1
+ #!/usr/bin/env tsx
2
+ "use strict";
3
+ /**
4
+ * SHIP-00 Identity CLI Example
5
+ *
6
+ * Interactive CLI demonstrating SHIP-00 identity and authentication
7
+ *
8
+ * Usage:
9
+ * yarn identity <username> <password>
10
+ *
11
+ * Features:
12
+ * - User signup and login
13
+ * - Login with keypair (multi-device)
14
+ * - Public key publication
15
+ * - User discovery and lookup
16
+ * - Key pair export/import
17
+ * - Ethereum address derivation
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.IdentityCLI = void 0;
54
+ const SHIP_00_1 = require("../implementation/SHIP_00");
55
+ const readline = __importStar(require("readline"));
56
+ const fs = __importStar(require("fs"));
57
+ // ============================================================================
58
+ // CLI Interface
59
+ // ============================================================================
60
+ class IdentityCLI {
61
+ constructor() {
62
+ this.username = "";
63
+ this.running = false;
64
+ // Initialize SHIP-00 with hardcoded peers
65
+ this.identity = new SHIP_00_1.SHIP_00({
66
+ gunOptions: {
67
+ peers: [
68
+ "https://peer.wallie.io/gun",
69
+ "https://v5g5jseqhgkp43lppgregcfbvi.srv.us/gun",
70
+ "https://relay.shogun-eco.xyz/gun",
71
+ ],
72
+ radisk: true,
73
+ localStorage: false,
74
+ },
75
+ });
76
+ this.rl = readline.createInterface({
77
+ input: process.stdin,
78
+ output: process.stdout,
79
+ });
80
+ }
81
+ // ==========================================================================
82
+ // Authentication
83
+ // ==========================================================================
84
+ async login(username, password) {
85
+ console.log(`\nšŸ” Logging in as ${username}...`);
86
+ try {
87
+ // Try login first
88
+ let result = await this.identity.login(username, password);
89
+ if (!result.success) {
90
+ // If login fails, offer to register
91
+ console.log("šŸ“ User not found, creating new identity...");
92
+ const signupResult = await this.identity.signup(username, password);
93
+ if (!signupResult.success) {
94
+ console.error(`āŒ Registration failed: ${signupResult.error}`);
95
+ return false;
96
+ }
97
+ // Login after signup
98
+ await new Promise((resolve) => setTimeout(resolve, 1000));
99
+ result = await this.identity.login(username, password);
100
+ }
101
+ if (result.success) {
102
+ this.username = username;
103
+ console.log("\nāœ… Authentication Successful!");
104
+ console.log("━".repeat(60));
105
+ console.log(` Username: ${username}`);
106
+ console.log(` Public Key: ${result.userPub?.substring(0, 40)}...`);
107
+ console.log(` Derived Address: ${result.derivedAddress}`);
108
+ console.log("━".repeat(60));
109
+ // Publish public key for discovery
110
+ console.log("\nšŸ“¢ Publishing public key to network...");
111
+ await this.identity.publishPublicKey();
112
+ await new Promise((resolve) => setTimeout(resolve, 1000));
113
+ console.log("āœ… Public key published!");
114
+ return true;
115
+ }
116
+ else {
117
+ console.error(`āŒ Login failed: ${result.error}`);
118
+ return false;
119
+ }
120
+ }
121
+ catch (error) {
122
+ console.error(`āŒ Error: ${error.message}`);
123
+ return false;
124
+ }
125
+ }
126
+ async loginWithKeypair() {
127
+ console.log("\nšŸ”‘ Login with Key Pair");
128
+ console.log("━".repeat(60));
129
+ const keypairStr = await this.prompt("Enter key pair (base64 or JSON): ");
130
+ try {
131
+ let seaPair;
132
+ // Try base64 decode
133
+ try {
134
+ const decoded = Buffer.from(keypairStr.trim(), "base64").toString("utf-8");
135
+ seaPair = JSON.parse(decoded);
136
+ }
137
+ catch {
138
+ // Try direct JSON parse
139
+ seaPair = JSON.parse(keypairStr.trim());
140
+ }
141
+ // Validate keypair
142
+ if (!seaPair.pub || !seaPair.priv || !seaPair.epub || !seaPair.epriv) {
143
+ throw new Error("Invalid keypair structure");
144
+ }
145
+ console.log("\nšŸ” Authenticating with keypair...");
146
+ const result = await this.identity.loginWithPair(seaPair);
147
+ if (result.success) {
148
+ this.username = result.username || seaPair.alias || "unknown";
149
+ console.log("\nāœ… Login Successful!");
150
+ console.log("━".repeat(60));
151
+ console.log(` Username: ${this.username}`);
152
+ console.log(` Public Key: ${seaPair.pub.substring(0, 40)}...`);
153
+ console.log(` Derived Address: ${result.derivedAddress}`);
154
+ console.log("━".repeat(60));
155
+ // Publish public key
156
+ await this.identity.publishPublicKey();
157
+ console.log("āœ… Public key published!");
158
+ }
159
+ else {
160
+ console.error(`āŒ Login failed: ${result.error}`);
161
+ }
162
+ }
163
+ catch (error) {
164
+ console.error(`āŒ Error: ${error.message}`);
165
+ }
166
+ }
167
+ // ==========================================================================
168
+ // Key Management
169
+ // ==========================================================================
170
+ async exportKeypair() {
171
+ console.log("\nšŸ“¤ Export Key Pair");
172
+ console.log("━".repeat(60));
173
+ const keypair = this.identity.exportKeyPair();
174
+ if (!keypair) {
175
+ console.error("āŒ Not logged in");
176
+ return;
177
+ }
178
+ // Create export object
179
+ const exportData = {
180
+ ...keypair,
181
+ alias: this.username,
182
+ exportedAt: Date.now(),
183
+ };
184
+ // Base64 encode
185
+ const jsonString = JSON.stringify(exportData);
186
+ const base64 = Buffer.from(jsonString).toString("base64");
187
+ console.log("\nāœ… KEY PAIR EXPORTED");
188
+ console.log("═".repeat(60));
189
+ console.log("\nšŸ”‘ Base64 Format:");
190
+ console.log(base64);
191
+ console.log("\nšŸ”‘ JSON Format:");
192
+ console.log(JSON.stringify(exportData, null, 2));
193
+ console.log("\n═".repeat(60));
194
+ // Save to file
195
+ const filename = `shogun-identity-${this.username}-${Date.now()}.txt`;
196
+ fs.writeFileSync(filename, base64);
197
+ console.log(`\nšŸ’¾ Saved to: ${filename}`);
198
+ console.log("\nāš ļø KEEP THIS SAFE! Contains your private keys!");
199
+ console.log("━".repeat(60));
200
+ }
201
+ async showCurrentUser() {
202
+ console.log("\nšŸ‘¤ Current User Info");
203
+ console.log("━".repeat(60));
204
+ const currentUser = this.identity.getCurrentUser();
205
+ if (!currentUser) {
206
+ console.log("āŒ Not logged in");
207
+ return;
208
+ }
209
+ console.log(` Alias: ${currentUser.alias}`);
210
+ console.log(` Public Key: ${currentUser.pub}`);
211
+ console.log(` Encryption Key: ${currentUser.epub}`);
212
+ // Derive Ethereum address
213
+ const ethAddress = await this.identity.deriveEthereumAddress();
214
+ console.log(` Ethereum Address: ${ethAddress}`);
215
+ console.log("━".repeat(60));
216
+ }
217
+ async showPublicKey() {
218
+ console.log("\nšŸ”‘ Your Public Keys");
219
+ console.log("━".repeat(60));
220
+ const keypair = this.identity.getKeyPair();
221
+ if (!keypair) {
222
+ console.log("āŒ Not logged in");
223
+ return;
224
+ }
225
+ console.log("\nšŸ“ Signing Keys:");
226
+ console.log(` Public: ${keypair.pub}`);
227
+ console.log(` Private: ${keypair.priv.substring(0, 20)}... (hidden)`);
228
+ console.log("\nšŸ” Encryption Keys:");
229
+ console.log(` Public: ${keypair.epub}`);
230
+ console.log(` Private: ${keypair.epriv.substring(0, 20)}... (hidden)`);
231
+ console.log("\nšŸ’” Share the PUBLIC keys only!");
232
+ console.log("━".repeat(60));
233
+ }
234
+ // ==========================================================================
235
+ // User Discovery
236
+ // ==========================================================================
237
+ async lookupUser() {
238
+ console.log("\nšŸ” Lookup User");
239
+ console.log("━".repeat(60));
240
+ const username = await this.prompt("Enter username to lookup: ");
241
+ if (!username.trim()) {
242
+ console.log("āŒ Username required");
243
+ return;
244
+ }
245
+ console.log(`\nšŸ” Searching for ${username}...`);
246
+ // Check if exists
247
+ const exists = await this.identity.userExists(username.trim());
248
+ if (!exists) {
249
+ console.log(`\nāŒ User not found: ${username}`);
250
+ console.log("\nšŸ’” User may not have registered yet");
251
+ return;
252
+ }
253
+ // Get user data
254
+ const userData = await this.identity.getUserByAlias(username.trim());
255
+ if (userData) {
256
+ console.log(`\nāœ… User Found:`);
257
+ console.log("━".repeat(60));
258
+ console.log(` Username: ${userData.username}`);
259
+ console.log(` Public Key: ${userData.userPub}`);
260
+ console.log(` Encryption Key: ${userData.epub || "Not published"}`);
261
+ if (userData.registeredAt) {
262
+ console.log(` Registered: ${new Date(userData.registeredAt).toLocaleString()}`);
263
+ }
264
+ if (userData.lastSeen) {
265
+ console.log(` Last Seen: ${new Date(userData.lastSeen).toLocaleString()}`);
266
+ }
267
+ }
268
+ // Get public key data
269
+ const publicKey = await this.identity.getPublicKey(username.trim());
270
+ if (publicKey) {
271
+ console.log("\nšŸ“ Published Keys:");
272
+ console.log(` Signing: ${publicKey.pub.substring(0, 40)}...`);
273
+ console.log(` Encryption: ${publicKey.epub.substring(0, 40)}...`);
274
+ if (publicKey.timestamp) {
275
+ console.log(` Published: ${new Date(parseInt(publicKey.timestamp)).toLocaleString()}`);
276
+ }
277
+ }
278
+ else {
279
+ console.log("\nāš ļø User has not published public keys yet");
280
+ }
281
+ console.log("━".repeat(60));
282
+ }
283
+ async lookupByPublicKey() {
284
+ console.log("\nšŸ” Lookup by Public Key");
285
+ console.log("━".repeat(60));
286
+ const pubKey = await this.prompt("Enter public key: ");
287
+ if (!pubKey.trim()) {
288
+ console.log("āŒ Public key required");
289
+ return;
290
+ }
291
+ console.log(`\nšŸ” Searching for public key...`);
292
+ const userData = await this.identity.getUserByPub(pubKey.trim());
293
+ if (!userData) {
294
+ console.log(`\nāŒ No user found for this public key`);
295
+ return;
296
+ }
297
+ console.log(`\nāœ… User Found:`);
298
+ console.log("━".repeat(60));
299
+ console.log(` Username: ${userData.username || "Unknown"}`);
300
+ console.log(` Public Key: ${userData.userPub}`);
301
+ console.log(` Encryption Key: ${userData.epub || "Not available"}`);
302
+ console.log("━".repeat(60));
303
+ }
304
+ // ==========================================================================
305
+ // Menu
306
+ // ==========================================================================
307
+ async showMenu() {
308
+ while (this.running) {
309
+ console.log("\nšŸ—”ļø SHIP-00 Identity Manager");
310
+ console.log("━".repeat(60));
311
+ console.log("1. View Current User");
312
+ console.log("2. View Public Keys");
313
+ console.log("3. Export Key Pair (Backup)");
314
+ console.log("4. Login with Key Pair");
315
+ console.log("5. Lookup User by Username");
316
+ console.log("6. Lookup User by Public Key");
317
+ console.log("7. Derive Ethereum Address");
318
+ console.log("8. Publish Public Key");
319
+ console.log("9. Logout");
320
+ console.log("10. Exit");
321
+ console.log("━".repeat(60));
322
+ const choice = await this.prompt("\nChoose option: ");
323
+ switch (choice.trim()) {
324
+ case "1":
325
+ await this.showCurrentUser();
326
+ break;
327
+ case "2":
328
+ await this.showPublicKey();
329
+ break;
330
+ case "3":
331
+ await this.exportKeypair();
332
+ break;
333
+ case "4":
334
+ await this.loginWithKeypair();
335
+ break;
336
+ case "5":
337
+ await this.lookupUser();
338
+ break;
339
+ case "6":
340
+ await this.lookupByPublicKey();
341
+ break;
342
+ case "7":
343
+ await this.deriveAddress();
344
+ break;
345
+ case "8":
346
+ await this.publishPublicKey();
347
+ break;
348
+ case "9":
349
+ await this.logout();
350
+ break;
351
+ case "10":
352
+ this.running = false;
353
+ console.log("\nšŸ‘‹ Goodbye!");
354
+ this.cleanup();
355
+ return;
356
+ default:
357
+ console.log("āŒ Invalid choice");
358
+ }
359
+ }
360
+ }
361
+ async deriveAddress() {
362
+ console.log("\nšŸ”— Derive Ethereum Address");
363
+ console.log("━".repeat(60));
364
+ if (!this.identity.isLoggedIn()) {
365
+ console.log("āŒ Not logged in");
366
+ return;
367
+ }
368
+ const address = await this.identity.deriveEthereumAddress();
369
+ console.log(`\nāœ… Ethereum Address: ${address}`);
370
+ console.log("\nšŸ’” This address is deterministically derived from your SHIP-00 identity");
371
+ console.log("šŸ’” Same identity = same address (always)");
372
+ console.log("━".repeat(60));
373
+ }
374
+ async publishPublicKey() {
375
+ console.log("\nšŸ“¢ Publish Public Key");
376
+ console.log("━".repeat(60));
377
+ if (!this.identity.isLoggedIn()) {
378
+ console.log("āŒ Not logged in");
379
+ return;
380
+ }
381
+ const result = await this.identity.publishPublicKey();
382
+ if (result.success) {
383
+ console.log("āœ… Public key published to Gun network!");
384
+ console.log("šŸ’” Other users can now discover you and send encrypted messages");
385
+ }
386
+ else {
387
+ console.error(`āŒ Error: ${result.error}`);
388
+ }
389
+ console.log("━".repeat(60));
390
+ }
391
+ async logout() {
392
+ console.log("\nšŸ‘‹ Logout");
393
+ console.log("━".repeat(60));
394
+ if (!this.identity.isLoggedIn()) {
395
+ console.log("āŒ Not logged in");
396
+ return;
397
+ }
398
+ this.identity.logout();
399
+ this.username = "";
400
+ console.log("āœ… Logged out successfully");
401
+ console.log("šŸ’” Your data remains on the Gun network");
402
+ console.log("━".repeat(60));
403
+ }
404
+ // ==========================================================================
405
+ // Utilities
406
+ // ==========================================================================
407
+ printHeader() {
408
+ console.log("\nā•”" + "═".repeat(58) + "ā•—");
409
+ console.log("ā•‘" + " ".repeat(12) + "šŸ—”ļø SHOGUN IDENTITY šŸ—”ļø" + " ".repeat(15) + "ā•‘");
410
+ console.log("ā•‘" + " ".repeat(10) + "SHIP-00: Decentralized Identity" + " ".repeat(10) + "ā•‘");
411
+ console.log("ā•š" + "═".repeat(58) + "ā•");
412
+ }
413
+ async prompt(question) {
414
+ return new Promise((resolve) => {
415
+ this.rl.question(question, (answer) => {
416
+ resolve(answer);
417
+ });
418
+ });
419
+ }
420
+ cleanup() {
421
+ this.rl.close();
422
+ process.exit(0);
423
+ }
424
+ async start(username, password) {
425
+ this.printHeader();
426
+ if (username && password) {
427
+ // Auto-login
428
+ const success = await this.login(username, password);
429
+ if (success) {
430
+ this.running = true;
431
+ await this.showMenu();
432
+ }
433
+ else {
434
+ console.log("\nāŒ Authentication failed");
435
+ this.cleanup();
436
+ }
437
+ }
438
+ else {
439
+ // Manual login
440
+ console.log("\nšŸ’” Commands:");
441
+ console.log(" yarn identity <username> <password> - Auto-login");
442
+ console.log(" yarn identity - Manual login");
443
+ const choice = await this.prompt("\n1. Login\n2. Login with Keypair\n3. Exit\n\nChoose option: ");
444
+ switch (choice.trim()) {
445
+ case "1":
446
+ const user = await this.prompt("Username: ");
447
+ const pass = await this.prompt("Password: ");
448
+ const success = await this.login(user, pass);
449
+ if (success) {
450
+ this.running = true;
451
+ await this.showMenu();
452
+ }
453
+ else {
454
+ this.cleanup();
455
+ }
456
+ break;
457
+ case "2":
458
+ await this.loginWithKeypair();
459
+ if (this.identity.isLoggedIn()) {
460
+ this.running = true;
461
+ await this.showMenu();
462
+ }
463
+ else {
464
+ this.cleanup();
465
+ }
466
+ break;
467
+ case "3":
468
+ this.cleanup();
469
+ break;
470
+ default:
471
+ console.log("āŒ Invalid choice");
472
+ this.cleanup();
473
+ }
474
+ }
475
+ }
476
+ }
477
+ exports.IdentityCLI = IdentityCLI;
478
+ // ============================================================================
479
+ // Main Entry Point
480
+ // ============================================================================
481
+ async function main() {
482
+ const args = process.argv.slice(2);
483
+ const cli = new IdentityCLI();
484
+ try {
485
+ if (args.length >= 2) {
486
+ // Auto-login mode
487
+ const [username, password] = args;
488
+ await cli.start(username, password);
489
+ }
490
+ else {
491
+ // Manual login mode
492
+ await cli.start();
493
+ }
494
+ }
495
+ catch (error) {
496
+ console.error("\nāŒ Error:", error);
497
+ process.exit(1);
498
+ }
499
+ }
500
+ // Run if called directly
501
+ if (require.main === module) {
502
+ main();
503
+ }