const storage = require('electron-storage'); const path = require('path'); class PaperclipDatabase { constructor() { this.walletFile = 'paperclip-wallets.json'; this.settingsFile = 'paperclip-settings.json'; } // Wallet operations getWallets() { try { const data = storage.getSync(this.walletFile); return data || { addresses: [], names: {}, keys: {} }; } catch (error) { return { addresses: [], names: {}, keys: {} }; } } saveWallet(wallet) { try { const wallets = this.getWallets(); // Add address if not exists if (!wallets.addresses.includes(wallet.address)) { wallets.addresses.push(wallet.address); } // Save wallet data wallets.names[wallet.address] = wallet.name; wallets.keys[wallet.address] = { publicKey: wallet.publicKey, privateKey: wallet.privateKey, // TODO: Encrypt with password created: wallet.created }; storage.setSync(this.walletFile, wallets); return true; } catch (error) { console.error('Failed to save wallet:', error); return false; } } getWallet(address) { try { const wallets = this.getWallets(); if (!wallets.addresses.includes(address)) { return null; } return { address: address, name: wallets.names[address] || 'Account', publicKey: wallets.keys[address]?.publicKey, privateKey: wallets.keys[address]?.privateKey, created: wallets.keys[address]?.created }; } catch (error) { console.error('Failed to get wallet:', error); return null; } } removeWallet(address) { try { const wallets = this.getWallets(); // Remove from addresses array const index = wallets.addresses.indexOf(address); if (index > -1) { wallets.addresses.splice(index, 1); } // Remove wallet data delete wallets.names[address]; delete wallets.keys[address]; storage.setSync(this.walletFile, wallets); return true; } catch (error) { console.error('Failed to remove wallet:', error); return false; } } updateWalletName(address, newName) { try { const wallets = this.getWallets(); if (wallets.addresses.includes(address)) { wallets.names[address] = newName; storage.setSync(this.walletFile, wallets); return true; } return false; } catch (error) { console.error('Failed to update wallet name:', error); return false; } } // Address book operations getAddressBook() { try { const data = storage.getSync('address-book.json'); return data || []; } catch (error) { return []; } } saveAddressBookEntry(entry) { try { const addressBook = this.getAddressBook(); // Check if address already exists const existingIndex = addressBook.findIndex(item => item.address === entry.address); if (existingIndex > -1) { // Update existing entry addressBook[existingIndex] = entry; } else { // Add new entry addressBook.push(entry); } storage.setSync('address-book.json', addressBook); return true; } catch (error) { console.error('Failed to save address book entry:', error); return false; } } removeAddressBookEntry(address) { try { const addressBook = this.getAddressBook(); const filtered = addressBook.filter(item => item.address !== address); storage.setSync('address-book.json', filtered); return true; } catch (error) { console.error('Failed to remove address book entry:', error); return false; } } // Settings operations getSettings() { try { const data = storage.getSync(this.settingsFile); return data || { rpcUrl: 'http://localhost:26657', autoConnect: true, notifications: true }; } catch (error) { return { rpcUrl: 'http://localhost:26657', autoConnect: true, notifications: true }; } } saveSetting(key, value) { try { const settings = this.getSettings(); settings[key] = value; storage.setSync(this.settingsFile, settings); return true; } catch (error) { console.error('Failed to save setting:', error); return false; } } saveSettings(settingsObj) { try { storage.setSync(this.settingsFile, settingsObj); return true; } catch (error) { console.error('Failed to save settings:', error); return false; } } // Transaction history (local cache) getTransactionHistory(address) { try { const data = storage.getSync(`tx-history-${address}.json`); return data || []; } catch (error) { return []; } } saveTransaction(address, transaction) { try { const history = this.getTransactionHistory(address); // Check if transaction already exists const exists = history.some(tx => tx.hash === transaction.hash); if (!exists) { history.unshift(transaction); // Add to beginning // Keep only last 100 transactions if (history.length > 100) { history.splice(100); } storage.setSync(`tx-history-${address}.json`, history); } return true; } catch (error) { console.error('Failed to save transaction:', error); return false; } } // Utility methods clearAllData() { try { storage.removeSync(this.walletFile); storage.removeSync(this.settingsFile); storage.removeSync('address-book.json'); // Clear transaction histories const wallets = this.getWallets(); wallets.addresses.forEach(address => { try { storage.removeSync(`tx-history-${address}.json`); } catch (e) { // Ignore errors for non-existent files } }); return true; } catch (error) { console.error('Failed to clear data:', error); return false; } } exportWallets() { try { const wallets = this.getWallets(); const settings = this.getSettings(); const addressBook = this.getAddressBook(); return { wallets: wallets, settings: settings, addressBook: addressBook, exportDate: new Date().toISOString() }; } catch (error) { console.error('Failed to export data:', error); return null; } } importWallets(data) { try { if (data.wallets) { storage.setSync(this.walletFile, data.wallets); } if (data.settings) { storage.setSync(this.settingsFile, data.settings); } if (data.addressBook) { storage.setSync('address-book.json', data.addressBook); } return true; } catch (error) { console.error('Failed to import data:', error); return false; } } } // Create global instance const paperclipDB = new PaperclipDatabase(); // Make it available globally if (typeof window !== 'undefined') { window.PaperclipDatabase = paperclipDB; } module.exports = paperclipDB;