gun-eth 1.2.0 → 1.2.2

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.
Binary file
package/gun-eth.js ADDED
@@ -0,0 +1,270 @@
1
+ /* const Gun = require("gun/gun");
2
+ const SEA = require("gun/sea");
3
+ const ethers = require("ethers");
4
+ const SHINE = require("./SHINE.json"); */
5
+
6
+ import Gun from "gun";
7
+ import SEA from "gun/sea";
8
+ import { ethers } from "ethers";
9
+
10
+ import SHINE from "./SHINE.json";
11
+
12
+ const SHINE_ABI = SHINE.abi;
13
+ const SHINE_OPTIMISM_SEPOLIA = SHINE.address;
14
+
15
+ let SHINE_CONTRACT_ADDRESS;
16
+
17
+ // Aggiungi il metodo alla catena di Gun
18
+ Gun.chain.verifySignature = async function (message, signature) {
19
+ try {
20
+ const recoveredAddress = ethers.verifyMessage(message, signature);
21
+ return recoveredAddress;
22
+ } catch (error) {
23
+ console.error("Errore durante la verifica della firma:", error);
24
+ return null;
25
+ }
26
+ };
27
+
28
+ Gun.chain.generatePassword = function (signature) {
29
+ try {
30
+ // Usa SHA-256 per derivare una password dalla firma
31
+ const hexSignature = ethers.hexlify(signature);
32
+ const hash = ethers.keccak256(hexSignature);
33
+
34
+ console.log("Password generata:", hash);
35
+ return hash;
36
+ } catch (error) {
37
+ console.error("Errore nella generazione della password:", error);
38
+ return null;
39
+ }
40
+ };
41
+
42
+ Gun.chain.createSignature = async function (message) {
43
+ try {
44
+ // Controlla se window.ethereum è disponibile (metamask o altro provider)
45
+ if (typeof window.ethereum !== "undefined") {
46
+ await window.ethereum.request({ method: "eth_requestAccounts" });
47
+ const provider = new ethers.BrowserProvider(window.ethereum);
48
+ const signer = await provider.getSigner();
49
+ const signature = await signer.signMessage(message);
50
+ console.log("Firma creata:", signature);
51
+ return signature;
52
+ } else {
53
+ throw new Error("Provider Ethereum non trovato");
54
+ }
55
+ } catch (error) {
56
+ console.error("Errore durante la creazione della firma:", error);
57
+ return null;
58
+ }
59
+ };
60
+
61
+ Gun.chain.createAndStoreEncryptedPair = async function (address, signature) {
62
+ try {
63
+ const gun = this;
64
+ const pair = await SEA.pair();
65
+ const encryptedPair = await SEA.encrypt(JSON.stringify(pair), signature);
66
+
67
+ await gun.get("users").get(address).put({ encryptedPair });
68
+ console.log("Pair crittografato e archiviato per:", address);
69
+ } catch (error) {
70
+ console.error(
71
+ "Errore durante la creazione e l'archiviazione del pair crittografato:",
72
+ error
73
+ );
74
+ }
75
+ };
76
+
77
+ Gun.chain.getAndDecryptPair = async function (address, signature) {
78
+ try {
79
+ const gun = this;
80
+ const encryptedData = await gun
81
+ .get("users")
82
+ .get(address)
83
+ .get("encryptedPair")
84
+ .then();
85
+ if (!encryptedData) {
86
+ throw new Error("Nessun dato crittografato trovato per questo indirizzo");
87
+ }
88
+
89
+ const decryptedPair = await SEA.decrypt(encryptedData, signature);
90
+
91
+ console.log(decryptedPair);
92
+ return decryptedPair;
93
+ } catch (error) {
94
+ console.error(
95
+ "Errore durante il recupero e la decrittazione del pair:",
96
+ error
97
+ );
98
+ return null;
99
+ }
100
+ };
101
+
102
+ Gun.chain.shine = function (chain, nodeId, data, callback) {
103
+ console.log("SHINE plugin called with:", { chain, nodeId, data });
104
+
105
+ if (typeof callback !== "function") {
106
+ console.error("Callback must be a function");
107
+ return this;
108
+ }
109
+
110
+ const gun = this;
111
+
112
+ // Seleziona l'indirizzo basato sulla catena
113
+ if (chain === "optimismSepolia") {
114
+ SHINE_CONTRACT_ADDRESS = SHINE_OPTIMISM_SEPOLIA;
115
+ } else {
116
+ throw new Error("Chain not supported");
117
+ }
118
+
119
+ // Funzione per ottenere il signer
120
+ const getSigner = async () => {
121
+ if (typeof window.ethereum !== "undefined") {
122
+ await window.ethereum.request({ method: "eth_requestAccounts" });
123
+ const provider = new ethers.BrowserProvider(window.ethereum);
124
+ return provider.getSigner();
125
+ } else {
126
+ throw new Error("Ethereum provider not found");
127
+ }
128
+ };
129
+
130
+ // Funzione per verificare on-chain
131
+ const verifyOnChain = async (nodeId, contentHash) => {
132
+ console.log("Verifying on chain:", { nodeId, contentHash });
133
+ const signer = await getSigner();
134
+ const contract = new ethers.Contract(
135
+ SHINE_CONTRACT_ADDRESS,
136
+ SHINE_ABI,
137
+ signer
138
+ );
139
+ const [isValid, timestamp, updater] = await contract.verifyData(
140
+ ethers.toUtf8Bytes(nodeId),
141
+ contentHash
142
+ );
143
+ console.log("Verification result:", { isValid, timestamp, updater });
144
+ return { isValid, timestamp, updater };
145
+ };
146
+
147
+ // Funzione per scrivere on-chain
148
+ const writeOnChain = async (nodeId, contentHash) => {
149
+ console.log("Writing on chain:", { nodeId, contentHash });
150
+ const signer = await getSigner();
151
+ const contract = new ethers.Contract(
152
+ SHINE_CONTRACT_ADDRESS,
153
+ SHINE_ABI,
154
+ signer
155
+ );
156
+ const tx = await contract.updateData(
157
+ ethers.toUtf8Bytes(nodeId),
158
+ contentHash
159
+ );
160
+ console.log("Transaction sent:", tx.hash);
161
+ const receipt = await tx.wait();
162
+ console.log("Transaction confirmed:", receipt);
163
+ return tx;
164
+ };
165
+
166
+ // Nuova funzione per ottenere l'ultimo record dalla blockchain
167
+ const getLatestRecord = async (nodeId) => {
168
+ const signer = await getSigner();
169
+ const contract = new ethers.Contract(
170
+ SHINE_CONTRACT_ADDRESS,
171
+ SHINE_ABI,
172
+ signer
173
+ );
174
+ const [contentHash, timestamp, updater] = await contract.getLatestRecord(
175
+ ethers.toUtf8Bytes(nodeId)
176
+ );
177
+ console.log("Latest record from blockchain:", {
178
+ nodeId,
179
+ contentHash,
180
+ timestamp,
181
+ updater,
182
+ });
183
+ return { contentHash, timestamp, updater };
184
+ };
185
+
186
+ // Processo SHINE
187
+ if (nodeId && !data) {
188
+ // Caso 1: Utente passa solo il nodo
189
+ gun.get(nodeId).once(async (existingData) => {
190
+ if (!existingData) {
191
+ if (callback) callback({ err: "Node not found in GunDB" });
192
+ return;
193
+ }
194
+
195
+ console.log("existingData", existingData);
196
+
197
+ // Usa il contentHash memorizzato invece di ricalcolarlo
198
+ const contentHash = existingData._contentHash;
199
+ console.log("contentHash", contentHash);
200
+
201
+ if (!contentHash) {
202
+ if (callback) callback({ err: "No content hash found for this node" });
203
+ return;
204
+ }
205
+
206
+ try {
207
+ const { isValid, timestamp, updater } = await verifyOnChain(
208
+ nodeId,
209
+ contentHash
210
+ );
211
+ const latestRecord = await getLatestRecord(nodeId);
212
+
213
+ if (isValid) {
214
+ if (callback)
215
+ callback({
216
+ ok: true,
217
+ message: "Data verified on blockchain",
218
+ timestamp,
219
+ updater,
220
+ latestRecord,
221
+ });
222
+ } else {
223
+ if (callback)
224
+ callback({
225
+ ok: false,
226
+ message: "Data not verified on blockchain",
227
+ latestRecord,
228
+ });
229
+ }
230
+ } catch (error) {
231
+ if (callback) callback({ err: error.message });
232
+ }
233
+ });
234
+ } else if (data && !nodeId) {
235
+ // Caso 2: Utente passa solo il testo (data)
236
+ const newNodeId = Gun.text.random();
237
+ const dataString = JSON.stringify(data);
238
+ const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
239
+
240
+ gun
241
+ .get(newNodeId)
242
+ .put({ ...data, _contentHash: contentHash }, async (ack) => {
243
+ console.log("ack", ack);
244
+ if (ack.err) {
245
+ if (callback) callback({ err: "Error saving data to GunDB" });
246
+ return;
247
+ }
248
+
249
+ try {
250
+ const tx = await writeOnChain(newNodeId, contentHash);
251
+ if (callback)
252
+ callback({
253
+ ok: true,
254
+ message: "Data written to GunDB and blockchain",
255
+ nodeId: newNodeId,
256
+ txHash: tx.hash,
257
+ });
258
+ } catch (error) {
259
+ if (callback) callback({ err: error.message });
260
+ }
261
+ });
262
+ } else {
263
+ if (callback)
264
+ callback({
265
+ err: "Invalid input. Provide either nodeId or data, not both.",
266
+ });
267
+ }
268
+
269
+ return gun;
270
+ };
package/index.js CHANGED
@@ -1,224 +1 @@
1
- const Gun = require("gun/gun");
2
- const SEA = require("gun/sea");
3
- const ethers = require("ethers");
4
-
5
- const SHINE = require("./SHINE.json");
6
- const SHINE_ABI = SHINE.abi;
7
- const SHINE_OPTIMISM_SEPOLIA = SHINE.address;
8
-
9
- let SHINE_CONTRACT_ADDRESS;
10
-
11
- // Aggiungi il metodo alla catena di Gun
12
- Gun.chain.verifySignature = async function (message, signature) {
13
- try {
14
- const recoveredAddress = ethers.verifyMessage(message, signature);
15
- return recoveredAddress;
16
- } catch (error) {
17
- console.error("Errore durante la verifica della firma:", error);
18
- return null;
19
- }
20
- };
21
-
22
- Gun.chain.generatePassword = function (signature) {
23
- try {
24
- // Usa SHA-256 per derivare una password dalla firma
25
- const hexSignature = ethers.hexlify(signature);
26
- const hash = ethers.keccak256(hexSignature);
27
-
28
- console.log("Password generata:", hash);
29
- return hash;
30
- } catch (error) {
31
- console.error("Errore nella generazione della password:", error);
32
- return null;
33
- }
34
- };
35
-
36
- Gun.chain.createSignature = async function (message) {
37
- try {
38
- // Controlla se window.ethereum è disponibile (metamask o altro provider)
39
- if (typeof window.ethereum !== "undefined") {
40
- await window.ethereum.request({ method: "eth_requestAccounts" });
41
- const provider = new ethers.BrowserProvider(window.ethereum);
42
- const signer = await provider.getSigner();
43
- const signature = await signer.signMessage(message);
44
- console.log("Firma creata:", signature);
45
- return signature;
46
- } else {
47
- throw new Error("Provider Ethereum non trovato");
48
- }
49
- } catch (error) {
50
- console.error("Errore durante la creazione della firma:", error);
51
- return null;
52
- }
53
- };
54
-
55
- Gun.chain.createAndStoreEncryptedPair = async function (address, signature) {
56
- try {
57
- const gun = this;
58
- const pair = await SEA.pair();
59
- const encryptedPair = await SEA.encrypt(JSON.stringify(pair), signature);
60
-
61
- await gun.get("users").get(address).put({ encryptedPair });
62
- console.log("Pair crittografato e archiviato per:", address);
63
- } catch (error) {
64
- console.error(
65
- "Errore durante la creazione e l'archiviazione del pair crittografato:",
66
- error
67
- );
68
- }
69
- };
70
-
71
- Gun.chain.getAndDecryptPair = async function (address, signature) {
72
- try {
73
- const gun = this;
74
- const encryptedData = await gun
75
- .get("users")
76
- .get(address)
77
- .get("encryptedPair")
78
- .then();
79
- if (!encryptedData) {
80
- throw new Error("Nessun dato crittografato trovato per questo indirizzo");
81
- }
82
-
83
- const decryptedPair = await SEA.decrypt(encryptedData, signature);
84
-
85
- console.log(decryptedPair);
86
- return decryptedPair;
87
- } catch (error) {
88
- console.error(
89
- "Errore durante il recupero e la decrittazione del pair:",
90
- error
91
- );
92
- return null;
93
- }
94
- };
95
-
96
- Gun.chain.shine = function (chain, nodeId, data, callback) {
97
- console.log("SHINE plugin called with:", { chain, nodeId, data });
98
-
99
- if (typeof callback !== "function") {
100
- console.error("Callback must be a function");
101
- return this;
102
- }
103
-
104
- const gun = this;
105
-
106
- // Seleziona l'indirizzo basato sulla catena
107
- if (chain === "optimismSepolia") {
108
- SHINE_CONTRACT_ADDRESS = SHINE_OPTIMISM_SEPOLIA;
109
- } else {
110
- throw new Error("Chain not supported");
111
- }
112
-
113
- // Funzione per ottenere il signer
114
- const getSigner = async () => {
115
- if (typeof window.ethereum !== "undefined") {
116
- await window.ethereum.request({ method: "eth_requestAccounts" });
117
- const provider = new ethers.BrowserProvider(window.ethereum);
118
- return provider.getSigner();
119
- } else {
120
- throw new Error("Ethereum provider not found");
121
- }
122
- };
123
-
124
- // Funzione per verificare on-chain
125
- const verifyOnChain = async (nodeId, contentHash) => {
126
- const signer = await getSigner();
127
- const contract = new ethers.Contract(
128
- SHINE_CONTRACT_ADDRESS,
129
- SHINE_ABI,
130
- signer
131
- );
132
- const [isValid, timestamp, updater] = await contract.verifyData(
133
- ethers.toUtf8Bytes(nodeId),
134
- contentHash
135
- );
136
- return { isValid, timestamp, updater };
137
- };
138
-
139
- // Funzione per scrivere on-chain
140
- const writeOnChain = async (nodeId, contentHash) => {
141
- const signer = await getSigner();
142
- const contract = new ethers.Contract(
143
- SHINE_CONTRACT_ADDRESS,
144
- SHINE_ABI,
145
- signer
146
- );
147
- const tx = await contract.updateData(
148
- ethers.toUtf8Bytes(nodeId),
149
- contentHash
150
- );
151
- await tx.wait();
152
- return tx;
153
- };
154
-
155
- // Processo SHINE
156
- if (nodeId && !data) {
157
- // Caso 1: Utente passa solo il nodo
158
- gun.get(nodeId).once(async (existingData) => {
159
- if (!existingData) {
160
- if (callback) callback({ err: "Node not found in GunDB" });
161
- return;
162
- }
163
-
164
- const dataString = JSON.stringify(existingData);
165
- const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
166
-
167
- try {
168
- const { isValid, timestamp, updater } = await verifyOnChain(
169
- nodeId,
170
- contentHash
171
- );
172
- if (isValid) {
173
- if (callback)
174
- callback({
175
- ok: true,
176
- message: "Data verified on blockchain",
177
- timestamp,
178
- updater,
179
- });
180
- } else {
181
- if (callback)
182
- callback({
183
- ok: false,
184
- message: "Data not verified on blockchain",
185
- });
186
- }
187
- } catch (error) {
188
- if (callback) callback({ err: error.message });
189
- }
190
- });
191
- } else if (data && !nodeId) {
192
- // Caso 2: Utente passa solo il testo (data)
193
- const newNodeId = Gun.text.random();
194
- const dataString = JSON.stringify(data);
195
- const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
196
-
197
- gun.get(newNodeId).put(data, async (ack) => {
198
- if (ack.err) {
199
- if (callback) callback({ err: "Error saving data to GunDB" });
200
- return;
201
- }
202
-
203
- try {
204
- const tx = await writeOnChain(newNodeId, contentHash);
205
- if (callback)
206
- callback({
207
- ok: true,
208
- message: "Data written to GunDB and blockchain",
209
- nodeId: newNodeId,
210
- txHash: tx.hash,
211
- });
212
- } catch (error) {
213
- if (callback) callback({ err: error.message });
214
- }
215
- });
216
- } else {
217
- if (callback)
218
- callback({
219
- err: "Invalid input. Provide either nodeId or data, not both.",
220
- });
221
- }
222
-
223
- return gun;
224
- };
1
+ import "./gun-eth.js";
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "gun-eth",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "A GunDB plugin for Ethereum, and Web3",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
8
8
  },
9
9
  "dependencies": {
10
- "gun": "^0.2020.1239",
11
- "ethers": "^6.0.0"
10
+ "ethers": "^6.0.0",
11
+ "gun": "^0.2020.1239"
12
12
  },
13
13
  "author": "scobru",
14
14
  "repository": {
@@ -16,7 +16,6 @@
16
16
  "url": "git+https://github.com/scobru/gun-eth.git"
17
17
  },
18
18
  "license": "MIT",
19
- "devDependencies": {},
20
19
  "keywords": [
21
20
  "gundb",
22
21
  "web3",