shogun-core 2.0.0 → 2.0.3
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 +74126 -91893
- package/dist/browser/shogun-core.js.map +1 -1
- package/dist/core.js +32 -36
- package/dist/gundb/crypto.js +17 -32
- package/dist/gundb/db.js +35 -82
- package/dist/gundb/derive.js +16 -19
- package/dist/gundb/errors.js +7 -17
- package/dist/gundb/index.js +1 -17
- package/dist/gundb/restricted-put.js +5 -11
- package/dist/gundb/rxjs.js +15 -19
- package/dist/gundb/types.js +1 -2
- package/dist/index.js +9 -34
- package/dist/plugins/base.js +2 -6
- package/dist/plugins/index.js +10 -36
- package/dist/plugins/nostr/index.js +4 -20
- package/dist/plugins/nostr/nostrConnector.js +22 -29
- package/dist/plugins/nostr/nostrConnectorPlugin.js +24 -28
- package/dist/plugins/nostr/nostrSigner.js +8 -15
- package/dist/plugins/nostr/types.js +1 -2
- package/dist/plugins/oauth/index.js +2 -7
- package/dist/plugins/oauth/oauthConnector.js +9 -16
- package/dist/plugins/oauth/oauthPlugin.js +21 -25
- package/dist/plugins/oauth/types.js +1 -2
- package/dist/plugins/web3/index.js +4 -20
- package/dist/plugins/web3/types.js +1 -2
- package/dist/plugins/web3/web3Connector.js +21 -27
- package/dist/plugins/web3/web3ConnectorPlugin.js +17 -21
- package/dist/plugins/web3/web3Signer.js +15 -22
- package/dist/plugins/webauthn/index.js +3 -19
- package/dist/plugins/webauthn/types.js +2 -5
- package/dist/plugins/webauthn/webauthn.js +21 -29
- package/dist/plugins/webauthn/webauthnPlugin.js +9 -13
- package/dist/plugins/webauthn/webauthnSigner.js +12 -19
- package/dist/storage/storage.js +1 -5
- package/dist/types/common.js +1 -2
- package/dist/types/events.js +2 -6
- package/dist/types/gundb/db.d.ts +2 -0
- package/dist/types/plugin.js +1 -2
- package/dist/types/shogun.js +4 -7
- package/dist/utils/errorHandler.js +4 -9
- package/dist/utils/eventEmitter.js +1 -5
- package/dist/utils/validation.js +7 -14
- package/package.json +9 -11
package/dist/core.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const nostrConnectorPlugin_1 = require("./plugins/nostr/nostrConnectorPlugin");
|
|
11
|
-
const oauthPlugin_1 = require("./plugins/oauth/oauthPlugin");
|
|
12
|
-
const gundb_1 = require("./gundb");
|
|
1
|
+
import { ShogunEventEmitter } from "./types/events";
|
|
2
|
+
import { ErrorHandler, ErrorType } from "./utils/errorHandler";
|
|
3
|
+
import { ShogunStorage } from "./storage/storage";
|
|
4
|
+
import { CorePlugins, } from "./types/shogun";
|
|
5
|
+
import { WebauthnPlugin } from "./plugins/webauthn/webauthnPlugin";
|
|
6
|
+
import { Web3ConnectorPlugin } from "./plugins/web3/web3ConnectorPlugin";
|
|
7
|
+
import { NostrConnectorPlugin } from "./plugins/nostr/nostrConnectorPlugin";
|
|
8
|
+
import { OAuthPlugin } from "./plugins/oauth/oauthPlugin";
|
|
9
|
+
import { restrictedPut, DataBase, RxJS, createGun, Gun, derive, } from "./gundb";
|
|
13
10
|
/**
|
|
14
11
|
* Main ShogunCore class - implements the IShogunCore interface
|
|
15
12
|
*
|
|
@@ -21,7 +18,7 @@ const gundb_1 = require("./gundb");
|
|
|
21
18
|
*
|
|
22
19
|
* @since 2.0.0
|
|
23
20
|
*/
|
|
24
|
-
class ShogunCore {
|
|
21
|
+
export class ShogunCore {
|
|
25
22
|
static API_VERSION = "^1.6.6";
|
|
26
23
|
db;
|
|
27
24
|
storage;
|
|
@@ -53,9 +50,9 @@ class ShogunCore {
|
|
|
53
50
|
};
|
|
54
51
|
}
|
|
55
52
|
this.config = config;
|
|
56
|
-
this.storage = new
|
|
57
|
-
this.eventEmitter = new
|
|
58
|
-
|
|
53
|
+
this.storage = new ShogunStorage();
|
|
54
|
+
this.eventEmitter = new ShogunEventEmitter();
|
|
55
|
+
ErrorHandler.addListener((error) => {
|
|
59
56
|
this.eventEmitter.emit("error", {
|
|
60
57
|
action: error.code,
|
|
61
58
|
message: error.message,
|
|
@@ -63,14 +60,14 @@ class ShogunCore {
|
|
|
63
60
|
});
|
|
64
61
|
});
|
|
65
62
|
if (config.authToken) {
|
|
66
|
-
|
|
63
|
+
restrictedPut(Gun, config.authToken);
|
|
67
64
|
}
|
|
68
65
|
try {
|
|
69
66
|
if (config.gunInstance) {
|
|
70
67
|
this._gun = config.gunInstance;
|
|
71
68
|
}
|
|
72
69
|
else {
|
|
73
|
-
this._gun =
|
|
70
|
+
this._gun = createGun({
|
|
74
71
|
peers: config.peers || [],
|
|
75
72
|
radisk: config.radisk || false,
|
|
76
73
|
localStorage: config.localStorage || false,
|
|
@@ -84,7 +81,7 @@ class ShogunCore {
|
|
|
84
81
|
throw new Error(`Failed to create Gun instance: ${error}`);
|
|
85
82
|
}
|
|
86
83
|
try {
|
|
87
|
-
this.db = new
|
|
84
|
+
this.db = new DataBase(this._gun, config.scope || "");
|
|
88
85
|
this._gun = this.db.gun;
|
|
89
86
|
this.setupGunEventForwarding();
|
|
90
87
|
}
|
|
@@ -116,12 +113,12 @@ class ShogunCore {
|
|
|
116
113
|
return;
|
|
117
114
|
const priv = user._?.sea?.epriv;
|
|
118
115
|
const pub = user._?.sea?.epub;
|
|
119
|
-
this.wallets = await
|
|
116
|
+
this.wallets = await derive(priv, pub, {
|
|
120
117
|
includeSecp256k1Bitcoin: true,
|
|
121
118
|
includeSecp256k1Ethereum: true,
|
|
122
119
|
});
|
|
123
120
|
});
|
|
124
|
-
this.rx = new
|
|
121
|
+
this.rx = new RxJS(this._gun);
|
|
125
122
|
this.registerBuiltinPlugins(config);
|
|
126
123
|
// Initialize async components
|
|
127
124
|
this.initialize().catch((error) => {
|
|
@@ -207,7 +204,7 @@ class ShogunCore {
|
|
|
207
204
|
if (typeof console !== "undefined" && console.warn) {
|
|
208
205
|
console.warn("OAuth plugin will be registered with provided configuration");
|
|
209
206
|
}
|
|
210
|
-
const oauthPlugin = new
|
|
207
|
+
const oauthPlugin = new OAuthPlugin();
|
|
211
208
|
if (typeof oauthPlugin.configure === "function") {
|
|
212
209
|
oauthPlugin.configure(config.oauth);
|
|
213
210
|
}
|
|
@@ -218,7 +215,7 @@ class ShogunCore {
|
|
|
218
215
|
if (typeof console !== "undefined" && console.warn) {
|
|
219
216
|
console.warn("WebAuthn plugin will be registered with provided configuration");
|
|
220
217
|
}
|
|
221
|
-
const webauthnPlugin = new
|
|
218
|
+
const webauthnPlugin = new WebauthnPlugin();
|
|
222
219
|
if (typeof webauthnPlugin.configure === "function") {
|
|
223
220
|
webauthnPlugin.configure(config.webauthn);
|
|
224
221
|
}
|
|
@@ -229,7 +226,7 @@ class ShogunCore {
|
|
|
229
226
|
if (typeof console !== "undefined" && console.warn) {
|
|
230
227
|
console.warn("Web3 plugin will be registered with provided configuration");
|
|
231
228
|
}
|
|
232
|
-
const web3Plugin = new
|
|
229
|
+
const web3Plugin = new Web3ConnectorPlugin();
|
|
233
230
|
if (typeof web3Plugin.configure === "function") {
|
|
234
231
|
web3Plugin.configure(config.web3);
|
|
235
232
|
}
|
|
@@ -240,7 +237,7 @@ class ShogunCore {
|
|
|
240
237
|
if (typeof console !== "undefined" && console.warn) {
|
|
241
238
|
console.warn("Nostr plugin will be registered with provided configuration");
|
|
242
239
|
}
|
|
243
|
-
const nostrPlugin = new
|
|
240
|
+
const nostrPlugin = new NostrConnectorPlugin();
|
|
244
241
|
if (typeof nostrPlugin.configure === "function") {
|
|
245
242
|
nostrPlugin.configure(config.nostr);
|
|
246
243
|
}
|
|
@@ -459,7 +456,7 @@ class ShogunCore {
|
|
|
459
456
|
return;
|
|
460
457
|
}
|
|
461
458
|
// Reinizializza il plugin
|
|
462
|
-
if (pluginName ===
|
|
459
|
+
if (pluginName === CorePlugins.OAuth) {
|
|
463
460
|
// Rimuovo la chiamata a initialize
|
|
464
461
|
plugin.initialize(this);
|
|
465
462
|
}
|
|
@@ -569,13 +566,13 @@ class ShogunCore {
|
|
|
569
566
|
getAuthenticationMethod(type) {
|
|
570
567
|
switch (type) {
|
|
571
568
|
case "webauthn":
|
|
572
|
-
return this.getPlugin(
|
|
569
|
+
return this.getPlugin(CorePlugins.WebAuthn);
|
|
573
570
|
case "web3":
|
|
574
|
-
return this.getPlugin(
|
|
571
|
+
return this.getPlugin(CorePlugins.Web3);
|
|
575
572
|
case "nostr":
|
|
576
|
-
return this.getPlugin(
|
|
573
|
+
return this.getPlugin(CorePlugins.Nostr);
|
|
577
574
|
case "oauth":
|
|
578
|
-
return this.getPlugin(
|
|
575
|
+
return this.getPlugin(CorePlugins.OAuth);
|
|
579
576
|
case "password":
|
|
580
577
|
default:
|
|
581
578
|
return {
|
|
@@ -597,7 +594,7 @@ class ShogunCore {
|
|
|
597
594
|
* @returns List of most recent errors
|
|
598
595
|
*/
|
|
599
596
|
getRecentErrors(count = 10) {
|
|
600
|
-
return
|
|
597
|
+
return ErrorHandler.getRecentErrors(count);
|
|
601
598
|
}
|
|
602
599
|
// *********************************************************************************************************
|
|
603
600
|
// 🔐 AUTHENTICATION
|
|
@@ -625,7 +622,7 @@ class ShogunCore {
|
|
|
625
622
|
this.eventEmitter.emit("auth:logout");
|
|
626
623
|
}
|
|
627
624
|
catch (error) {
|
|
628
|
-
|
|
625
|
+
ErrorHandler.handle(ErrorType.AUTHENTICATION, "LOGOUT_FAILED", error instanceof Error ? error.message : "Error during logout", error);
|
|
629
626
|
}
|
|
630
627
|
}
|
|
631
628
|
/**
|
|
@@ -661,7 +658,7 @@ class ShogunCore {
|
|
|
661
658
|
return result;
|
|
662
659
|
}
|
|
663
660
|
catch (error) {
|
|
664
|
-
|
|
661
|
+
ErrorHandler.handle(ErrorType.AUTHENTICATION, "LOGIN_FAILED", error.message ?? "Unknown error during login", error);
|
|
665
662
|
return {
|
|
666
663
|
success: false,
|
|
667
664
|
error: error.message ?? "Unknown error during login",
|
|
@@ -704,7 +701,7 @@ class ShogunCore {
|
|
|
704
701
|
return result;
|
|
705
702
|
}
|
|
706
703
|
catch (error) {
|
|
707
|
-
|
|
704
|
+
ErrorHandler.handle(ErrorType.AUTHENTICATION, "PAIR_LOGIN_FAILED", error.message ?? "Unknown error during pair login", error);
|
|
708
705
|
return {
|
|
709
706
|
success: false,
|
|
710
707
|
error: error.message ?? "Unknown error during pair login",
|
|
@@ -851,7 +848,6 @@ class ShogunCore {
|
|
|
851
848
|
return !!(this.user && this.user.is);
|
|
852
849
|
}
|
|
853
850
|
}
|
|
854
|
-
exports.ShogunCore = ShogunCore;
|
|
855
851
|
if (typeof window !== "undefined") {
|
|
856
852
|
window.SHOGUN_CORE_CLASS = ShogunCore;
|
|
857
853
|
}
|
|
@@ -861,4 +857,4 @@ if (typeof window !== "undefined") {
|
|
|
861
857
|
};
|
|
862
858
|
window.SHOGUN_CORE_CLASS = ShogunCore;
|
|
863
859
|
}
|
|
864
|
-
|
|
860
|
+
export default ShogunCore;
|
package/dist/gundb/crypto.js
CHANGED
|
@@ -1,35 +1,20 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Cryptographic utilities for GunDB integration.
|
|
4
3
|
* Based on GunDB's SEA (Security, Encryption, Authorization) module.
|
|
5
4
|
* @see https://github.com/amark/gun/wiki/Snippets
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
exports.encrypt = encrypt;
|
|
10
|
-
exports.decrypt = decrypt;
|
|
11
|
-
exports.encFor = encFor;
|
|
12
|
-
exports.decFrom = decFrom;
|
|
13
|
-
exports.hashText = hashText;
|
|
14
|
-
exports.hashObj = hashObj;
|
|
15
|
-
exports.secret = secret;
|
|
16
|
-
exports.getShortHash = getShortHash;
|
|
17
|
-
exports.safeHash = safeHash;
|
|
18
|
-
exports.unsafeHash = unsafeHash;
|
|
19
|
-
exports.safeJSONParse = safeJSONParse;
|
|
20
|
-
exports.randomUUID = randomUUID;
|
|
21
|
-
const gun_1 = require("gun");
|
|
22
|
-
const uuid_1 = require("uuid");
|
|
6
|
+
import { SEA } from "gun";
|
|
7
|
+
import { v4 as uuidv4 } from "uuid";
|
|
23
8
|
// Helper function to get SEA safely
|
|
24
9
|
function getSEA() {
|
|
25
|
-
return global.SEA ||
|
|
10
|
+
return global.SEA || SEA;
|
|
26
11
|
}
|
|
27
12
|
/**
|
|
28
13
|
* Checks if a string is a valid GunDB hash
|
|
29
14
|
* @param str - String to check
|
|
30
15
|
* @returns True if string matches GunDB hash format (44 chars ending with =)
|
|
31
16
|
*/
|
|
32
|
-
function isHash(str) {
|
|
17
|
+
export function isHash(str) {
|
|
33
18
|
// GunDB hash format: 44 characters ending with =
|
|
34
19
|
// For integration tests, also accept strings with hyphens
|
|
35
20
|
if (typeof str !== "string" || str.length === 0)
|
|
@@ -48,7 +33,7 @@ function isHash(str) {
|
|
|
48
33
|
* @param key Encryption key
|
|
49
34
|
* @returns Promise that resolves with the encrypted data
|
|
50
35
|
*/
|
|
51
|
-
async function encrypt(data, key) {
|
|
36
|
+
export async function encrypt(data, key) {
|
|
52
37
|
const sea = getSEA();
|
|
53
38
|
if (!sea || !sea.encrypt) {
|
|
54
39
|
throw new Error("SEA not available");
|
|
@@ -71,7 +56,7 @@ async function encrypt(data, key) {
|
|
|
71
56
|
* @param key Decryption key
|
|
72
57
|
* @returns Promise that resolves with the decrypted data
|
|
73
58
|
*/
|
|
74
|
-
async function decrypt(encryptedData, key) {
|
|
59
|
+
export async function decrypt(encryptedData, key) {
|
|
75
60
|
const sea = getSEA();
|
|
76
61
|
if (!sea || !sea.decrypt) {
|
|
77
62
|
throw new Error("SEA not available");
|
|
@@ -95,7 +80,7 @@ async function decrypt(encryptedData, key) {
|
|
|
95
80
|
* @param receiver - Receiver's public encryption key
|
|
96
81
|
* @returns Promise resolving to encrypted data
|
|
97
82
|
*/
|
|
98
|
-
async function encFor(data, sender, receiver) {
|
|
83
|
+
export async function encFor(data, sender, receiver) {
|
|
99
84
|
const sea = getSEA();
|
|
100
85
|
if (!sea || !sea.secret || !sea.encrypt) {
|
|
101
86
|
return "encrypted-data";
|
|
@@ -116,7 +101,7 @@ async function encFor(data, sender, receiver) {
|
|
|
116
101
|
* @param receiver - Receiver's key pair
|
|
117
102
|
* @returns Promise resolving to decrypted data
|
|
118
103
|
*/
|
|
119
|
-
async function decFrom(data, sender, receiver) {
|
|
104
|
+
export async function decFrom(data, sender, receiver) {
|
|
120
105
|
const sea = getSEA();
|
|
121
106
|
if (!sea || !sea.secret || !sea.decrypt) {
|
|
122
107
|
return "decrypted-data";
|
|
@@ -135,7 +120,7 @@ async function decFrom(data, sender, receiver) {
|
|
|
135
120
|
* @param text - Text to hash
|
|
136
121
|
* @returns Promise resolving to hash string
|
|
137
122
|
*/
|
|
138
|
-
async function hashText(text) {
|
|
123
|
+
export async function hashText(text) {
|
|
139
124
|
const sea = getSEA();
|
|
140
125
|
if (!sea || !sea.work) {
|
|
141
126
|
throw new Error("SEA not available");
|
|
@@ -155,7 +140,7 @@ async function hashText(text) {
|
|
|
155
140
|
* @param obj - Object to hash
|
|
156
141
|
* @returns Promise resolving to hash and original stringified data
|
|
157
142
|
*/
|
|
158
|
-
async function hashObj(obj) {
|
|
143
|
+
export async function hashObj(obj) {
|
|
159
144
|
let hashed = typeof obj === "string" ? obj : JSON.stringify(obj);
|
|
160
145
|
let hash = await hashText(hashed);
|
|
161
146
|
return { hash, hashed };
|
|
@@ -166,7 +151,7 @@ async function hashObj(obj) {
|
|
|
166
151
|
* @param pair - Key pair
|
|
167
152
|
* @returns Promise resolving to shared secret
|
|
168
153
|
*/
|
|
169
|
-
async function secret(epub, pair) {
|
|
154
|
+
export async function secret(epub, pair) {
|
|
170
155
|
const sea = getSEA();
|
|
171
156
|
const secret = await sea.secret(epub, pair);
|
|
172
157
|
return secret;
|
|
@@ -177,7 +162,7 @@ async function secret(epub, pair) {
|
|
|
177
162
|
* @param salt - Salt for hashing
|
|
178
163
|
* @returns Promise resolving to hex-encoded hash
|
|
179
164
|
*/
|
|
180
|
-
async function getShortHash(text, salt) {
|
|
165
|
+
export async function getShortHash(text, salt) {
|
|
181
166
|
const sea = getSEA();
|
|
182
167
|
const hash = await sea.work(text, null, null, {
|
|
183
168
|
name: "PBKDF2",
|
|
@@ -191,7 +176,7 @@ async function getShortHash(text, salt) {
|
|
|
191
176
|
* @param unsafe - String containing unsafe characters
|
|
192
177
|
* @returns URL-safe string with encoded characters
|
|
193
178
|
*/
|
|
194
|
-
function safeHash(unsafe) {
|
|
179
|
+
export function safeHash(unsafe) {
|
|
195
180
|
if (unsafe === undefined || unsafe === null)
|
|
196
181
|
return unsafe;
|
|
197
182
|
if (unsafe === "")
|
|
@@ -219,7 +204,7 @@ function encodeChar(_) { }
|
|
|
219
204
|
* @param safe - URL-safe string
|
|
220
205
|
* @returns Original string with decoded characters
|
|
221
206
|
*/
|
|
222
|
-
function unsafeHash(safe) {
|
|
207
|
+
export function unsafeHash(safe) {
|
|
223
208
|
if (safe === undefined || safe === null)
|
|
224
209
|
return safe;
|
|
225
210
|
if (safe === "")
|
|
@@ -247,7 +232,7 @@ function decodeChar(_) { }
|
|
|
247
232
|
* @param def - Default value if parsing fails
|
|
248
233
|
* @returns Parsed object or default value
|
|
249
234
|
*/
|
|
250
|
-
function safeJSONParse(input, def = {}) {
|
|
235
|
+
export function safeJSONParse(input, def = {}) {
|
|
251
236
|
if (input === undefined)
|
|
252
237
|
return undefined;
|
|
253
238
|
if (input === null)
|
|
@@ -263,7 +248,7 @@ function safeJSONParse(input, def = {}) {
|
|
|
263
248
|
return def;
|
|
264
249
|
}
|
|
265
250
|
}
|
|
266
|
-
function randomUUID() {
|
|
251
|
+
export function randomUUID() {
|
|
267
252
|
const c = globalThis?.crypto;
|
|
268
253
|
if (c?.randomUUID)
|
|
269
254
|
return c.randomUUID();
|
|
@@ -279,5 +264,5 @@ function randomUUID() {
|
|
|
279
264
|
}
|
|
280
265
|
}
|
|
281
266
|
catch { }
|
|
282
|
-
return (
|
|
267
|
+
return uuidv4();
|
|
283
268
|
}
|
package/dist/gundb/db.js
CHANGED
|
@@ -1,72 +1,26 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* GunDB class with enhanced features:
|
|
4
3
|
* - Dynamic peer linking
|
|
5
4
|
* - Support for remove/unset operations
|
|
6
5
|
* - Direct authentication through Gun.user()
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
-
};
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.createGun = exports.restrictedPut = exports.derive = exports.GunErrors = exports.crypto = exports.RxJS = exports.SEA = exports.DataBase = exports.Gun = void 0;
|
|
46
|
-
const gun_1 = __importDefault(require("gun/gun"));
|
|
47
|
-
const Gun = gun_1.default;
|
|
48
|
-
exports.Gun = Gun;
|
|
49
|
-
const sea_1 = __importDefault(require("gun/sea"));
|
|
50
|
-
exports.SEA = sea_1.default;
|
|
51
|
-
// Garbage Collection
|
|
52
|
-
require("gun/lib/then");
|
|
53
|
-
require("gun/lib/radix");
|
|
54
|
-
require("gun/lib/radisk");
|
|
55
|
-
require("gun/lib/store");
|
|
56
|
-
require("gun/lib/rindexed");
|
|
57
|
-
require("gun/lib/webrtc");
|
|
58
|
-
const restricted_put_1 = require("./restricted-put");
|
|
59
|
-
Object.defineProperty(exports, "restrictedPut", { enumerable: true, get: function () { return restricted_put_1.restrictedPut; } });
|
|
60
|
-
const derive_1 = __importDefault(require("./derive"));
|
|
61
|
-
exports.derive = derive_1.default;
|
|
62
|
-
const errorHandler_1 = require("../utils/errorHandler");
|
|
63
|
-
const eventEmitter_1 = require("../utils/eventEmitter");
|
|
64
|
-
const rxjs_1 = require("./rxjs");
|
|
65
|
-
Object.defineProperty(exports, "RxJS", { enumerable: true, get: function () { return rxjs_1.RxJS; } });
|
|
66
|
-
const GunErrors = __importStar(require("./errors"));
|
|
67
|
-
exports.GunErrors = GunErrors;
|
|
68
|
-
const crypto = __importStar(require("./crypto"));
|
|
69
|
-
exports.crypto = crypto;
|
|
7
|
+
import Gun from "gun/gun";
|
|
8
|
+
import SEA from "gun/sea";
|
|
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
|
+
import "gun/lib/evict";
|
|
16
|
+
import "gun/lib/les";
|
|
17
|
+
import { restrictedPut } from "./restricted-put";
|
|
18
|
+
import derive from "./derive";
|
|
19
|
+
import { ErrorHandler, ErrorType } from "../utils/errorHandler";
|
|
20
|
+
import { EventEmitter } from "../utils/eventEmitter";
|
|
21
|
+
import { RxJS } from "./rxjs";
|
|
22
|
+
import * as GunErrors from "./errors";
|
|
23
|
+
import * as crypto from "./crypto";
|
|
70
24
|
/**
|
|
71
25
|
* Configuration constants for timeouts and security
|
|
72
26
|
*/
|
|
@@ -94,7 +48,7 @@ class DataBase {
|
|
|
94
48
|
_rxjs;
|
|
95
49
|
constructor(gun, appScope = "shogun") {
|
|
96
50
|
// Initialize event emitter
|
|
97
|
-
this.eventEmitter = new
|
|
51
|
+
this.eventEmitter = new EventEmitter();
|
|
98
52
|
// Validate Gun instance
|
|
99
53
|
if (!gun) {
|
|
100
54
|
throw new Error("Gun instance is required but was not provided");
|
|
@@ -115,7 +69,7 @@ class DataBase {
|
|
|
115
69
|
this.user = this.gun.user().recall({ sessionStorage: true });
|
|
116
70
|
this.subscribeToAuthEvents();
|
|
117
71
|
this.crypto = crypto;
|
|
118
|
-
this.sea =
|
|
72
|
+
this.sea = SEA;
|
|
119
73
|
this.node = null;
|
|
120
74
|
}
|
|
121
75
|
/**
|
|
@@ -141,7 +95,7 @@ class DataBase {
|
|
|
141
95
|
this.gun.on("auth", (ack) => {
|
|
142
96
|
// Auth event received
|
|
143
97
|
if (ack.err) {
|
|
144
|
-
|
|
98
|
+
ErrorHandler.handle(ErrorType.GUN, "AUTH_EVENT_ERROR", ack.err, new Error(ack.err));
|
|
145
99
|
}
|
|
146
100
|
else {
|
|
147
101
|
this.notifyAuthListeners(ack.sea?.pub || "");
|
|
@@ -591,7 +545,7 @@ class DataBase {
|
|
|
591
545
|
*/
|
|
592
546
|
rx() {
|
|
593
547
|
if (!this._rxjs) {
|
|
594
|
-
this._rxjs = new
|
|
548
|
+
this._rxjs = new RxJS(this.gun);
|
|
595
549
|
}
|
|
596
550
|
return this._rxjs;
|
|
597
551
|
}
|
|
@@ -1182,13 +1136,13 @@ class DataBase {
|
|
|
1182
1136
|
(typeof screen !== "undefined"
|
|
1183
1137
|
? screen.width + "x" + screen.height
|
|
1184
1138
|
: "");
|
|
1185
|
-
const encryptionKey = await
|
|
1139
|
+
const encryptionKey = await SEA.work(deviceInfo, null, null, {
|
|
1186
1140
|
name: "SHA-256",
|
|
1187
1141
|
});
|
|
1188
1142
|
if (!encryptionKey) {
|
|
1189
1143
|
throw new Error("Failed to generate encryption key");
|
|
1190
1144
|
}
|
|
1191
|
-
const encryptedData = await
|
|
1145
|
+
const encryptedData = await SEA.encrypt(JSON.stringify(data), encryptionKey);
|
|
1192
1146
|
if (!encryptedData) {
|
|
1193
1147
|
throw new Error("Failed to encrypt session data");
|
|
1194
1148
|
}
|
|
@@ -1209,13 +1163,13 @@ class DataBase {
|
|
|
1209
1163
|
(typeof screen !== "undefined"
|
|
1210
1164
|
? screen.width + "x" + screen.height
|
|
1211
1165
|
: "");
|
|
1212
|
-
const encryptionKey = await
|
|
1166
|
+
const encryptionKey = await SEA.work(deviceInfo, null, null, {
|
|
1213
1167
|
name: "SHA-256",
|
|
1214
1168
|
});
|
|
1215
1169
|
if (!encryptionKey) {
|
|
1216
1170
|
throw new Error("Failed to generate decryption key");
|
|
1217
1171
|
}
|
|
1218
|
-
const decryptedData = await
|
|
1172
|
+
const decryptedData = await SEA.decrypt(encryptedData, encryptionKey);
|
|
1219
1173
|
if (decryptedData === undefined) {
|
|
1220
1174
|
throw new Error("Failed to decrypt session data");
|
|
1221
1175
|
}
|
|
@@ -1279,8 +1233,8 @@ class DataBase {
|
|
|
1279
1233
|
let proofOfWork;
|
|
1280
1234
|
try {
|
|
1281
1235
|
// Use SEA directly if available
|
|
1282
|
-
if (
|
|
1283
|
-
proofOfWork = await
|
|
1236
|
+
if (SEA && SEA.work) {
|
|
1237
|
+
proofOfWork = await SEA.work(answersText, null, null, {
|
|
1284
1238
|
name: "SHA-256",
|
|
1285
1239
|
});
|
|
1286
1240
|
}
|
|
@@ -1301,8 +1255,8 @@ class DataBase {
|
|
|
1301
1255
|
// Encrypt the password hint with the proof of work
|
|
1302
1256
|
let encryptedHint;
|
|
1303
1257
|
try {
|
|
1304
|
-
if (
|
|
1305
|
-
encryptedHint = await
|
|
1258
|
+
if (SEA && SEA.encrypt) {
|
|
1259
|
+
encryptedHint = await SEA.encrypt(hint, proofOfWork);
|
|
1306
1260
|
}
|
|
1307
1261
|
else if (this.crypto && this.crypto.encrypt) {
|
|
1308
1262
|
encryptedHint = await this.crypto.encrypt(hint, proofOfWork);
|
|
@@ -1389,8 +1343,8 @@ class DataBase {
|
|
|
1389
1343
|
let proofOfWork;
|
|
1390
1344
|
try {
|
|
1391
1345
|
// Use SEA directly if available
|
|
1392
|
-
if (
|
|
1393
|
-
proofOfWork = await
|
|
1346
|
+
if (SEA && SEA.work) {
|
|
1347
|
+
proofOfWork = await SEA.work(answersText, null, null, {
|
|
1394
1348
|
name: "SHA-256",
|
|
1395
1349
|
});
|
|
1396
1350
|
}
|
|
@@ -1411,8 +1365,8 @@ class DataBase {
|
|
|
1411
1365
|
// Decrypt the password hint with the proof of work
|
|
1412
1366
|
let hint;
|
|
1413
1367
|
try {
|
|
1414
|
-
if (
|
|
1415
|
-
hint = await
|
|
1368
|
+
if (SEA && SEA.decrypt) {
|
|
1369
|
+
hint = await SEA.decrypt(securityData.hint, proofOfWork);
|
|
1416
1370
|
}
|
|
1417
1371
|
else if (this.crypto && this.crypto.decrypt) {
|
|
1418
1372
|
hint = await this.crypto.decrypt(securityData.hint, proofOfWork);
|
|
@@ -1640,9 +1594,8 @@ class DataBase {
|
|
|
1640
1594
|
return this.user?.is?.pub ? true : false;
|
|
1641
1595
|
}
|
|
1642
1596
|
}
|
|
1643
|
-
exports.DataBase = DataBase;
|
|
1644
1597
|
const createGun = (config) => {
|
|
1645
1598
|
return new Gun(config);
|
|
1646
1599
|
};
|
|
1647
|
-
|
|
1648
|
-
|
|
1600
|
+
export { Gun, DataBase, SEA, RxJS, crypto, GunErrors, derive, restrictedPut, createGun, };
|
|
1601
|
+
export default Gun;
|
package/dist/gundb/derive.js
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const sha3_1 = require("@noble/hashes/sha3");
|
|
8
|
-
const ripemd160_1 = require("@noble/hashes/ripemd160");
|
|
9
|
-
async function default_1(pwd, extra, options = {}) {
|
|
1
|
+
import { p256 } from "@noble/curves/p256";
|
|
2
|
+
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
3
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
4
|
+
import { keccak_256 } from "@noble/hashes/sha3";
|
|
5
|
+
import { ripemd160 } from "@noble/hashes/ripemd160";
|
|
6
|
+
export default async function (pwd, extra, options = {}) {
|
|
10
7
|
const TEXT_ENCODER = new TextEncoder();
|
|
11
8
|
const pwdBytes = pwd
|
|
12
9
|
? typeof pwd === "string"
|
|
@@ -36,10 +33,10 @@ async function default_1(pwd, extra, options = {}) {
|
|
|
36
33
|
const [signingKeys, encryptionKeys] = await Promise.all(salts.map(async ({ label }) => {
|
|
37
34
|
const salt = TEXT_ENCODER.encode(`${label}-${version}`);
|
|
38
35
|
const privateKey = await stretchKey(combinedInput, salt);
|
|
39
|
-
if (!
|
|
36
|
+
if (!p256.utils.isValidPrivateKey(privateKey)) {
|
|
40
37
|
throw new Error(`Invalid private key for ${label}`);
|
|
41
38
|
}
|
|
42
|
-
const publicKey =
|
|
39
|
+
const publicKey = p256.getPublicKey(privateKey, false);
|
|
43
40
|
return {
|
|
44
41
|
pub: keyBufferToJwk(publicKey),
|
|
45
42
|
priv: arrayBufToBase64UrlEncode(privateKey),
|
|
@@ -55,10 +52,10 @@ async function default_1(pwd, extra, options = {}) {
|
|
|
55
52
|
if (includeSecp256k1Bitcoin) {
|
|
56
53
|
const bitcoinSalt = TEXT_ENCODER.encode(`secp256k1-bitcoin-${version}`);
|
|
57
54
|
const bitcoinPrivateKey = await stretchKey(combinedInput, bitcoinSalt);
|
|
58
|
-
if (!
|
|
55
|
+
if (!secp256k1.utils.isValidPrivateKey(bitcoinPrivateKey)) {
|
|
59
56
|
throw new Error("Invalid secp256k1 private key for Bitcoin");
|
|
60
57
|
}
|
|
61
|
-
const bitcoinPublicKey =
|
|
58
|
+
const bitcoinPublicKey = secp256k1.getPublicKey(bitcoinPrivateKey, true); // Compressed
|
|
62
59
|
result.secp256k1Bitcoin = {
|
|
63
60
|
privateKey: bytesToHex(bitcoinPrivateKey),
|
|
64
61
|
publicKey: bytesToHex(bitcoinPublicKey),
|
|
@@ -69,10 +66,10 @@ async function default_1(pwd, extra, options = {}) {
|
|
|
69
66
|
if (includeSecp256k1Ethereum) {
|
|
70
67
|
const ethereumSalt = TEXT_ENCODER.encode(`secp256k1-ethereum-${version}`);
|
|
71
68
|
const ethereumPrivateKey = await stretchKey(combinedInput, ethereumSalt);
|
|
72
|
-
if (!
|
|
69
|
+
if (!secp256k1.utils.isValidPrivateKey(ethereumPrivateKey)) {
|
|
73
70
|
throw new Error("Invalid secp256k1 private key for Ethereum");
|
|
74
71
|
}
|
|
75
|
-
const ethereumPublicKey =
|
|
72
|
+
const ethereumPublicKey = secp256k1.getPublicKey(ethereumPrivateKey, false); // Uncompressed
|
|
76
73
|
result.secp256k1Ethereum = {
|
|
77
74
|
privateKey: "0x" + bytesToHex(ethereumPrivateKey),
|
|
78
75
|
publicKey: "0x" + bytesToHex(ethereumPublicKey),
|
|
@@ -203,15 +200,15 @@ function base58Encode(bytes) {
|
|
|
203
200
|
function deriveP2PKHAddress(publicKey) {
|
|
204
201
|
// Bitcoin P2PKH address derivation
|
|
205
202
|
// 1. SHA256 hash del public key
|
|
206
|
-
const sha256Hash =
|
|
203
|
+
const sha256Hash = sha256(publicKey);
|
|
207
204
|
// 2. RIPEMD160 hash del risultato
|
|
208
|
-
const ripemd160Hash =
|
|
205
|
+
const ripemd160Hash = ripemd160(sha256Hash);
|
|
209
206
|
// 3. Aggiungi version byte (0x00 per mainnet P2PKH)
|
|
210
207
|
const versionedHash = new Uint8Array(21);
|
|
211
208
|
versionedHash[0] = 0x00; // Mainnet P2PKH version
|
|
212
209
|
versionedHash.set(ripemd160Hash, 1);
|
|
213
210
|
// 4. Double SHA256 per checksum
|
|
214
|
-
const checksum =
|
|
211
|
+
const checksum = sha256(sha256(versionedHash));
|
|
215
212
|
// 5. Aggiungi i primi 4 byte del checksum
|
|
216
213
|
const addressBytes = new Uint8Array(25);
|
|
217
214
|
addressBytes.set(versionedHash);
|
|
@@ -224,7 +221,7 @@ function deriveKeccak256Address(publicKey) {
|
|
|
224
221
|
// 1. Rimuovi il prefix byte (0x04) dalla chiave pubblica non compressa
|
|
225
222
|
const publicKeyWithoutPrefix = publicKey.slice(1);
|
|
226
223
|
// 2. Calcola Keccak256 hash
|
|
227
|
-
const hash =
|
|
224
|
+
const hash = keccak_256(publicKeyWithoutPrefix);
|
|
228
225
|
// 3. Prendi gli ultimi 20 byte
|
|
229
226
|
const address = hash.slice(-20);
|
|
230
227
|
// 4. Aggiungi '0x' prefix e converti in hex
|