shogun-core 3.3.7 → 4.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.
- package/README.md +1378 -1221
- package/dist/browser/shogun-core.js +78074 -45286
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/core.js +2 -3
- package/dist/examples/simple-api-test.js +90 -65
- package/dist/examples/zkproof-credentials-example.js +218 -0
- package/dist/examples/zkproof-example.js +206 -0
- package/dist/gundb/api.js +111 -467
- package/dist/index.js +10 -1
- package/dist/interfaces/shogun.js +2 -2
- package/dist/managers/AuthManager.js +0 -2
- package/dist/managers/CoreInitializer.js +9 -12
- package/dist/plugins/index.js +9 -21
- package/dist/plugins/nostr/nostrConnectorPlugin.js +2 -2
- package/dist/plugins/webauthn/webauthn.js +20 -7
- package/dist/plugins/webauthn/webauthnPlugin.js +101 -17
- package/dist/plugins/zkproof/index.js +53 -0
- package/dist/plugins/zkproof/zkCredentials.js +213 -0
- package/dist/plugins/zkproof/zkProofConnector.js +198 -0
- package/dist/plugins/zkproof/zkProofPlugin.js +272 -0
- package/dist/types/core.d.ts +1 -1
- package/dist/types/examples/simple-api-test.d.ts +6 -1
- package/dist/types/examples/zkproof-credentials-example.d.ts +12 -0
- package/dist/types/examples/zkproof-example.d.ts +11 -0
- package/dist/types/gundb/api.d.ts +77 -165
- package/dist/types/gundb/types.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interfaces/events.d.ts +3 -3
- package/dist/types/interfaces/shogun.d.ts +9 -24
- package/dist/types/plugins/index.d.ts +5 -3
- package/dist/types/plugins/webauthn/types.d.ts +22 -1
- package/dist/types/plugins/webauthn/webauthn.d.ts +1 -1
- package/dist/types/plugins/webauthn/webauthnPlugin.d.ts +23 -2
- package/dist/types/plugins/zkproof/index.d.ts +48 -0
- package/dist/types/plugins/zkproof/types.d.ts +123 -0
- package/dist/types/plugins/zkproof/zkCredentials.d.ts +112 -0
- package/dist/types/plugins/zkproof/zkProofConnector.d.ts +46 -0
- package/dist/types/plugins/zkproof/zkProofPlugin.d.ts +76 -0
- package/dist/types/utils/seedPhrase.d.ts +50 -0
- package/dist/types/utils/validation.d.ts +2 -2
- package/dist/utils/seedPhrase.js +97 -0
- package/dist/utils/validation.js +3 -1
- package/package.json +14 -8
- package/dist/examples/api-test.js +0 -273
- package/dist/migration-test.js +0 -96
- package/dist/plugins/oauth/index.js +0 -8
- package/dist/plugins/oauth/oauthConnector.js +0 -759
- package/dist/plugins/oauth/oauthPlugin.js +0 -400
- package/dist/types/examples/api-test.d.ts +0 -12
- package/dist/types/migration-test.d.ts +0 -16
- package/dist/types/plugins/oauth/index.d.ts +0 -3
- package/dist/types/plugins/oauth/oauthConnector.d.ts +0 -110
- package/dist/types/plugins/oauth/oauthPlugin.d.ts +0 -91
- package/dist/types/plugins/oauth/types.d.ts +0 -114
- /package/dist/plugins/{oauth → zkproof}/types.js +0 -0
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
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;
|
|
20
|
+
exports.normalizeSeedPhrase = exports.formatSeedPhrase = exports.deriveCredentialsFromMnemonic = exports.seedToPassword = exports.mnemonicToSeed = exports.validateSeedPhrase = exports.generateSeedPhrase = 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;
|
|
21
21
|
const core_1 = require("./core");
|
|
22
22
|
Object.defineProperty(exports, "ShogunCore", { enumerable: true, get: function () { return core_1.ShogunCore; } });
|
|
23
23
|
const db_1 = require("./gundb/db");
|
|
@@ -42,3 +42,12 @@ __exportStar(require("./utils/errorHandler"), exports);
|
|
|
42
42
|
__exportStar(require("./plugins"), exports);
|
|
43
43
|
__exportStar(require("./interfaces/shogun"), exports);
|
|
44
44
|
__exportStar(require("./config/simplified-config"), exports);
|
|
45
|
+
// Export seed phrase utilities for WebAuthn multi-device support
|
|
46
|
+
var seedPhrase_1 = require("./utils/seedPhrase");
|
|
47
|
+
Object.defineProperty(exports, "generateSeedPhrase", { enumerable: true, get: function () { return seedPhrase_1.generateSeedPhrase; } });
|
|
48
|
+
Object.defineProperty(exports, "validateSeedPhrase", { enumerable: true, get: function () { return seedPhrase_1.validateSeedPhrase; } });
|
|
49
|
+
Object.defineProperty(exports, "mnemonicToSeed", { enumerable: true, get: function () { return seedPhrase_1.mnemonicToSeed; } });
|
|
50
|
+
Object.defineProperty(exports, "seedToPassword", { enumerable: true, get: function () { return seedPhrase_1.seedToPassword; } });
|
|
51
|
+
Object.defineProperty(exports, "deriveCredentialsFromMnemonic", { enumerable: true, get: function () { return seedPhrase_1.deriveCredentialsFromMnemonic; } });
|
|
52
|
+
Object.defineProperty(exports, "formatSeedPhrase", { enumerable: true, get: function () { return seedPhrase_1.formatSeedPhrase; } });
|
|
53
|
+
Object.defineProperty(exports, "normalizeSeedPhrase", { enumerable: true, get: function () { return seedPhrase_1.normalizeSeedPhrase; } });
|
|
@@ -32,6 +32,6 @@ var CorePlugins;
|
|
|
32
32
|
CorePlugins["Web3"] = "web3";
|
|
33
33
|
/** Bitcoin wallet plugin */
|
|
34
34
|
CorePlugins["Nostr"] = "nostr";
|
|
35
|
-
/**
|
|
36
|
-
CorePlugins["
|
|
35
|
+
/** Zero-Knowledge Proof plugin */
|
|
36
|
+
CorePlugins["ZkProof"] = "zkproof";
|
|
37
37
|
})(CorePlugins || (exports.CorePlugins = CorePlugins = {}));
|
|
@@ -6,7 +6,7 @@ const errorHandler_1 = require("../utils/errorHandler");
|
|
|
6
6
|
const webauthnPlugin_1 = require("../plugins/webauthn/webauthnPlugin");
|
|
7
7
|
const web3ConnectorPlugin_1 = require("../plugins/web3/web3ConnectorPlugin");
|
|
8
8
|
const nostrConnectorPlugin_1 = require("../plugins/nostr/nostrConnectorPlugin");
|
|
9
|
-
const
|
|
9
|
+
const zkProofPlugin_1 = require("../plugins/zkproof/zkProofPlugin");
|
|
10
10
|
const gundb_1 = require("../gundb");
|
|
11
11
|
/**
|
|
12
12
|
* Handles initialization of ShogunCore components
|
|
@@ -186,17 +186,6 @@ class CoreInitializer {
|
|
|
186
186
|
*/
|
|
187
187
|
registerBuiltinPlugins(config) {
|
|
188
188
|
try {
|
|
189
|
-
// Register OAuth plugin if configuration is provided
|
|
190
|
-
if (config.oauth) {
|
|
191
|
-
if (typeof console !== "undefined" && console.warn) {
|
|
192
|
-
console.warn("OAuth plugin will be registered with provided configuration");
|
|
193
|
-
}
|
|
194
|
-
const oauthPlugin = new oauthPlugin_1.OAuthPlugin();
|
|
195
|
-
if (typeof oauthPlugin.configure === "function") {
|
|
196
|
-
oauthPlugin.configure(config.oauth);
|
|
197
|
-
}
|
|
198
|
-
this.core.pluginManager.register(oauthPlugin);
|
|
199
|
-
}
|
|
200
189
|
// Register WebAuthn plugin if configuration is provided
|
|
201
190
|
if (config.webauthn) {
|
|
202
191
|
if (typeof console !== "undefined" && console.warn) {
|
|
@@ -230,6 +219,14 @@ class CoreInitializer {
|
|
|
230
219
|
}
|
|
231
220
|
this.core.pluginManager.register(nostrPlugin);
|
|
232
221
|
}
|
|
222
|
+
// Register ZK-Proof plugin if configuration is provided
|
|
223
|
+
if (config.zkproof) {
|
|
224
|
+
if (typeof console !== "undefined" && console.warn) {
|
|
225
|
+
console.warn("ZK-Proof plugin will be registered with provided configuration");
|
|
226
|
+
}
|
|
227
|
+
const zkproofPlugin = new zkProofPlugin_1.ZkProofPlugin(config.zkproof);
|
|
228
|
+
this.core.pluginManager.register(zkproofPlugin);
|
|
229
|
+
}
|
|
233
230
|
}
|
|
234
231
|
catch (error) {
|
|
235
232
|
if (typeof console !== "undefined" && console.error) {
|
package/dist/plugins/index.js
CHANGED
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
3
|
+
exports.CredentialType = exports.ZkCredentials = exports.ZkProofPlugin = exports.ZkProofConnector = exports.NostrConnectorPlugin = exports.NostrConnector = exports.Web3ConnectorPlugin = exports.Web3Connector = exports.WebauthnPlugin = exports.Webauthn = exports.BasePlugin = void 0;
|
|
18
4
|
// Base plugin interface and types
|
|
19
5
|
var base_1 = require("./base");
|
|
20
6
|
Object.defineProperty(exports, "BasePlugin", { enumerable: true, get: function () { return base_1.BasePlugin; } });
|
|
@@ -33,9 +19,11 @@ var nostrConnector_1 = require("./nostr/nostrConnector");
|
|
|
33
19
|
Object.defineProperty(exports, "NostrConnector", { enumerable: true, get: function () { return nostrConnector_1.NostrConnector; } });
|
|
34
20
|
var nostrConnectorPlugin_1 = require("./nostr/nostrConnectorPlugin");
|
|
35
21
|
Object.defineProperty(exports, "NostrConnectorPlugin", { enumerable: true, get: function () { return nostrConnectorPlugin_1.NostrConnectorPlugin; } });
|
|
36
|
-
//
|
|
37
|
-
var
|
|
38
|
-
Object.defineProperty(exports, "
|
|
39
|
-
var
|
|
40
|
-
Object.defineProperty(exports, "
|
|
41
|
-
|
|
22
|
+
// ZK-Proof plugin exports
|
|
23
|
+
var zkProofConnector_1 = require("./zkproof/zkProofConnector");
|
|
24
|
+
Object.defineProperty(exports, "ZkProofConnector", { enumerable: true, get: function () { return zkProofConnector_1.ZkProofConnector; } });
|
|
25
|
+
var zkProofPlugin_1 = require("./zkproof/zkProofPlugin");
|
|
26
|
+
Object.defineProperty(exports, "ZkProofPlugin", { enumerable: true, get: function () { return zkProofPlugin_1.ZkProofPlugin; } });
|
|
27
|
+
var zkCredentials_1 = require("./zkproof/zkCredentials");
|
|
28
|
+
Object.defineProperty(exports, "ZkCredentials", { enumerable: true, get: function () { return zkCredentials_1.ZkCredentials; } });
|
|
29
|
+
Object.defineProperty(exports, "CredentialType", { enumerable: true, get: function () { return zkCredentials_1.CredentialType; } });
|
|
@@ -353,7 +353,7 @@ class NostrConnectorPlugin extends base_1.BasePlugin {
|
|
|
353
353
|
core.emit("auth:login", {
|
|
354
354
|
userPub: loginResult.userPub || "",
|
|
355
355
|
username: credentials.username,
|
|
356
|
-
method: "
|
|
356
|
+
method: "nostr",
|
|
357
357
|
});
|
|
358
358
|
return loginResult;
|
|
359
359
|
}
|
|
@@ -410,7 +410,7 @@ class NostrConnectorPlugin extends base_1.BasePlugin {
|
|
|
410
410
|
core.emit("auth:signup", {
|
|
411
411
|
userPub: authResult.userPub || "",
|
|
412
412
|
username: credentials.username,
|
|
413
|
-
method: "
|
|
413
|
+
method: "nostr",
|
|
414
414
|
});
|
|
415
415
|
return { ...authResult };
|
|
416
416
|
}
|
|
@@ -15,6 +15,7 @@ const errorHandler_1 = require("../../utils/errorHandler");
|
|
|
15
15
|
const eventEmitter_1 = require("../../utils/eventEmitter");
|
|
16
16
|
const types_1 = require("./types");
|
|
17
17
|
const derive_1 = __importDefault(require("../../gundb/derive"));
|
|
18
|
+
const seedPhrase_1 = require("../../utils/seedPhrase");
|
|
18
19
|
/**
|
|
19
20
|
* Constants for WebAuthn configuration
|
|
20
21
|
*/
|
|
@@ -473,11 +474,23 @@ if (typeof window !== "undefined") {
|
|
|
473
474
|
else if (typeof global !== "undefined") {
|
|
474
475
|
global.Webauthn = Webauthn;
|
|
475
476
|
}
|
|
476
|
-
// Funzione helper per derivare chiavi WebAuthn
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
477
|
+
// Funzione helper per derivare chiavi WebAuthn
|
|
478
|
+
// Supporta sia credentialId (legacy) che seed phrase (nuovo, multi-device)
|
|
479
|
+
async function deriveWebauthnKeys(username, credentialIdOrSeedPhrase, useSeedPhrase = false) {
|
|
480
|
+
if (useSeedPhrase) {
|
|
481
|
+
// New method: derive from BIP39 seed phrase for multi-device support
|
|
482
|
+
const { password, seed } = (0, seedPhrase_1.deriveCredentialsFromMnemonic)(credentialIdOrSeedPhrase, username);
|
|
483
|
+
// Use the seed phrase-derived password for Gun key derivation
|
|
484
|
+
return await (0, derive_1.default)(password, username, {
|
|
485
|
+
includeP256: true,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
else {
|
|
489
|
+
// Legacy method: derive from credentialId (device-bound)
|
|
490
|
+
const hashedCredentialId = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(credentialIdOrSeedPhrase));
|
|
491
|
+
const salt = `${username}_${credentialIdOrSeedPhrase}`;
|
|
492
|
+
return await (0, derive_1.default)(hashedCredentialId, salt, {
|
|
493
|
+
includeP256: true,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
483
496
|
}
|
|
@@ -5,6 +5,8 @@ const base_1 = require("../base");
|
|
|
5
5
|
const webauthn_1 = require("./webauthn");
|
|
6
6
|
const webauthnSigner_1 = require("./webauthnSigner");
|
|
7
7
|
const errorHandler_1 = require("../../utils/errorHandler");
|
|
8
|
+
const seedPhrase_1 = require("../../utils/seedPhrase");
|
|
9
|
+
const webauthn_2 = require("./webauthn");
|
|
8
10
|
/**
|
|
9
11
|
* Plugin per la gestione delle funzionalità WebAuthn in ShogunCore
|
|
10
12
|
*/
|
|
@@ -359,11 +361,13 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
359
361
|
* Register new user with WebAuthn
|
|
360
362
|
* This is the recommended method for WebAuthn registration
|
|
361
363
|
* @param username - Username
|
|
362
|
-
* @
|
|
364
|
+
* @param options - Optional signup options (seed phrase support)
|
|
365
|
+
* @returns {Promise<SignUpResult>} Registration result with optional seed phrase
|
|
363
366
|
* @description Creates a new user account using WebAuthn credentials.
|
|
364
367
|
* Requires browser support for WebAuthn.
|
|
368
|
+
* If generateSeedPhrase is true, returns a BIP39 mnemonic for multi-device support.
|
|
365
369
|
*/
|
|
366
|
-
async signUp(username) {
|
|
370
|
+
async signUp(username, options) {
|
|
367
371
|
try {
|
|
368
372
|
const core = this.assertInitialized();
|
|
369
373
|
if (!username) {
|
|
@@ -372,25 +376,60 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
372
376
|
if (!this.isSupported()) {
|
|
373
377
|
throw new Error("WebAuthn is not supported by this browser");
|
|
374
378
|
}
|
|
375
|
-
//
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
379
|
+
// Determine seed phrase to use
|
|
380
|
+
let seedPhrase;
|
|
381
|
+
const shouldGenerateSeed = options?.generateSeedPhrase !== false; // Default to true
|
|
382
|
+
if (options?.seedPhrase) {
|
|
383
|
+
// Use provided seed phrase
|
|
384
|
+
if (!(0, seedPhrase_1.validateSeedPhrase)(options.seedPhrase)) {
|
|
385
|
+
throw new Error("Invalid seed phrase provided");
|
|
386
|
+
}
|
|
387
|
+
seedPhrase = options.seedPhrase;
|
|
380
388
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
389
|
+
else if (shouldGenerateSeed) {
|
|
390
|
+
// Generate new seed phrase for multi-device support
|
|
391
|
+
seedPhrase = (0, seedPhrase_1.generateSeedPhrase)();
|
|
392
|
+
console.log("[webauthnPlugin] Generated seed phrase for multi-device support");
|
|
393
|
+
}
|
|
394
|
+
// Derive Gun credentials from seed phrase if available
|
|
395
|
+
let pair;
|
|
396
|
+
if (seedPhrase) {
|
|
397
|
+
// Use seed phrase derivation
|
|
398
|
+
const { password } = (0, seedPhrase_1.deriveCredentialsFromMnemonic)(seedPhrase, username);
|
|
399
|
+
const derivedKeys = await (0, webauthn_2.deriveWebauthnKeys)(username, seedPhrase, true);
|
|
400
|
+
pair = {
|
|
401
|
+
pub: derivedKeys.pub,
|
|
402
|
+
priv: derivedKeys.priv,
|
|
403
|
+
epub: derivedKeys.epub,
|
|
404
|
+
epriv: derivedKeys.epriv,
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
// Legacy WebAuthn credential-based flow (device-bound)
|
|
409
|
+
const credentials = await this.generateCredentials(username, null, false);
|
|
410
|
+
if (!credentials?.success) {
|
|
411
|
+
throw new Error(credentials?.error || "Unable to generate WebAuthn credentials");
|
|
412
|
+
}
|
|
413
|
+
const generatedPair = await this.generatePairFromCredentials(credentials);
|
|
414
|
+
if (!generatedPair) {
|
|
415
|
+
throw new Error("Failed to generate SEA pair from WebAuthn credentials");
|
|
416
|
+
}
|
|
417
|
+
pair = generatedPair;
|
|
385
418
|
}
|
|
386
419
|
core.setAuthMethod("webauthn");
|
|
387
|
-
//
|
|
388
|
-
const
|
|
389
|
-
if
|
|
390
|
-
|
|
420
|
+
// Register user with Gun (using email parameter slot for pair)
|
|
421
|
+
const result = await core.signUp(username, undefined, pair);
|
|
422
|
+
// Add seed phrase to result if generated
|
|
423
|
+
if (seedPhrase && shouldGenerateSeed) {
|
|
424
|
+
return {
|
|
425
|
+
...result,
|
|
426
|
+
message: seedPhrase
|
|
427
|
+
? "🔑 IMPORTANT: Save your 12-word seed phrase to access your account from other devices!"
|
|
428
|
+
: result.message,
|
|
429
|
+
seedPhrase: seedPhrase,
|
|
430
|
+
};
|
|
391
431
|
}
|
|
392
|
-
|
|
393
|
-
return await core.signUp(username, undefined, pair);
|
|
432
|
+
return result;
|
|
394
433
|
}
|
|
395
434
|
catch (error) {
|
|
396
435
|
console.error(`Error during WebAuthn registration: ${error}`);
|
|
@@ -401,5 +440,50 @@ class WebauthnPlugin extends base_1.BasePlugin {
|
|
|
401
440
|
};
|
|
402
441
|
}
|
|
403
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* Import existing account from seed phrase
|
|
445
|
+
* Allows accessing the same account across multiple devices
|
|
446
|
+
* @param username - Username
|
|
447
|
+
* @param seedPhrase - 12-word BIP39 mnemonic seed phrase
|
|
448
|
+
* @returns {Promise<SignUpResult>} Registration result
|
|
449
|
+
*/
|
|
450
|
+
async importFromSeed(username, seedPhrase) {
|
|
451
|
+
try {
|
|
452
|
+
if (!username) {
|
|
453
|
+
throw new Error("Username required");
|
|
454
|
+
}
|
|
455
|
+
// Normalize and validate seed phrase
|
|
456
|
+
const normalizedSeed = (0, seedPhrase_1.normalizeSeedPhrase)(seedPhrase);
|
|
457
|
+
if (!(0, seedPhrase_1.validateSeedPhrase)(normalizedSeed)) {
|
|
458
|
+
throw new Error("Invalid seed phrase. Please check and try again.");
|
|
459
|
+
}
|
|
460
|
+
console.log("[webauthnPlugin] Importing account from seed phrase");
|
|
461
|
+
// Use signUp with existing seed phrase
|
|
462
|
+
return await this.signUp(username, {
|
|
463
|
+
seedPhrase: normalizedSeed,
|
|
464
|
+
generateSeedPhrase: false, // Don't generate new seed
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
console.error(`Error importing from seed: ${error.message}`);
|
|
469
|
+
errorHandler_1.ErrorHandler.handle(errorHandler_1.ErrorType.WEBAUTHN, "WEBAUTHN_IMPORT_ERROR", error.message || "Error importing from seed phrase", error);
|
|
470
|
+
return {
|
|
471
|
+
success: false,
|
|
472
|
+
error: error.message || "Error importing from seed phrase",
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Get seed phrase for current user (if stored)
|
|
478
|
+
* Note: Seed phrases are NOT stored by default for security
|
|
479
|
+
* Users should save their seed phrase during registration
|
|
480
|
+
* @param username - Username
|
|
481
|
+
* @returns {Promise<string | null>} Seed phrase or null
|
|
482
|
+
*/
|
|
483
|
+
async getSeedPhrase(username) {
|
|
484
|
+
console.warn("[webauthnPlugin] Seed phrases are not stored for security reasons");
|
|
485
|
+
console.warn("[webauthnPlugin] Users must save their seed phrase during registration");
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
404
488
|
}
|
|
405
489
|
exports.WebauthnPlugin = WebauthnPlugin;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ZK-Proof Plugin for Shogun Core
|
|
4
|
+
*
|
|
5
|
+
* Provides Zero-Knowledge Proof authentication using Semaphore protocol
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Anonymous authentication without revealing identity
|
|
9
|
+
* - Multi-device support via trapdoor backup
|
|
10
|
+
* - Privacy-preserving group membership proofs
|
|
11
|
+
* - Compatible with Gun decentralized storage
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Initialize Shogun with ZK-Proof plugin
|
|
16
|
+
* const shogun = new ShogunCore({
|
|
17
|
+
* peers: ['https://gun-manhattan.herokuapp.com/gun'],
|
|
18
|
+
* zkproof: {
|
|
19
|
+
* enabled: true,
|
|
20
|
+
* defaultGroupId: 'my-app-users'
|
|
21
|
+
* }
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* await shogun.initialize();
|
|
25
|
+
*
|
|
26
|
+
* // Get the plugin
|
|
27
|
+
* const zkPlugin = shogun.getPlugin<ZkProofPlugin>('zkproof');
|
|
28
|
+
*
|
|
29
|
+
* // Sign up with ZK-Proof
|
|
30
|
+
* const signupResult = await zkPlugin.signUp();
|
|
31
|
+
* if (signupResult.success) {
|
|
32
|
+
* console.log('Trapdoor (save this!):', signupResult.seedPhrase);
|
|
33
|
+
* console.log('Public commitment:', signupResult.username);
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* // Login with trapdoor
|
|
37
|
+
* const loginResult = await zkPlugin.login(trapdoor);
|
|
38
|
+
* if (loginResult.success) {
|
|
39
|
+
* console.log('Logged in anonymously!');
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @module zkproof
|
|
44
|
+
*/
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.CredentialType = exports.ZkCredentials = exports.ZkProofConnector = exports.ZkProofPlugin = void 0;
|
|
47
|
+
var zkProofPlugin_1 = require("./zkProofPlugin");
|
|
48
|
+
Object.defineProperty(exports, "ZkProofPlugin", { enumerable: true, get: function () { return zkProofPlugin_1.ZkProofPlugin; } });
|
|
49
|
+
var zkProofConnector_1 = require("./zkProofConnector");
|
|
50
|
+
Object.defineProperty(exports, "ZkProofConnector", { enumerable: true, get: function () { return zkProofConnector_1.ZkProofConnector; } });
|
|
51
|
+
var zkCredentials_1 = require("./zkCredentials");
|
|
52
|
+
Object.defineProperty(exports, "ZkCredentials", { enumerable: true, get: function () { return zkCredentials_1.ZkCredentials; } });
|
|
53
|
+
Object.defineProperty(exports, "CredentialType", { enumerable: true, get: function () { return zkCredentials_1.CredentialType; } });
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ZkCredentials = exports.CredentialType = void 0;
|
|
4
|
+
const group_1 = require("@semaphore-protocol/group");
|
|
5
|
+
const proof_1 = require("@semaphore-protocol/proof");
|
|
6
|
+
const ethers_1 = require("ethers");
|
|
7
|
+
const errorHandler_1 = require("../../utils/errorHandler");
|
|
8
|
+
/**
|
|
9
|
+
* Types of verifiable credentials
|
|
10
|
+
*/
|
|
11
|
+
var CredentialType;
|
|
12
|
+
(function (CredentialType) {
|
|
13
|
+
CredentialType["AGE"] = "age";
|
|
14
|
+
CredentialType["CITIZENSHIP"] = "citizenship";
|
|
15
|
+
CredentialType["EDUCATION"] = "education";
|
|
16
|
+
CredentialType["INCOME"] = "income";
|
|
17
|
+
CredentialType["EMPLOYMENT"] = "employment";
|
|
18
|
+
CredentialType["HEALTH"] = "health";
|
|
19
|
+
CredentialType["CUSTOM"] = "custom";
|
|
20
|
+
})(CredentialType || (exports.CredentialType = CredentialType = {}));
|
|
21
|
+
/**
|
|
22
|
+
* ZK Credentials Manager
|
|
23
|
+
* Extends ZK-Proof functionality to support verifiable credentials
|
|
24
|
+
*/
|
|
25
|
+
class ZkCredentials {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.groups = new Map();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a verifiable credential from private data
|
|
31
|
+
*/
|
|
32
|
+
createCredential(identity, credentialData) {
|
|
33
|
+
try {
|
|
34
|
+
// Hash the private data to create a credential commitment
|
|
35
|
+
const privateDataString = JSON.stringify(credentialData.privateData);
|
|
36
|
+
const credentialHash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(privateDataString));
|
|
37
|
+
// For now, return a basic credential structure
|
|
38
|
+
// Full proof generation requires circuit files
|
|
39
|
+
const credential = {
|
|
40
|
+
type: credentialData.type,
|
|
41
|
+
claim: credentialData.claim,
|
|
42
|
+
proof: {
|
|
43
|
+
merkleTreeRoot: "",
|
|
44
|
+
nullifierHash: "",
|
|
45
|
+
signal: credentialHash,
|
|
46
|
+
externalNullifier: "",
|
|
47
|
+
proof: [],
|
|
48
|
+
},
|
|
49
|
+
credentialHash,
|
|
50
|
+
timestamp: Date.now(),
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
credential,
|
|
54
|
+
credentialHash,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
errorHandler_1.ErrorHandler.handle(errorHandler_1.ErrorType.ENCRYPTION, "CREDENTIAL_CREATION_FAILED", `Failed to create verifiable credential: ${error.message}`, error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Prove an attribute about yourself without revealing the underlying data
|
|
64
|
+
*/
|
|
65
|
+
async proveAttribute(identity, credentialData, groupId = "verified-credentials") {
|
|
66
|
+
try {
|
|
67
|
+
const { credential, credentialHash } = this.createCredential(identity, credentialData);
|
|
68
|
+
// Convert claim to signal
|
|
69
|
+
const signal = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(credentialData.claim));
|
|
70
|
+
const signalBigInt = BigInt(signal);
|
|
71
|
+
// Create or get group
|
|
72
|
+
const group = this.getOrCreateGroup(groupId);
|
|
73
|
+
// Add identity if not already in group
|
|
74
|
+
if (!group.members.includes(identity.commitment)) {
|
|
75
|
+
group.addMember(identity.commitment);
|
|
76
|
+
}
|
|
77
|
+
// External nullifier from credential type
|
|
78
|
+
const externalNullifier = BigInt(ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(credentialData.type)));
|
|
79
|
+
// Generate ZK proof
|
|
80
|
+
// Note: This requires circuit files to be available
|
|
81
|
+
const fullProof = await (0, proof_1.generateProof)(identity, group, signalBigInt, externalNullifier);
|
|
82
|
+
return {
|
|
83
|
+
type: credentialData.type,
|
|
84
|
+
claim: credentialData.claim,
|
|
85
|
+
proof: {
|
|
86
|
+
merkleTreeRoot: fullProof.merkleTreeRoot.toString(),
|
|
87
|
+
nullifierHash: fullProof.nullifierHash.toString(),
|
|
88
|
+
signal: fullProof.signal.toString(),
|
|
89
|
+
externalNullifier: fullProof.externalNullifier.toString(),
|
|
90
|
+
proof: fullProof.proof.map((p) => p.toString()),
|
|
91
|
+
},
|
|
92
|
+
credentialHash,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
errorHandler_1.ErrorHandler.handle(errorHandler_1.ErrorType.ENCRYPTION, "ATTRIBUTE_PROOF_FAILED", `Failed to prove attribute: ${error.message}`, error);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Verify a credential proof
|
|
103
|
+
*/
|
|
104
|
+
async verifyCredential(proof, treeDepth = 20) {
|
|
105
|
+
try {
|
|
106
|
+
const verified = await (0, proof_1.verifyProof)(proof.proof, treeDepth);
|
|
107
|
+
return {
|
|
108
|
+
verified,
|
|
109
|
+
type: proof.type,
|
|
110
|
+
claim: proof.claim,
|
|
111
|
+
timestamp: proof.timestamp,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
errorHandler_1.ErrorHandler.handle(errorHandler_1.ErrorType.ENCRYPTION, "CREDENTIAL_VERIFICATION_FAILED", `Failed to verify credential: ${error.message}`, error);
|
|
116
|
+
return {
|
|
117
|
+
verified: false,
|
|
118
|
+
error: error.message,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create a group for credential holders
|
|
124
|
+
*/
|
|
125
|
+
getOrCreateGroup(groupId) {
|
|
126
|
+
if (!this.groups.has(groupId)) {
|
|
127
|
+
const groupIdHash = ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes(groupId));
|
|
128
|
+
const groupIdNumber = BigInt(groupIdHash);
|
|
129
|
+
this.groups.set(groupId, new group_1.Group(groupIdNumber));
|
|
130
|
+
}
|
|
131
|
+
return this.groups.get(groupId);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Add an identity to a credentials group
|
|
135
|
+
*/
|
|
136
|
+
addToCredentialGroup(identity, groupId = "verified-credentials") {
|
|
137
|
+
const group = this.getOrCreateGroup(groupId);
|
|
138
|
+
if (!group.members.includes(identity.commitment)) {
|
|
139
|
+
group.addMember(identity.commitment);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Common credential proofs
|
|
144
|
+
*/
|
|
145
|
+
/**
|
|
146
|
+
* Prove age without revealing exact birthdate
|
|
147
|
+
*/
|
|
148
|
+
async proveAge(identity, birthDate, minimumAge) {
|
|
149
|
+
const age = Math.floor((Date.now() - birthDate.getTime()) / (365.25 * 24 * 60 * 60 * 1000));
|
|
150
|
+
if (age < minimumAge) {
|
|
151
|
+
throw new Error(`Age ${age} is less than required ${minimumAge}`);
|
|
152
|
+
}
|
|
153
|
+
return this.proveAttribute(identity, {
|
|
154
|
+
type: CredentialType.AGE,
|
|
155
|
+
claim: `Age is ${minimumAge} or older`,
|
|
156
|
+
privateData: {
|
|
157
|
+
birthDate: birthDate.toISOString(),
|
|
158
|
+
actualAge: age,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Prove citizenship without revealing country
|
|
164
|
+
*/
|
|
165
|
+
async proveCitizenship(identity, country, region = "EU") {
|
|
166
|
+
return this.proveAttribute(identity, {
|
|
167
|
+
type: CredentialType.CITIZENSHIP,
|
|
168
|
+
claim: `Citizen of ${region}`,
|
|
169
|
+
privateData: {
|
|
170
|
+
country,
|
|
171
|
+
passportNumber: "hidden",
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Prove education without revealing institution
|
|
177
|
+
*/
|
|
178
|
+
async proveEducation(identity, degree, university, year) {
|
|
179
|
+
return this.proveAttribute(identity, {
|
|
180
|
+
type: CredentialType.EDUCATION,
|
|
181
|
+
claim: `Has ${degree} degree`,
|
|
182
|
+
privateData: {
|
|
183
|
+
university,
|
|
184
|
+
degree,
|
|
185
|
+
year,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Prove income range without revealing exact amount
|
|
191
|
+
*/
|
|
192
|
+
async proveIncome(identity, amount, minimumRequired, currency = "USD") {
|
|
193
|
+
if (amount < minimumRequired) {
|
|
194
|
+
throw new Error(`Income ${amount} is less than required ${minimumRequired}`);
|
|
195
|
+
}
|
|
196
|
+
return this.proveAttribute(identity, {
|
|
197
|
+
type: CredentialType.INCOME,
|
|
198
|
+
claim: `Income ≥ ${minimumRequired} ${currency}`,
|
|
199
|
+
privateData: {
|
|
200
|
+
actualIncome: amount,
|
|
201
|
+
currency,
|
|
202
|
+
verified: true,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Cleanup resources
|
|
208
|
+
*/
|
|
209
|
+
cleanup() {
|
|
210
|
+
this.groups.clear();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
exports.ZkCredentials = ZkCredentials;
|