gun-eth 1.4.32 → 1.4.34

Sign up to get free protection for your applications and to get access to all the features.
package/src/index.js CHANGED
@@ -1,50 +1,71 @@
1
- // =============================================
2
- // IMPORTS AND GLOBAL VARIABLES
3
- // =============================================
4
1
  import Gun from "gun";
5
- import SEA from "gun/sea.js";
6
2
  import { ethers } from "ethers";
7
- import {
8
- PROOF_OF_INTEGRITY_ABI,
9
- STEALTH_ANNOUNCER_ABI,
10
- getAddressesForChain,
3
+ import {
4
+ PROOF_OF_INTEGRITY_ABI,
5
+ STEALTH_ANNOUNCER_ABI,
6
+ getAddressesForChain,
11
7
  isLocalEnvironment,
12
- CHAIN_CONFIG
8
+ CHAIN_CONFIG,
13
9
  } from "./abis/abis.js";
14
10
  import { LOCAL_CONFIG } from "./config/local.js";
15
- import { fileURLToPath } from 'url';
16
- import { dirname } from 'path';
17
- import { readFileSync } from 'fs';
18
-
19
- let PROOF_CONTRACT_ADDRESS;
20
- let rpcUrl = "";
21
- let privateKey = "";
22
11
 
23
- export const MESSAGE_TO_SIGN = "Access GunDB with Ethereum";
12
+ import 'gun/sea.js'; // Questo modifica Gun globalmente
13
+ const SEA = Gun.SEA;
24
14
 
15
+ let PROOF_CONTRACT_ADDRESS;
25
16
  let contractAddresses = {
26
- PROOF_OF_INTEGRITY_ADDRESS: CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS,
27
- STEALTH_ANNOUNCER_ADDRESS: CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS
17
+ PROOF_OF_INTEGRITY_ADDRESS:
18
+ CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS,
19
+ STEALTH_ANNOUNCER_ADDRESS:
20
+ CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS,
28
21
  };
29
22
 
30
- // Solo per Node.js
31
- if (typeof window === 'undefined') {
32
- try {
33
- const __filename = fileURLToPath(import.meta.url);
34
- const __dirname = dirname(__filename);
35
-
23
+ // Funzione di inizializzazione per Node.js
24
+ const initNodeEnvironment = async () => {
25
+ if (typeof window === "undefined") {
36
26
  try {
37
- const rawdata = readFileSync(path.join(__dirname, 'contract-address.json'), 'utf8');
38
- contractAddresses = JSON.parse(rawdata);
39
- console.log('Loaded contract addresses:', contractAddresses);
40
- } catch (err) {
41
- console.warn('Warning: contract-address.json not found or invalid');
27
+ // Importazioni dinamiche
28
+ const { fileURLToPath } = await import("url");
29
+ const { dirname } = await import("path");
30
+ const { readFile } = await import("fs/promises");
31
+ const { join } = await import("path");
32
+
33
+ const __filename = fileURLToPath(import.meta.url);
34
+ const __dirname = dirname(__filename);
35
+
36
+ try {
37
+ const rawdata = await readFile(
38
+ join(__dirname, "contract-address.json"),
39
+ "utf8"
40
+ );
41
+ contractAddresses = JSON.parse(rawdata);
42
+ console.log("Loaded contract addresses:", contractAddresses);
43
+ } catch (err) {
44
+ console.warn("Warning: contract-address.json not found or invalid");
45
+ }
46
+ } catch (error) {
47
+ console.error("Error loading Node.js modules:", error);
42
48
  }
43
- } catch (error) {
44
- console.error('Error loading Node.js modules:', error);
45
49
  }
50
+ };
51
+
52
+ // Inizializza solo in ambiente Node.js
53
+ if (typeof window === "undefined") {
54
+ initNodeEnvironment();
46
55
  }
47
56
 
57
+ // ... resto del codice ...
58
+
59
+ // Esporta tutto ciò che serve
60
+ export {
61
+ Gun,
62
+ initNodeEnvironment,
63
+ // ... altre esportazioni ...
64
+ };
65
+
66
+ // Export default
67
+ export default Gun;
68
+
48
69
  // =============================================
49
70
  // UTILITY FUNCTIONS
50
71
  // =============================================
@@ -115,7 +136,7 @@ export const getSigner = async () => {
115
136
  if (rpcUrl && privateKey) {
116
137
  const provider = new ethers.JsonRpcProvider(rpcUrl, {
117
138
  chainId: LOCAL_CONFIG.CHAIN_ID,
118
- name: "localhost"
139
+ name: "localhost",
119
140
  });
120
141
  return new Wallet(privateKey, provider);
121
142
  } else if (
@@ -140,27 +161,24 @@ export function deriveStealthAddress(sharedSecret, spendingPublicKey) {
140
161
  try {
141
162
  const sharedSecretBytes = ethers.toUtf8Bytes(sharedSecret);
142
163
  const spendingPublicKeyBytes = ethers.toUtf8Bytes(spendingPublicKey);
143
-
164
+
144
165
  const stealthPrivateKey = ethers.keccak256(
145
- ethers.concat([
146
- sharedSecretBytes,
147
- spendingPublicKeyBytes
148
- ])
166
+ ethers.concat([sharedSecretBytes, spendingPublicKeyBytes])
149
167
  );
150
-
168
+
151
169
  const stealthWallet = new Wallet(stealthPrivateKey);
152
170
 
153
171
  console.log("Debug deriveStealthAddress:", {
154
172
  sharedSecretHex: stealthPrivateKey,
155
173
  spendingPublicKey,
156
174
  stealthPrivateKey,
157
- stealthAddress: stealthWallet.address
175
+ stealthAddress: stealthWallet.address,
158
176
  });
159
177
 
160
178
  return {
161
179
  stealthPrivateKey,
162
180
  stealthAddress: stealthWallet.address,
163
- wallet: stealthWallet
181
+ wallet: stealthWallet,
164
182
  };
165
183
  } catch (error) {
166
184
  console.error("Error in deriveStealthAddress:", error);
@@ -262,17 +280,21 @@ Gun.chain.createAndStoreEncryptedPair = async function (address, signature) {
262
280
  const viewingAccount = gunToEthAccount(v_pair.priv);
263
281
  const spendingAccount = gunToEthAccount(s_pair.priv);
264
282
 
265
- gun.get("gun-eth").get("users").get(address).put({
266
- pair: encryptedPair,
267
- v_pair: encryptedV_pair,
268
- s_pair: encryptedS_pair,
269
- publicKeys: {
270
- viewingPublicKey: v_pair.epub, // Use SEA encryption public key
271
- viewingPublicKey: v_pair.epub, // Use SEA encryption public key
272
- spendingPublicKey: spendingAccount.publicKey, // Use Ethereum address
273
- ethViewingAddress: viewingAccount.publicKey // Also save Ethereum address
274
- }
275
- });
283
+ gun
284
+ .get("gun-eth")
285
+ .get("users")
286
+ .get(address)
287
+ .put({
288
+ pair: encryptedPair,
289
+ v_pair: encryptedV_pair,
290
+ s_pair: encryptedS_pair,
291
+ publicKeys: {
292
+ viewingPublicKey: v_pair.epub, // Use SEA encryption public key
293
+ viewingPublicKey: v_pair.epub, // Use SEA encryption public key
294
+ spendingPublicKey: spendingAccount.publicKey, // Use Ethereum address
295
+ ethViewingAddress: viewingAccount.publicKey, // Also save Ethereum address
296
+ },
297
+ });
276
298
 
277
299
  console.log("Encrypted pairs and public keys stored for:", address);
278
300
  } catch (error) {
@@ -330,9 +352,9 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
330
352
 
331
353
  try {
332
354
  // Se siamo in localhost e in development, usa automaticamente la chain locale
333
- const targetChain = isLocalEnvironment() ? 'localhost' : chain;
355
+ const targetChain = isLocalEnvironment() ? "localhost" : chain;
334
356
  const chainConfig = getAddressesForChain(targetChain);
335
-
357
+
336
358
  console.log(`Using ${targetChain} configuration:`, chainConfig);
337
359
 
338
360
  // Usa gli indirizzi dalla configurazione
@@ -368,10 +390,7 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
368
390
  PROOF_OF_INTEGRITY_ABI,
369
391
  signer
370
392
  );
371
- const tx = await contract.updateData(
372
- toUtf8Bytes(nodeId),
373
- contentHash
374
- );
393
+ const tx = await contract.updateData(toUtf8Bytes(nodeId), contentHash);
375
394
  console.log("Transaction sent:", tx.hash);
376
395
  const receipt = await tx.wait();
377
396
  console.log("Transaction confirmed:", receipt);
@@ -398,7 +417,6 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
398
417
  return { contentHash, timestamp, updater };
399
418
  };
400
419
 
401
-
402
420
  if (nodeId && !data) {
403
421
  // Case 1: User passes only node
404
422
  gun.get(nodeId).once(async (existingData) => {
@@ -414,7 +432,8 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
414
432
  console.log("contentHash", contentHash);
415
433
 
416
434
  if (!contentHash) {
417
- if (callback) callback({ err: "No content hash found for this node" });
435
+ if (callback)
436
+ callback({ err: "No content hash found for this node" });
418
437
  return;
419
438
  }
420
439
 
@@ -506,10 +525,13 @@ Gun.chain.gunToEthAccount = function (gunPrivateKey) {
506
525
  * @param {string} signature - The sender's signature to access their keys
507
526
  * @returns {Promise<Object>} Object containing stealth addresses and keys
508
527
  */
509
- Gun.chain.generateStealthAddress = async function (recipientAddress, signature) {
528
+ Gun.chain.generateStealthAddress = async function (
529
+ recipientAddress,
530
+ signature
531
+ ) {
510
532
  try {
511
533
  const gun = this;
512
-
534
+
513
535
  // Get recipient's public keys
514
536
  const recipientData = await gun
515
537
  .get("gun-eth")
@@ -518,14 +540,21 @@ Gun.chain.generateStealthAddress = async function (recipientAddress, signature)
518
540
  .get("publicKeys")
519
541
  .then();
520
542
 
521
- if (!recipientData || !recipientData.viewingPublicKey || !recipientData.spendingPublicKey) {
543
+ if (
544
+ !recipientData ||
545
+ !recipientData.viewingPublicKey ||
546
+ !recipientData.spendingPublicKey
547
+ ) {
522
548
  throw new Error("Recipient's public keys not found");
523
549
  }
524
550
 
525
551
  // Get sender's keys
526
- const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);
552
+ const senderAddress = await this.verifySignature(
553
+ MESSAGE_TO_SIGN,
554
+ signature
555
+ );
527
556
  const password = generatePassword(signature);
528
-
557
+
529
558
  const senderData = await gun
530
559
  .get("gun-eth")
531
560
  .get("users")
@@ -540,16 +569,20 @@ Gun.chain.generateStealthAddress = async function (recipientAddress, signature)
540
569
  let spendingKeyPair;
541
570
  try {
542
571
  const decryptedData = await SEA.decrypt(senderData.s_pair, password);
543
- spendingKeyPair = typeof decryptedData === 'string' ?
544
- JSON.parse(decryptedData) :
545
- decryptedData;
572
+ spendingKeyPair =
573
+ typeof decryptedData === "string"
574
+ ? JSON.parse(decryptedData)
575
+ : decryptedData;
546
576
  } catch (error) {
547
577
  console.error("Error decrypting spending pair:", error);
548
578
  throw new Error("Unable to decrypt spending pair");
549
579
  }
550
580
 
551
581
  // Generate shared secret using SEA ECDH with encryption public key
552
- const sharedSecret = await SEA.secret(recipientData.viewingPublicKey, spendingKeyPair);
582
+ const sharedSecret = await SEA.secret(
583
+ recipientData.viewingPublicKey,
584
+ spendingKeyPair
585
+ );
553
586
 
554
587
  if (!sharedSecret) {
555
588
  throw new Error("Unable to generate shared secret");
@@ -565,9 +598,8 @@ Gun.chain.generateStealthAddress = async function (recipientAddress, signature)
565
598
  return {
566
599
  stealthAddress,
567
600
  senderPublicKey: spendingKeyPair.epub, // Use encryption public key
568
- spendingPublicKey: recipientData.spendingPublicKey
601
+ spendingPublicKey: recipientData.spendingPublicKey,
569
602
  };
570
-
571
603
  } catch (error) {
572
604
  console.error("Error generating stealth address:", error);
573
605
  throw error;
@@ -655,10 +687,14 @@ Gun.chain.recoverStealthFunds = async function (
655
687
  // Decrypt viewing and spending pairs
656
688
  let viewingKeyPair;
657
689
  try {
658
- const decryptedViewingData = await SEA.decrypt(encryptedData.v_pair, password);
659
- viewingKeyPair = typeof decryptedViewingData === 'string' ?
660
- JSON.parse(decryptedViewingData) :
661
- decryptedViewingData;
690
+ const decryptedViewingData = await SEA.decrypt(
691
+ encryptedData.v_pair,
692
+ password
693
+ );
694
+ viewingKeyPair =
695
+ typeof decryptedViewingData === "string"
696
+ ? JSON.parse(decryptedViewingData)
697
+ : decryptedViewingData;
662
698
  } catch (error) {
663
699
  console.error("Error decrypting keys:", error);
664
700
  throw new Error("Unable to decrypt keys");
@@ -683,7 +719,7 @@ Gun.chain.recoverStealthFunds = async function (
683
719
  console.error("Mismatch:", {
684
720
  recovered: recoveredAddress,
685
721
  expected: stealthAddress,
686
- sharedSecret
722
+ sharedSecret,
687
723
  });
688
724
  throw new Error("Recovered stealth address does not match");
689
725
  }
@@ -711,11 +747,14 @@ Gun.chain.announceStealthPayment = async function (
711
747
  senderPublicKey,
712
748
  spendingPublicKey,
713
749
  signature,
714
- options = { onChain: false, chain: 'optimismSepolia' }
750
+ options = { onChain: false, chain: "optimismSepolia" }
715
751
  ) {
716
752
  try {
717
753
  const gun = this;
718
- const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);
754
+ const senderAddress = await this.verifySignature(
755
+ MESSAGE_TO_SIGN,
756
+ signature
757
+ );
719
758
 
720
759
  if (options.onChain) {
721
760
  // On-chain announcement
@@ -742,24 +781,21 @@ Gun.chain.announceStealthPayment = async function (
742
781
  stealthAddress,
743
782
  { value: devFee }
744
783
  );
745
-
784
+
746
785
  console.log("Transaction sent:", tx.hash);
747
786
  const receipt = await tx.wait();
748
787
  console.log("Transaction confirmed:", receipt.hash);
749
-
788
+
750
789
  console.log("Stealth payment announced on-chain (dev fee paid)");
751
790
  } else {
752
791
  // Off-chain announcement (GunDB)
753
- gun
754
- .get("gun-eth")
755
- .get("stealth-payments")
756
- .set({
757
- stealthAddress,
758
- senderAddress,
759
- senderPublicKey,
760
- spendingPublicKey,
761
- timestamp: Date.now(),
762
- });
792
+ gun.get("gun-eth").get("stealth-payments").set({
793
+ stealthAddress,
794
+ senderAddress,
795
+ senderPublicKey,
796
+ spendingPublicKey,
797
+ timestamp: Date.now(),
798
+ });
763
799
  console.log("Stealth payment announced off-chain");
764
800
  }
765
801
  } catch (error) {
@@ -774,13 +810,18 @@ Gun.chain.announceStealthPayment = async function (
774
810
  * @param {string} signature - The signature to authenticate the user
775
811
  * @returns {Promise<Array>} List of stealth payments
776
812
  */
777
- Gun.chain.getStealthPayments = async function (signature, options = { source: 'both' }) {
813
+ Gun.chain.getStealthPayments = async function (
814
+ signature,
815
+ options = { source: "both" }
816
+ ) {
778
817
  try {
779
818
  const payments = [];
780
819
 
781
- if (options.source === 'onChain' || options.source === 'both') {
820
+ if (options.source === "onChain" || options.source === "both") {
782
821
  const signer = await getSigner();
783
- const chainConfig = getAddressesForChain(options.chain || 'optimismSepolia');
822
+ const chainConfig = getAddressesForChain(
823
+ options.chain || "optimismSepolia"
824
+ );
784
825
  const contractAddress = chainConfig.STEALTH_ANNOUNCER_ADDRESS;
785
826
 
786
827
  const contract = new Contract(
@@ -788,28 +829,32 @@ Gun.chain.getStealthPayments = async function (signature, options = { source: 'b
788
829
  STEALTH_ANNOUNCER_ABI,
789
830
  signer
790
831
  );
791
-
832
+
792
833
  try {
793
834
  // Get total number of announcements
794
835
  const totalAnnouncements = await contract.getAnnouncementsCount();
795
836
  const totalCount = Number(totalAnnouncements.toString());
796
837
  console.log("Total on-chain announcements:", totalCount);
797
-
838
+
798
839
  if (totalCount > 0) {
799
840
  // Get announcements in batches of 100
800
841
  const batchSize = 100;
801
842
  const lastIndex = totalCount - 1;
802
-
803
- for(let i = 0; i <= lastIndex; i += batchSize) {
843
+
844
+ for (let i = 0; i <= lastIndex; i += batchSize) {
804
845
  const toIndex = Math.min(i + batchSize - 1, lastIndex);
805
846
  const batch = await contract.getAnnouncementsInRange(i, toIndex);
806
-
847
+
807
848
  // For each announcement, try to decrypt
808
- for(const announcement of batch) {
849
+ for (const announcement of batch) {
809
850
  try {
810
851
  // Verify announcement is valid
811
- if (!announcement || !announcement.stealthAddress ||
812
- !announcement.senderPublicKey || !announcement.spendingPublicKey) {
852
+ if (
853
+ !announcement ||
854
+ !announcement.stealthAddress ||
855
+ !announcement.senderPublicKey ||
856
+ !announcement.spendingPublicKey
857
+ ) {
813
858
  console.log("Invalid announcement:", announcement);
814
859
  continue;
815
860
  }
@@ -821,20 +866,21 @@ Gun.chain.getStealthPayments = async function (signature, options = { source: 'b
821
866
  signature,
822
867
  announcement.spendingPublicKey
823
868
  );
824
-
869
+
825
870
  // If no errors thrown, announcement is for us
826
871
  payments.push({
827
872
  stealthAddress: announcement.stealthAddress,
828
873
  senderPublicKey: announcement.senderPublicKey,
829
874
  spendingPublicKey: announcement.spendingPublicKey,
830
875
  timestamp: Number(announcement.timestamp),
831
- source: 'onChain',
832
- wallet: recoveredWallet
876
+ source: "onChain",
877
+ wallet: recoveredWallet,
833
878
  });
834
-
835
879
  } catch (e) {
836
880
  // Not for us, continue
837
- console.log(`Announcement not for us: ${announcement.stealthAddress}`);
881
+ console.log(
882
+ `Announcement not for us: ${announcement.stealthAddress}`
883
+ );
838
884
  continue;
839
885
  }
840
886
  }
@@ -845,7 +891,7 @@ Gun.chain.getStealthPayments = async function (signature, options = { source: 'b
845
891
  }
846
892
  }
847
893
 
848
- if (options.source === 'offChain' || options.source === 'both') {
894
+ if (options.source === "offChain" || options.source === "both") {
849
895
  // Get off-chain payments
850
896
  const gun = this;
851
897
  const offChainPayments = await new Promise((resolve) => {
@@ -857,12 +903,12 @@ Gun.chain.getStealthPayments = async function (signature, options = { source: 'b
857
903
  .map()
858
904
  .once((payment, id) => {
859
905
  if (payment?.stealthAddress) {
860
- p.push({ ...payment, id, source: 'offChain' });
906
+ p.push({ ...payment, id, source: "offChain" });
861
907
  }
862
908
  });
863
909
  setTimeout(() => resolve(p), 2000);
864
910
  });
865
-
911
+
866
912
  payments.push(...offChainPayments);
867
913
  }
868
914
 
@@ -879,7 +925,7 @@ Gun.chain.getStealthPayments = async function (signature, options = { source: 'b
879
925
  * @param {string} recipientAddress - The recipient's address
880
926
  * @returns {Promise<void>}
881
927
  */
882
- Gun.chain.cleanStealthPayments = async function(recipientAddress) {
928
+ Gun.chain.cleanStealthPayments = async function (recipientAddress) {
883
929
  try {
884
930
  const gun = this;
885
931
  const payments = await gun
@@ -894,7 +940,12 @@ Gun.chain.cleanStealthPayments = async function(recipientAddress) {
894
940
  if (payments) {
895
941
  Object.keys(payments).forEach(async (key) => {
896
942
  const payment = payments[key];
897
- if (!payment || !payment.stealthAddress || !payment.senderPublicKey || !payment.spendingPublicKey) {
943
+ if (
944
+ !payment ||
945
+ !payment.stealthAddress ||
946
+ !payment.senderPublicKey ||
947
+ !payment.spendingPublicKey
948
+ ) {
898
949
  await gun
899
950
  .get("gun-eth")
900
951
  .get("stealth-payments")
@@ -921,7 +972,7 @@ export class GunEth {
921
972
  static gunToEthAccount = gunToEthAccount;
922
973
  static getSigner = getSigner;
923
974
  static deriveStealthAddress = deriveStealthAddress;
924
-
975
+
925
976
  // Chain methods
926
977
  static chainMethods = {
927
978
  setSigner: Gun.chain.setSigner,
@@ -938,7 +989,7 @@ export class GunEth {
938
989
  recoverStealthFunds: Gun.chain.recoverStealthFunds,
939
990
  announceStealthPayment: Gun.chain.announceStealthPayment,
940
991
  getStealthPayments: Gun.chain.getStealthPayments,
941
- cleanStealthPayments: Gun.chain.cleanStealthPayments
992
+ cleanStealthPayments: Gun.chain.cleanStealthPayments,
942
993
  };
943
994
 
944
995
  // Constants
@@ -946,6 +997,3 @@ export class GunEth {
946
997
  static PROOF_CONTRACT_ADDRESS = PROOF_CONTRACT_ADDRESS;
947
998
  static LOCAL_CONFIG = LOCAL_CONFIG;
948
999
  }
949
-
950
- // Esporta Gun come default
951
- export default Gun;