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.
- package/dist/browser/shogun-core.js +83301 -148719
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/ship/examples/ephemeral-cli.js +234 -0
- package/dist/ship/examples/identity-cli.js +503 -0
- package/dist/ship/examples/stealth-cli.js +433 -0
- package/dist/ship/examples/storage-cli.js +615 -0
- package/dist/ship/examples/vault-cli.js +444 -0
- package/dist/ship/implementation/SHIP_04.js +589 -0
- package/dist/ship/implementation/SHIP_05.js +1064 -0
- package/dist/ship/implementation/SHIP_06.js +350 -0
- package/dist/ship/implementation/SHIP_07.js +635 -0
- package/dist/ship/index.js +17 -0
- package/dist/ship/interfaces/ISHIP_04.js +62 -0
- package/dist/ship/interfaces/ISHIP_05.js +59 -0
- package/dist/ship/interfaces/ISHIP_06.js +144 -0
- package/dist/ship/interfaces/ISHIP_07.js +194 -0
- package/dist/src/index.js +1 -15
- package/dist/types/ship/examples/ephemeral-cli.d.ts +13 -0
- package/dist/types/ship/examples/identity-cli.d.ts +40 -0
- package/dist/types/ship/examples/stealth-cli.d.ts +31 -0
- package/dist/types/ship/examples/storage-cli.d.ts +48 -0
- package/dist/types/ship/examples/vault-cli.d.ts +13 -0
- package/dist/types/ship/implementation/SHIP_04.d.ts +76 -0
- package/dist/types/ship/implementation/SHIP_05.d.ts +70 -0
- package/dist/types/ship/implementation/SHIP_06.d.ts +66 -0
- package/dist/types/ship/implementation/SHIP_07.d.ts +101 -0
- package/dist/types/ship/index.d.ts +14 -0
- package/dist/types/ship/interfaces/ISHIP_04.d.ts +245 -0
- package/dist/types/ship/interfaces/ISHIP_05.d.ts +234 -0
- package/dist/types/ship/interfaces/ISHIP_06.d.ts +370 -0
- package/dist/types/ship/interfaces/ISHIP_07.d.ts +522 -0
- package/dist/types/src/index.d.ts +0 -10
- package/dist/types/src/types/shogun.d.ts +2 -0
- package/package.json +1 -1
- package/dist/browser/_e6ae.shogun-core.js +0 -14
- 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
|
+
}
|