Update wallet UI to use PaperclipChain

- Remove Ethereum/Web3 references from HTML
- Create PaperclipWallets class with Ed25519 key support
- Add PaperclipDatabase for wallet storage
- Update module loading order in index.html
- Convert button classes from btn-etho to btn-clips
This commit is contained in:
2025-06-15 18:39:48 -07:00
parent dab604463f
commit 1ceb56c7b8
4 changed files with 604 additions and 39 deletions

View File

@@ -0,0 +1,296 @@
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 PaperclipDatabase = new PaperclipDatabase();
// Make it available globally
window.PaperclipDatabase = PaperclipDatabase;
module.exports = PaperclipDatabase;