diff --git a/src/components/WalletModal.js b/src/components/WalletModal.js index bc5832b..c13ab0d 100644 --- a/src/components/WalletModal.js +++ b/src/components/WalletModal.js @@ -1,18 +1,85 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; import styles from './WalletModal.module.css'; -import { Eye, EyeOff } from 'lucide-react'; +import { Eye, EyeOff, Info, X } from 'lucide-react'; const WalletModal = () => { const { isLoading, error } = useSelector(state => state.walletModal); const [copiedStates, setCopiedStates] = useState({}); - const [revealedMnemonics, setRevealedMnemonics] = useState({ - master: false, - layer1: false, - layer2_thunder: false, - layer2_bitnames: false, - layer2_zside: false - }); + const [revealedPaths, setRevealedPaths] = useState({ master: false }); + const [, setConfig] = useState(null); + const [derivationPaths, setDerivationPaths] = useState({}); + const [mnemonics, setMnemonics] = useState({ master: '••••••••••••' }); + const [chainsList, setChainsList] = useState([]); + const [showInfoModal, setShowInfoModal] = useState(false); + + // Load config on component mount + useEffect(() => { + const fetchConfig = async () => { + try { + const result = await window.electronAPI.getConfig(); + setConfig(result); + + if (result && result.chains) { + // Find the L1 chain (enforcer) + const enforcerChain = result.chains.find(chain => chain.id === 'enforcer'); + + // Setup initial paths object with L1 (hardcoded path as specified) + const paths = {}; + if (enforcerChain) { + paths['enforcer'] = "m/44'/0'/256'"; + } + + // Find all L2 chains and compute their paths based on slot + const l2Chains = result.chains.filter(chain => chain.chain_layer === 2 && chain.slot); + + // Process L2 chains + l2Chains.forEach(chain => { + paths[chain.id] = `m/44'/0'/${chain.slot}'`; + }); + + setDerivationPaths(paths); + + // Initialize revealed state for all chains + const initialRevealState = { master: false }; + if (enforcerChain) { + initialRevealState['enforcer'] = false; + } + + l2Chains.forEach(chain => { + initialRevealState[chain.id] = false; + }); + + setRevealedPaths(initialRevealState); + + // Setup the chains list for rendering + const chains = []; + + // Add L1 chain + if (enforcerChain) { + chains.push({ + ...enforcerChain, + type: 'L1', + display_name: 'Bitcoin Core (Patched)' + }); + } + + // Add L2 chains + l2Chains.forEach(chain => { + chains.push({ + ...chain, + type: 'L2' + }); + }); + + setChainsList(chains); + } + } catch (error) { + console.error("Error fetching chain config:", error); + } + }; + fetchConfig(); + }, []); const handleCopy = async (text, type, event) => { try { @@ -46,53 +113,22 @@ const WalletModal = () => { mnemonicCol.scrollLeft += event.deltaY; } }; - const [mnemonics, setMnemonics] = useState({ - master: '••••••••••••', - layer1: '••••••••••••', - layer2_thunder: '••••••••••••', - layer2_bitnames: '••••••••••••', - layer2_zside: '••••••••••••' - }); - - const toggleMnemonic = async (key) => { - // If we're hiding the current one, just hide it - if (revealedMnemonics[key]) { - setRevealedMnemonics(prev => ({ - master: false, - layer1: false, - layer2_thunder: false, - layer2_bitnames: false, - layer2_zside: false - })); - return; - } + + const toggleReveal = async (key) => { + // Toggle the current path's reveal state + setRevealedPaths(prev => ({ + ...prev, + [key]: !prev[key] + })); - // If we're revealing a new one, hide all others first - if (!revealedMnemonics[key] && mnemonics[key] === '••••••••••••') { + // For master key, we need to fetch the actual mnemonic + if (key === 'master' && !revealedPaths[key] && mnemonics[key] === '••••••••••••') { try { - let type; - switch (key) { - case 'master': - type = 'master'; - break; - case 'layer1': - type = 'layer1'; - break; - case 'layer2_thunder': - type = 'thunder'; - break; - case 'layer2_bitnames': - type = 'bitnames'; - break; - case 'layer2_zside': - type = 'zside'; - break; - } - const result = await window.electronAPI.getWalletStarter(type); + const result = await window.electronAPI.getWalletStarter('master'); if (result.success) { setMnemonics(prev => ({ ...prev, - [key]: result.data + master: result.data })); } } catch (error) { @@ -100,16 +136,23 @@ const WalletModal = () => { } } - // Set only the current one to visible - setRevealedMnemonics({ - master: false, - layer1: false, - layer2_thunder: false, - layer2_bitnames: false, - layer2_zside: false, - [key]: true - }); + // For chain wallets, we don't need to fetch actual mnemonics, just reveal their paths + }; + + const getChainType = (chain) => { + if (chain.type === 'L1') { + return styles.l1Badge; + } else if (chain.type === 'L2') { + return styles.l2Badge; + } else { + return ''; + } }; + + const getChainTypeText = (chain) => { + return chain.type; + }; + return (
+ Your wallet seeds are stored locally and are never transmitted over the internet. +