gun-eth 1.3.6 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. package/dist/gun-eth-protocol.cjs.js +11528 -0
  2. package/dist/gun-eth-protocol.esm.js +11503 -0
  3. package/dist/gun-eth-protocol.js +18 -0
  4. package/dist/gun-eth-protocol.react.js +11503 -0
  5. package/dist/gun-eth-protocol.umd.js +18 -0
  6. package/jsdoc.json +7 -0
  7. package/package.json +28 -25
  8. package/rollup.config.js +80 -0
  9. package/src/index.js +160 -512
  10. package/src/lib/authentication/index.js +13 -0
  11. package/src/lib/authentication/isAuthenticated.js +20 -0
  12. package/src/lib/authentication/login.js +25 -0
  13. package/src/lib/authentication/register.js +58 -0
  14. package/src/lib/blockchain/ethereum.js +74 -0
  15. package/src/lib/blockchain/shine.js +204 -0
  16. package/src/lib/certificates/friendsCertificates.js +92 -0
  17. package/src/lib/certificates/index.js +44 -0
  18. package/src/lib/certificates/messagingCertificates.js +94 -0
  19. package/src/lib/friends/acceptFriendRequest.js +69 -0
  20. package/src/lib/friends/addFriendRequest.js +49 -0
  21. package/src/lib/friends/friendRequests.js +51 -0
  22. package/src/lib/friends/friendsList.js +57 -0
  23. package/src/lib/friends/index.js +36 -0
  24. package/src/lib/friends/rejectFriendRequest.js +31 -0
  25. package/src/lib/messaging/chatsList.js +42 -0
  26. package/src/lib/messaging/createChat.js +132 -0
  27. package/src/lib/messaging/index.js +36 -0
  28. package/src/lib/messaging/messageList.js +106 -0
  29. package/src/lib/messaging/sendMessage.js +132 -0
  30. package/src/lib/messaging/sendVoiceMessage.js +119 -0
  31. package/src/lib/notes/createNote.js +41 -0
  32. package/src/lib/notes/deleteNote.js +12 -0
  33. package/src/lib/notes/getNote.js +25 -0
  34. package/src/lib/notes/getUserNote.js +59 -0
  35. package/src/lib/notes/index.js +8 -0
  36. package/src/lib/notes/updateNotes.js +35 -0
  37. package/src/lib/post/createPost.js +17 -0
  38. package/src/lib/post/decryptPost.js +14 -0
  39. package/src/lib/post/deletePost.js +13 -0
  40. package/src/lib/post/encryptPost,js +16 -0
  41. package/src/lib/post/getPost.js +36 -0
  42. package/src/lib/post/index.js +9 -0
  43. package/src/lib/post/updatePost.js +16 -0
  44. package/src/state/gun.js +33 -0
  45. package/types/types.d.ts +244 -0
  46. package/TUTORIAL.md +0 -103
  47. package/src/examples/eth2gun.html +0 -163
  48. package/src/examples/gun2eth.html +0 -164
  49. package/src/examples/shine.html +0 -256
  50. /package/src/{abis → lib/blockchain/abis}/SHINE.json +0 -0
  51. /package/src/{contracts → lib/blockchain/contracts}/SHINE.sol +0 -0
package/src/index.js CHANGED
@@ -1,533 +1,181 @@
1
- (function (root, factory) {
2
- if (typeof define === "function" && define.amd) {
3
- define(["gun", "gun/sea", "ethers"], factory);
4
- } else if (typeof module === "object" && module.exports) {
5
- module.exports = factory(
6
- require("gun"),
7
- require("gun/sea"),
8
- require("ethers")
9
- );
10
- } else {
11
- factory(root.Gun, root.SEA, root.ethers);
12
- }
13
- })(typeof self !== "undefined" ? self : this, function (Gun, SEA, ethers) {
14
- console.log("Factory del plugin Gun-Eth chiamata");
15
-
16
- const MESSAGE_TO_SIGN = "Accesso a GunDB con Ethereum";
17
-
18
- // Funzione per verificare se ethers è disponibile
19
- function checkEthers() {
20
- if (typeof ethers === "undefined") {
21
- console.error(
22
- "Ethers.js non è disponibile. Assicurati che sia caricato prima di questo script."
1
+ import * as authentication from "./lib/authentication";
2
+ import * as certificates from "./lib/certificates";
3
+ import * as friends from "./lib/friends";
4
+ import * as messaging from "./lib/messaging";
5
+ import { gun, user } from "./state/gun";
6
+ import Gun from "gun";
7
+
8
+ import {
9
+ getEnsName,
10
+ getSigner,
11
+ getProvider,
12
+ setStandaloneConfig,
13
+ } from "./lib/blockchain/ethereum";
14
+
15
+ Gun.chain.GunEth = function (gun, SEA, ethers) {
16
+ console.log("gunEth called");
17
+ console.log("gun in gunEth:", gun);
18
+
19
+ return {
20
+ shine: (chain, nodeId, data, callback) =>
21
+ Gun.chain.shine.call(gun, chain, nodeId, data, callback),
22
+
23
+ setStandaloneConfig: (newRpcUrl, newPrivateKey) => {
24
+ console.log(
25
+ "setStandaloneConfig called with:",
26
+ newRpcUrl,
27
+ newPrivateKey
23
28
  );
24
- return false;
25
- }
26
- console.log("Ethers version:", ethers.version);
27
- return true;
28
- }
29
-
30
- // Global variables
31
- let SHINE_ABI = [
32
- {
33
- anonymous: false,
34
- inputs: [
35
- {
36
- indexed: true,
37
- internalType: "bytes",
38
- name: "nodeId",
39
- type: "bytes",
40
- },
41
- {
42
- indexed: false,
43
- internalType: "bytes32",
44
- name: "contentHash",
45
- type: "bytes32",
46
- },
47
- {
48
- indexed: false,
49
- internalType: "address",
50
- name: "updater",
51
- type: "address",
52
- },
53
- ],
54
- name: "DataUpdated",
55
- type: "event",
56
- },
57
- {
58
- inputs: [
59
- {
60
- internalType: "bytes[]",
61
- name: "nodeIds",
62
- type: "bytes[]",
63
- },
64
- {
65
- internalType: "bytes32[]",
66
- name: "contentHashes",
67
- type: "bytes32[]",
68
- },
69
- ],
70
- name: "batchUpdateData",
71
- outputs: [],
72
- stateMutability: "nonpayable",
73
- type: "function",
74
- },
75
- {
76
- inputs: [
77
- {
78
- internalType: "bytes",
79
- name: "nodeId",
80
- type: "bytes",
81
- },
82
- ],
83
- name: "getLatestRecord",
84
- outputs: [
85
- {
86
- internalType: "bytes32",
87
- name: "",
88
- type: "bytes32",
89
- },
90
- {
91
- internalType: "uint256",
92
- name: "",
93
- type: "uint256",
94
- },
95
- {
96
- internalType: "address",
97
- name: "",
98
- type: "address",
99
- },
100
- ],
101
- stateMutability: "view",
102
- type: "function",
103
- },
104
- {
105
- inputs: [
106
- {
107
- internalType: "bytes",
108
- name: "",
109
- type: "bytes",
110
- },
111
- ],
112
- name: "nodeData",
113
- outputs: [
114
- {
115
- internalType: "bytes32",
116
- name: "contentHash",
117
- type: "bytes32",
118
- },
119
- {
120
- internalType: "uint256",
121
- name: "timestamp",
122
- type: "uint256",
123
- },
124
- {
125
- internalType: "address",
126
- name: "updater",
127
- type: "address",
128
- },
129
- ],
130
- stateMutability: "view",
131
- type: "function",
29
+ setStandaloneConfig(newRpcUrl, newPrivateKey);
30
+ console.log("Standalone configuration set");
31
+ return this.gun;
132
32
  },
133
- {
134
- inputs: [
135
- {
136
- internalType: "bytes",
137
- name: "nodeId",
138
- type: "bytes",
139
- },
140
- {
141
- internalType: "bytes32",
142
- name: "contentHash",
143
- type: "bytes32",
144
- },
145
- ],
146
- name: "updateData",
147
- outputs: [],
148
- stateMutability: "nonpayable",
149
- type: "function",
150
- },
151
- {
152
- inputs: [
153
- {
154
- internalType: "bytes",
155
- name: "nodeId",
156
- type: "bytes",
157
- },
158
- {
159
- internalType: "bytes32",
160
- name: "contentHash",
161
- type: "bytes32",
162
- },
163
- ],
164
- name: "verifyData",
165
- outputs: [
166
- {
167
- internalType: "bool",
168
- name: "",
169
- type: "bool",
170
- },
171
- {
172
- internalType: "uint256",
173
- name: "",
174
- type: "uint256",
175
- },
176
- {
177
- internalType: "address",
178
- name: "",
179
- type: "address",
180
- },
181
- ],
182
- stateMutability: "view",
183
- type: "function",
184
- },
185
- ];
186
-
187
- let SHINE_OPTIMISM_SEPOLIA = "0x43D838b683F772F08f321E5FA265ad3e333BE9C2";
188
- let SHINE_CONTRACT_ADDRESS;
189
- let rpcUrl = "";
190
- let privateKey = "";
191
-
192
- /**
193
- * Funzione per ottenere il signer
194
- * @returns {Promise<ethers.Signer>} Il signer.
195
- */
196
- const getSigner = async () => {
197
- if (rpcUrl && privateKey) {
198
- // Modalità standalone
199
- const provider = new ethers.JsonRpcProvider(rpcUrl);
200
- return new ethers.Wallet(privateKey, provider);
201
- } else if (
202
- typeof window !== "undefined" &&
203
- typeof window.ethereum !== "undefined"
204
- ) {
205
- // Modalità browser
206
- await window.ethereum.request({ method: "eth_requestAccounts" });
207
- const provider = new ethers.BrowserProvider(window.ethereum);
208
- return provider.getSigner();
209
- } else {
210
- throw new Error("No valid Ethereum provider found");
211
- }
212
- };
213
-
214
- /**
215
- * Sets standalone configuration for Gun.
216
- * @param {string} newRpcUrl - The new RPC URL.
217
- * @param {string} newPrivateKey - The new private key.
218
- * @returns {Gun} The Gun instance for chaining.
219
- */
220
- Gun.chain.setStandaloneConfig = function (newRpcUrl, newPrivateKey) {
221
- rpcUrl = newRpcUrl;
222
- privateKey = newPrivateKey;
223
- console.log("Standalone configuration set");
224
- return this;
225
- };
226
33
 
227
- /**
228
- * Verifies an Ethereum signature.
229
- * @param {string} message - The original message that was signed.
230
- * @param {string} signature - The signature to verify.
231
- * @returns {Promise<string|null>} The recovered address or null if verification fails.
232
- */
233
- Gun.chain.verifySignature = async function (message, signature) {
234
- try {
235
- const recoveredAddress = ethers.verifyMessage(message, signature);
236
- return recoveredAddress;
237
- } catch (error) {
238
- console.error("Error verifying signature:", error);
239
- return null;
240
- }
241
- };
242
-
243
- /**
244
- * Generates a password from a signature.
245
- * @param {string} signature - The signature to derive the password from.
246
- * @returns {string|null} The generated password or null if generation fails.
247
- */
248
- Gun.chain.generatePassword = function (signature) {
249
- try {
250
- const hexSignature = ethers.hexlify(signature);
251
- const hash = ethers.keccak256(hexSignature);
252
- console.log("Generated password:", hash);
253
- return hash;
254
- } catch (error) {
255
- console.error("Error generating password:", error);
256
- return null;
257
- }
258
- };
259
-
260
- /**
261
- * Creates an Ethereum signature for a given message.
262
- * @param {string} message - The message to sign.
263
- * @returns {Promise<string|null>} The signature or null if signing fails.
264
- */
265
- Gun.chain.createSignature = async function (message) {
266
- try {
267
- // Verifica se il messaggio è uguale a MESSAGE_TO_SIGN
268
- if (message !== MESSAGE_TO_SIGN) {
269
- throw new Error(
270
- "Invalid message, valid message is: " + MESSAGE_TO_SIGN
271
- );
34
+ verifySignature: async (message, signature) => {
35
+ try {
36
+ return ethers.verifyMessage(message, signature);
37
+ } catch (error) {
38
+ console.error("Error verifying signature:", error);
39
+ return null;
272
40
  }
273
- const signer = await getSigner();
274
- const signature = await signer.signMessage(message);
275
- console.log("Signature created:", signature);
276
- return signature;
277
- } catch (error) {
278
- console.error("Error creating signature:", error);
279
- return null;
280
- }
281
- };
282
-
283
- /**
284
- * Creates and stores an encrypted key pair for a given address.
285
- * @param {string} address - The Ethereum address to associate with the key pair.
286
- * @param {string} signature - The signature to use for encryption.
287
- * @returns {Promise<void>}
288
- */
289
- Gun.chain.createAndStoreEncryptedPair = async function (address, signature) {
290
- try {
291
- const gun = this;
292
- const pair = await SEA.pair();
293
- const encryptedPair = await SEA.encrypt(JSON.stringify(pair), signature);
294
- await gun.get("gun-eth").get("users").get(address).put({ encryptedPair });
295
- console.log("Encrypted pair stored for:", address);
296
- } catch (error) {
297
- console.error("Error creating and storing encrypted pair:", error);
298
- }
299
- };
41
+ },
300
42
 
301
- /**
302
- * Retrieves and decrypts a stored key pair for a given address.
303
- * @param {string} address - The Ethereum address associated with the key pair.
304
- * @param {string} signature - The signature to use for decryption.
305
- * @returns {Promise<Object|null>} The decrypted key pair or null if retrieval fails.
306
- */
307
- Gun.chain.getAndDecryptPair = async function (address, signature) {
308
- try {
309
- const gun = this;
310
- const encryptedData = await gun
311
- .get("gun-eth")
312
- .get("users")
313
- .get(address)
314
- .get("encryptedPair")
315
- .then();
316
- if (!encryptedData) {
317
- throw new Error("No encrypted data found for this address");
43
+ generatePassword: (signature) => {
44
+ try {
45
+ const hexSignature = ethers.hexlify(signature);
46
+ const hash = ethers.keccak256(hexSignature);
47
+ console.log("Generated password:", hash);
48
+ return hash;
49
+ } catch (error) {
50
+ console.error("Error generating password:", error);
51
+ return null;
318
52
  }
319
- const decryptedPair = await SEA.decrypt(encryptedData, signature);
320
- console.log(decryptedPair);
321
- return decryptedPair;
322
- } catch (error) {
323
- console.error("Error retrieving and decrypting pair:", error);
324
- return null;
325
- }
326
- };
327
-
328
- /**
329
- * SHINE (Secure Hybrid Information and Network Environment) functionality.
330
- * @param {string} chain - The blockchain to use (e.g., "optimismSepolia").
331
- * @param {string} nodeId - The ID of the node to verify or write.
332
- * @param {Object} data - The data to write (if writing).
333
- * @param {Function} callback - Callback function to handle the result.
334
- * @returns {Gun} The Gun instance for chaining.
335
- */
336
- Gun.chain.shine = function (chain, nodeId, data, callback) {
337
- console.log("SHINE plugin called with:", { chain, nodeId, data });
338
-
339
- if (!checkEthers()) {
340
- if (callback) callback({ err: "Ethers.js non è disponibile" });
341
- return this;
342
- }
343
-
344
- if (typeof callback !== "function") {
345
- console.error("Callback must be a function");
346
- return this;
347
- }
348
-
349
- const gun = this;
350
-
351
- // Seleziona l'indirizzo basato sulla catena
352
- if (chain === "optimismSepolia") {
353
- SHINE_CONTRACT_ADDRESS = SHINE_OPTIMISM_SEPOLIA;
354
- } else {
355
- throw new Error("Chain not supported");
356
- }
357
-
358
- // Funzione per verificare on-chain
359
- const verifyOnChain = async (nodeId, contentHash) => {
360
- console.log("Verifying on chain:", { nodeId, contentHash });
361
- const signer = await getSigner();
362
- const contract = new ethers.Contract(
363
- SHINE_CONTRACT_ADDRESS,
364
- SHINE_ABI,
365
- signer
366
- );
367
- const [isValid, timestamp, updater] = await contract.verifyData(
368
- ethers.toUtf8Bytes(nodeId),
369
- contentHash
370
- );
371
- console.log("Verification result:", { isValid, timestamp, updater });
372
- return { isValid, timestamp, updater };
373
- };
374
-
375
- // Funzione per scrivere on-chain
376
- const writeOnChain = async (nodeId, contentHash) => {
377
- console.log("Writing on chain:", { nodeId, contentHash });
378
- const signer = await getSigner();
379
- const contract = new ethers.Contract(
380
- SHINE_CONTRACT_ADDRESS,
381
- SHINE_ABI,
382
- signer
383
- );
384
- const tx = await contract.updateData(
385
- ethers.toUtf8Bytes(nodeId),
386
- contentHash
387
- );
388
- console.log("Transaction sent:", tx.hash);
389
- const receipt = await tx.wait();
390
- console.log("Transaction confirmed:", receipt);
391
- return tx;
392
- };
393
-
394
- // Nuova funzione per ottenere l'ultimo record dalla blockchain
395
- const getLatestRecord = async (nodeId) => {
396
- const signer = await getSigner();
397
- const contract = new ethers.Contract(
398
- SHINE_CONTRACT_ADDRESS,
399
- SHINE_ABI,
400
- signer
401
- );
402
- const [contentHash, timestamp, updater] = await contract.getLatestRecord(
403
- ethers.toUtf8Bytes(nodeId)
404
- );
405
- console.log("Latest record from blockchain:", {
406
- nodeId,
407
- contentHash,
408
- timestamp,
409
- updater,
410
- });
411
- return { contentHash, timestamp, updater };
412
- };
53
+ },
413
54
 
414
- // Processo SHINE
415
- if (nodeId && !data) {
416
- // Caso 1: Utente passa solo il nodo
417
- gun.get(nodeId).once(async (existingData) => {
418
- if (!existingData) {
419
- if (callback) callback({ err: "Node not found in GunDB" });
420
- return;
421
- }
55
+ createSignature: async () => {
56
+ try {
57
+ const signer = await getSigner();
58
+ const signature = await signer.signMessage(
59
+ "GunDB access with Ethereum"
60
+ );
61
+ console.log("Signature created:", signature);
62
+ return signature;
63
+ } catch (error) {
64
+ console.error("Error creating signature:", error);
65
+ return null;
66
+ }
67
+ },
422
68
 
423
- console.log("existingData", existingData);
69
+ createAndStoreEncryptedPair: async (address, password) => {
70
+ try {
71
+ const pair = await user._.sea;
72
+ const encryptedPair = await SEA.encrypt(
73
+ JSON.stringify(pair),
74
+ password
75
+ );
424
76
 
425
- // Usa il contentHash memorizzato invece di ricalcolarlo
426
- const contentHash = existingData._contentHash;
427
- console.log("contentHash", contentHash);
77
+ // TODO: Add spending and viewing pairs implementation
78
+ // const encryptedSpendingPair = await SEA.encrypt(JSON.stringify(pair), password + "_spending");
79
+ // const encryptedViewingPair = await SEA.encrypt(JSON.stringify(pair), password + "_viewing");
428
80
 
429
- if (!contentHash) {
430
- if (callback)
431
- callback({ err: "No content hash found for this node" });
432
- return;
433
- }
81
+ let ethAccount;
434
82
 
435
83
  try {
436
- const { isValid, timestamp, updater } = await verifyOnChain(
437
- nodeId,
438
- contentHash
439
- );
440
- const latestRecord = await getLatestRecord(nodeId);
441
-
442
- if (isValid) {
443
- if (callback)
444
- callback({
445
- ok: true,
446
- message: "Data verified on blockchain",
447
- timestamp,
448
- updater,
449
- latestRecord,
450
- });
451
- } else {
452
- if (callback)
453
- callback({
454
- ok: false,
455
- message: "Data not verified on blockchain",
456
- latestRecord,
457
- });
458
- }
84
+ const ensName = await getEnsName(address);
85
+ ethAccount = ensName ? ensName : address;
459
86
  } catch (error) {
460
- if (callback) callback({ err: error.message });
87
+ console.error("Error getting ENS name:", error);
88
+ ethAccount = address;
461
89
  }
462
- });
463
- } else if (data && !nodeId) {
464
- // Caso 2: Utente passa solo il testo (data)
465
- const newNodeId = Gun.text.random();
466
- const dataString = JSON.stringify(data);
467
- const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
468
90
 
469
- gun
470
- .get(newNodeId)
471
- .put({ ...data, _contentHash: contentHash }, async (ack) => {
472
- console.log("ack", ack);
473
- if (ack.err) {
474
- if (callback) callback({ err: "Error saving data to GunDB" });
475
- return;
476
- }
91
+ const data = {
92
+ pub: encryptedPair.pub,
93
+ address: address,
94
+ ensName: ethAccount,
95
+ };
96
+
97
+ await gun
98
+ .get("gun-eth")
99
+ .get("users")
100
+ .get(address)
101
+ .put({ encryptedPair });
102
+ await gun
103
+ .get("gun-eth")
104
+ .get("usersData")
105
+ .get(encryptedPair.pub)
106
+ .put({ data });
107
+
108
+ await gun
109
+ .get(`~${encryptedPair.pub}`)
110
+ .get("safe")
111
+ .get("enc")
112
+ .put({ encryptedPair });
113
+
114
+ console.log("Encrypted pair stored for:", address);
115
+ } catch (error) {
116
+ console.error("Error creating and storing encrypted pair:", error);
117
+ }
118
+ },
477
119
 
478
- try {
479
- const tx = await writeOnChain(newNodeId, contentHash);
480
- if (callback)
481
- callback({
482
- ok: true,
483
- message: "Data written to GunDB and blockchain",
484
- nodeId: newNodeId,
485
- txHash: tx.hash,
486
- });
487
- } catch (error) {
488
- if (callback) callback({ err: error.message });
489
- }
490
- });
491
- } else {
492
- if (callback)
493
- callback({
494
- err: "Invalid input. Provide either nodeId or data, not both.",
495
- });
496
- }
120
+ getAndDecryptPair: async (address, password) => {
121
+ try {
122
+ const encryptedData = await gun
123
+ .get("gun-eth")
124
+ .get("users")
125
+ .get(address)
126
+ .get("encryptedPair")
127
+ .then();
128
+ if (!encryptedData) {
129
+ throw new Error("No encrypted data found for this address");
130
+ }
131
+ const decryptedPair = await SEA.decrypt(encryptedData, password);
132
+ console.log(decryptedPair);
133
+ return decryptedPair;
134
+ } catch (error) {
135
+ console.error("Error retrieving and decrypting pair:", error);
136
+ return null;
137
+ }
138
+ },
497
139
 
498
- return gun;
140
+ gunToEthAccount: (gunPrivateKey) => {
141
+ const base64UrlToHex = (base64url) => {
142
+ const padding = "=".repeat((4 - (base64url.length % 4)) % 4);
143
+ const base64 =
144
+ base64url.replace(/-/g, "+").replace(/_/g, "/") + padding;
145
+ const binaryString = atob(base64);
146
+ return Array.from(binaryString, (char) =>
147
+ char.charCodeAt(0).toString(16).padStart(2, "0")
148
+ ).join("");
149
+ };
150
+
151
+ const hexPrivateKey = "0x" + base64UrlToHex(gunPrivateKey);
152
+ const wallet = new ethers.Wallet(hexPrivateKey);
153
+ const publicKey = wallet.address;
154
+
155
+ return {
156
+ account: wallet,
157
+ publicKey: publicKey,
158
+ };
159
+ },
499
160
  };
161
+ };
162
+
163
+ const GunEthProtocol = () => {
164
+ return {
165
+ authentication,
166
+ certificates,
167
+ friends,
168
+ messaging,
169
+ gun,
170
+ user
171
+ }
172
+ }
500
173
 
501
- /**
502
- * Converts a Gun private key to an Ethereum account.
503
- * @param {string} gunPrivateKey - The Gun private key in base64url format.
504
- * @returns {Object} An object containing the Ethereum account and public key.
505
- */
506
- Gun.chain.gunToEthAccount = function (gunPrivateKey) {
507
- // Function to convert base64url to hex
508
- const base64UrlToHex = (base64url) => {
509
- const padding = "=".repeat((4 - (base64url.length % 4)) % 4);
510
- const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/") + padding;
511
- const binary = atob(base64);
512
- return Array.from(binary, (char) =>
513
- char.charCodeAt(0).toString(16).padStart(2, "0")
514
- ).join("");
515
- };
516
-
517
- // Convert Gun private key to hex format
518
- const hexPrivateKey = "0x" + base64UrlToHex(gunPrivateKey);
519
-
520
- // Create an Ethereum wallet from the private key
521
- const wallet = new ethers.Wallet(hexPrivateKey);
522
-
523
- // Get the public address (public key)
524
- const publicKey = wallet.address;
174
+ if (typeof window !== "undefined") {
175
+ window.Gun = gun;
176
+ window.GunEthProtocol = GunEthProtocol();
177
+ window.User = user;
178
+ }
525
179
 
526
- return {
527
- account: wallet,
528
- publicKey: publicKey,
529
- };
530
- };
180
+ export { authentication, certificates, friends, messaging, gun, user };
531
181
 
532
- console.log("Plugin Gun-Eth successfully loaded");
533
- });