// Import our WebAssembly module import init, { create_key_space, encrypt_key_space, decrypt_key_space, logout, create_keypair, select_keypair, list_keypairs, keypair_pub_key, create_ethereum_wallet, create_ethereum_wallet_from_name, create_ethereum_wallet_from_private_key, get_ethereum_address, get_ethereum_private_key, format_eth_balance, clear_ethereum_wallets } from '../../pkg/webassembly.js'; // Helper function to convert ArrayBuffer to hex string function bufferToHex(buffer) { return Array.from(new Uint8Array(buffer)) .map(b => b.toString(16).padStart(2, '0')) .join(''); } // Helper function to convert hex string to Uint8Array function hexToBuffer(hex) { const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.substr(i, 2), 16); } return bytes; } // LocalStorage functions for Ethereum wallets const ETH_WALLET_PREFIX = 'eth_wallet_'; // Save Ethereum wallet to localStorage function saveEthWalletToStorage(address, privateKey) { localStorage.setItem(`${ETH_WALLET_PREFIX}${address}`, privateKey); } // Get Ethereum wallet from localStorage function getEthWalletFromStorage(address) { return localStorage.getItem(`${ETH_WALLET_PREFIX}${address}`); } // Session state let selectedKeypair = null; let hasEthereumWallet = false; // Update UI based on login state function updateLoginUI() { const loginStatus = document.getElementById('login-status'); try { // Try to list keypairs to check if logged in const keypairs = list_keypairs(); if (keypairs && keypairs.length > 0) { loginStatus.textContent = 'Status: Logged in'; loginStatus.className = 'status logged-in'; // Update keypairs list updateKeypairsList(); } else { loginStatus.textContent = 'Status: Not logged in. Please login in the Main Crypto Demo page first.'; loginStatus.className = 'status logged-out'; // Hide Ethereum wallet info when logged out document.getElementById('ethereum-wallet-info').classList.add('hidden'); hasEthereumWallet = false; } } catch (e) { loginStatus.textContent = 'Status: Not logged in. Please login in the Main Crypto Demo page first.'; loginStatus.className = 'status logged-out'; // Hide Ethereum wallet info when logged out document.getElementById('ethereum-wallet-info').classList.add('hidden'); hasEthereumWallet = false; } } // Update the keypairs dropdown list function updateKeypairsList() { const selectKeypair = document.getElementById('select-keypair'); // Clear existing options while (selectKeypair.options.length > 1) { selectKeypair.remove(1); } try { // Get keypairs list const keypairs = list_keypairs(); // Add options for each keypair keypairs.forEach(keypairName => { const option = document.createElement('option'); option.value = keypairName; option.textContent = keypairName; selectKeypair.appendChild(option); }); // If there's a selected keypair, select it in the dropdown if (selectedKeypair) { selectKeypair.value = selectedKeypair; } } catch (e) { console.error('Error updating keypairs list:', e); } } // Select a keypair async function performSelectKeypair() { const keypairName = document.getElementById('select-keypair').value; if (!keypairName) { document.getElementById('keypair-management-result').textContent = 'Please select a keypair'; return; } try { // Select keypair const result = select_keypair(keypairName); if (result === 0) { selectedKeypair = keypairName; document.getElementById('keypair-management-result').textContent = `Selected keypair "${keypairName}"`; // Hide Ethereum wallet info when changing keypairs document.getElementById('ethereum-wallet-info').classList.add('hidden'); hasEthereumWallet = false; } else { document.getElementById('keypair-management-result').textContent = `Error selecting keypair: ${result}`; } } catch (e) { document.getElementById('keypair-management-result').textContent = `Error: ${e}`; } } // Create an Ethereum wallet from the selected keypair async function performCreateEthereumWallet() { if (!selectedKeypair) { document.getElementById('ethereum-wallet-result').textContent = 'Please select a keypair first'; return; } try { // Create Ethereum wallet const result = create_ethereum_wallet(); if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key const privateKey = get_ethereum_private_key(); document.getElementById('ethereum-private-key-value').textContent = privateKey; // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); // Save the wallet to localStorage saveEthWalletToStorage(address, privateKey); document.getElementById('ethereum-wallet-result').textContent = 'Successfully created Ethereum wallet'; } else { document.getElementById('ethereum-wallet-result').textContent = `Error creating Ethereum wallet: ${result}`; } } catch (e) { document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } // Create an Ethereum wallet from a name and the selected keypair async function performCreateEthereumWalletFromName() { if (!selectedKeypair) { document.getElementById('ethereum-wallet-result').textContent = 'Please select a keypair first'; return; } const name = document.getElementById('wallet-name').value.trim(); if (!name) { document.getElementById('ethereum-wallet-result').textContent = 'Please enter a name for derivation'; return; } try { // Create Ethereum wallet from name const result = create_ethereum_wallet_from_name(name); if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key const privateKey = get_ethereum_private_key(); document.getElementById('ethereum-private-key-value').textContent = privateKey; // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); // Save the wallet to localStorage saveEthWalletToStorage(address, privateKey); document.getElementById('ethereum-wallet-result').textContent = `Successfully created Ethereum wallet from name "${name}"`; } else { document.getElementById('ethereum-wallet-result').textContent = `Error creating Ethereum wallet: ${result}`; } } catch (e) { document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } // Create an Ethereum wallet from a private key async function performCreateEthereumWalletFromPrivateKey() { const privateKey = document.getElementById('private-key').value.trim(); if (!privateKey) { document.getElementById('ethereum-wallet-result').textContent = 'Please enter a private key'; return; } try { // Create Ethereum wallet from private key const result = create_ethereum_wallet_from_private_key(privateKey); if (result === 0) { hasEthereumWallet = true; // Get and display Ethereum address const address = get_ethereum_address(); document.getElementById('ethereum-address-value').textContent = address; // Get and display private key const displayPrivateKey = get_ethereum_private_key(); document.getElementById('ethereum-private-key-value').textContent = displayPrivateKey; // Show the wallet info document.getElementById('ethereum-wallet-info').classList.remove('hidden'); // Save the wallet to localStorage saveEthWalletToStorage(address, displayPrivateKey); document.getElementById('ethereum-wallet-result').textContent = 'Successfully imported Ethereum wallet from private key'; } else { document.getElementById('ethereum-wallet-result').textContent = `Error importing Ethereum wallet: ${result}`; } } catch (e) { document.getElementById('ethereum-wallet-result').textContent = `Error: ${e}`; } } // Check the balance of an Ethereum address async function checkBalance() { if (!hasEthereumWallet) { document.getElementById('balance-result').textContent = 'Please create an Ethereum wallet first'; return; } try { const address = get_ethereum_address(); document.getElementById('balance-result').textContent = 'Checking balance...'; // Use the Ethereum Web3 API directly from JavaScript const response = await fetch(GNOSIS_RPC_URL, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ jsonrpc: '2.0', method: 'eth_getBalance', params: [address, 'latest'], id: 1, }), }); const data = await response.json(); if (data.error) { document.getElementById('balance-result').textContent = `Error: ${data.error.message}`; return; } const balanceHex = data.result; const formattedBalance = format_eth_balance(balanceHex); document.getElementById('balance-result').textContent = `Balance: ${formattedBalance}`; } catch (e) { document.getElementById('balance-result').textContent = `Error: ${e}`; } } // Copy text to clipboard function copyToClipboard(text, successMessage) { navigator.clipboard.writeText(text) .then(() => { alert(successMessage); }) .catch(err => { console.error('Could not copy text: ', err); }); } // Constants const GNOSIS_RPC_URL = "https://rpc.gnosis.gateway.fm"; const GNOSIS_EXPLORER = "https://gnosisscan.io"; async function run() { // Initialize the WebAssembly module await init(); console.log('WebAssembly crypto module initialized!'); // Set up the keypair selection document.getElementById('select-keypair').addEventListener('change', performSelectKeypair); // Set up the Ethereum wallet management document.getElementById('create-ethereum-wallet-button').addEventListener('click', performCreateEthereumWallet); document.getElementById('create-from-name-button').addEventListener('click', performCreateEthereumWalletFromName); document.getElementById('import-private-key-button').addEventListener('click', performCreateEthereumWalletFromPrivateKey); // Set up the copy buttons document.getElementById('copy-address-button').addEventListener('click', () => { const address = document.getElementById('ethereum-address-value').textContent; copyToClipboard(address, 'Ethereum address copied to clipboard!'); }); document.getElementById('copy-private-key-button').addEventListener('click', () => { const privateKey = document.getElementById('ethereum-private-key-value').textContent; copyToClipboard(privateKey, 'Private key copied to clipboard!'); }); // Set up the balance check document.getElementById('check-balance-button').addEventListener('click', checkBalance); // Initialize UI updateLoginUI(); } run().catch(console.error);