gun-eth 1.4.31 → 1.4.32

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- {"version":3,"file":"gun-eth.min.js","sources":["../src/config/local.js","../src/abis/abis.js","../src/index.js"],"sourcesContent":["let contractAddresses = {\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512\",\r\n STEALTH_ANNOUNCER_ADDRESS: \"0x5FbDB2315678afecb367f032d93F642f64180aa3\"\r\n};\r\n\r\nif (typeof window === 'undefined') {\r\n const { fileURLToPath } = require('url');\r\n const { dirname } = require('path');\r\n const { readFileSync } = require('fs');\r\n const { join } = require('path');\r\n\r\n try {\r\n const __filename = fileURLToPath(import.meta.url);\r\n const __dirname = dirname(__filename);\r\n const rawdata = readFileSync(join(__dirname, 'contract-address.json'), 'utf8');\r\n contractAddresses = JSON.parse(rawdata);\r\n console.log(\"Loaded contract addresses:\", contractAddresses);\r\n } catch (error) {\r\n console.warn(\"Warning: contract-address.json not found or invalid\");\r\n }\r\n}\r\n\r\nexport const LOCAL_CONFIG = {\r\n CHAIN_ID: 1337,\r\n PROOF_OF_INTEGRITY_ADDRESS: contractAddresses.PROOF_OF_INTEGRITY_ADDRESS,\r\n STEALTH_ANNOUNCER_ADDRESS: contractAddresses.STEALTH_ANNOUNCER_ADDRESS,\r\n RPC_URL: \"http://127.0.0.1:8545\",\r\n GUN_PEER: \"http://localhost:8765/gun\"\r\n}; ","import { LOCAL_CONFIG } from '../config/local.js';\r\n\r\n// Indirizzi di produzione per diverse chain\r\nexport const CHAIN_CONFIG = {\r\n optimismSepolia: {\r\n STEALTH_ANNOUNCER_ADDRESS: \"0xD0F2e9DA59d2DFECFdE67CcF17300BB6093A72f8\",\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0x...\",\r\n RPC_URL: \"https://sepolia.optimism.io\",\r\n CHAIN_ID: 11155420\r\n },\r\n arbitrumSepolia: {\r\n STEALTH_ANNOUNCER_ADDRESS: \"0x...\",\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0x...\",\r\n RPC_URL: \"https://sepolia-rollup.arbitrum.io/rpc\",\r\n CHAIN_ID: 421614\r\n },\r\n localhost: {\r\n RPC_URL: \"http://127.0.0.1:8545\",\r\n CHAIN_ID: 1337\r\n }\r\n};\r\n\r\n// Esporta gli indirizzi di default (Optimism Sepolia)\r\nexport const STEALTH_ANNOUNCER_ADDRESS = CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS;\r\nexport const PROOF_OF_INTEGRITY_ADDRESS = CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS;\r\n\r\n// Funzione per ottenere gli indirizzi corretti\r\nexport function getAddressesForChain(chainName) {\r\n let config;\r\n\r\n // Se è localhost, prova a caricare gli indirizzi locali\r\n if (chainName === 'localhost') {\r\n try {\r\n // Carica gli indirizzi dal file generato dal deploy locale\r\n const localAddresses = require('../config/contract-address.json');\r\n config = {\r\n ...CHAIN_CONFIG.localhost,\r\n ...localAddresses\r\n };\r\n console.log(\"Using local addresses:\", config);\r\n return config;\r\n } catch (err) {\r\n console.warn('No local addresses found');\r\n throw new Error('No local addresses found. Did you run local deployment?');\r\n }\r\n }\r\n\r\n // Altrimenti usa gli indirizzi di produzione\r\n config = CHAIN_CONFIG[chainName];\r\n if (!config) {\r\n throw new Error(`Chain ${chainName} not supported. Supported chains: ${Object.keys(CHAIN_CONFIG).join(', ')}`);\r\n }\r\n\r\n return config;\r\n}\r\n\r\n// Funzione helper per verificare se siamo in ambiente locale\r\nexport function isLocalEnvironment() {\r\n return process.env.NODE_ENV === 'development' && \r\n typeof window !== 'undefined' && \r\n window.location.hostname === 'localhost';\r\n}\r\n\r\nexport const STEALTH_ANNOUNCER_ABI = [\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"_devAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"constructor\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"timestamp\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"StealthPaymentAnnounced\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"newAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"DevAddressUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"newFee\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"DevFeeUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"announcePayment\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"payable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"devAddress\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"devFee\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"getAnnouncementsCount\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"fromIndex\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"toIndex\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"getAnnouncementsInRange\",\r\n \"outputs\": [\r\n {\r\n \"components\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"timestamp\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"internalType\": \"struct StealthAnnouncer.StealthAnnouncement[]\",\r\n \"name\": \"\",\r\n \"type\": \"tuple[]\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"_newFee\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"updateDevFee\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"_newAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"updateDevAddress\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"withdrawStuckETH\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n }\r\n];\r\n\r\nexport const PROOF_OF_INTEGRITY_ABI = [\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes[]\",\r\n \"name\": \"nodeIds\",\r\n \"type\": \"bytes[]\"\r\n },\r\n {\r\n \"internalType\": \"bytes32[]\",\r\n \"name\": \"contentHashes\",\r\n \"type\": \"bytes32[]\"\r\n }\r\n ],\r\n \"name\": \"batchUpdateData\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"indexed\": true,\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"indexed\": false,\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n },\r\n {\r\n \"indexed\": false,\r\n \"internalType\": \"address\",\r\n \"name\": \"updater\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"DataUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n }\r\n ],\r\n \"name\": \"getLatestRecord\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"\",\r\n \"type\": \"bytes32\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n }\r\n ],\r\n \"name\": \"updateData\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n }\r\n ],\r\n \"name\": \"verifyData\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"bool\",\r\n \"name\": \"\",\r\n \"type\": \"bool\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n }\r\n];\r\n\r\n\r\nexport const SHINE_OPTIMISM_SEPOLIA = \"0x43D838b683F772F08f321E5FA265ad3e333BE9C2\";\r\n","// =============================================\r\n// IMPORTS AND GLOBAL VARIABLES\r\n// =============================================\r\nimport Gun from \"gun\";\r\nimport SEA from \"gun/sea.js\";\r\nimport { ethers } from \"ethers\";\r\nimport { \r\n PROOF_OF_INTEGRITY_ABI, \r\n STEALTH_ANNOUNCER_ABI, \r\n getAddressesForChain, \r\n isLocalEnvironment,\r\n CHAIN_CONFIG\r\n} from \"./abis/abis.js\";\r\nimport { LOCAL_CONFIG } from \"./config/local.js\";\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\nimport { readFileSync } from 'fs';\r\nimport { \r\n JsonRpcProvider, \r\n BrowserProvider, \r\n Wallet,\r\n Contract,\r\n concat,\r\n keccak256,\r\n verifyMessage,\r\n getBytes\r\n} from 'ethers';\r\n\r\nlet PROOF_CONTRACT_ADDRESS;\r\nlet rpcUrl = \"\";\r\nlet privateKey = \"\";\r\n\r\nexport const MESSAGE_TO_SIGN = \"Access GunDB with Ethereum\";\r\n\r\nlet contractAddresses = {\r\n PROOF_OF_INTEGRITY_ADDRESS: CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS,\r\n STEALTH_ANNOUNCER_ADDRESS: CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS\r\n};\r\n\r\n// Solo per Node.js\r\nif (typeof window === 'undefined') {\r\n try {\r\n const __filename = fileURLToPath(import.meta.url);\r\n const __dirname = dirname(__filename);\r\n\r\n try {\r\n const rawdata = readFileSync(path.join(__dirname, 'contract-address.json'), 'utf8');\r\n contractAddresses = JSON.parse(rawdata);\r\n console.log('Loaded contract addresses:', contractAddresses);\r\n } catch (err) {\r\n console.warn('Warning: contract-address.json not found or invalid');\r\n }\r\n } catch (error) {\r\n console.error('Error loading Node.js modules:', error);\r\n }\r\n}\r\n\r\n// =============================================\r\n// UTILITY FUNCTIONS\r\n// =============================================\r\n/**\r\n * Generates a random node ID for GunDB\r\n * @returns {string} A random hexadecimal string\r\n */\r\nexport function generateRandomId() {\r\n const randomBytes = ethers.randomBytes(32);\r\n return ethers.hexlify(randomBytes).slice(2);\r\n}\r\n\r\n/**\r\n * Generates a password from a signature.\r\n * @param {string} signature - The signature to derive the password from.\r\n * @returns {string|null} The generated password or null if generation fails.\r\n */\r\nexport function generatePassword(signature) {\r\n try {\r\n const signatureBytes = ethers.getBytes(signature);\r\n const hash = ethers.keccak256(signatureBytes);\r\n console.log(\"Generated password:\", hash);\r\n return hash;\r\n } catch (error) {\r\n console.error(\"Error generating password:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a Gun private key to an Ethereum account.\r\n * @param {string} gunPrivateKey - The Gun private key in base64url format.\r\n * @returns {Object} An object containing the Ethereum account and public key.\r\n */\r\nexport function gunToEthAccount(gunPrivateKey) {\r\n // Function to convert base64url to hex\r\n const base64UrlToHex = (base64url) => {\r\n const padding = \"=\".repeat((4 - (base64url.length % 4)) % 4);\r\n const base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\") + padding;\r\n const binary = atob(base64);\r\n return Array.from(binary, (char) =>\r\n char.charCodeAt(0).toString(16).padStart(2, \"0\")\r\n ).join(\"\");\r\n };\r\n\r\n // Convert Gun private key to hex format\r\n const hexPrivateKey = \"0x\" + base64UrlToHex(gunPrivateKey);\r\n\r\n // Create an Ethereum wallet from the private key\r\n const wallet = new ethers.Wallet(hexPrivateKey);\r\n\r\n // Get the public address (public key)\r\n const publicKey = wallet.address;\r\n\r\n return {\r\n account: wallet,\r\n publicKey: publicKey,\r\n privateKey: hexPrivateKey,\r\n };\r\n}\r\n\r\n/**\r\n * Gets an Ethereum signer based on current configuration\r\n * @returns {Promise<ethers.Signer>} The configured signer\r\n * @throws {Error} If no valid provider is found\r\n */\r\nexport const getSigner = async () => {\r\n if (rpcUrl && privateKey) {\r\n const provider = new ethers.JsonRpcProvider(rpcUrl, {\r\n chainId: LOCAL_CONFIG.CHAIN_ID,\r\n name: \"localhost\"\r\n });\r\n return new Wallet(privateKey, provider);\r\n } else if (\r\n typeof window !== \"undefined\" &&\r\n typeof window.ethereum !== \"undefined\"\r\n ) {\r\n await window.ethereum.request({ method: \"eth_requestAccounts\" });\r\n const provider = new BrowserProvider(window.ethereum);\r\n return provider.getSigner();\r\n } else {\r\n throw new Error(\"No valid Ethereum provider found\");\r\n }\r\n};\r\n\r\n/**\r\n * Utility function to generate stealth address\r\n * @param {string} sharedSecret - The shared secret\r\n * @param {string} spendingPublicKey - The spending public key\r\n * @returns {Object} The stealth address and private key\r\n */\r\nexport function deriveStealthAddress(sharedSecret, spendingPublicKey) {\r\n try {\r\n const sharedSecretBytes = getBytes(sharedSecret);\r\n const spendingPublicKeyBytes = getBytes(spendingPublicKey);\r\n \r\n const stealthPrivateKey = keccak256(\r\n concat([\r\n sharedSecretBytes,\r\n spendingPublicKeyBytes\r\n ])\r\n );\r\n \r\n const stealthWallet = new Wallet(stealthPrivateKey);\r\n\r\n console.log(\"Debug deriveStealthAddress:\", {\r\n sharedSecretHex: stealthPrivateKey,\r\n spendingPublicKey,\r\n stealthPrivateKey,\r\n stealthAddress: stealthWallet.address\r\n });\r\n\r\n return {\r\n stealthPrivateKey,\r\n stealthAddress: stealthWallet.address,\r\n wallet: stealthWallet\r\n };\r\n } catch (error) {\r\n console.error(\"Error in deriveStealthAddress:\", error);\r\n throw error;\r\n }\r\n}\r\n\r\n// =============================================\r\n// BASIC GUN-ETH CHAIN METHODS\r\n// =============================================\r\n\r\n// Set the message to sign\r\nGun.chain.MESSAGE_TO_SIGN = MESSAGE_TO_SIGN;\r\n\r\n/**\r\n * Sets standalone configuration for Gun.\r\n * @param {string} newRpcUrl - The new RPC URL.\r\n * @param {string} newPrivateKey - The new private key.\r\n * @returns {Gun} The Gun instance for chaining.\r\n */\r\nGun.chain.setSigner = function (newRpcUrl, newPrivateKey) {\r\n rpcUrl = newRpcUrl;\r\n privateKey = newPrivateKey;\r\n console.log(\"Standalone configuration set\");\r\n return this;\r\n};\r\n\r\nGun.chain.getSigner = getSigner();\r\n\r\n/**\r\n * Verifies an Ethereum signature.\r\n * @param {string} message - The original message that was signed.\r\n * @param {string} signature - The signature to verify.\r\n * @returns {Promise<string|null>} The recovered address or null if verification fails.\r\n */\r\nGun.chain.verifySignature = async function (message, signature) {\r\n try {\r\n const recoveredAddress = verifyMessage(message, signature);\r\n return recoveredAddress;\r\n } catch (error) {\r\n console.error(\"Error verifying signature:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Generates a password from a signature.\r\n * @param {string} signature - The signature to derive the password from.\r\n * @returns {string|null} The generated password or null if generation fails.\r\n */\r\nGun.chain.generatePassword = function (signature) {\r\n return generatePassword(signature);\r\n};\r\n\r\n/**\r\n * Creates an Ethereum signature for a given message.\r\n * @param {string} message - The message to sign.\r\n * @returns {Promise<string|null>} The signature or null if signing fails.\r\n */\r\nGun.chain.createSignature = async function (message) {\r\n try {\r\n // Check if message matches MESSAGE_TO_SIGN\r\n if (message !== MESSAGE_TO_SIGN) {\r\n throw new Error(\"Invalid message, valid message is: \" + MESSAGE_TO_SIGN);\r\n }\r\n const signer = await getSigner();\r\n const signature = await signer.signMessage(message);\r\n console.log(\"Signature created:\", signature);\r\n return signature;\r\n } catch (error) {\r\n console.error(\"Error creating signature:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n// =============================================\r\n// KEY PAIR MANAGEMENT\r\n// =============================================\r\n/**\r\n * Creates and stores an encrypted key pair for a given address.\r\n * @param {string} address - The Ethereum address to associate with the key pair.\r\n * @param {string} signature - The signature to use for encryption.\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.createAndStoreEncryptedPair = async function (address, signature) {\r\n try {\r\n const gun = this;\r\n const pair = await SEA.pair();\r\n const v_pair = await SEA.pair();\r\n const s_pair = await SEA.pair();\r\n const password = generatePassword(signature);\r\n\r\n // Save original SEA pairs\r\n const encryptedPair = await SEA.encrypt(JSON.stringify(pair), password);\r\n const encryptedV_pair = await SEA.encrypt(JSON.stringify(v_pair), password);\r\n const encryptedS_pair = await SEA.encrypt(JSON.stringify(s_pair), password);\r\n\r\n // Convert only to get Ethereum addresses\r\n const viewingAccount = gunToEthAccount(v_pair.priv);\r\n const spendingAccount = gunToEthAccount(s_pair.priv);\r\n\r\n gun.get(\"gun-eth\").get(\"users\").get(address).put({\r\n pair: encryptedPair,\r\n v_pair: encryptedV_pair,\r\n s_pair: encryptedS_pair,\r\n publicKeys: {\r\n viewingPublicKey: v_pair.epub, // Use SEA encryption public key\r\n viewingPublicKey: v_pair.epub, // Use SEA encryption public key\r\n spendingPublicKey: spendingAccount.publicKey, // Use Ethereum address\r\n ethViewingAddress: viewingAccount.publicKey // Also save Ethereum address\r\n }\r\n });\r\n\r\n console.log(\"Encrypted pairs and public keys stored for:\", address);\r\n } catch (error) {\r\n console.error(\"Error creating and storing encrypted pair:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Retrieves and decrypts a stored key pair for a given address.\r\n * @param {string} address - The Ethereum address associated with the key pair.\r\n * @param {string} signature - The signature to use for decryption.\r\n * @returns {Promise<Object|null>} The decrypted key pair or null if retrieval fails.\r\n */\r\nGun.chain.getAndDecryptPair = async function (address, signature) {\r\n try {\r\n const gun = this;\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(address)\r\n .get(\"pair\")\r\n .then();\r\n if (!encryptedData) {\r\n throw new Error(\"No encrypted data found for this address\");\r\n }\r\n const password = generatePassword(signature);\r\n const decryptedPair = await SEA.decrypt(encryptedData, password);\r\n console.log(decryptedPair);\r\n return decryptedPair;\r\n } catch (error) {\r\n console.error(\"Error retrieving and decrypting pair:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n// =============================================\r\n// PROOF OF INTEGRITY\r\n// =============================================\r\n/**\r\n * Proof of Integrity\r\n * @param {string} chain - The blockchain to use (e.g., \"optimismSepolia\").\r\n * @param {string} nodeId - The ID of the node to verify or write.\r\n * @param {Object} data - The data to write (if writing).\r\n * @param {Function} callback - Callback function to handle the result.\r\n * @returns {Gun} The Gun instance for chaining.\r\n */\r\nGun.chain.proof = function (chain, nodeId, data, callback) {\r\n console.log(\"Proof plugin called with:\", { chain, nodeId, data });\r\n\r\n if (typeof callback !== \"function\") {\r\n console.error(\"Callback must be a function\");\r\n return this;\r\n }\r\n\r\n try {\r\n // Se siamo in localhost e in development, usa automaticamente la chain locale\r\n const targetChain = isLocalEnvironment() ? 'localhost' : chain;\r\n const chainConfig = getAddressesForChain(targetChain);\r\n \r\n console.log(`Using ${targetChain} configuration:`, chainConfig);\r\n\r\n // Usa gli indirizzi dalla configurazione\r\n const contract = new Contract(\r\n chainConfig.PROOF_OF_INTEGRITY_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n\r\n // Funzione per verificare on-chain\r\n const verifyOnChain = async (nodeId, contentHash) => {\r\n console.log(\"Verifying on chain:\", { nodeId, contentHash });\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const [isValid, timestamp, updater] = await contract.verifyData(\r\n toUtf8Bytes(nodeId),\r\n contentHash\r\n );\r\n console.log(\"Verification result:\", { isValid, timestamp, updater });\r\n return { isValid, timestamp, updater };\r\n };\r\n\r\n // Funzione per scrivere on-chain\r\n const writeOnChain = async (nodeId, contentHash) => {\r\n console.log(\"Writing on chain:\", { nodeId, contentHash });\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const tx = await contract.updateData(\r\n toUtf8Bytes(nodeId),\r\n contentHash\r\n );\r\n console.log(\"Transaction sent:\", tx.hash);\r\n const receipt = await tx.wait();\r\n console.log(\"Transaction confirmed:\", receipt);\r\n return tx;\r\n };\r\n\r\n // Funzione per ottenere l'ultimo record\r\n const getLatestRecord = async (nodeId) => {\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const [contentHash, timestamp, updater] = await contract.getLatestRecord(\r\n toUtf8Bytes(nodeId)\r\n );\r\n console.log(\"Latest record from blockchain:\", {\r\n nodeId,\r\n contentHash,\r\n timestamp,\r\n updater,\r\n });\r\n return { contentHash, timestamp, updater };\r\n };\r\n\r\n \r\n if (nodeId && !data) {\r\n // Case 1: User passes only node\r\n gun.get(nodeId).once(async (existingData) => {\r\n if (!existingData) {\r\n if (callback) callback({ err: \"Node not found in GunDB\" });\r\n return;\r\n }\r\n\r\n console.log(\"existingData\", existingData);\r\n\r\n // Use stored contentHash instead of recalculating\r\n const contentHash = existingData._contentHash;\r\n console.log(\"contentHash\", contentHash);\r\n\r\n if (!contentHash) {\r\n if (callback) callback({ err: \"No content hash found for this node\" });\r\n return;\r\n }\r\n\r\n try {\r\n const { isValid, timestamp, updater } = await verifyOnChain(\r\n nodeId,\r\n contentHash\r\n );\r\n const latestRecord = await getLatestRecord(nodeId);\r\n\r\n if (isValid) {\r\n if (callback)\r\n callback({\r\n ok: true,\r\n message: \"Data verified on blockchain\",\r\n timestamp,\r\n updater,\r\n latestRecord,\r\n });\r\n } else {\r\n if (callback)\r\n callback({\r\n ok: false,\r\n message: \"Data not verified on blockchain\",\r\n latestRecord,\r\n });\r\n }\r\n } catch (error) {\r\n if (callback) callback({ err: error.message });\r\n }\r\n });\r\n } else if (data && !nodeId) {\r\n // Case 2: User passes only text (data)\r\n const newNodeId = generateRandomId();\r\n const dataString = JSON.stringify(data);\r\n const contentHash = keccak256(toUtf8Bytes(dataString));\r\n\r\n gun\r\n .get(newNodeId)\r\n .put({ ...data, _contentHash: contentHash }, async (ack) => {\r\n console.log(\"ack\", ack);\r\n if (ack.err) {\r\n if (callback) callback({ err: \"Error saving data to GunDB\" });\r\n return;\r\n }\r\n\r\n try {\r\n const tx = await writeOnChain(newNodeId, contentHash);\r\n if (callback)\r\n callback({\r\n ok: true,\r\n message: \"Data written to GunDB and blockchain\",\r\n nodeId: newNodeId,\r\n txHash: tx.hash,\r\n });\r\n } catch (error) {\r\n if (callback) callback({ err: error.message });\r\n }\r\n });\r\n } else {\r\n if (callback)\r\n callback({\r\n err: \"Invalid input. Provide either nodeId or data, not both.\",\r\n });\r\n }\r\n\r\n return gun;\r\n } catch (error) {\r\n callback({ err: error.message });\r\n return this;\r\n }\r\n};\r\n\r\n// =============================================\r\n// STEALTH ADDRESS CORE FUNCTIONS\r\n// =============================================\r\n/**\r\n * Converts a Gun private key to an Ethereum account.\r\n * @param {string} gunPrivateKey - The Gun private key in base64url format.\r\n * @returns {Object} An object containing the Ethereum account and public key.\r\n */\r\nGun.chain.gunToEthAccount = function (gunPrivateKey) {\r\n return gunToEthAccount(gunPrivateKey);\r\n};\r\n\r\n/**\r\n * Generate a stealth key and related key pairs\r\n * @param {string} recipientAddress - The recipient's Ethereum address\r\n * @param {string} signature - The sender's signature to access their keys\r\n * @returns {Promise<Object>} Object containing stealth addresses and keys\r\n */\r\nGun.chain.generateStealthAddress = async function (recipientAddress, signature) {\r\n try {\r\n const gun = this;\r\n \r\n // Get recipient's public keys\r\n const recipientData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(recipientAddress)\r\n .get(\"publicKeys\")\r\n .then();\r\n\r\n if (!recipientData || !recipientData.viewingPublicKey || !recipientData.spendingPublicKey) {\r\n throw new Error(\"Recipient's public keys not found\");\r\n }\r\n\r\n // Get sender's keys\r\n const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const password = generatePassword(signature);\r\n \r\n const senderData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(senderAddress)\r\n .then();\r\n\r\n if (!senderData || !senderData.s_pair) {\r\n throw new Error(\"Sender's keys not found\");\r\n }\r\n\r\n // Decrypt sender's spending pair\r\n let spendingKeyPair;\r\n try {\r\n const decryptedData = await SEA.decrypt(senderData.s_pair, password);\r\n spendingKeyPair = typeof decryptedData === 'string' ? \r\n JSON.parse(decryptedData) : \r\n decryptedData;\r\n } catch (error) {\r\n console.error(\"Error decrypting spending pair:\", error);\r\n throw new Error(\"Unable to decrypt spending pair\");\r\n }\r\n\r\n // Generate shared secret using SEA ECDH with encryption public key\r\n const sharedSecret = await SEA.secret(recipientData.viewingPublicKey, spendingKeyPair);\r\n\r\n if (!sharedSecret) {\r\n throw new Error(\"Unable to generate shared secret\");\r\n }\r\n\r\n console.log(\"Generate shared secret:\", sharedSecret);\r\n\r\n const { stealthAddress } = deriveStealthAddress(\r\n sharedSecret,\r\n recipientData.spendingPublicKey\r\n );\r\n\r\n return {\r\n stealthAddress,\r\n senderPublicKey: spendingKeyPair.epub, // Use encryption public key\r\n spendingPublicKey: recipientData.spendingPublicKey\r\n };\r\n\r\n } catch (error) {\r\n console.error(\"Error generating stealth address:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Publish public keys needed to receive stealth payments\r\n * @param {string} signature - The signature to authenticate the user\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.publishStealthKeys = async function (signature) {\r\n try {\r\n const gun = this;\r\n const address = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const password = generatePassword(signature);\r\n\r\n // Get encrypted key pairs\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(address)\r\n .then();\r\n\r\n if (!encryptedData || !encryptedData.v_pair || !encryptedData.s_pair) {\r\n throw new Error(\"Keys not found\");\r\n }\r\n\r\n // Decrypt viewing and spending pairs\r\n const viewingKeyPair = JSON.parse(\r\n await SEA.decrypt(encryptedData.v_pair, password)\r\n );\r\n const spendingKeyPair = JSON.parse(\r\n await SEA.decrypt(encryptedData.s_pair, password)\r\n );\r\n\r\n const viewingAccount = gunToEthAccount(viewingKeyPair.priv);\r\n const spendingAccount = gunToEthAccount(spendingKeyPair.priv);\r\n\r\n // Publish only public keys\r\n gun.get(\"gun-eth\").get(\"users\").get(address).get(\"publicKeys\").put({\r\n viewingPublicKey: viewingAccount.publicKey,\r\n spendingPublicKey: spendingAccount.publicKey,\r\n });\r\n\r\n console.log(\"Stealth public keys published successfully\");\r\n } catch (error) {\r\n console.error(\"Error publishing stealth keys:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n// =============================================\r\n// STEALTH PAYMENT FUNCTIONS\r\n// =============================================\r\n/**\r\n * Recover funds from a stealth address\r\n * @param {string} stealthAddress - The stealth address to recover funds from\r\n * @param {string} senderPublicKey - The sender's public key used to generate the address\r\n * @param {string} signature - The signature to decrypt private keys\r\n * @returns {Promise<Object>} Object containing wallet to access funds\r\n */\r\nGun.chain.recoverStealthFunds = async function (\r\n stealthAddress,\r\n senderPublicKey,\r\n signature,\r\n spendingPublicKey\r\n) {\r\n try {\r\n const gun = this;\r\n const password = generatePassword(signature);\r\n\r\n // Get own key pairs\r\n const myAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(myAddress)\r\n .then();\r\n\r\n if (!encryptedData || !encryptedData.v_pair || !encryptedData.s_pair) {\r\n throw new Error(\"Keys not found\");\r\n }\r\n\r\n // Decrypt viewing and spending pairs\r\n let viewingKeyPair;\r\n try {\r\n const decryptedViewingData = await SEA.decrypt(encryptedData.v_pair, password);\r\n viewingKeyPair = typeof decryptedViewingData === 'string' ? \r\n JSON.parse(decryptedViewingData) : \r\n decryptedViewingData;\r\n } catch (error) {\r\n console.error(\"Error decrypting keys:\", error);\r\n throw new Error(\"Unable to decrypt keys\");\r\n }\r\n\r\n // Generate shared secret using SEA ECDH\r\n const sharedSecret = await SEA.secret(senderPublicKey, viewingKeyPair);\r\n\r\n if (!sharedSecret) {\r\n throw new Error(\"Unable to generate shared secret\");\r\n }\r\n\r\n console.log(\"Recover shared secret:\", sharedSecret);\r\n\r\n const { wallet, stealthAddress: recoveredAddress } = deriveStealthAddress(\r\n sharedSecret,\r\n spendingPublicKey\r\n );\r\n\r\n // Verify address matches\r\n if (recoveredAddress.toLowerCase() !== stealthAddress.toLowerCase()) {\r\n console.error(\"Mismatch:\", {\r\n recovered: recoveredAddress,\r\n expected: stealthAddress,\r\n sharedSecret\r\n });\r\n throw new Error(\"Recovered stealth address does not match\");\r\n }\r\n\r\n return {\r\n wallet,\r\n address: recoveredAddress,\r\n };\r\n } catch (error) {\r\n console.error(\"Error recovering stealth funds:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Announce a stealth payment\r\n * @param {string} stealthAddress - The generated stealth address\r\n * @param {string} senderPublicKey - The sender's public key\r\n * @param {string} spendingPublicKey - The spending public key\r\n * @param {string} signature - The sender's signature\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.announceStealthPayment = async function (\r\n stealthAddress,\r\n senderPublicKey,\r\n spendingPublicKey,\r\n signature,\r\n options = { onChain: false, chain: 'optimismSepolia' }\r\n) {\r\n try {\r\n const gun = this;\r\n const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n\r\n if (options.onChain) {\r\n // On-chain announcement\r\n const signer = await getSigner();\r\n const chainConfig = getAddressesForChain(options.chain);\r\n const contractAddress = chainConfig.STEALTH_ANNOUNCER_ADDRESS;\r\n\r\n console.log(\"Using contract address:\", contractAddress);\r\n\r\n const contract = new Contract(\r\n contractAddress,\r\n STEALTH_ANNOUNCER_ABI,\r\n signer\r\n );\r\n\r\n // Get dev fee from contract\r\n const devFee = await contract.devFee();\r\n console.log(\"Dev fee:\", devFee.toString());\r\n\r\n // Call contract\r\n const tx = await contract.announcePayment(\r\n senderPublicKey,\r\n spendingPublicKey,\r\n stealthAddress,\r\n { value: devFee }\r\n );\r\n \r\n console.log(\"Transaction sent:\", tx.hash);\r\n const receipt = await tx.wait();\r\n console.log(\"Transaction confirmed:\", receipt.hash);\r\n \r\n console.log(\"Stealth payment announced on-chain (dev fee paid)\");\r\n } else {\r\n // Off-chain announcement (GunDB)\r\n gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .set({\r\n stealthAddress,\r\n senderAddress,\r\n senderPublicKey,\r\n spendingPublicKey,\r\n timestamp: Date.now(),\r\n });\r\n console.log(\"Stealth payment announced off-chain\");\r\n }\r\n } catch (error) {\r\n console.error(\"Error announcing stealth payment:\", error);\r\n console.error(\"Error details:\", error.stack);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Get all stealth payments for an address\r\n * @param {string} signature - The signature to authenticate the user\r\n * @returns {Promise<Array>} List of stealth payments\r\n */\r\nGun.chain.getStealthPayments = async function (signature, options = { source: 'both' }) {\r\n try {\r\n const payments = [];\r\n\r\n if (options.source === 'onChain' || options.source === 'both') {\r\n const signer = await getSigner();\r\n const chainConfig = getAddressesForChain(options.chain || 'optimismSepolia');\r\n const contractAddress = chainConfig.STEALTH_ANNOUNCER_ADDRESS;\r\n\r\n const contract = new Contract(\r\n contractAddress,\r\n STEALTH_ANNOUNCER_ABI,\r\n signer\r\n );\r\n \r\n try {\r\n // Get total number of announcements\r\n const totalAnnouncements = await contract.getAnnouncementsCount();\r\n const totalCount = Number(totalAnnouncements.toString());\r\n console.log(\"Total on-chain announcements:\", totalCount);\r\n \r\n if (totalCount > 0) {\r\n // Get announcements in batches of 100\r\n const batchSize = 100;\r\n const lastIndex = totalCount - 1;\r\n \r\n for(let i = 0; i <= lastIndex; i += batchSize) {\r\n const toIndex = Math.min(i + batchSize - 1, lastIndex);\r\n const batch = await contract.getAnnouncementsInRange(i, toIndex);\r\n \r\n // For each announcement, try to decrypt\r\n for(const announcement of batch) {\r\n try {\r\n // Verify announcement is valid\r\n if (!announcement || !announcement.stealthAddress || \r\n !announcement.senderPublicKey || !announcement.spendingPublicKey) {\r\n console.log(\"Invalid announcement:\", announcement);\r\n continue;\r\n }\r\n\r\n // Try to recover funds to verify if announcement is for us\r\n const recoveredWallet = await this.recoverStealthFunds(\r\n announcement.stealthAddress,\r\n announcement.senderPublicKey,\r\n signature,\r\n announcement.spendingPublicKey\r\n );\r\n \r\n // If no errors thrown, announcement is for us\r\n payments.push({\r\n stealthAddress: announcement.stealthAddress,\r\n senderPublicKey: announcement.senderPublicKey,\r\n spendingPublicKey: announcement.spendingPublicKey,\r\n timestamp: Number(announcement.timestamp),\r\n source: 'onChain',\r\n wallet: recoveredWallet\r\n });\r\n\r\n } catch (e) {\r\n // Not for us, continue\r\n console.log(`Announcement not for us: ${announcement.stealthAddress}`);\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error(\"Error retrieving on-chain announcements:\", error);\r\n }\r\n }\r\n\r\n if (options.source === 'offChain' || options.source === 'both') {\r\n // Get off-chain payments\r\n const gun = this;\r\n const offChainPayments = await new Promise((resolve) => {\r\n const p = [];\r\n gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .map()\r\n .once((payment, id) => {\r\n if (payment?.stealthAddress) {\r\n p.push({ ...payment, id, source: 'offChain' });\r\n }\r\n });\r\n setTimeout(() => resolve(p), 2000);\r\n });\r\n \r\n payments.push(...offChainPayments);\r\n }\r\n\r\n console.log(`Found ${payments.length} stealth payments`);\r\n return payments;\r\n } catch (error) {\r\n console.error(\"Error retrieving stealth payments:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Clean up old stealth payments\r\n * @param {string} recipientAddress - The recipient's address\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.cleanStealthPayments = async function(recipientAddress) {\r\n try {\r\n const gun = this;\r\n const payments = await gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .map()\r\n .once()\r\n .then();\r\n\r\n // Remove empty or invalid nodes\r\n if (payments) {\r\n Object.keys(payments).forEach(async (key) => {\r\n const payment = payments[key];\r\n if (!payment || !payment.stealthAddress || !payment.senderPublicKey || !payment.spendingPublicKey) {\r\n await gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .get(key)\r\n .put(null);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error(\"Error cleaning stealth payments:\", error);\r\n }\r\n};\r\n\r\n// =============================================\r\n// EXPORTS\r\n// =============================================\r\n\r\n// Crea una classe GunEth che contiene tutti i metodi e le utility\r\nexport class GunEth {\r\n // Static utility methods\r\n static generateRandomId = generateRandomId;\r\n static generatePassword = generatePassword;\r\n static gunToEthAccount = gunToEthAccount;\r\n static getSigner = getSigner;\r\n static deriveStealthAddress = deriveStealthAddress;\r\n \r\n // Chain methods\r\n static chainMethods = {\r\n setSigner: Gun.chain.setSigner,\r\n getSigner: Gun.chain.getSigner,\r\n verifySignature: Gun.chain.verifySignature,\r\n generatePassword: Gun.chain.generatePassword,\r\n createSignature: Gun.chain.createSignature,\r\n createAndStoreEncryptedPair: Gun.chain.createAndStoreEncryptedPair,\r\n getAndDecryptPair: Gun.chain.getAndDecryptPair,\r\n proof: Gun.chain.proof,\r\n gunToEthAccount: Gun.chain.gunToEthAccount,\r\n generateStealthAddress: Gun.chain.generateStealthAddress,\r\n publishStealthKeys: Gun.chain.publishStealthKeys,\r\n recoverStealthFunds: Gun.chain.recoverStealthFunds,\r\n announceStealthPayment: Gun.chain.announceStealthPayment,\r\n getStealthPayments: Gun.chain.getStealthPayments,\r\n cleanStealthPayments: Gun.chain.cleanStealthPayments\r\n };\r\n\r\n // Constants\r\n static MESSAGE_TO_SIGN = MESSAGE_TO_SIGN;\r\n static PROOF_CONTRACT_ADDRESS = PROOF_CONTRACT_ADDRESS;\r\n static LOCAL_CONFIG = LOCAL_CONFIG;\r\n}\r\n\r\n// Esporta Gun come default\r\nexport default Gun;\r\n"],"names":["contractAddresses","PROOF_OF_INTEGRITY_ADDRESS","STEALTH_ANNOUNCER_ADDRESS","window","fileURLToPath","require","dirname","readFileSync","join","__filename","document","location","pathToFileURL","href","_documentCurrentScript","tagName","toUpperCase","src","URL","baseURI","rawdata","JSON","parse","console","log","error","warn","LOCAL_CONFIG","CHAIN_ID","RPC_URL","GUN_PEER","CHAIN_CONFIG","optimismSepolia","arbitrumSepolia","localhost","getAddressesForChain","chainName","config","localAddresses","err","Error","Object","keys","STEALTH_ANNOUNCER_ABI","inputs","internalType","name","type","stateMutability","anonymous","outputs","components","PROOF_OF_INTEGRITY_ABI","indexed","PROOF_CONTRACT_ADDRESS","rpcUrl","privateKey","MESSAGE_TO_SIGN","__dirname","path","generateRandomId","randomBytes","ethers","hexlify","slice","generatePassword","signature","signatureBytes","getBytes","hash","keccak256","gunToEthAccount","gunPrivateKey","hexPrivateKey","base64url","padding","repeat","length","base64","replace","binary","atob","Array","from","char","charCodeAt","toString","padStart","base64UrlToHex","wallet","Wallet","account","publicKey","address","getSigner","async","provider","JsonRpcProvider","chainId","ethereum","request","method","BrowserProvider","deriveStealthAddress","sharedSecret","spendingPublicKey","sharedSecretBytes","spendingPublicKeyBytes","stealthPrivateKey","concat","stealthWallet","sharedSecretHex","stealthAddress","Gun","chain","setSigner","newRpcUrl","newPrivateKey","this","verifySignature","message","verifyMessage","createSignature","signer","signMessage","createAndStoreEncryptedPair","gun","pair","SEA","v_pair","s_pair","password","encryptedPair","encrypt","stringify","encryptedV_pair","encryptedS_pair","viewingAccount","priv","spendingAccount","get","put","publicKeys","viewingPublicKey","epub","ethViewingAddress","getAndDecryptPair","encryptedData","then","decryptedPair","decrypt","proof","nodeId","data","callback","targetChain","process","env","NODE_ENV","hostname","chainConfig","Contract","verifyOnChain","contentHash","contract","isValid","timestamp","updater","verifyData","toUtf8Bytes","writeOnChain","tx","updateData","receipt","wait","getLatestRecord","once","existingData","_contentHash","latestRecord","ok","newNodeId","dataString","ack","txHash","generateStealthAddress","recipientAddress","recipientData","senderAddress","senderData","spendingKeyPair","decryptedData","secret","senderPublicKey","publishStealthKeys","viewingKeyPair","recoverStealthFunds","myAddress","decryptedViewingData","recoveredAddress","toLowerCase","recovered","expected","announceStealthPayment","options","onChain","contractAddress","devFee","announcePayment","value","set","Date","now","stack","getStealthPayments","source","payments","totalAnnouncements","getAnnouncementsCount","totalCount","Number","batchSize","lastIndex","i","toIndex","Math","min","batch","getAnnouncementsInRange","announcement","recoveredWallet","push","e","offChainPayments","Promise","resolve","p","map","payment","id","setTimeout","cleanStealthPayments","forEach","key","GunEth","static"],"mappings":"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"}
1
+ {"version":3,"file":"gun-eth.min.js","sources":["../src/config/local.js","../src/abis/abis.js","../src/index.js"],"sourcesContent":["let contractAddresses = {\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512\",\r\n STEALTH_ANNOUNCER_ADDRESS: \"0x5FbDB2315678afecb367f032d93F642f64180aa3\"\r\n};\r\n\r\nif (typeof window === 'undefined') {\r\n const { fileURLToPath } = require('url');\r\n const { dirname } = require('path');\r\n const { readFileSync } = require('fs');\r\n const { join } = require('path');\r\n\r\n try {\r\n const __filename = fileURLToPath(import.meta.url);\r\n const __dirname = dirname(__filename);\r\n const rawdata = readFileSync(join(__dirname, 'contract-address.json'), 'utf8');\r\n contractAddresses = JSON.parse(rawdata);\r\n console.log(\"Loaded contract addresses:\", contractAddresses);\r\n } catch (error) {\r\n console.warn(\"Warning: contract-address.json not found or invalid\");\r\n }\r\n}\r\n\r\nexport const LOCAL_CONFIG = {\r\n CHAIN_ID: 1337,\r\n PROOF_OF_INTEGRITY_ADDRESS: contractAddresses.PROOF_OF_INTEGRITY_ADDRESS,\r\n STEALTH_ANNOUNCER_ADDRESS: contractAddresses.STEALTH_ANNOUNCER_ADDRESS,\r\n RPC_URL: \"http://127.0.0.1:8545\",\r\n GUN_PEER: \"http://localhost:8765/gun\"\r\n}; ","import { LOCAL_CONFIG } from '../config/local.js';\r\n\r\n// Indirizzi di produzione per diverse chain\r\nexport const CHAIN_CONFIG = {\r\n optimismSepolia: {\r\n STEALTH_ANNOUNCER_ADDRESS: \"0xD0F2e9DA59d2DFECFdE67CcF17300BB6093A72f8\",\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0x...\",\r\n RPC_URL: \"https://sepolia.optimism.io\",\r\n CHAIN_ID: 11155420\r\n },\r\n arbitrumSepolia: {\r\n STEALTH_ANNOUNCER_ADDRESS: \"0x...\",\r\n PROOF_OF_INTEGRITY_ADDRESS: \"0x...\",\r\n RPC_URL: \"https://sepolia-rollup.arbitrum.io/rpc\",\r\n CHAIN_ID: 421614\r\n },\r\n localhost: {\r\n RPC_URL: \"http://127.0.0.1:8545\",\r\n CHAIN_ID: 1337\r\n }\r\n};\r\n\r\n// Esporta gli indirizzi di default (Optimism Sepolia)\r\nexport const STEALTH_ANNOUNCER_ADDRESS = CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS;\r\nexport const PROOF_OF_INTEGRITY_ADDRESS = CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS;\r\n\r\n// Funzione per ottenere gli indirizzi corretti\r\nexport function getAddressesForChain(chainName) {\r\n let config;\r\n\r\n // Se è localhost, prova a caricare gli indirizzi locali\r\n if (chainName === 'localhost') {\r\n try {\r\n // Carica gli indirizzi dal file generato dal deploy locale\r\n const localAddresses = require('../config/contract-address.json');\r\n config = {\r\n ...CHAIN_CONFIG.localhost,\r\n ...localAddresses\r\n };\r\n console.log(\"Using local addresses:\", config);\r\n return config;\r\n } catch (err) {\r\n console.warn('No local addresses found');\r\n throw new Error('No local addresses found. Did you run local deployment?');\r\n }\r\n }\r\n\r\n // Altrimenti usa gli indirizzi di produzione\r\n config = CHAIN_CONFIG[chainName];\r\n if (!config) {\r\n throw new Error(`Chain ${chainName} not supported. Supported chains: ${Object.keys(CHAIN_CONFIG).join(', ')}`);\r\n }\r\n\r\n return config;\r\n}\r\n\r\n// Funzione helper per verificare se siamo in ambiente locale\r\nexport function isLocalEnvironment() {\r\n return process.env.NODE_ENV === 'development' && \r\n typeof window !== 'undefined' && \r\n window.location.hostname === 'localhost';\r\n}\r\n\r\nexport const STEALTH_ANNOUNCER_ABI = [\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"_devAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"constructor\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"timestamp\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"StealthPaymentAnnounced\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"newAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"DevAddressUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"newFee\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"DevFeeUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"announcePayment\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"payable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"devAddress\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"devFee\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"getAnnouncementsCount\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"fromIndex\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"toIndex\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"getAnnouncementsInRange\",\r\n \"outputs\": [\r\n {\r\n \"components\": [\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"senderPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"string\",\r\n \"name\": \"spendingPublicKey\",\r\n \"type\": \"string\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"stealthAddress\",\r\n \"type\": \"address\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"timestamp\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"internalType\": \"struct StealthAnnouncer.StealthAnnouncement[]\",\r\n \"name\": \"\",\r\n \"type\": \"tuple[]\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"_newFee\",\r\n \"type\": \"uint256\"\r\n }\r\n ],\r\n \"name\": \"updateDevFee\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"_newAddress\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"updateDevAddress\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [],\r\n \"name\": \"withdrawStuckETH\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n }\r\n];\r\n\r\nexport const PROOF_OF_INTEGRITY_ABI = [\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes[]\",\r\n \"name\": \"nodeIds\",\r\n \"type\": \"bytes[]\"\r\n },\r\n {\r\n \"internalType\": \"bytes32[]\",\r\n \"name\": \"contentHashes\",\r\n \"type\": \"bytes32[]\"\r\n }\r\n ],\r\n \"name\": \"batchUpdateData\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"anonymous\": false,\r\n \"inputs\": [\r\n {\r\n \"indexed\": true,\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"indexed\": false,\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n },\r\n {\r\n \"indexed\": false,\r\n \"internalType\": \"address\",\r\n \"name\": \"updater\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"name\": \"DataUpdated\",\r\n \"type\": \"event\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n }\r\n ],\r\n \"name\": \"getLatestRecord\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"\",\r\n \"type\": \"bytes32\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n }\r\n ],\r\n \"name\": \"updateData\",\r\n \"outputs\": [],\r\n \"stateMutability\": \"nonpayable\",\r\n \"type\": \"function\"\r\n },\r\n {\r\n \"inputs\": [\r\n {\r\n \"internalType\": \"bytes\",\r\n \"name\": \"nodeId\",\r\n \"type\": \"bytes\"\r\n },\r\n {\r\n \"internalType\": \"bytes32\",\r\n \"name\": \"contentHash\",\r\n \"type\": \"bytes32\"\r\n }\r\n ],\r\n \"name\": \"verifyData\",\r\n \"outputs\": [\r\n {\r\n \"internalType\": \"bool\",\r\n \"name\": \"\",\r\n \"type\": \"bool\"\r\n },\r\n {\r\n \"internalType\": \"uint256\",\r\n \"name\": \"\",\r\n \"type\": \"uint256\"\r\n },\r\n {\r\n \"internalType\": \"address\",\r\n \"name\": \"\",\r\n \"type\": \"address\"\r\n }\r\n ],\r\n \"stateMutability\": \"view\",\r\n \"type\": \"function\"\r\n }\r\n];\r\n\r\n\r\nexport const SHINE_OPTIMISM_SEPOLIA = \"0x43D838b683F772F08f321E5FA265ad3e333BE9C2\";\r\n","// =============================================\r\n// IMPORTS AND GLOBAL VARIABLES\r\n// =============================================\r\nimport Gun from \"gun\";\r\nimport SEA from \"gun/sea.js\";\r\nimport { ethers } from \"ethers\";\r\nimport { \r\n PROOF_OF_INTEGRITY_ABI, \r\n STEALTH_ANNOUNCER_ABI, \r\n getAddressesForChain, \r\n isLocalEnvironment,\r\n CHAIN_CONFIG\r\n} from \"./abis/abis.js\";\r\nimport { LOCAL_CONFIG } from \"./config/local.js\";\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\nimport { readFileSync } from 'fs';\r\n\r\nlet PROOF_CONTRACT_ADDRESS;\r\nlet rpcUrl = \"\";\r\nlet privateKey = \"\";\r\n\r\nexport const MESSAGE_TO_SIGN = \"Access GunDB with Ethereum\";\r\n\r\nlet contractAddresses = {\r\n PROOF_OF_INTEGRITY_ADDRESS: CHAIN_CONFIG.optimismSepolia.PROOF_OF_INTEGRITY_ADDRESS,\r\n STEALTH_ANNOUNCER_ADDRESS: CHAIN_CONFIG.optimismSepolia.STEALTH_ANNOUNCER_ADDRESS\r\n};\r\n\r\n// Solo per Node.js\r\nif (typeof window === 'undefined') {\r\n try {\r\n const __filename = fileURLToPath(import.meta.url);\r\n const __dirname = dirname(__filename);\r\n\r\n try {\r\n const rawdata = readFileSync(path.join(__dirname, 'contract-address.json'), 'utf8');\r\n contractAddresses = JSON.parse(rawdata);\r\n console.log('Loaded contract addresses:', contractAddresses);\r\n } catch (err) {\r\n console.warn('Warning: contract-address.json not found or invalid');\r\n }\r\n } catch (error) {\r\n console.error('Error loading Node.js modules:', error);\r\n }\r\n}\r\n\r\n// =============================================\r\n// UTILITY FUNCTIONS\r\n// =============================================\r\n/**\r\n * Generates a random node ID for GunDB\r\n * @returns {string} A random hexadecimal string\r\n */\r\nexport function generateRandomId() {\r\n const randomBytes = ethers.randomBytes(32);\r\n return ethers.hexlify(randomBytes).slice(2);\r\n}\r\n\r\n/**\r\n * Generates a password from a signature.\r\n * @param {string} signature - The signature to derive the password from.\r\n * @returns {string|null} The generated password or null if generation fails.\r\n */\r\nexport function generatePassword(signature) {\r\n try {\r\n const signatureBytes = ethers.toUtf8Bytes(signature);\r\n const hash = ethers.keccak256(signatureBytes);\r\n console.log(\"Generated password:\", hash);\r\n return hash;\r\n } catch (error) {\r\n console.error(\"Error generating password:\", error);\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Converts a Gun private key to an Ethereum account.\r\n * @param {string} gunPrivateKey - The Gun private key in base64url format.\r\n * @returns {Object} An object containing the Ethereum account and public key.\r\n */\r\nexport function gunToEthAccount(gunPrivateKey) {\r\n // Function to convert base64url to hex\r\n const base64UrlToHex = (base64url) => {\r\n const padding = \"=\".repeat((4 - (base64url.length % 4)) % 4);\r\n const base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\") + padding;\r\n const binary = atob(base64);\r\n return Array.from(binary, (char) =>\r\n char.charCodeAt(0).toString(16).padStart(2, \"0\")\r\n ).join(\"\");\r\n };\r\n\r\n // Convert Gun private key to hex format\r\n const hexPrivateKey = \"0x\" + base64UrlToHex(gunPrivateKey);\r\n\r\n // Create an Ethereum wallet from the private key\r\n const wallet = new ethers.Wallet(hexPrivateKey);\r\n\r\n // Get the public address (public key)\r\n const publicKey = wallet.address;\r\n\r\n return {\r\n account: wallet,\r\n publicKey: publicKey,\r\n privateKey: hexPrivateKey,\r\n };\r\n}\r\n\r\n/**\r\n * Gets an Ethereum signer based on current configuration\r\n * @returns {Promise<ethers.Signer>} The configured signer\r\n * @throws {Error} If no valid provider is found\r\n */\r\nexport const getSigner = async () => {\r\n if (rpcUrl && privateKey) {\r\n const provider = new ethers.JsonRpcProvider(rpcUrl, {\r\n chainId: LOCAL_CONFIG.CHAIN_ID,\r\n name: \"localhost\"\r\n });\r\n return new Wallet(privateKey, provider);\r\n } else if (\r\n typeof window !== \"undefined\" &&\r\n typeof window.ethereum !== \"undefined\"\r\n ) {\r\n await window.ethereum.request({ method: \"eth_requestAccounts\" });\r\n const provider = new ethers.BrowserProvider(window.ethereum);\r\n return provider.getSigner();\r\n } else {\r\n throw new Error(\"No valid Ethereum provider found\");\r\n }\r\n};\r\n\r\n/**\r\n * Utility function to generate stealth address\r\n * @param {string} sharedSecret - The shared secret\r\n * @param {string} spendingPublicKey - The spending public key\r\n * @returns {Object} The stealth address and private key\r\n */\r\nexport function deriveStealthAddress(sharedSecret, spendingPublicKey) {\r\n try {\r\n const sharedSecretBytes = ethers.toUtf8Bytes(sharedSecret);\r\n const spendingPublicKeyBytes = ethers.toUtf8Bytes(spendingPublicKey);\r\n \r\n const stealthPrivateKey = ethers.keccak256(\r\n ethers.concat([\r\n sharedSecretBytes,\r\n spendingPublicKeyBytes\r\n ])\r\n );\r\n \r\n const stealthWallet = new Wallet(stealthPrivateKey);\r\n\r\n console.log(\"Debug deriveStealthAddress:\", {\r\n sharedSecretHex: stealthPrivateKey,\r\n spendingPublicKey,\r\n stealthPrivateKey,\r\n stealthAddress: stealthWallet.address\r\n });\r\n\r\n return {\r\n stealthPrivateKey,\r\n stealthAddress: stealthWallet.address,\r\n wallet: stealthWallet\r\n };\r\n } catch (error) {\r\n console.error(\"Error in deriveStealthAddress:\", error);\r\n throw error;\r\n }\r\n}\r\n\r\n// =============================================\r\n// BASIC GUN-ETH CHAIN METHODS\r\n// =============================================\r\n\r\n// Set the message to sign\r\nGun.chain.MESSAGE_TO_SIGN = MESSAGE_TO_SIGN;\r\n\r\n/**\r\n * Sets standalone configuration for Gun.\r\n * @param {string} newRpcUrl - The new RPC URL.\r\n * @param {string} newPrivateKey - The new private key.\r\n * @returns {Gun} The Gun instance for chaining.\r\n */\r\nGun.chain.setSigner = function (newRpcUrl, newPrivateKey) {\r\n rpcUrl = newRpcUrl;\r\n privateKey = newPrivateKey;\r\n console.log(\"Standalone configuration set\");\r\n return this;\r\n};\r\n\r\nGun.chain.getSigner = getSigner();\r\n\r\n/**\r\n * Verifies an Ethereum signature.\r\n * @param {string} message - The original message that was signed.\r\n * @param {string} signature - The signature to verify.\r\n * @returns {Promise<string|null>} The recovered address or null if verification fails.\r\n */\r\nGun.chain.verifySignature = async function (message, signature) {\r\n try {\r\n const recoveredAddress = ethers.verifyMessage(message, signature);\r\n return recoveredAddress;\r\n } catch (error) {\r\n console.error(\"Error verifying signature:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Generates a password from a signature.\r\n * @param {string} signature - The signature to derive the password from.\r\n * @returns {string|null} The generated password or null if generation fails.\r\n */\r\nGun.chain.generatePassword = function (signature) {\r\n return generatePassword(signature);\r\n};\r\n\r\n/**\r\n * Creates an Ethereum signature for a given message.\r\n * @param {string} message - The message to sign.\r\n * @returns {Promise<string|null>} The signature or null if signing fails.\r\n */\r\nGun.chain.createSignature = async function (message) {\r\n try {\r\n // Check if message matches MESSAGE_TO_SIGN\r\n if (message !== MESSAGE_TO_SIGN) {\r\n throw new Error(\"Invalid message, valid message is: \" + MESSAGE_TO_SIGN);\r\n }\r\n const signer = await getSigner();\r\n const signature = await signer.signMessage(message);\r\n console.log(\"Signature created:\", signature);\r\n return signature;\r\n } catch (error) {\r\n console.error(\"Error creating signature:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n// =============================================\r\n// KEY PAIR MANAGEMENT\r\n// =============================================\r\n/**\r\n * Creates and stores an encrypted key pair for a given address.\r\n * @param {string} address - The Ethereum address to associate with the key pair.\r\n * @param {string} signature - The signature to use for encryption.\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.createAndStoreEncryptedPair = async function (address, signature) {\r\n try {\r\n const gun = this;\r\n const pair = await SEA.pair();\r\n const v_pair = await SEA.pair();\r\n const s_pair = await SEA.pair();\r\n const password = generatePassword(signature);\r\n\r\n // Save original SEA pairs\r\n const encryptedPair = await SEA.encrypt(JSON.stringify(pair), password);\r\n const encryptedV_pair = await SEA.encrypt(JSON.stringify(v_pair), password);\r\n const encryptedS_pair = await SEA.encrypt(JSON.stringify(s_pair), password);\r\n\r\n // Convert only to get Ethereum addresses\r\n const viewingAccount = gunToEthAccount(v_pair.priv);\r\n const spendingAccount = gunToEthAccount(s_pair.priv);\r\n\r\n gun.get(\"gun-eth\").get(\"users\").get(address).put({\r\n pair: encryptedPair,\r\n v_pair: encryptedV_pair,\r\n s_pair: encryptedS_pair,\r\n publicKeys: {\r\n viewingPublicKey: v_pair.epub, // Use SEA encryption public key\r\n viewingPublicKey: v_pair.epub, // Use SEA encryption public key\r\n spendingPublicKey: spendingAccount.publicKey, // Use Ethereum address\r\n ethViewingAddress: viewingAccount.publicKey // Also save Ethereum address\r\n }\r\n });\r\n\r\n console.log(\"Encrypted pairs and public keys stored for:\", address);\r\n } catch (error) {\r\n console.error(\"Error creating and storing encrypted pair:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Retrieves and decrypts a stored key pair for a given address.\r\n * @param {string} address - The Ethereum address associated with the key pair.\r\n * @param {string} signature - The signature to use for decryption.\r\n * @returns {Promise<Object|null>} The decrypted key pair or null if retrieval fails.\r\n */\r\nGun.chain.getAndDecryptPair = async function (address, signature) {\r\n try {\r\n const gun = this;\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(address)\r\n .get(\"pair\")\r\n .then();\r\n if (!encryptedData) {\r\n throw new Error(\"No encrypted data found for this address\");\r\n }\r\n const password = generatePassword(signature);\r\n const decryptedPair = await SEA.decrypt(encryptedData, password);\r\n console.log(decryptedPair);\r\n return decryptedPair;\r\n } catch (error) {\r\n console.error(\"Error retrieving and decrypting pair:\", error);\r\n return null;\r\n }\r\n};\r\n\r\n// =============================================\r\n// PROOF OF INTEGRITY\r\n// =============================================\r\n/**\r\n * Proof of Integrity\r\n * @param {string} chain - The blockchain to use (e.g., \"optimismSepolia\").\r\n * @param {string} nodeId - The ID of the node to verify or write.\r\n * @param {Object} data - The data to write (if writing).\r\n * @param {Function} callback - Callback function to handle the result.\r\n * @returns {Gun} The Gun instance for chaining.\r\n */\r\nGun.chain.proof = function (chain, nodeId, data, callback) {\r\n console.log(\"Proof plugin called with:\", { chain, nodeId, data });\r\n\r\n if (typeof callback !== \"function\") {\r\n console.error(\"Callback must be a function\");\r\n return this;\r\n }\r\n\r\n try {\r\n // Se siamo in localhost e in development, usa automaticamente la chain locale\r\n const targetChain = isLocalEnvironment() ? 'localhost' : chain;\r\n const chainConfig = getAddressesForChain(targetChain);\r\n \r\n console.log(`Using ${targetChain} configuration:`, chainConfig);\r\n\r\n // Usa gli indirizzi dalla configurazione\r\n const contract = new ethers.Contract(\r\n chainConfig.PROOF_OF_INTEGRITY_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n\r\n // Funzione per verificare on-chain\r\n const verifyOnChain = async (nodeId, contentHash) => {\r\n console.log(\"Verifying on chain:\", { nodeId, contentHash });\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const [isValid, timestamp, updater] = await contract.verifyData(\r\n ethers.toUtf8Bytes(nodeId),\r\n contentHash\r\n );\r\n console.log(\"Verification result:\", { isValid, timestamp, updater });\r\n return { isValid, timestamp, updater };\r\n };\r\n\r\n // Funzione per scrivere on-chain\r\n const writeOnChain = async (nodeId, contentHash) => {\r\n console.log(\"Writing on chain:\", { nodeId, contentHash });\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const tx = await contract.updateData(\r\n toUtf8Bytes(nodeId),\r\n contentHash\r\n );\r\n console.log(\"Transaction sent:\", tx.hash);\r\n const receipt = await tx.wait();\r\n console.log(\"Transaction confirmed:\", receipt);\r\n return tx;\r\n };\r\n\r\n // Funzione per ottenere l'ultimo record\r\n const getLatestRecord = async (nodeId) => {\r\n const signer = await getSigner();\r\n const contract = new Contract(\r\n PROOF_CONTRACT_ADDRESS,\r\n PROOF_OF_INTEGRITY_ABI,\r\n signer\r\n );\r\n const [contentHash, timestamp, updater] = await contract.getLatestRecord(\r\n toUtf8Bytes(nodeId)\r\n );\r\n console.log(\"Latest record from blockchain:\", {\r\n nodeId,\r\n contentHash,\r\n timestamp,\r\n updater,\r\n });\r\n return { contentHash, timestamp, updater };\r\n };\r\n\r\n \r\n if (nodeId && !data) {\r\n // Case 1: User passes only node\r\n gun.get(nodeId).once(async (existingData) => {\r\n if (!existingData) {\r\n if (callback) callback({ err: \"Node not found in GunDB\" });\r\n return;\r\n }\r\n\r\n console.log(\"existingData\", existingData);\r\n\r\n // Use stored contentHash instead of recalculating\r\n const contentHash = existingData._contentHash;\r\n console.log(\"contentHash\", contentHash);\r\n\r\n if (!contentHash) {\r\n if (callback) callback({ err: \"No content hash found for this node\" });\r\n return;\r\n }\r\n\r\n try {\r\n const { isValid, timestamp, updater } = await verifyOnChain(\r\n nodeId,\r\n contentHash\r\n );\r\n const latestRecord = await getLatestRecord(nodeId);\r\n\r\n if (isValid) {\r\n if (callback)\r\n callback({\r\n ok: true,\r\n message: \"Data verified on blockchain\",\r\n timestamp,\r\n updater,\r\n latestRecord,\r\n });\r\n } else {\r\n if (callback)\r\n callback({\r\n ok: false,\r\n message: \"Data not verified on blockchain\",\r\n latestRecord,\r\n });\r\n }\r\n } catch (error) {\r\n if (callback) callback({ err: error.message });\r\n }\r\n });\r\n } else if (data && !nodeId) {\r\n // Case 2: User passes only text (data)\r\n const newNodeId = generateRandomId();\r\n const dataString = JSON.stringify(data);\r\n const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));\r\n\r\n gun\r\n .get(newNodeId)\r\n .put({ ...data, _contentHash: contentHash }, async (ack) => {\r\n console.log(\"ack\", ack);\r\n if (ack.err) {\r\n if (callback) callback({ err: \"Error saving data to GunDB\" });\r\n return;\r\n }\r\n\r\n try {\r\n const tx = await writeOnChain(newNodeId, contentHash);\r\n if (callback)\r\n callback({\r\n ok: true,\r\n message: \"Data written to GunDB and blockchain\",\r\n nodeId: newNodeId,\r\n txHash: tx.hash,\r\n });\r\n } catch (error) {\r\n if (callback) callback({ err: error.message });\r\n }\r\n });\r\n } else {\r\n if (callback)\r\n callback({\r\n err: \"Invalid input. Provide either nodeId or data, not both.\",\r\n });\r\n }\r\n\r\n return gun;\r\n } catch (error) {\r\n callback({ err: error.message });\r\n return this;\r\n }\r\n};\r\n\r\n// =============================================\r\n// STEALTH ADDRESS CORE FUNCTIONS\r\n// =============================================\r\n/**\r\n * Converts a Gun private key to an Ethereum account.\r\n * @param {string} gunPrivateKey - The Gun private key in base64url format.\r\n * @returns {Object} An object containing the Ethereum account and public key.\r\n */\r\nGun.chain.gunToEthAccount = function (gunPrivateKey) {\r\n return gunToEthAccount(gunPrivateKey);\r\n};\r\n\r\n/**\r\n * Generate a stealth key and related key pairs\r\n * @param {string} recipientAddress - The recipient's Ethereum address\r\n * @param {string} signature - The sender's signature to access their keys\r\n * @returns {Promise<Object>} Object containing stealth addresses and keys\r\n */\r\nGun.chain.generateStealthAddress = async function (recipientAddress, signature) {\r\n try {\r\n const gun = this;\r\n \r\n // Get recipient's public keys\r\n const recipientData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(recipientAddress)\r\n .get(\"publicKeys\")\r\n .then();\r\n\r\n if (!recipientData || !recipientData.viewingPublicKey || !recipientData.spendingPublicKey) {\r\n throw new Error(\"Recipient's public keys not found\");\r\n }\r\n\r\n // Get sender's keys\r\n const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const password = generatePassword(signature);\r\n \r\n const senderData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(senderAddress)\r\n .then();\r\n\r\n if (!senderData || !senderData.s_pair) {\r\n throw new Error(\"Sender's keys not found\");\r\n }\r\n\r\n // Decrypt sender's spending pair\r\n let spendingKeyPair;\r\n try {\r\n const decryptedData = await SEA.decrypt(senderData.s_pair, password);\r\n spendingKeyPair = typeof decryptedData === 'string' ? \r\n JSON.parse(decryptedData) : \r\n decryptedData;\r\n } catch (error) {\r\n console.error(\"Error decrypting spending pair:\", error);\r\n throw new Error(\"Unable to decrypt spending pair\");\r\n }\r\n\r\n // Generate shared secret using SEA ECDH with encryption public key\r\n const sharedSecret = await SEA.secret(recipientData.viewingPublicKey, spendingKeyPair);\r\n\r\n if (!sharedSecret) {\r\n throw new Error(\"Unable to generate shared secret\");\r\n }\r\n\r\n console.log(\"Generate shared secret:\", sharedSecret);\r\n\r\n const { stealthAddress } = deriveStealthAddress(\r\n sharedSecret,\r\n recipientData.spendingPublicKey\r\n );\r\n\r\n return {\r\n stealthAddress,\r\n senderPublicKey: spendingKeyPair.epub, // Use encryption public key\r\n spendingPublicKey: recipientData.spendingPublicKey\r\n };\r\n\r\n } catch (error) {\r\n console.error(\"Error generating stealth address:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Publish public keys needed to receive stealth payments\r\n * @param {string} signature - The signature to authenticate the user\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.publishStealthKeys = async function (signature) {\r\n try {\r\n const gun = this;\r\n const address = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const password = generatePassword(signature);\r\n\r\n // Get encrypted key pairs\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(address)\r\n .then();\r\n\r\n if (!encryptedData || !encryptedData.v_pair || !encryptedData.s_pair) {\r\n throw new Error(\"Keys not found\");\r\n }\r\n\r\n // Decrypt viewing and spending pairs\r\n const viewingKeyPair = JSON.parse(\r\n await SEA.decrypt(encryptedData.v_pair, password)\r\n );\r\n const spendingKeyPair = JSON.parse(\r\n await SEA.decrypt(encryptedData.s_pair, password)\r\n );\r\n\r\n const viewingAccount = gunToEthAccount(viewingKeyPair.priv);\r\n const spendingAccount = gunToEthAccount(spendingKeyPair.priv);\r\n\r\n // Publish only public keys\r\n gun.get(\"gun-eth\").get(\"users\").get(address).get(\"publicKeys\").put({\r\n viewingPublicKey: viewingAccount.publicKey,\r\n spendingPublicKey: spendingAccount.publicKey,\r\n });\r\n\r\n console.log(\"Stealth public keys published successfully\");\r\n } catch (error) {\r\n console.error(\"Error publishing stealth keys:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n// =============================================\r\n// STEALTH PAYMENT FUNCTIONS\r\n// =============================================\r\n/**\r\n * Recover funds from a stealth address\r\n * @param {string} stealthAddress - The stealth address to recover funds from\r\n * @param {string} senderPublicKey - The sender's public key used to generate the address\r\n * @param {string} signature - The signature to decrypt private keys\r\n * @returns {Promise<Object>} Object containing wallet to access funds\r\n */\r\nGun.chain.recoverStealthFunds = async function (\r\n stealthAddress,\r\n senderPublicKey,\r\n signature,\r\n spendingPublicKey\r\n) {\r\n try {\r\n const gun = this;\r\n const password = generatePassword(signature);\r\n\r\n // Get own key pairs\r\n const myAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n const encryptedData = await gun\r\n .get(\"gun-eth\")\r\n .get(\"users\")\r\n .get(myAddress)\r\n .then();\r\n\r\n if (!encryptedData || !encryptedData.v_pair || !encryptedData.s_pair) {\r\n throw new Error(\"Keys not found\");\r\n }\r\n\r\n // Decrypt viewing and spending pairs\r\n let viewingKeyPair;\r\n try {\r\n const decryptedViewingData = await SEA.decrypt(encryptedData.v_pair, password);\r\n viewingKeyPair = typeof decryptedViewingData === 'string' ? \r\n JSON.parse(decryptedViewingData) : \r\n decryptedViewingData;\r\n } catch (error) {\r\n console.error(\"Error decrypting keys:\", error);\r\n throw new Error(\"Unable to decrypt keys\");\r\n }\r\n\r\n // Generate shared secret using SEA ECDH\r\n const sharedSecret = await SEA.secret(senderPublicKey, viewingKeyPair);\r\n\r\n if (!sharedSecret) {\r\n throw new Error(\"Unable to generate shared secret\");\r\n }\r\n\r\n console.log(\"Recover shared secret:\", sharedSecret);\r\n\r\n const { wallet, stealthAddress: recoveredAddress } = deriveStealthAddress(\r\n sharedSecret,\r\n spendingPublicKey\r\n );\r\n\r\n // Verify address matches\r\n if (recoveredAddress.toLowerCase() !== stealthAddress.toLowerCase()) {\r\n console.error(\"Mismatch:\", {\r\n recovered: recoveredAddress,\r\n expected: stealthAddress,\r\n sharedSecret\r\n });\r\n throw new Error(\"Recovered stealth address does not match\");\r\n }\r\n\r\n return {\r\n wallet,\r\n address: recoveredAddress,\r\n };\r\n } catch (error) {\r\n console.error(\"Error recovering stealth funds:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Announce a stealth payment\r\n * @param {string} stealthAddress - The generated stealth address\r\n * @param {string} senderPublicKey - The sender's public key\r\n * @param {string} spendingPublicKey - The spending public key\r\n * @param {string} signature - The sender's signature\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.announceStealthPayment = async function (\r\n stealthAddress,\r\n senderPublicKey,\r\n spendingPublicKey,\r\n signature,\r\n options = { onChain: false, chain: 'optimismSepolia' }\r\n) {\r\n try {\r\n const gun = this;\r\n const senderAddress = await this.verifySignature(MESSAGE_TO_SIGN, signature);\r\n\r\n if (options.onChain) {\r\n // On-chain announcement\r\n const signer = await getSigner();\r\n const chainConfig = getAddressesForChain(options.chain);\r\n const contractAddress = chainConfig.STEALTH_ANNOUNCER_ADDRESS;\r\n\r\n console.log(\"Using contract address:\", contractAddress);\r\n\r\n const contract = new Contract(\r\n contractAddress,\r\n STEALTH_ANNOUNCER_ABI,\r\n signer\r\n );\r\n\r\n // Get dev fee from contract\r\n const devFee = await contract.devFee();\r\n console.log(\"Dev fee:\", devFee.toString());\r\n\r\n // Call contract\r\n const tx = await contract.announcePayment(\r\n senderPublicKey,\r\n spendingPublicKey,\r\n stealthAddress,\r\n { value: devFee }\r\n );\r\n \r\n console.log(\"Transaction sent:\", tx.hash);\r\n const receipt = await tx.wait();\r\n console.log(\"Transaction confirmed:\", receipt.hash);\r\n \r\n console.log(\"Stealth payment announced on-chain (dev fee paid)\");\r\n } else {\r\n // Off-chain announcement (GunDB)\r\n gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .set({\r\n stealthAddress,\r\n senderAddress,\r\n senderPublicKey,\r\n spendingPublicKey,\r\n timestamp: Date.now(),\r\n });\r\n console.log(\"Stealth payment announced off-chain\");\r\n }\r\n } catch (error) {\r\n console.error(\"Error announcing stealth payment:\", error);\r\n console.error(\"Error details:\", error.stack);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Get all stealth payments for an address\r\n * @param {string} signature - The signature to authenticate the user\r\n * @returns {Promise<Array>} List of stealth payments\r\n */\r\nGun.chain.getStealthPayments = async function (signature, options = { source: 'both' }) {\r\n try {\r\n const payments = [];\r\n\r\n if (options.source === 'onChain' || options.source === 'both') {\r\n const signer = await getSigner();\r\n const chainConfig = getAddressesForChain(options.chain || 'optimismSepolia');\r\n const contractAddress = chainConfig.STEALTH_ANNOUNCER_ADDRESS;\r\n\r\n const contract = new Contract(\r\n contractAddress,\r\n STEALTH_ANNOUNCER_ABI,\r\n signer\r\n );\r\n \r\n try {\r\n // Get total number of announcements\r\n const totalAnnouncements = await contract.getAnnouncementsCount();\r\n const totalCount = Number(totalAnnouncements.toString());\r\n console.log(\"Total on-chain announcements:\", totalCount);\r\n \r\n if (totalCount > 0) {\r\n // Get announcements in batches of 100\r\n const batchSize = 100;\r\n const lastIndex = totalCount - 1;\r\n \r\n for(let i = 0; i <= lastIndex; i += batchSize) {\r\n const toIndex = Math.min(i + batchSize - 1, lastIndex);\r\n const batch = await contract.getAnnouncementsInRange(i, toIndex);\r\n \r\n // For each announcement, try to decrypt\r\n for(const announcement of batch) {\r\n try {\r\n // Verify announcement is valid\r\n if (!announcement || !announcement.stealthAddress || \r\n !announcement.senderPublicKey || !announcement.spendingPublicKey) {\r\n console.log(\"Invalid announcement:\", announcement);\r\n continue;\r\n }\r\n\r\n // Try to recover funds to verify if announcement is for us\r\n const recoveredWallet = await this.recoverStealthFunds(\r\n announcement.stealthAddress,\r\n announcement.senderPublicKey,\r\n signature,\r\n announcement.spendingPublicKey\r\n );\r\n \r\n // If no errors thrown, announcement is for us\r\n payments.push({\r\n stealthAddress: announcement.stealthAddress,\r\n senderPublicKey: announcement.senderPublicKey,\r\n spendingPublicKey: announcement.spendingPublicKey,\r\n timestamp: Number(announcement.timestamp),\r\n source: 'onChain',\r\n wallet: recoveredWallet\r\n });\r\n\r\n } catch (e) {\r\n // Not for us, continue\r\n console.log(`Announcement not for us: ${announcement.stealthAddress}`);\r\n continue;\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n console.error(\"Error retrieving on-chain announcements:\", error);\r\n }\r\n }\r\n\r\n if (options.source === 'offChain' || options.source === 'both') {\r\n // Get off-chain payments\r\n const gun = this;\r\n const offChainPayments = await new Promise((resolve) => {\r\n const p = [];\r\n gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .map()\r\n .once((payment, id) => {\r\n if (payment?.stealthAddress) {\r\n p.push({ ...payment, id, source: 'offChain' });\r\n }\r\n });\r\n setTimeout(() => resolve(p), 2000);\r\n });\r\n \r\n payments.push(...offChainPayments);\r\n }\r\n\r\n console.log(`Found ${payments.length} stealth payments`);\r\n return payments;\r\n } catch (error) {\r\n console.error(\"Error retrieving stealth payments:\", error);\r\n throw error;\r\n }\r\n};\r\n\r\n/**\r\n * Clean up old stealth payments\r\n * @param {string} recipientAddress - The recipient's address\r\n * @returns {Promise<void>}\r\n */\r\nGun.chain.cleanStealthPayments = async function(recipientAddress) {\r\n try {\r\n const gun = this;\r\n const payments = await gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .map()\r\n .once()\r\n .then();\r\n\r\n // Remove empty or invalid nodes\r\n if (payments) {\r\n Object.keys(payments).forEach(async (key) => {\r\n const payment = payments[key];\r\n if (!payment || !payment.stealthAddress || !payment.senderPublicKey || !payment.spendingPublicKey) {\r\n await gun\r\n .get(\"gun-eth\")\r\n .get(\"stealth-payments\")\r\n .get(recipientAddress)\r\n .get(key)\r\n .put(null);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error(\"Error cleaning stealth payments:\", error);\r\n }\r\n};\r\n\r\n// =============================================\r\n// EXPORTS\r\n// =============================================\r\n\r\n// Crea una classe GunEth che contiene tutti i metodi e le utility\r\nexport class GunEth {\r\n // Static utility methods\r\n static generateRandomId = generateRandomId;\r\n static generatePassword = generatePassword;\r\n static gunToEthAccount = gunToEthAccount;\r\n static getSigner = getSigner;\r\n static deriveStealthAddress = deriveStealthAddress;\r\n \r\n // Chain methods\r\n static chainMethods = {\r\n setSigner: Gun.chain.setSigner,\r\n getSigner: Gun.chain.getSigner,\r\n verifySignature: Gun.chain.verifySignature,\r\n generatePassword: Gun.chain.generatePassword,\r\n createSignature: Gun.chain.createSignature,\r\n createAndStoreEncryptedPair: Gun.chain.createAndStoreEncryptedPair,\r\n getAndDecryptPair: Gun.chain.getAndDecryptPair,\r\n proof: Gun.chain.proof,\r\n gunToEthAccount: Gun.chain.gunToEthAccount,\r\n generateStealthAddress: Gun.chain.generateStealthAddress,\r\n publishStealthKeys: Gun.chain.publishStealthKeys,\r\n recoverStealthFunds: Gun.chain.recoverStealthFunds,\r\n announceStealthPayment: Gun.chain.announceStealthPayment,\r\n getStealthPayments: Gun.chain.getStealthPayments,\r\n cleanStealthPayments: Gun.chain.cleanStealthPayments\r\n };\r\n\r\n // Constants\r\n static MESSAGE_TO_SIGN = MESSAGE_TO_SIGN;\r\n static PROOF_CONTRACT_ADDRESS = PROOF_CONTRACT_ADDRESS;\r\n static LOCAL_CONFIG = LOCAL_CONFIG;\r\n}\r\n\r\n// Esporta Gun come default\r\nexport default Gun;\r\n"],"names":["contractAddresses","PROOF_OF_INTEGRITY_ADDRESS","STEALTH_ANNOUNCER_ADDRESS","window","fileURLToPath","require","dirname","readFileSync","join","__filename","document","location","pathToFileURL","href","_documentCurrentScript","tagName","toUpperCase","src","URL","baseURI","rawdata","JSON","parse","console","log","error","warn","LOCAL_CONFIG","CHAIN_ID","RPC_URL","GUN_PEER","CHAIN_CONFIG","optimismSepolia","arbitrumSepolia","localhost","getAddressesForChain","chainName","config","localAddresses","err","Error","Object","keys","STEALTH_ANNOUNCER_ABI","inputs","internalType","name","type","stateMutability","anonymous","outputs","components","PROOF_OF_INTEGRITY_ABI","indexed","PROOF_CONTRACT_ADDRESS","rpcUrl","privateKey","MESSAGE_TO_SIGN","__dirname","path","generateRandomId","randomBytes","ethers","hexlify","slice","generatePassword","signature","signatureBytes","toUtf8Bytes","hash","keccak256","gunToEthAccount","gunPrivateKey","hexPrivateKey","base64url","padding","repeat","length","base64","replace","binary","atob","Array","from","char","charCodeAt","toString","padStart","base64UrlToHex","wallet","Wallet","account","publicKey","address","getSigner","async","provider","JsonRpcProvider","chainId","ethereum","request","method","BrowserProvider","deriveStealthAddress","sharedSecret","spendingPublicKey","sharedSecretBytes","spendingPublicKeyBytes","stealthPrivateKey","concat","stealthWallet","sharedSecretHex","stealthAddress","Gun","chain","setSigner","newRpcUrl","newPrivateKey","this","verifySignature","message","verifyMessage","createSignature","signer","signMessage","createAndStoreEncryptedPair","gun","pair","SEA","v_pair","s_pair","password","encryptedPair","encrypt","stringify","encryptedV_pair","encryptedS_pair","viewingAccount","priv","spendingAccount","get","put","publicKeys","viewingPublicKey","epub","ethViewingAddress","getAndDecryptPair","encryptedData","then","decryptedPair","decrypt","proof","nodeId","data","callback","targetChain","process","env","NODE_ENV","hostname","chainConfig","Contract","verifyOnChain","contentHash","contract","isValid","timestamp","updater","verifyData","writeOnChain","tx","updateData","receipt","wait","getLatestRecord","once","existingData","_contentHash","latestRecord","ok","newNodeId","dataString","ack","txHash","generateStealthAddress","recipientAddress","recipientData","senderAddress","senderData","spendingKeyPair","decryptedData","secret","senderPublicKey","publishStealthKeys","viewingKeyPair","recoverStealthFunds","myAddress","decryptedViewingData","recoveredAddress","toLowerCase","recovered","expected","announceStealthPayment","options","onChain","contractAddress","devFee","announcePayment","value","set","Date","now","stack","getStealthPayments","source","payments","totalAnnouncements","getAnnouncementsCount","totalCount","Number","batchSize","lastIndex","i","toIndex","Math","min","batch","getAnnouncementsInRange","announcement","recoveredWallet","push","e","offChainPayments","Promise","resolve","p","map","payment","id","setTimeout","cleanStealthPayments","forEach","key","GunEth","static"],"mappings":"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"}
package/dist/gun-eth.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import Gun from 'gun';
2
2
  export { default } from 'gun';
3
3
  import SEA from 'gun/sea.js';
4
- import { verifyMessage, Contract, keccak256, ethers, Wallet, BrowserProvider, getBytes, concat } from 'ethers';
4
+ import { ethers } from 'ethers';
5
5
  import { fileURLToPath } from 'url';
6
6
  import { dirname } from 'path';
7
7
  import { readFileSync } from 'fs';
@@ -482,7 +482,7 @@ function generateRandomId() {
482
482
  */
483
483
  function generatePassword(signature) {
484
484
  try {
485
- const signatureBytes = ethers.getBytes(signature);
485
+ const signatureBytes = ethers.toUtf8Bytes(signature);
486
486
  const hash = ethers.keccak256(signatureBytes);
487
487
  console.log("Generated password:", hash);
488
488
  return hash;
@@ -541,7 +541,7 @@ const getSigner = async () => {
541
541
  typeof window.ethereum !== "undefined"
542
542
  ) {
543
543
  await window.ethereum.request({ method: "eth_requestAccounts" });
544
- const provider = new BrowserProvider(window.ethereum);
544
+ const provider = new ethers.BrowserProvider(window.ethereum);
545
545
  return provider.getSigner();
546
546
  } else {
547
547
  throw new Error("No valid Ethereum provider found");
@@ -556,11 +556,11 @@ const getSigner = async () => {
556
556
  */
557
557
  function deriveStealthAddress(sharedSecret, spendingPublicKey) {
558
558
  try {
559
- const sharedSecretBytes = getBytes(sharedSecret);
560
- const spendingPublicKeyBytes = getBytes(spendingPublicKey);
559
+ const sharedSecretBytes = ethers.toUtf8Bytes(sharedSecret);
560
+ const spendingPublicKeyBytes = ethers.toUtf8Bytes(spendingPublicKey);
561
561
 
562
- const stealthPrivateKey = keccak256(
563
- concat([
562
+ const stealthPrivateKey = ethers.keccak256(
563
+ ethers.concat([
564
564
  sharedSecretBytes,
565
565
  spendingPublicKeyBytes
566
566
  ])
@@ -616,7 +616,7 @@ Gun.chain.getSigner = getSigner();
616
616
  */
617
617
  Gun.chain.verifySignature = async function (message, signature) {
618
618
  try {
619
- const recoveredAddress = verifyMessage(message, signature);
619
+ const recoveredAddress = ethers.verifyMessage(message, signature);
620
620
  return recoveredAddress;
621
621
  } catch (error) {
622
622
  console.error("Error verifying signature:", error);
@@ -754,7 +754,7 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
754
754
  console.log(`Using ${targetChain} configuration:`, chainConfig);
755
755
 
756
756
  // Usa gli indirizzi dalla configurazione
757
- const contract = new Contract(
757
+ const contract = new ethers.Contract(
758
758
  chainConfig.PROOF_OF_INTEGRITY_ADDRESS,
759
759
  PROOF_OF_INTEGRITY_ABI,
760
760
  signer
@@ -770,7 +770,7 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
770
770
  signer
771
771
  );
772
772
  const [isValid, timestamp, updater] = await contract.verifyData(
773
- toUtf8Bytes(nodeId),
773
+ ethers.toUtf8Bytes(nodeId),
774
774
  contentHash
775
775
  );
776
776
  console.log("Verification result:", { isValid, timestamp, updater });
@@ -868,7 +868,7 @@ Gun.chain.proof = function (chain, nodeId, data, callback) {
868
868
  // Case 2: User passes only text (data)
869
869
  const newNodeId = generateRandomId();
870
870
  const dataString = JSON.stringify(data);
871
- const contentHash = keccak256(toUtf8Bytes(dataString));
871
+ const contentHash = ethers.keccak256(ethers.toUtf8Bytes(dataString));
872
872
 
873
873
  gun
874
874
  .get(newNodeId)