gun-eth 1.2.7 → 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/README.md +86 -21
  2. package/TUTORIAL.md +103 -0
  3. package/package.json +2 -2
  4. package/{index.js → src/index.js} +90 -39
  5. package/.yarn/cache/@adraffy-ens-normalize-npm-1.10.1-e60d7ca58d-0836f394ea.zip +0 -0
  6. package/.yarn/cache/@noble-curves-npm-1.2.0-9b40ee1239-bb798d7a66.zip +0 -0
  7. package/.yarn/cache/@noble-hashes-npm-1.3.2-1e619f9da0-fe23536b43.zip +0 -0
  8. package/.yarn/cache/@peculiar-asn1-schema-npm-2.3.13-7e52f15480-245cf39899.zip +0 -0
  9. package/.yarn/cache/@peculiar-json-schema-npm-1.1.12-f914d2ea65-b26ececdc2.zip +0 -0
  10. package/.yarn/cache/@peculiar-webcrypto-npm-1.5.0-4d84865c57-9022d7452d.zip +0 -0
  11. package/.yarn/cache/@types-node-npm-18.15.13-14d4d1b98f-79cc5a2b5f.zip +0 -0
  12. package/.yarn/cache/aes-js-npm-4.0.0-beta.5-c70da65547-cc2ea969d7.zip +0 -0
  13. package/.yarn/cache/asn1js-npm-3.0.5-cf5558af33-3b6af1bbad.zip +0 -0
  14. package/.yarn/cache/ethers-npm-6.13.2-177cd791bd-981860c736.zip +0 -0
  15. package/.yarn/cache/gun-npm-0.2020.1240-e808e9ee90-0effb70596.zip +0 -0
  16. package/.yarn/cache/pvtsutils-npm-1.3.5-b3122eabea-e734516b3c.zip +0 -0
  17. package/.yarn/cache/pvutils-npm-1.1.3-da8b07d6cf-2ee26a9e51.zip +0 -0
  18. package/.yarn/cache/tslib-npm-2.4.0-9cb6dc5030-8c4aa6a3c5.zip +0 -0
  19. package/.yarn/cache/tslib-npm-2.7.0-21668f5c21-1606d5c89f.zip +0 -0
  20. package/.yarn/cache/webcrypto-core-npm-1.8.0-b7c655d14a-4f128f5283.zip +0 -0
  21. package/.yarn/cache/ws-npm-7.5.10-878ccb886b-f9bb062abf.zip +0 -0
  22. package/.yarn/cache/ws-npm-8.17.1-f57fb24a2c-442badcce1.zip +0 -0
  23. package/.yarn/install-state.gz +0 -0
  24. /package/{SHINE.json → abis/SHINE.json} +0 -0
  25. /package/{SHINE.sol → contracts/SHINE.sol} +0 -0
package/README.md CHANGED
@@ -1,93 +1,147 @@
1
- # gun-eth
1
+ # GUN-ETH
2
2
 
3
- ## Description
3
+ <img src="https://imgs.search.brave.com/RM76D4wyToxCzGffJLw33O_L3glhpIVS3KLvXehpMt8/rs:fit:500:0:0:0/g:ce/aHR0cHM6Ly93d3cu/dXNlcmxvZ29zLm9y/Zy9maWxlcy9sb2dv/cy9mZXJuYW5kb3Nh/bnR1Y2NpLzI5NDY5/X2d1bmRiLWxvZ28u/cG5n" alt="gun" width="200"/>
4
+ <img src="https://imgs.search.brave.com/kQyriTMPqw42DEhIQj3eEKIcLZu_C4nNIVR8KtAn3lo/rs:fit:500:0:0:0/g:ce/aHR0cHM6Ly93d3cu/bG9nby53aW5lL2Ev/bG9nby9FdGhlcmV1/bS9FdGhlcmV1bS1E/aWFtb25kLUxvZ28u/d2luZS5zdmc" alt="eth" width="200"/>
4
5
 
5
- gun-eth is a plugin for GunDB that integrates Ethereum and Web3 functionality. This plugin extends GunDB's capabilities by allowing interaction with the Ethereum blockchain and providing cryptographic and signature management features.
6
+ ## Table of Contents
7
+
8
+ 1. [Description](#description)
9
+ 2. [Smart Contract](#smart-contract)
10
+ 3. [Key Features](#key-features)
11
+ 4. [How to Install](#how-to-install)
12
+ 5. [How to Use](#how-to-use)
13
+ 6. [Core Functions](#core-functions)
14
+ 7. [SHINE](#shine)
15
+ 8. [Standalone Mode](#standalone-mode)
16
+ 9. [Security Considerations](#security-considerations)
17
+ 10. [Contributing](#contributing)
18
+ 11. [License](#license)
19
+ 12. [Contact](#contact)
20
+
21
+ ## DESCRIPTION
22
+
23
+ Gun-eth is a plugin for GunDB that integrates Ethereum and Web3 functionality. This plugin extends GunDB's capabilities by allowing interaction with the Ethereum blockchain and providing cryptographic and signature management features.
24
+
25
+ ## SMART CONTRACT
6
26
 
7
27
  SHINE Smart Contract deployed on Optimism Sepolia: [0x43D838b683F772F08f321E5FA265ad3e333BE9C2](https://sepolia-optimism.etherscan.io/address/0x43D838b683F772F08f321E5FA265ad3e333BE9C2)
8
28
 
9
29
  Currently, the contract is deployed only on Optimism Sepolia. In the future, it will be deployed on multiple chains.
10
30
 
11
- ### Key Features
31
+ ## No time? Check the [TUTORIAL](./TUTORIAL.md)
32
+
33
+ ## KEY FEATURES
12
34
 
13
35
  - **Ethereum Signature Verification**: Verify Ethereum signatures for messages.
14
36
  - **Password Generation**: Generate secure passwords from Ethereum signatures.
15
37
  - **Signature Creation**: Create Ethereum signatures for messages.
16
38
  - **Encrypted Key Pair Management**: Create, store, and retrieve encrypted key pairs.
17
39
  - **SHINE Implementation**: Implement the SHINE for data verification on the blockchain.
40
+ - **Custom Token Management**: Set and retrieve custom tokens for Gun operations.
18
41
 
19
- ### How to install
42
+ ## HOW TO INSTALL
20
43
 
21
44
  ```bash
22
45
  npm install gun-eth
23
46
  ```
24
47
 
25
- ```bash
48
+ ```javascript
26
49
  import gun from "gun";
27
50
  import "gun-eth";
28
51
 
29
- const gun = gun();
52
+ const gun = Gun();
30
53
 
31
54
  await gun.generatePassword("YOUR_SIGNATURE");
32
55
  ```
33
56
 
34
- ### How to use
57
+ ## HOW TO USE
35
58
 
36
59
  Learn more about Gun.js [here](https://gun.eco/docs/Getting-Started).
37
60
 
38
61
  Learn more about plugin implementation [here](https://github.com/amark/gun/wiki/Adding-Methods-to-the-Gun-Chain#abstraction-layers).
39
62
 
40
- ### Core Functions
63
+ ## CORE FUNCTIONS
41
64
 
42
65
  - `verifySignature(message, signature)`: Verifies an Ethereum signature for a given message.
43
66
 
44
- ```js
67
+ ```javascript
45
68
  const recoveredAddress = await gun.verifySignature(message, signature);
46
69
  ```
47
70
 
48
71
  - `generatePassword(signature)`: Generates a password from an Ethereum signature.
49
72
 
50
- ```js
73
+ ```javascript
51
74
  const password = gun.generatePassword(signature);
52
75
  ```
53
76
 
54
77
  - `createSignature(message)`: Creates an Ethereum signature for a message.
55
78
 
56
- ```js
79
+ ```javascript
57
80
  const signature = await gun.createSignature(message);
58
81
  ```
59
82
 
60
83
  - `createAndStoreEncryptedPair(address, signature)`: Creates and stores an encrypted key pair.
61
84
 
62
- ```js
85
+ ```javascript
63
86
  await gun.createAndStoreEncryptedPair(address, signature);
64
87
  ```
65
88
 
66
89
  - `getAndDecryptPair(address, signature)`: Retrieves and decrypts a stored key pair.
67
90
 
68
- ```js
91
+ ```javascript
69
92
  const decryptedPair = await gun.getAndDecryptPair(address, signature);
70
93
  ```
71
94
 
72
95
  - `shine(chain, nodeId, data, callback)`: Implements SHINE for data verification and storage on the blockchain.
73
- ```js
96
+
97
+ ```javascript
74
98
  gun.shine("optimismSepolia", nodeId, data, callback);
75
99
  ```
76
100
 
77
- ### SHINE
101
+ - `setToken(token)`: Sets a custom token for Gun operations.
102
+
103
+ ```javascript
104
+ gun.setToken("yourCustomToken");
105
+ ```
106
+
107
+ - `getToken()`: Retrieves the current custom token.
108
+
109
+ ```javascript
110
+ const currentToken = gun.getToken();
111
+ ```
112
+
113
+ ## SHINE
78
114
 
79
115
  SHINE (Secure Hash Integrity Network Ethereum) provides a mechanism for verifying data integrity using Ethereum and Gun.js.
80
116
 
81
- 1. **Data Storage**: When saving data, a content hash is generated and stored in both Gun.js and on the Ethereum blockchain.
82
- 2. **Data Verification**: To verify data, the stored hash is compared with a hash generated from the data retrieved from Gun.js.
83
- 3. **Blockchain Interaction**: The plugin interacts with an Ethereum smart contract to store and verify data hashes.
117
+ #### SHINE Contract Configuration
118
+
119
+ Currently, SHINE supports only the Optimism Sepolia network. The contract address is managed internally:
120
+
121
+ ```javascript
122
+ const SHINE_OPTIMISM_SEPOLIA = "0x43D838b683F772F08f321E5FA265ad3e333BE9C2";
123
+ ```
124
+
125
+ To support other chains in the future, the plugin will select the appropriate address based on the `chain` parameter provided to the `shine` function.
126
+
127
+ #### SHINE Helper Functions
128
+
129
+ SHINE uses several internal helper functions to interact with the blockchain:
130
+
131
+ - `getSigner()`: Retrieves an Ethereum signer from the browser provider (e.g., MetaMask).
132
+ - `verifyOnChain(nodeId, contentHash)`: Verifies data integrity on the blockchain.
133
+ - `writeOnChain(nodeId, contentHash)`: Writes the content hash to the blockchain.
134
+ - `getLatestRecord(nodeId)`: Retrieves the latest record associated with a nodeId from the blockchain.
135
+
136
+ These functions are used internally by the `shine` method and are not directly exposed to the user.
84
137
 
85
138
  ### Usage Examples
86
139
 
87
140
  #### Verifying Data by NodeId
88
141
 
89
- ```js
142
+ ```javascript
90
143
  const nodeId = "your-node-id-here";
144
+
91
145
  gun.shine("optimismSepolia", nodeId, null, (ack) => {
92
146
  if (ack.ok) {
93
147
  console.log("Data verified on blockchain", ack);
@@ -102,8 +156,9 @@ gun.shine("optimismSepolia", nodeId, null, (ack) => {
102
156
 
103
157
  #### Storing New Data
104
158
 
105
- ```js
159
+ ```javascript
106
160
  const data = { message: "Hello, blockchain!" };
161
+
107
162
  gun.shine("optimismSepolia", null, data, (ack) => {
108
163
  if (ack.ok) {
109
164
  console.log("Data stored on Gun.js and blockchain", ack);
@@ -115,6 +170,16 @@ gun.shine("optimismSepolia", null, data, (ack) => {
115
170
  });
116
171
  ```
117
172
 
173
+ ## STANDALONE MODE
174
+
175
+ For users who want to run the plugin without a browser wallet, you can use the standalone mode. This requires setting up an RPC URL and a private key:
176
+
177
+ ```javascript
178
+ gun.setStandaloneConfig("https://your-rpc-url", "your-private-key");
179
+ ```
180
+
181
+ Make sure to keep your private key secure and never expose it in client-side code.
182
+
118
183
  ### Security Considerations
119
184
 
120
185
  - Use a secure Ethereum provider (e.g., MetaMask) when interacting with functions that require signatures.
package/TUTORIAL.md ADDED
@@ -0,0 +1,103 @@
1
+ # Tutorial: Illuminating Your Data with SHINE in GunDB 🌟
2
+
3
+ Hey there, GunDB aficionado! Ready to take your decentralized data game to the next level? Enter SHINE: your ticket to blockchain-verified data integrity. It's not just about storing data anymore; it's about making it cryptographically awesome!
4
+
5
+ ## Step 0: Wallet Integration - Your Blockchain Passport
6
+
7
+ Before we dive into the SHINE pool, remember: this plugin requires a browser-based wallet provider. Think of it as your blockchain passport. Here's how to check if you're ready to roll:
8
+
9
+ ```javascript
10
+ async function connectWallet() {
11
+ if (typeof window.ethereum !== "undefined") {
12
+ console.log("Ethereum object detected");
13
+ try {
14
+ await window.ethereum.request({ method: "eth_requestAccounts" });
15
+ console.log("Wallet connected successfully");
16
+ return true;
17
+ } catch (error) {
18
+ console.error("Wallet connection denied:", error);
19
+ return false;
20
+ }
21
+ } else {
22
+ console.log(
23
+ "Please install MetaMask or another Ethereum-compatible wallet"
24
+ );
25
+ return false;
26
+ }
27
+ }
28
+
29
+ // Make sure to call this before using SHINE
30
+ await connectWallet();
31
+ ```
32
+
33
+ Pro tip: Always ensure your wallet is connected before invoking SHINE functions. No wallet, no blockchain magic!
34
+
35
+ ## Step 1: Installation - Equipping Your Toolbelt
36
+
37
+ Let's add SHINE to your development arsenal:
38
+
39
+ ```bash
40
+ npm install gun-eth
41
+ ```
42
+
43
+ If your terminal responds without errors, you're locked and loaded!
44
+
45
+ ## Step 2: Import - Assembling the Pieces
46
+
47
+ Time to bring Gun and SHINE into your JavaScript playground:
48
+
49
+ ```javascript
50
+ import Gun from "gun";
51
+ import "gun-eth";
52
+ const gun = Gun();
53
+ ```
54
+
55
+ ## Step 3: SHINE in Action - Blockchain Meets Database
56
+
57
+ Let's say you've got some mission-critical data to store. Here's how you'd use SHINE to give it that blockchain-grade integrity:
58
+
59
+ ```javascript
60
+ const criticalData = {
61
+ key1: "Encrypted message",
62
+ key2: "Top secret algorithm",
63
+ key3: "42",
64
+ };
65
+
66
+ gun.shine("optimismSepolia", null, criticalData, (ack) => {
67
+ if (ack.ok) {
68
+ console.log("Data successfully anchored to the blockchain");
69
+ console.log("Node ID for future reference:", ack.nodeId);
70
+ } else {
71
+ console.error("Blockchain anchoring failed:", ack.err);
72
+ }
73
+ });
74
+ ```
75
+
76
+ Remember, your wallet needs to be ready to sign this transaction. It's like pushing code without commit access - it just won't fly!
77
+
78
+ ## Step 4: Verification - Trust the Crypto, Not the Hearsay
79
+
80
+ When it's time to verify your data's integrity:
81
+
82
+ ```javascript
83
+ const nodeId = "your-data-node-id";
84
+ gun.shine("optimismSepolia", nodeId, null, (ack) => {
85
+ if (ack.ok) {
86
+ console.log("Data integrity verified on the blockchain");
87
+ console.log("Timestamp:", ack.timestamp);
88
+ console.log("Last updater:", ack.updater);
89
+ } else {
90
+ console.error("Integrity check failed:", ack.err);
91
+ }
92
+ });
93
+ ```
94
+
95
+ Again, wallet connection is crucial. No blockchain access, no verification!
96
+
97
+ ## Step 5: Reap the Benefits
98
+
99
+ Congratulations! You've just leveled up your data management game. Your data is now cryptographically verifiable, tamper-evident, and blockchain-secured.
100
+
101
+ Remember: With SHINE, you're not just storing data; you're creating a cryptographic proof of its existence and integrity. Use this power wisely!
102
+
103
+ P.S. SHINE responsibly. With great cryptographic power comes great responsibility. Happy coding, and may your data always maintain its integrity! 🚀🔐
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "gun-eth",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "description": "A GunDB plugin for Ethereum, and Web3",
5
- "main": "index.js",
5
+ "main": "./src/index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
8
8
  },
@@ -1,98 +1,136 @@
1
1
  const Gun = require("gun/gun");
2
2
  const SEA = require("gun/sea");
3
3
  const ethers = require("ethers");
4
- const SHINE = require("./SHINE.json");
4
+ const SHINE = require("../abis/SHINE.json");
5
5
 
6
6
  const SHINE_ABI = SHINE.abi;
7
7
  const SHINE_OPTIMISM_SEPOLIA = SHINE.address;
8
8
 
9
9
  let SHINE_CONTRACT_ADDRESS;
10
-
11
10
  let customToken = "";
12
11
 
12
+ let rpcUrl = "";
13
+ let privateKey = "";
14
+
15
+ /**
16
+ * Sets standalone configuration for Gun.
17
+ * @param {string} newRpcUrl - The new RPC URL.
18
+ * @param {string} newPrivateKey - The new private key.
19
+ * @returns {Gun} The Gun instance for chaining.
20
+ */
21
+ Gun.chain.setStandaloneConfig = function (newRpcUrl, newPrivateKey) {
22
+ rpcUrl = newRpcUrl;
23
+ privateKey = newPrivateKey;
24
+ console.log("Standalone configuration set");
25
+ return this;
26
+ };
27
+
28
+ /**
29
+ * Sets a custom token for Gun operations.
30
+ * @param {string} token - The token to be set.
31
+ * @returns {Gun} The Gun instance for chaining.
32
+ */
13
33
  Gun.chain.setToken = function (token) {
14
34
  if (typeof token === "string" && token.length > 0) {
15
35
  customToken = token;
16
- console.log("Token impostato con successo:", token);
36
+ console.log("Token set successfully:", token);
17
37
  } else {
18
- console.error("Token non valido. Deve essere una stringa non vuota.");
38
+ console.error("Invalid token. Must be a non-empty string.");
19
39
  }
20
40
  return this;
21
41
  };
22
42
 
43
+ /**
44
+ * Retrieves the current custom token.
45
+ * @returns {string} The current custom token.
46
+ */
23
47
  Gun.chain.getToken = function () {
24
48
  return customToken;
25
49
  };
26
50
 
51
+ // Add custom token to all 'put' operations
27
52
  Gun.on("put", function (msg) {
28
53
  const to = this.to;
29
- // Usa il token personalizzato
30
54
  msg.headers = {
31
55
  token: customToken,
32
56
  };
33
- to.next(msg); // passa al prossimo middleware
57
+ to.next(msg);
34
58
  });
35
59
 
36
- // Aggiungi il metodo alla catena di Gun
60
+ /**
61
+ * Verifies an Ethereum signature.
62
+ * @param {string} message - The original message that was signed.
63
+ * @param {string} signature - The signature to verify.
64
+ * @returns {Promise<string|null>} The recovered address or null if verification fails.
65
+ */
37
66
  Gun.chain.verifySignature = async function (message, signature) {
38
67
  try {
39
68
  const recoveredAddress = ethers.verifyMessage(message, signature);
40
69
  return recoveredAddress;
41
70
  } catch (error) {
42
- console.error("Errore durante la verifica della firma:", error);
71
+ console.error("Error verifying signature:", error);
43
72
  return null;
44
73
  }
45
74
  };
46
75
 
76
+ /**
77
+ * Generates a password from a signature.
78
+ * @param {string} signature - The signature to derive the password from.
79
+ * @returns {string|null} The generated password or null if generation fails.
80
+ */
47
81
  Gun.chain.generatePassword = function (signature) {
48
82
  try {
49
- // Usa SHA-256 per derivare una password dalla firma
50
83
  const hexSignature = ethers.hexlify(signature);
51
84
  const hash = ethers.keccak256(hexSignature);
52
-
53
- console.log("Password generata:", hash);
85
+ console.log("Generated password:", hash);
54
86
  return hash;
55
87
  } catch (error) {
56
- console.error("Errore nella generazione della password:", error);
88
+ console.error("Error generating password:", error);
57
89
  return null;
58
90
  }
59
91
  };
60
92
 
93
+ /**
94
+ * Creates an Ethereum signature for a given message.
95
+ * @param {string} message - The message to sign.
96
+ * @returns {Promise<string|null>} The signature or null if signing fails.
97
+ */
61
98
  Gun.chain.createSignature = async function (message) {
62
99
  try {
63
- // Controlla se window.ethereum è disponibile (metamask o altro provider)
64
- if (typeof window.ethereum !== "undefined") {
65
- await window.ethereum.request({ method: "eth_requestAccounts" });
66
- const provider = new ethers.BrowserProvider(window.ethereum);
67
- const signer = await provider.getSigner();
68
- const signature = await signer.signMessage(message);
69
- console.log("Firma creata:", signature);
70
- return signature;
71
- } else {
72
- throw new Error("Provider Ethereum non trovato");
73
- }
100
+ const signer = await getSigner();
101
+ const signature = await signer.signMessage(message);
102
+ console.log("Signature created:", signature);
103
+ return signature;
74
104
  } catch (error) {
75
- console.error("Errore durante la creazione della firma:", error);
105
+ console.error("Error creating signature:", error);
76
106
  return null;
77
107
  }
78
108
  };
79
109
 
110
+ /**
111
+ * Creates and stores an encrypted key pair for a given address.
112
+ * @param {string} address - The Ethereum address to associate with the key pair.
113
+ * @param {string} signature - The signature to use for encryption.
114
+ * @returns {Promise<void>}
115
+ */
80
116
  Gun.chain.createAndStoreEncryptedPair = async function (address, signature) {
81
117
  try {
82
118
  const gun = this;
83
119
  const pair = await SEA.pair();
84
120
  const encryptedPair = await SEA.encrypt(JSON.stringify(pair), signature);
85
-
86
121
  await gun.get("users").get(address).put({ encryptedPair });
87
- console.log("Pair crittografato e archiviato per:", address);
122
+ console.log("Encrypted pair stored for:", address);
88
123
  } catch (error) {
89
- console.error(
90
- "Errore durante la creazione e l'archiviazione del pair crittografato:",
91
- error
92
- );
124
+ console.error("Error creating and storing encrypted pair:", error);
93
125
  }
94
126
  };
95
127
 
128
+ /**
129
+ * Retrieves and decrypts a stored key pair for a given address.
130
+ * @param {string} address - The Ethereum address associated with the key pair.
131
+ * @param {string} signature - The signature to use for decryption.
132
+ * @returns {Promise<Object|null>} The decrypted key pair or null if retrieval fails.
133
+ */
96
134
  Gun.chain.getAndDecryptPair = async function (address, signature) {
97
135
  try {
98
136
  const gun = this;
@@ -102,22 +140,25 @@ Gun.chain.getAndDecryptPair = async function (address, signature) {
102
140
  .get("encryptedPair")
103
141
  .then();
104
142
  if (!encryptedData) {
105
- throw new Error("Nessun dato crittografato trovato per questo indirizzo");
143
+ throw new Error("No encrypted data found for this address");
106
144
  }
107
-
108
145
  const decryptedPair = await SEA.decrypt(encryptedData, signature);
109
-
110
146
  console.log(decryptedPair);
111
147
  return decryptedPair;
112
148
  } catch (error) {
113
- console.error(
114
- "Errore durante il recupero e la decrittazione del pair:",
115
- error
116
- );
149
+ console.error("Error retrieving and decrypting pair:", error);
117
150
  return null;
118
151
  }
119
152
  };
120
153
 
154
+ /**
155
+ * SHINE (Secure Hybrid Information and Network Environment) functionality.
156
+ * @param {string} chain - The blockchain to use (e.g., "optimismSepolia").
157
+ * @param {string} nodeId - The ID of the node to verify or write.
158
+ * @param {Object} data - The data to write (if writing).
159
+ * @param {Function} callback - Callback function to handle the result.
160
+ * @returns {Gun} The Gun instance for chaining.
161
+ */
121
162
  Gun.chain.shine = function (chain, nodeId, data, callback) {
122
163
  console.log("SHINE plugin called with:", { chain, nodeId, data });
123
164
 
@@ -137,12 +178,20 @@ Gun.chain.shine = function (chain, nodeId, data, callback) {
137
178
 
138
179
  // Funzione per ottenere il signer
139
180
  const getSigner = async () => {
140
- if (typeof window.ethereum !== "undefined") {
181
+ if (rpcUrl && privateKey) {
182
+ // Modalità standalone
183
+ const provider = new ethers.JsonRpcProvider(rpcUrl);
184
+ return new ethers.Wallet(privateKey, provider);
185
+ } else if (
186
+ typeof window !== "undefined" &&
187
+ typeof window.ethereum !== "undefined"
188
+ ) {
189
+ // Modalità browser
141
190
  await window.ethereum.request({ method: "eth_requestAccounts" });
142
191
  const provider = new ethers.BrowserProvider(window.ethereum);
143
192
  return provider.getSigner();
144
193
  } else {
145
- throw new Error("Ethereum provider not found");
194
+ throw new Error("No valid Ethereum provider found");
146
195
  }
147
196
  };
148
197
 
@@ -287,3 +336,5 @@ Gun.chain.shine = function (chain, nodeId, data, callback) {
287
336
 
288
337
  return gun;
289
338
  };
339
+
340
+ module.exports = Gun;
Binary file
File without changes
File without changes