shogun-core 5.2.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +123 -20
  2. package/dist/browser/shogun-core.js +1134 -493
  3. package/dist/browser/shogun-core.js.map +1 -1
  4. package/dist/config/simplified-config.js +108 -40
  5. package/dist/crypto/mls.js +34 -15
  6. package/dist/crypto/sframe.js +13 -11
  7. package/dist/examples/auth-test.js +263 -59
  8. package/dist/examples/crypto-identity-example.js +55 -21
  9. package/dist/examples/mls-3-member-test.js +97 -0
  10. package/dist/examples/mls-multi-member.js +153 -0
  11. package/dist/examples/mls-sframe-test.js +14 -11
  12. package/dist/examples/mls-simple-test.js +58 -0
  13. package/dist/examples/shogun-core-example.js +90 -0
  14. package/dist/examples/zkproof-credentials-example.js +9 -5
  15. package/dist/examples/zkproof-example.js +14 -10
  16. package/dist/gundb/api.js +17 -16
  17. package/dist/gundb/db.js +769 -328
  18. package/dist/index.js +4 -4
  19. package/dist/managers/CoreInitializer.js +21 -15
  20. package/dist/managers/CryptoIdentityManager.js +79 -32
  21. package/dist/plugins/zkproof/zkCredentials.js +4 -1
  22. package/dist/types/config/simplified-config.d.ts +64 -3
  23. package/dist/types/crypto/sframe.d.ts +4 -0
  24. package/dist/types/examples/mls-3-member-test.d.ts +6 -0
  25. package/dist/types/examples/mls-multi-member.d.ts +6 -0
  26. package/dist/types/examples/mls-simple-test.d.ts +6 -0
  27. package/dist/types/examples/shogun-core-example.d.ts +8 -0
  28. package/dist/types/gundb/api.d.ts +6 -13
  29. package/dist/types/gundb/db.d.ts +84 -41
  30. package/dist/types/index.d.ts +4 -2
  31. package/dist/types/interfaces/shogun.d.ts +1 -2
  32. package/dist/types/managers/CryptoIdentityManager.d.ts +2 -1
  33. package/package.json +11 -8
  34. package/dist/examples/mls-advanced-example.js +0 -294
  35. package/dist/examples/quick-auth-test.js +0 -61
  36. package/dist/examples/simple-api-test.js +0 -114
  37. package/dist/examples/simple-crypto-identity-example.js +0 -84
  38. package/dist/examples/timeout-test.js +0 -227
  39. package/dist/types/examples/mls-advanced-example.d.ts +0 -53
  40. package/dist/types/examples/quick-auth-test.d.ts +0 -8
  41. package/dist/types/examples/simple-api-test.d.ts +0 -10
  42. package/dist/types/examples/simple-crypto-identity-example.d.ts +0 -6
  43. package/dist/types/examples/timeout-test.d.ts +0 -8
package/dist/index.js CHANGED
@@ -34,10 +34,10 @@ Object.defineProperty(exports, "quickStart", { enumerable: true, get: function (
34
34
  Object.defineProperty(exports, "createSimpleAPI", { enumerable: true, get: function () { return gundb_1.createSimpleAPI; } });
35
35
  Object.defineProperty(exports, "AutoQuickStart", { enumerable: true, get: function () { return gundb_1.AutoQuickStart; } });
36
36
  Object.defineProperty(exports, "autoQuickStart", { enumerable: true, get: function () { return gundb_1.autoQuickStart; } });
37
- const db_2 = require("./gundb/db");
38
- Object.defineProperty(exports, "SEA", { enumerable: true, get: function () { return db_2.SEA; } });
39
- const db_3 = __importDefault(require("./gundb/db"));
40
- exports.Gun = db_3.default;
37
+ const gun_1 = __importDefault(require("gun"));
38
+ exports.Gun = gun_1.default;
39
+ const sea_1 = __importDefault(require("gun/sea"));
40
+ exports.SEA = sea_1.default;
41
41
  __exportStar(require("./utils/errorHandler"), exports);
42
42
  __exportStar(require("./plugins"), exports);
43
43
  __exportStar(require("./interfaces/shogun"), exports);
@@ -61,37 +61,43 @@ class CoreInitializer {
61
61
  /**
62
62
  * Initialize Gun instance
63
63
  */
64
- // Sì, è corretto.
65
64
  initializeGun(config) {
66
65
  try {
67
- if (config.gunInstance) {
68
- console.log("Using existing Gun instance:", config.gunInstance);
69
- this.core._gun = config.gunInstance;
66
+ if (!config.gunInstance) {
67
+ throw new Error("Gun instance is required but was not provided");
70
68
  }
71
- else if (config.gunOptions && config.gunInstance === undefined) {
72
- console.log("Creating Gun instance with config:", config.gunOptions);
73
- this.core._gun = (0, gundb_1.createGun)(config.gunOptions);
69
+ // Validate Gun instance
70
+ if (typeof config.gunInstance !== "object") {
71
+ throw new Error(`Gun instance must be an object, received: ${typeof config.gunInstance}`);
74
72
  }
75
- else if (config.gunInstance && config.gunOptions) {
76
- throw new Error("Gun instance and gun options cannot be provided together");
77
- return false;
73
+ if (typeof config.gunInstance.user !== "function") {
74
+ throw new Error(`Gun instance is invalid: gun.user is not a function. Received gun.user type: ${typeof config.gunInstance.user}`);
78
75
  }
76
+ if (typeof config.gunInstance.get !== "function") {
77
+ throw new Error(`Gun instance is invalid: gun.get is not a function. Received gun.get type: ${typeof config.gunInstance.get}`);
78
+ }
79
+ if (typeof config.gunInstance.on !== "function") {
80
+ throw new Error(`Gun instance is invalid: gun.on is not a function. Received gun.on type: ${typeof config.gunInstance.on}`);
81
+ }
82
+ console.log("Using provided Gun instance:", config.gunInstance);
83
+ this.core._gun = config.gunInstance;
79
84
  }
80
85
  catch (error) {
81
86
  if (typeof console !== "undefined" && console.error) {
82
- console.error("Error creating Gun instance:", error);
87
+ console.error("Error validating Gun instance:", error);
83
88
  }
84
- return false;
89
+ throw new Error(`Failed to validate Gun instance: ${error}`);
85
90
  }
86
91
  try {
87
- this.core.db = new gundb_1.DataBase(this.core._gun, config.gunOptions?.scope || "", this.core);
92
+ this.core.db = new gundb_1.DataBase(this.core._gun, "shogun", // Default app scope
93
+ this.core);
88
94
  return true;
89
95
  }
90
96
  catch (error) {
91
97
  if (typeof console !== "undefined" && console.error) {
92
- console.error("Error initializing GunInstance:", error);
98
+ console.error("Error initializing DataBase:", error);
93
99
  }
94
- throw new Error(`Failed to initialize GunInstance: ${error}`);
100
+ throw new Error(`Failed to initialize DataBase: ${error}`);
95
101
  }
96
102
  }
97
103
  /**
@@ -21,8 +21,9 @@ const errorHandler_1 = require("../utils/errorHandler");
21
21
  * Genera automaticamente tutte le identità crypto disponibili dopo l'autenticazione SEA
22
22
  */
23
23
  class CryptoIdentityManager {
24
- constructor(core) {
24
+ constructor(core, db) {
25
25
  this.core = core;
26
+ this.db = db || core.db; // Use core.db if db not provided
26
27
  this.pgpManager = new pgp_1.PGPManager();
27
28
  this.mlsManager = new mls_1.MLSManager("default-user");
28
29
  this.sframeManager = new sframe_1.SFrameManager();
@@ -109,6 +110,11 @@ class CryptoIdentityManager {
109
110
  console.error(`❌ [${username}] SFrame key generation failed:`, error);
110
111
  }
111
112
  console.log(`✅ [CryptoIdentityManager] All crypto identities generated for: ${username}`);
113
+ // Force garbage collection after generation
114
+ if (typeof global !== "undefined" && global.gc) {
115
+ global.gc();
116
+ console.log(`🧹 [${username}] Forced garbage collection after identity generation`);
117
+ }
112
118
  return {
113
119
  success: true,
114
120
  identities,
@@ -144,41 +150,76 @@ class CryptoIdentityManager {
144
150
  }
145
151
  // Salva su GunDB nel percorso privato dell'utente
146
152
  const saveResult = await new Promise((resolve, reject) => {
147
- this.core.gun
148
- .user()
149
- .get("crypto-identities")
150
- .put(encryptedIdentities, (ack) => {
151
- if (ack.err) {
152
- console.error(`❌ [${username}] Failed to save identities:`, ack.err);
153
- reject(new Error(ack.err));
154
- }
155
- else {
156
- console.log(`✅ [${username}] Crypto identities saved successfully`);
157
- savedKeys.push("crypto-identities");
158
- resolve(true);
159
- }
160
- });
153
+ const timeout = setTimeout(() => {
154
+ console.warn(`⚠️ [${username}] Save identities timeout after 5 seconds, continuing anyway`);
155
+ savedKeys.push("crypto-identities");
156
+ resolve(true); // Resolve anyway to not block the process
157
+ }, 5000); // 5 second timeout
158
+ try {
159
+ this.db.gun
160
+ .user()
161
+ .get("crypto-identities")
162
+ .put(encryptedIdentities, (ack) => {
163
+ clearTimeout(timeout);
164
+ if (ack && ack.err) {
165
+ console.error(`❌ [${username}] Failed to save identities:`, ack.err);
166
+ reject(new Error(ack.err));
167
+ }
168
+ else {
169
+ console.log(`✅ [${username}] Crypto identities saved successfully`);
170
+ savedKeys.push("crypto-identities");
171
+ resolve(true);
172
+ }
173
+ });
174
+ }
175
+ catch (putError) {
176
+ clearTimeout(timeout);
177
+ console.error(`❌ [${username}] Error during put operation:`, putError);
178
+ // Don't reject, just resolve to not block - Gun might save eventually
179
+ savedKeys.push("crypto-identities");
180
+ resolve(true);
181
+ }
161
182
  });
162
183
  // Salva anche una copia di backup nel percorso pubblico (solo hash per verifica)
163
184
  const identitiesHash = await sea_1.default.work(identitiesJson, null, null, {
164
185
  name: "SHA-256",
165
186
  });
166
187
  await new Promise((resolve, reject) => {
167
- this.core.gun
168
- .user()
169
- .get("crypto-identities-hash")
170
- .put(identitiesHash, (ack) => {
171
- if (ack.err) {
172
- console.error(`❌ [${username}] Failed to save identities hash:`, ack.err);
173
- reject(new Error(ack.err));
174
- }
175
- else {
176
- console.log(`✅ [${username}] Crypto identities hash saved`);
177
- savedKeys.push("crypto-identities-hash");
178
- resolve(true);
179
- }
180
- });
188
+ const timeout = setTimeout(() => {
189
+ console.warn(`⚠️ [${username}] Save identities hash timeout after 5 seconds, continuing anyway`);
190
+ savedKeys.push("crypto-identities-hash");
191
+ resolve(true); // Resolve anyway to not block the process
192
+ }, 5000); // 5 second timeout
193
+ try {
194
+ this.db.gun
195
+ .user()
196
+ .get("crypto-identities-hash")
197
+ .put(identitiesHash, (ack) => {
198
+ clearTimeout(timeout);
199
+ if (ack && ack.err) {
200
+ console.error(`❌ [${username}] Failed to save identities hash:`, ack.err);
201
+ reject(new Error(ack.err));
202
+ }
203
+ else {
204
+ console.log(`✅ [${username}] Crypto identities hash saved`);
205
+ savedKeys.push("crypto-identities-hash");
206
+ resolve(true);
207
+ }
208
+ });
209
+ }
210
+ catch (putError) {
211
+ clearTimeout(timeout);
212
+ console.error(`❌ [${username}] Error during hash put operation:`, putError);
213
+ // Don't reject, just resolve to not block - Gun might save eventually
214
+ savedKeys.push("crypto-identities-hash");
215
+ resolve(true);
216
+ }
181
217
  });
218
+ // Force garbage collection after saving
219
+ if (typeof global !== "undefined" && global.gc) {
220
+ global.gc();
221
+ console.log(`🧹 [${username}] Forced garbage collection after saving identities`);
222
+ }
182
223
  return {
183
224
  success: true,
184
225
  savedKeys,
@@ -205,7 +246,7 @@ class CryptoIdentityManager {
205
246
  console.log(`🔍 [CryptoIdentityManager] Retrieving crypto identities for: ${username}`);
206
247
  // Recupera le identità criptate da GunDB
207
248
  const encryptedIdentities = await new Promise((resolve, reject) => {
208
- this.core.gun
249
+ this.db.gun
209
250
  .user()
210
251
  .get("crypto-identities")
211
252
  .once((data) => {
@@ -257,7 +298,7 @@ class CryptoIdentityManager {
257
298
  async hasStoredIdentities(username) {
258
299
  try {
259
300
  const hasIdentities = await new Promise((resolve) => {
260
- this.core.gun
301
+ this.db.gun
261
302
  .user()
262
303
  .get("crypto-identities")
263
304
  .once((data) => {
@@ -344,7 +385,13 @@ class CryptoIdentityManager {
344
385
  };
345
386
  }
346
387
  // Ottieni il SEA pair dell'utente corrente
347
- const userInstance = this.core.gun.user();
388
+ if (!this.db || !this.db.gun) {
389
+ return {
390
+ success: false,
391
+ error: "Database not available",
392
+ };
393
+ }
394
+ const userInstance = this.db.gun.user();
348
395
  const seaPair = userInstance?._?.sea;
349
396
  if (!seaPair) {
350
397
  return {
@@ -78,7 +78,10 @@ class ZkCredentials {
78
78
  const externalNullifier = BigInt(ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(credentialData.type)));
79
79
  // Generate ZK proof
80
80
  // Note: This requires circuit files to be available
81
- const fullProof = await (0, proof_1.generateProof)(identity, group, signalBigInt, externalNullifier);
81
+ const fullProof = await (0, proof_1.generateProof)(identity, group, signalBigInt, externalNullifier, {
82
+ wasmFilePath: "./circuits/semaphore/20/semaphore.wasm",
83
+ zkeyFilePath: "./circuits/semaphore/20/semaphore.zkey",
84
+ });
82
85
  return {
83
86
  type: credentialData.type,
84
87
  claim: credentialData.claim,
@@ -1,48 +1,98 @@
1
1
  /**
2
2
  * Simplified configuration options to reduce complexity
3
3
  * Provides sensible defaults and easy-to-use presets
4
+ *
5
+ * NOTE: This file is deprecated. ShogunCore now requires an existing Gun instance.
6
+ * Use the examples in the examples/ directory for proper usage.
4
7
  */
5
8
  import { ShogunCoreConfig } from "../interfaces/shogun";
9
+ import "gun/lib/then";
10
+ import "gun/lib/radix";
11
+ import "gun/lib/radisk";
12
+ import "gun/lib/store";
13
+ import "gun/lib/rindexed";
14
+ import "gun/lib/webrtc";
15
+ /**
16
+ * Helper functions to create Gun instances with common configurations
17
+ * These functions create Gun instances that can be passed to ShogunCore
18
+ */
19
+ export declare const GunInstanceHelpers: {
20
+ /**
21
+ * Create a minimal Gun instance for simple apps
22
+ */
23
+ minimal: () => import("gun").IGunInstance<any>;
24
+ /**
25
+ * Create a development Gun instance with local storage
26
+ */
27
+ development: () => import("gun").IGunInstance<any>;
28
+ /**
29
+ * Create a production Gun instance with multiple peers
30
+ */
31
+ production: (customPeers?: string[]) => import("gun").IGunInstance<any>;
32
+ /**
33
+ * Create an offline-first Gun instance
34
+ */
35
+ offline: () => import("gun").IGunInstance<any>;
36
+ /**
37
+ * Create a Gun instance for Web3-enabled apps
38
+ */
39
+ web3: () => import("gun").IGunInstance<any>;
40
+ /**
41
+ * Create a Gun instance for WebAuthn-enabled apps
42
+ */
43
+ webauthn: () => import("gun").IGunInstance<any>;
44
+ };
6
45
  /**
7
46
  * Preset configurations for common use cases
47
+ * @deprecated Use GunInstanceHelpers to create Gun instances and pass them to ShogunCore
8
48
  */
9
49
  export declare const ShogunPresets: {
10
50
  /**
11
51
  * Minimal configuration for simple apps
52
+ * @deprecated Use GunInstanceHelpers.minimal() instead
12
53
  */
13
54
  minimal: () => ShogunCoreConfig;
14
55
  /**
15
56
  * Development configuration with local storage
57
+ * @deprecated Use GunInstanceHelpers.development() instead
16
58
  */
17
59
  development: () => ShogunCoreConfig;
18
60
  /**
19
61
  * Production configuration with multiple peers
62
+ * @deprecated Use GunInstanceHelpers.production() instead
20
63
  */
21
64
  production: (customPeers?: string[]) => ShogunCoreConfig;
22
65
  /**
23
66
  * Offline-first configuration
67
+ * @deprecated Use GunInstanceHelpers.offline() instead
24
68
  */
25
69
  offline: () => ShogunCoreConfig;
26
70
  /**
27
71
  * Web3-enabled configuration
72
+ * @deprecated Use GunInstanceHelpers.web3() instead
28
73
  */
29
74
  web3: () => ShogunCoreConfig;
30
75
  /**
31
76
  * WebAuthn-enabled configuration
77
+ * @deprecated Use GunInstanceHelpers.webauthn() instead
32
78
  */
33
79
  webauthn: () => ShogunCoreConfig;
34
80
  };
35
81
  /**
36
82
  * Configuration builder for custom setups
83
+ * @deprecated Use GunInstanceHelpers to create Gun instances and pass them to ShogunCore
37
84
  */
38
85
  export declare class ShogunConfigBuilder {
39
86
  private config;
87
+ private gunOptions;
40
88
  /**
41
- * Set Gun options
89
+ * Set Gun options (deprecated - use GunInstanceHelpers instead)
90
+ * @deprecated Use GunInstanceHelpers to create Gun instances
42
91
  */
43
- gunOptions(options: any): this;
92
+ setGunOptions(options: any): this;
44
93
  /**
45
- * Add peers
94
+ * Add peers (deprecated - use GunInstanceHelpers instead)
95
+ * @deprecated Use GunInstanceHelpers to create Gun instances
46
96
  */
47
97
  peers(peerList: string[]): this;
48
98
  /**
@@ -67,48 +117,59 @@ export declare class ShogunConfigBuilder {
67
117
  }): this;
68
118
  /**
69
119
  * Build the final configuration
120
+ * @deprecated Use GunInstanceHelpers to create Gun instances and pass them to ShogunCore
70
121
  */
71
122
  build(): ShogunCoreConfig;
72
123
  }
73
124
  /**
74
125
  * Helper functions for common configuration patterns
126
+ * @deprecated Use GunInstanceHelpers to create Gun instances and pass them to ShogunCore
75
127
  */
76
128
  export declare const ConfigHelpers: {
77
129
  /**
78
130
  * Create a configuration for a specific environment
131
+ * @deprecated Use GunInstanceHelpers instead
79
132
  */
80
133
  forEnvironment(env: "development" | "production" | "test"): ShogunCoreConfig;
81
134
  /**
82
135
  * Create a configuration with custom peers
136
+ * @deprecated Use GunInstanceHelpers.production(peers) instead
83
137
  */
84
138
  withPeers(peers: string[]): ShogunCoreConfig;
85
139
  /**
86
140
  * Create a configuration for a specific use case
141
+ * @deprecated Use GunInstanceHelpers instead
87
142
  */
88
143
  forUseCase(useCase: "chat" | "social" | "gaming" | "finance"): ShogunCoreConfig;
89
144
  };
90
145
  /**
91
146
  * Quick configuration functions
147
+ * @deprecated Use GunInstanceHelpers to create Gun instances and pass them to ShogunCore
92
148
  */
93
149
  export declare const QuickConfig: {
94
150
  /**
95
151
  * Minimal setup for quick testing
152
+ * @deprecated Use GunInstanceHelpers.minimal() instead
96
153
  */
97
154
  test: () => ShogunCoreConfig;
98
155
  /**
99
156
  * Standard setup for most apps
157
+ * @deprecated Use GunInstanceHelpers.production() instead
100
158
  */
101
159
  standard: () => ShogunCoreConfig;
102
160
  /**
103
161
  * Setup with WebAuthn for secure apps
162
+ * @deprecated Use GunInstanceHelpers.webauthn() instead
104
163
  */
105
164
  secure: () => ShogunCoreConfig;
106
165
  /**
107
166
  * Setup with Web3 for crypto apps
167
+ * @deprecated Use GunInstanceHelpers.web3() instead
108
168
  */
109
169
  crypto: () => ShogunCoreConfig;
110
170
  /**
111
171
  * Offline setup for local development
172
+ * @deprecated Use GunInstanceHelpers.offline() instead
112
173
  */
113
174
  local: () => ShogunCoreConfig;
114
175
  };
@@ -38,6 +38,10 @@ export declare class SFrameManager {
38
38
  * RFC 9605 Section 5.2: MLS-based key management
39
39
  */
40
40
  deriveKeyFromMLSSecret(mlsSecret: ArrayBuffer, keyId: number, context?: string): Promise<SFrameKey>;
41
+ /**
42
+ * Set a shared SFrame key (e.g., from another member)
43
+ */
44
+ setSharedKey(sframeKey: SFrameKey): Promise<void>;
41
45
  /**
42
46
  * Set the active encryption key
43
47
  */
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MLS 3-Member Test
3
+ * Test specifico per gruppi di 3 membri
4
+ */
5
+ declare function testMLS3Members(): Promise<void>;
6
+ export { testMLS3Members };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MLS Working Multi-Member Test
3
+ * Usa l'approccio corretto basato sull'implementazione funzionante
4
+ */
5
+ declare function testMLSWorkingMultiMembers(): Promise<void>;
6
+ export { testMLSWorkingMultiMembers };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Simple MLS Test
3
+ * Minimal test to verify MLS functionality
4
+ */
5
+ declare function testMLS(): Promise<void>;
6
+ export { testMLS };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ShogunCore Example with Existing Gun Instance
3
+ *
4
+ * This example shows how to use ShogunCore with an existing Gun instance.
5
+ * ShogunCore now requires an existing Gun instance to be passed in.
6
+ */
7
+ declare function shogunCoreExample(): Promise<void>;
8
+ export { shogunCoreExample };
@@ -9,6 +9,7 @@
9
9
  * - High-level user data helpers (profile, settings, collections)
10
10
  */
11
11
  import { DataBase } from "./db";
12
+ import { IGunInstance } from "gun/types";
12
13
  /**
13
14
  * Simple API wrapper that provides high-level helper methods.
14
15
  * For basic operations, use the DataBase instance directly via the `database` property.
@@ -154,18 +155,14 @@ export declare class QuickStart {
154
155
  get database(): DataBase;
155
156
  }
156
157
  /**
157
- * Auto Quick Start helper - creates a simple API with automatic Gun instance creation
158
- * No need to pass a Gun instance, it creates one automatically
158
+ * Auto Quick Start helper - creates a simple API with an existing Gun instance
159
+ * Requires a Gun instance to be passed in
159
160
  */
160
161
  export declare class AutoQuickStart {
161
162
  private db;
162
163
  private simpleAPI;
163
164
  private gunInstance;
164
- constructor(config?: {
165
- peers?: string[];
166
- appScope?: string;
167
- [key: string]: any;
168
- });
165
+ constructor(gunInstance: IGunInstance, appScope?: string);
169
166
  init(): Promise<void>;
170
167
  get api(): SimpleGunAPI;
171
168
  get database(): DataBase;
@@ -176,10 +173,6 @@ export declare class AutoQuickStart {
176
173
  */
177
174
  export declare function quickStart(gunInstance: any, appScope?: string): QuickStart;
178
175
  /**
179
- * Global helper for auto quick setup - creates Gun instance automatically
176
+ * Global helper for auto quick setup - requires existing Gun instance
180
177
  */
181
- export declare function autoQuickStart(config?: {
182
- peers?: string[];
183
- appScope?: string;
184
- [key: string]: any;
185
- }): AutoQuickStart;
178
+ export declare function autoQuickStart(gunInstance: IGunInstance, appScope?: string): AutoQuickStart;