shogun-core 3.2.2 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/browser/shogun-core.js +108133 -43791
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/ship/examples/messenger-cli.js +173 -60
- package/dist/ship/examples/wallet-cli.js +767 -0
- package/dist/ship/implementation/SHIP_00.js +478 -0
- package/dist/ship/implementation/SHIP_01.js +300 -695
- package/dist/ship/implementation/SHIP_02.js +1366 -0
- package/dist/ship/implementation/SHIP_03.js +855 -0
- package/dist/ship/interfaces/ISHIP_00.js +135 -0
- package/dist/ship/interfaces/ISHIP_01.js +81 -24
- package/dist/ship/interfaces/ISHIP_02.js +57 -0
- package/dist/ship/interfaces/ISHIP_03.js +61 -0
- package/dist/src/gundb/db.js +55 -11
- package/dist/src/index.js +10 -2
- package/dist/src/managers/CoreInitializer.js +41 -13
- package/dist/src/storage/storage.js +22 -9
- package/dist/types/ship/examples/messenger-cli.d.ts +7 -1
- package/dist/types/ship/examples/wallet-cli.d.ts +131 -0
- package/dist/types/ship/implementation/SHIP_00.d.ts +113 -0
- package/dist/types/ship/implementation/SHIP_01.d.ts +47 -76
- package/dist/types/ship/implementation/SHIP_02.d.ts +297 -0
- package/dist/types/ship/implementation/SHIP_03.d.ts +127 -0
- package/dist/types/ship/interfaces/ISHIP_00.d.ts +410 -0
- package/dist/types/ship/interfaces/ISHIP_01.d.ts +157 -119
- package/dist/types/ship/interfaces/ISHIP_02.d.ts +470 -0
- package/dist/types/ship/interfaces/ISHIP_03.d.ts +295 -0
- package/dist/types/src/gundb/db.d.ts +10 -3
- package/dist/types/src/index.d.ts +7 -0
- package/dist/types/src/interfaces/shogun.d.ts +2 -0
- package/dist/types/src/storage/storage.d.ts +2 -1
- package/package.json +23 -9
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SHIP-00: Decentralized Identity & Authentication Interface
|
|
3
|
+
*
|
|
4
|
+
* @title ISHIP_00 - Identity Foundation
|
|
5
|
+
* @notice Base interface for decentralized identity in Shogun ecosystem
|
|
6
|
+
*
|
|
7
|
+
* ## Abstract
|
|
8
|
+
*
|
|
9
|
+
* This standard defines the foundational interface for identity that enables:
|
|
10
|
+
* - Username/password authentication with deterministic key generation
|
|
11
|
+
* - SEA key pair management (export, import, backup)
|
|
12
|
+
* - Public key publication and discovery on GunDB
|
|
13
|
+
* - User registry and lookup system
|
|
14
|
+
* - Blockchain address derivation (Ethereum, Bitcoin, etc.)
|
|
15
|
+
*
|
|
16
|
+
* ## Specification
|
|
17
|
+
*
|
|
18
|
+
* Based on:
|
|
19
|
+
* - GunDB for P2P identity storage
|
|
20
|
+
* - SEA (Security, Encryption, Authorization) for key management
|
|
21
|
+
* - Shogun Core DataBase API for authentication
|
|
22
|
+
* - BIP32-like derivation for blockchain addresses
|
|
23
|
+
*
|
|
24
|
+
* ## Usage
|
|
25
|
+
*
|
|
26
|
+
* SHIP-00 serves as the foundation for all other SHIPs:
|
|
27
|
+
* - SHIP-01 (Messaging) depends on SHIP-00 for identity
|
|
28
|
+
* - SHIP-02 (Address Derivation) extends SHIP-00
|
|
29
|
+
* - SHIP-03 (Multi-Modal Auth) extends SHIP-00
|
|
30
|
+
* - SHIP-04 (File Storage) uses SHIP-00 for ACL
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* @notice Authentication result
|
|
34
|
+
*/
|
|
35
|
+
export interface AuthResult {
|
|
36
|
+
success: boolean;
|
|
37
|
+
userPub?: string;
|
|
38
|
+
username?: string;
|
|
39
|
+
derivedAddress?: string;
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @notice Signup result
|
|
44
|
+
*/
|
|
45
|
+
export interface SignupResult {
|
|
46
|
+
success: boolean;
|
|
47
|
+
userPub?: string;
|
|
48
|
+
username?: string;
|
|
49
|
+
derivedAddress?: string;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @notice SEA key pair structure
|
|
54
|
+
* Complete keypair for authentication and encryption
|
|
55
|
+
*/
|
|
56
|
+
export interface SEAPair {
|
|
57
|
+
pub: string;
|
|
58
|
+
priv: string;
|
|
59
|
+
epub: string;
|
|
60
|
+
epriv: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* @notice User identity information
|
|
64
|
+
* Current authenticated user data
|
|
65
|
+
*/
|
|
66
|
+
export interface UserIdentity {
|
|
67
|
+
pub: string;
|
|
68
|
+
alias?: string;
|
|
69
|
+
epub?: string;
|
|
70
|
+
derivedAddress?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* @notice User data from registry
|
|
74
|
+
* Information about registered users
|
|
75
|
+
*/
|
|
76
|
+
export interface UserData {
|
|
77
|
+
userPub: string;
|
|
78
|
+
username?: string;
|
|
79
|
+
epub?: string;
|
|
80
|
+
registeredAt?: number;
|
|
81
|
+
lastSeen?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* @notice Public key data
|
|
85
|
+
* User's public keys for encryption
|
|
86
|
+
*/
|
|
87
|
+
export interface PublicKeyData {
|
|
88
|
+
pub: string;
|
|
89
|
+
epub: string;
|
|
90
|
+
algorithm?: string;
|
|
91
|
+
timestamp?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* @notice Operation result
|
|
95
|
+
*/
|
|
96
|
+
export interface OperationResult {
|
|
97
|
+
success: boolean;
|
|
98
|
+
error?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @title ISHIP_00 - Decentralized Identity
|
|
102
|
+
* @notice Main interface for identity and authentication system
|
|
103
|
+
* @dev This is the foundation interface that other SHIPs depend on
|
|
104
|
+
*/
|
|
105
|
+
export interface ISHIP_00 {
|
|
106
|
+
/**
|
|
107
|
+
* @notice Register a new user
|
|
108
|
+
* @dev Creates new SEA keypair deterministically from credentials
|
|
109
|
+
* @param username Desired username (must be unique)
|
|
110
|
+
* @param password Password for key derivation
|
|
111
|
+
* @return Result with userPub and derivedAddress
|
|
112
|
+
*
|
|
113
|
+
* Process:
|
|
114
|
+
* 1. Validate username uniqueness
|
|
115
|
+
* 2. Generate SEA keypair via PBKDF2
|
|
116
|
+
* 3. Store user in GunDB registry
|
|
117
|
+
* 4. Return user public key
|
|
118
|
+
*/
|
|
119
|
+
signup(username: string, password: string): Promise<SignupResult>;
|
|
120
|
+
/**
|
|
121
|
+
* @notice Login with username and password
|
|
122
|
+
* @dev Derives SEA keypair from credentials
|
|
123
|
+
* @param username Username
|
|
124
|
+
* @param password Password
|
|
125
|
+
* @return Result with userPub and derivedAddress
|
|
126
|
+
*
|
|
127
|
+
* Process:
|
|
128
|
+
* 1. Derive SEA keypair from credentials
|
|
129
|
+
* 2. Authenticate with GunDB
|
|
130
|
+
* 3. Restore session
|
|
131
|
+
* 4. Return authentication result
|
|
132
|
+
*/
|
|
133
|
+
login(username: string, password: string): Promise<AuthResult>;
|
|
134
|
+
/**
|
|
135
|
+
* @notice Login with exported SEA key pair
|
|
136
|
+
* @dev Direct authentication using exported keypair
|
|
137
|
+
* @param seaPair Exported SEA key pair (contains pub, priv, epub, epriv)
|
|
138
|
+
* @return Result with userPub and derivedAddress
|
|
139
|
+
*
|
|
140
|
+
* Use cases:
|
|
141
|
+
* - Account recovery without password
|
|
142
|
+
* - Multi-device identity sync
|
|
143
|
+
* - Identity backup/restore
|
|
144
|
+
*
|
|
145
|
+
* Security: SEA pair must be kept secure (contains private keys)
|
|
146
|
+
*/
|
|
147
|
+
loginWithPair(seaPair: SEAPair): Promise<AuthResult>;
|
|
148
|
+
/**
|
|
149
|
+
* @notice Logout current user
|
|
150
|
+
* @dev Clears session but keeps data on GunDB
|
|
151
|
+
*/
|
|
152
|
+
logout(): void;
|
|
153
|
+
/**
|
|
154
|
+
* @notice Check if user is authenticated
|
|
155
|
+
* @return True if user has active session
|
|
156
|
+
*/
|
|
157
|
+
isLoggedIn(): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* @notice Get underlying ShogunCore instance
|
|
160
|
+
* @dev Provides access to Gun, SEA, and crypto utilities
|
|
161
|
+
* @return ShogunCore instance
|
|
162
|
+
*
|
|
163
|
+
* Use cases:
|
|
164
|
+
* - Access Gun database directly
|
|
165
|
+
* - Use SEA encryption utilities
|
|
166
|
+
* - Use crypto helpers (hash, encrypt, etc.)
|
|
167
|
+
*
|
|
168
|
+
* Note: This is used by other SHIP implementations (SHIP-01, SHIP-06, etc.)
|
|
169
|
+
*/
|
|
170
|
+
getShogun(): any;
|
|
171
|
+
/**
|
|
172
|
+
* @notice Publish public key on GunDB
|
|
173
|
+
* @dev Makes user's public key discoverable by others
|
|
174
|
+
* @return Operation result
|
|
175
|
+
*
|
|
176
|
+
* Published data includes:
|
|
177
|
+
* - pub: Public signing key
|
|
178
|
+
* - epub: Encryption public key
|
|
179
|
+
* - algorithm: ECDSA
|
|
180
|
+
* - timestamp: Publication time
|
|
181
|
+
*/
|
|
182
|
+
publishPublicKey(): Promise<OperationResult>;
|
|
183
|
+
/**
|
|
184
|
+
* @notice Export current user's SEA key pair
|
|
185
|
+
* @dev For backup and multi-device usage
|
|
186
|
+
* @return SEA key pair or null if not logged in
|
|
187
|
+
*
|
|
188
|
+
* Security warnings:
|
|
189
|
+
* - Contains private keys in plain text
|
|
190
|
+
* - Must be stored securely
|
|
191
|
+
* - Consider additional encryption layer
|
|
192
|
+
* - Never share or expose backups
|
|
193
|
+
*/
|
|
194
|
+
exportKeyPair(): SEAPair | null;
|
|
195
|
+
/**
|
|
196
|
+
* @notice Get current user's key pair
|
|
197
|
+
* @return SEA pair or null if not logged in
|
|
198
|
+
*/
|
|
199
|
+
getKeyPair(): SEAPair | null;
|
|
200
|
+
/**
|
|
201
|
+
* @notice Get user information by username
|
|
202
|
+
* @dev Looks up user in GunDB registry
|
|
203
|
+
* @param username Username to look up
|
|
204
|
+
* @return User data or null if not found
|
|
205
|
+
*
|
|
206
|
+
* Returned data includes:
|
|
207
|
+
* - userPub: User's public key
|
|
208
|
+
* - username: Username/alias
|
|
209
|
+
* - epub: Encryption public key
|
|
210
|
+
* - registeredAt: Registration timestamp
|
|
211
|
+
* - lastSeen: Last activity timestamp
|
|
212
|
+
*/
|
|
213
|
+
getUserByAlias(username: string): Promise<UserData | null>;
|
|
214
|
+
/**
|
|
215
|
+
* @notice Get user information by public key
|
|
216
|
+
* @param userPub User's public key
|
|
217
|
+
* @return User data or null if not found
|
|
218
|
+
*/
|
|
219
|
+
getUserByPub(userPub: string): Promise<UserData | null>;
|
|
220
|
+
/**
|
|
221
|
+
* @notice Check if user exists in registry
|
|
222
|
+
* @param username Username to check
|
|
223
|
+
* @return True if user exists
|
|
224
|
+
*/
|
|
225
|
+
userExists(username: string): Promise<boolean>;
|
|
226
|
+
/**
|
|
227
|
+
* @notice Get public key by username
|
|
228
|
+
* @dev Returns both signing and encryption keys
|
|
229
|
+
* @param username Username
|
|
230
|
+
* @return Public keys or null if not found
|
|
231
|
+
*/
|
|
232
|
+
getPublicKey(username: string): Promise<PublicKeyData | null>;
|
|
233
|
+
/**
|
|
234
|
+
* @notice Get current authenticated user info
|
|
235
|
+
* @return Current user identity or null if not logged in
|
|
236
|
+
*
|
|
237
|
+
* Returned data includes:
|
|
238
|
+
* - pub: Public key
|
|
239
|
+
* - alias: Username
|
|
240
|
+
* - epub: Encryption public key
|
|
241
|
+
* - derivedAddress: Ethereum address (if derived)
|
|
242
|
+
*/
|
|
243
|
+
getCurrentUser(): UserIdentity | null;
|
|
244
|
+
/**
|
|
245
|
+
* @notice Derive Ethereum address from SEA keypair
|
|
246
|
+
* @dev Uses deterministic derivation for consistent results
|
|
247
|
+
* @param publicKey Optional public key (uses current user if not provided)
|
|
248
|
+
* @return Ethereum address (0x...)
|
|
249
|
+
*
|
|
250
|
+
* Process:
|
|
251
|
+
* 1. Get SEA private key
|
|
252
|
+
* 2. Use derive function with secp256k1Ethereum
|
|
253
|
+
* 3. Return address with EIP-55 checksum
|
|
254
|
+
*
|
|
255
|
+
* Properties:
|
|
256
|
+
* - Deterministic: Same keypair → same address
|
|
257
|
+
* - Secure: Uses proven cryptographic derivation
|
|
258
|
+
* - Compatible: Standard Ethereum address format
|
|
259
|
+
*/
|
|
260
|
+
deriveEthereumAddress(publicKey?: string): Promise<string>;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* @notice Identity system configuration
|
|
264
|
+
*/
|
|
265
|
+
export interface IdentityConfig {
|
|
266
|
+
/**
|
|
267
|
+
* @notice GunDB peers for P2P network
|
|
268
|
+
*/
|
|
269
|
+
peers: string[];
|
|
270
|
+
/**
|
|
271
|
+
* @notice Application scope/namespace
|
|
272
|
+
*/
|
|
273
|
+
scope?: string;
|
|
274
|
+
/**
|
|
275
|
+
* @notice Operation timeout (ms)
|
|
276
|
+
*/
|
|
277
|
+
timeout?: number;
|
|
278
|
+
/**
|
|
279
|
+
* @notice Enable debug logging
|
|
280
|
+
*/
|
|
281
|
+
debug?: boolean;
|
|
282
|
+
/**
|
|
283
|
+
* @notice Enable local storage
|
|
284
|
+
*/
|
|
285
|
+
localStorage?: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* @notice Enable radisk (persistent storage)
|
|
288
|
+
*/
|
|
289
|
+
radisk?: boolean;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* @notice Key derivation options
|
|
293
|
+
*/
|
|
294
|
+
export interface DerivationOptions {
|
|
295
|
+
/**
|
|
296
|
+
* @notice Include Ethereum address derivation
|
|
297
|
+
*/
|
|
298
|
+
includeEthereum?: boolean;
|
|
299
|
+
/**
|
|
300
|
+
* @notice Include Bitcoin address derivation
|
|
301
|
+
*/
|
|
302
|
+
includeBitcoin?: boolean;
|
|
303
|
+
/**
|
|
304
|
+
* @notice Include Solana address derivation
|
|
305
|
+
*/
|
|
306
|
+
includeSolana?: boolean;
|
|
307
|
+
/**
|
|
308
|
+
* @notice Custom derivation path
|
|
309
|
+
*/
|
|
310
|
+
customPath?: string;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Example of how to implement ISHIP_00
|
|
314
|
+
*
|
|
315
|
+
* ```typescript
|
|
316
|
+
* import { ShogunCore } from 'shogun-core';
|
|
317
|
+
* import { ISHIP_00, SEAPair, AuthResult, SignupResult } from './interfaces/ISHIP_00';
|
|
318
|
+
*
|
|
319
|
+
* class IdentityManager implements ISHIP_00 {
|
|
320
|
+
* private shogun: ShogunCore;
|
|
321
|
+
*
|
|
322
|
+
* constructor(config: IdentityConfig) {
|
|
323
|
+
* this.shogun = new ShogunCore({
|
|
324
|
+
* gunOptions: {
|
|
325
|
+
* peers: config.peers,
|
|
326
|
+
* radisk: config.radisk,
|
|
327
|
+
* localStorage: config.localStorage
|
|
328
|
+
* },
|
|
329
|
+
* scope: config.scope
|
|
330
|
+
* });
|
|
331
|
+
* }
|
|
332
|
+
*
|
|
333
|
+
* async signup(username: string, password: string): Promise<SignupResult> {
|
|
334
|
+
* // Use Shogun Core signUp method
|
|
335
|
+
* const result = await this.shogun.signUp(username, password);
|
|
336
|
+
*
|
|
337
|
+
* if (result.success) {
|
|
338
|
+
* // Publish public key
|
|
339
|
+
* await this.publishPublicKey();
|
|
340
|
+
*
|
|
341
|
+
* // Derive Ethereum address
|
|
342
|
+
* const derivedAddress = await this.deriveEthereumAddress(result.userPub);
|
|
343
|
+
*
|
|
344
|
+
* return {
|
|
345
|
+
* success: true,
|
|
346
|
+
* userPub: result.userPub,
|
|
347
|
+
* username: username,
|
|
348
|
+
* derivedAddress: derivedAddress
|
|
349
|
+
* };
|
|
350
|
+
* }
|
|
351
|
+
*
|
|
352
|
+
* return {
|
|
353
|
+
* success: false,
|
|
354
|
+
* error: result.error || 'Signup failed'
|
|
355
|
+
* };
|
|
356
|
+
* }
|
|
357
|
+
*
|
|
358
|
+
* async login(username: string, password: string): Promise<AuthResult> {
|
|
359
|
+
* // Use Shogun Core login method
|
|
360
|
+
* const result = await this.shogun.login(username, password);
|
|
361
|
+
*
|
|
362
|
+
* if (result.success) {
|
|
363
|
+
* const derivedAddress = await this.deriveEthereumAddress(result.userPub);
|
|
364
|
+
*
|
|
365
|
+
* return {
|
|
366
|
+
* success: true,
|
|
367
|
+
* userPub: result.userPub,
|
|
368
|
+
* username: username,
|
|
369
|
+
* derivedAddress: derivedAddress
|
|
370
|
+
* };
|
|
371
|
+
* }
|
|
372
|
+
*
|
|
373
|
+
* return {
|
|
374
|
+
* success: false,
|
|
375
|
+
* error: result.error || 'Login failed'
|
|
376
|
+
* };
|
|
377
|
+
* }
|
|
378
|
+
*
|
|
379
|
+
* exportKeyPair(): SEAPair | null {
|
|
380
|
+
* if (!this.isLoggedIn()) return null;
|
|
381
|
+
*
|
|
382
|
+
* const seaPair = (this.shogun.db.gun.user() as any)?._?.sea;
|
|
383
|
+
* if (!seaPair) return null;
|
|
384
|
+
*
|
|
385
|
+
* return {
|
|
386
|
+
* pub: seaPair.pub,
|
|
387
|
+
* priv: seaPair.priv,
|
|
388
|
+
* epub: seaPair.epub,
|
|
389
|
+
* epriv: seaPair.epriv
|
|
390
|
+
* };
|
|
391
|
+
* }
|
|
392
|
+
*
|
|
393
|
+
* async getUserByAlias(username: string): Promise<UserData | null> {
|
|
394
|
+
* // Use Shogun Core getUserByAlias method
|
|
395
|
+
* return await this.shogun.db.getUserByAlias(username);
|
|
396
|
+
* }
|
|
397
|
+
*
|
|
398
|
+
* async deriveEthereumAddress(publicKey?: string): Promise<string> {
|
|
399
|
+
* // Use shogun-derive package
|
|
400
|
+
* const derived = await derive(seaPair.priv, null, {
|
|
401
|
+
* includeSecp256k1Ethereum: true
|
|
402
|
+
* });
|
|
403
|
+
*
|
|
404
|
+
* return derived.secp256k1Ethereum.address;
|
|
405
|
+
* }
|
|
406
|
+
*
|
|
407
|
+
* // ... implement other methods
|
|
408
|
+
* }
|
|
409
|
+
* ```
|
|
410
|
+
*/
|