Spaces:
Running
Running
make the downloaded fikes for electrum be accesible download please - Follow Up Deployment
5ae9a7f verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>BitVault | Secure Bitcoin Wallet Scanner</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background-color: #0f172a; | |
| } | |
| .glass-card { | |
| background: rgba(15, 23, 42, 0.7); | |
| backdrop-filter: blur(10px); | |
| -webkit-backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.08); | |
| } | |
| .gradient-text { | |
| background: linear-gradient(90deg, #38bdf8 0%, #818cf8 50%, #c084fc 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| .progress-ring { | |
| transition: stroke-dashoffset 0.5s; | |
| transform: rotate(-90deg); | |
| transform-origin: 50% 50%; | |
| } | |
| .wallet-card { | |
| transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); | |
| box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); | |
| } | |
| .wallet-card:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); | |
| } | |
| .scan-pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { | |
| box-shadow: 0 0 0 0 rgba(56, 189, 248, 0.7); | |
| } | |
| 70% { | |
| box-shadow: 0 0 0 10px rgba(56, 189, 248, 0); | |
| } | |
| 100% { | |
| box-shadow: 0 0 0 0 rgba(56, 189, 248, 0); | |
| } | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .custom-scrollbar::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| .custom-scrollbar::-webkit-scrollbar-track { | |
| background: rgba(255, 255, 255, 0.05); | |
| border-radius: 10px; | |
| } | |
| .custom-scrollbar::-webkit-scrollbar-thumb { | |
| background: rgba(255, 255, 255, 0.2); | |
| border-radius: 10px; | |
| } | |
| .custom-scrollbar::-webkit-scrollbar-thumb:hover { | |
| background: rgba(255, 255, 255, 0.3); | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen text-gray-100"> | |
| <div class="container mx-auto px-4 py-8 max-w-7xl"> | |
| <!-- Header with logo and tagline --> | |
| <header class="mb-12 text-center"> | |
| <div class="flex items-center justify-center mb-4"> | |
| <div class="w-12 h-12 rounded-full bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center mr-3"> | |
| <i class="fas fa-bitcoin text-xl"></i> | |
| </div> | |
| <h1 class="text-4xl font-bold gradient-text">BitVault</h1> | |
| </div> | |
| <p class="text-gray-400 max-w-2xl mx-auto text-lg"> | |
| Locally scan for Bitcoin wallets with military-grade security and privacy | |
| </p> | |
| </header> | |
| <!-- Main content grid --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> | |
| <!-- Scanner panel --> | |
| <div class="lg:col-span-2 glass-card rounded-2xl p-8"> | |
| <div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-8"> | |
| <div> | |
| <h2 class="text-2xl font-semibold mb-1">Wallet Scanner</h2> | |
| <p class="text-gray-400 text-sm">Find and analyze Bitcoin wallets on your device</p> | |
| </div> | |
| <div class="flex space-x-3 mt-4 sm:mt-0"> | |
| <button id="scanBtn" class="bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 px-5 py-2.5 rounded-xl flex items-center font-medium shadow-lg"> | |
| <i class="fas fa-search mr-2"></i> Scan Now | |
| </button> | |
| <button id="exportBtn" class="bg-gray-700 hover:bg-gray-600 px-5 py-2.5 rounded-xl flex items-center font-medium" disabled> | |
| <i class="fas fa-file-export mr-2"></i> Export | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Directory selection with modern design --> | |
| <div class="mb-8"> | |
| <label class="block text-gray-300 mb-3 font-medium">Scan Directory</label> | |
| <div class="relative"> | |
| <input type="text" id="directoryPath" class="w-full bg-gray-800 border border-gray-700 rounded-xl px-5 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Select a directory to scan..." value="C:\Users\"> | |
| <button class="absolute right-3 top-3 bg-gray-700 hover:bg-gray-600 p-2 rounded-lg"> | |
| <i class="fas fa-folder-open text-blue-400"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Scan options with toggle switches --> | |
| <div class="mb-8"> | |
| <label class="block text-gray-300 mb-3 font-medium">Scan Options</label> | |
| <div class="grid grid-cols-1 sm:grid-cols-3 gap-4"> | |
| <label class="flex items-center space-x-3 bg-gray-800 hover:bg-gray-750 rounded-xl p-3 cursor-pointer transition-colors"> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input type="checkbox" checked class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer transition-all duration-200 ease-in-out" /> | |
| <label class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-600 cursor-pointer transition-colors duration-200 ease-in-out"></label> | |
| </div> | |
| <span>.dat files</span> | |
| </label> | |
| <label class="flex items-center space-x-3 bg-gray-800 hover:bg-gray-750 rounded-xl p-3 cursor-pointer transition-colors"> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input type="checkbox" checked class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer transition-all duration-200 ease-in-out" /> | |
| <label class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-600 cursor-pointer transition-colors duration-200 ease-in-out"></label> | |
| </div> | |
| <span>Seed Phrases</span> | |
| </label> | |
| <label class="flex items-center space-x-3 bg-gray-800 hover:bg-gray-750 rounded-xl p-3 cursor-pointer transition-colors"> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input type="checkbox" checked class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer transition-all duration-200 ease-in-out" /> | |
| <label class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-600 cursor-pointer transition-colors duration-200 ease-in-out"></label> | |
| </div> | |
| <span>Private Keys</span> | |
| </label> | |
| </div> | |
| </div> | |
| <!-- Circular progress indicator --> | |
| <div class="mb-8 flex flex-col items-center"> | |
| <div class="relative w-32 h-32 mb-4"> | |
| <svg class="w-full h-full" viewBox="0 0 100 100"> | |
| <circle class="text-gray-800" stroke-width="8" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" /> | |
| <circle id="progressCircle" class="progress-ring text-blue-500" stroke-width="8" stroke-linecap="round" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" stroke-dasharray="251.2" stroke-dashoffset="251.2" /> | |
| </svg> | |
| <div class="absolute inset-0 flex items-center justify-center"> | |
| <span id="progressText" class="text-2xl font-bold">0%</span> | |
| </div> | |
| </div> | |
| <p id="progressStatus" class="text-gray-400">Ready to scan</p> | |
| </div> | |
| <!-- Scan results with animated cards --> | |
| <div> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-semibold">Scan Results</h3> | |
| <span class="text-sm text-gray-400" id="fileCount">0 files scanned</span> | |
| </div> | |
| <div id="resultsContainer" class="glass-card rounded-2xl p-6 min-h-48 max-h-96 overflow-y-auto custom-scrollbar"> | |
| <div class="text-center py-10"> | |
| <div class="w-16 h-16 mx-auto mb-4 rounded-full bg-gray-800 flex items-center justify-center"> | |
| <i class="fas fa-search text-2xl text-blue-400"></i> | |
| </div> | |
| <h4 class="text-lg font-medium mb-1">No scan results yet</h4> | |
| <p class="text-gray-400">Click "Scan Now" to begin searching for wallets</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Wallet info panel --> | |
| <div class="glass-card rounded-2xl p-8"> | |
| <div class="flex items-center justify-between mb-8"> | |
| <div> | |
| <h2 class="text-2xl font-semibold mb-1">Detected Wallets</h2> | |
| <p class="text-gray-400 text-sm">Found <span id="walletsFound" class="font-medium">0</span> wallets</p> | |
| </div> | |
| <div class="relative"> | |
| <div id="totalBalance" class="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent"> | |
| 0.00 BTC | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Stats cards --> | |
| <div class="grid grid-cols-2 gap-4 mb-8"> | |
| <div class="bg-gray-800 rounded-xl p-4"> | |
| <div class="flex items-center"> | |
| <div class="w-10 h-10 rounded-full bg-blue-900/30 text-blue-400 flex items-center justify-center mr-3"> | |
| <i class="fas fa-wallet"></i> | |
| </div> | |
| <div> | |
| <p class="text-xs text-gray-400">With Balance</p> | |
| <p id="walletsWithBalance" class="font-bold text-lg">0</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-800 rounded-xl p-4"> | |
| <div class="flex items-center"> | |
| <div class="w-10 h-10 rounded-full bg-purple-900/30 text-purple-400 flex items-center justify-center mr-3"> | |
| <i class="fas fa-lock"></i> | |
| </div> | |
| <div> | |
| <p class="text-xs text-gray-400">Encrypted</p> | |
| <p id="encryptedWallets" class="font-bold text-lg">0</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Wallets list --> | |
| <div class="space-y-4 mb-8 max-h-96 overflow-y-auto custom-scrollbar" id="walletsList"> | |
| <div class="text-center py-10"> | |
| <div class="w-16 h-16 mx-auto mb-4 rounded-full bg-gray-800 flex items-center justify-center"> | |
| <i class="fas fa-wallet text-2xl text-purple-400"></i> | |
| </div> | |
| <h4 class="text-lg font-medium mb-1">No wallets detected</h4> | |
| <p class="text-gray-400">Scan your device to find Bitcoin wallets</p> | |
| </div> | |
| </div> | |
| <!-- Security assurance --> | |
| <div class="bg-gradient-to-br from-blue-900/30 to-purple-900/30 rounded-xl p-5 border border-blue-800/30"> | |
| <div class="flex items-start"> | |
| <div class="w-10 h-10 rounded-full bg-blue-900/30 text-blue-400 flex items-center justify-center mr-3 mt-1"> | |
| <i class="fas fa-shield-alt"></i> | |
| </div> | |
| <div> | |
| <h4 class="font-semibold mb-2">100% Local Processing</h4> | |
| <p class="text-sm text-gray-400"> | |
| All operations run on your device. No data is sent to external servers. Your private keys never leave your computer. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Encryption modal --> | |
| <div id="encryptModal" class="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50 hidden px-4"> | |
| <div class="glass-card rounded-2xl p-8 max-w-md w-full border border-gray-700 transform transition-all duration-300 scale-95 opacity-0" id="modalContent"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h3 class="text-xl font-semibold">Secure Export</h3> | |
| <button id="closeModal" class="text-gray-400 hover:text-white p-1 rounded-full hover:bg-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <p class="mb-6 text-gray-400"> | |
| Protect your wallet data with AES-256 encryption before exporting. Choose a strong passphrase. | |
| </p> | |
| <div class="space-y-5"> | |
| <div> | |
| <label class="block text-gray-300 mb-2 text-sm font-medium">Passphrase</label> | |
| <div class="relative"> | |
| <input type="password" id="encryptionPass" class="w-full bg-gray-800 border border-gray-700 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Enter passphrase"> | |
| <button class="absolute right-3 top-3 text-gray-400 hover:text-gray-300" id="togglePass1"> | |
| <i class="fas fa-eye"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-gray-300 mb-2 text-sm font-medium">Confirm Passphrase</label> | |
| <div class="relative"> | |
| <input type="password" id="confirmPass" class="w-full bg-gray-800 border border-gray-700 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Confirm passphrase"> | |
| <button class="absolute right-3 top-3 text-gray-400 hover:text-gray-300" id="togglePass2"> | |
| <i class="fas fa-eye"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-400"> | |
| <i class="fas fa-info-circle mr-2 text-blue-400"></i> | |
| <span>Remember this passphrase - it cannot be recovered</span> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3 mt-8"> | |
| <button id="cancelEncrypt" class="px-5 py-2.5 rounded-xl border border-gray-600 hover:bg-gray-700 font-medium"> | |
| Cancel | |
| </button> | |
| <button id="confirmEncrypt" class="bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 px-5 py-2.5 rounded-xl font-medium shadow-lg"> | |
| Encrypt & Export | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Success toast notification --> | |
| <div id="successToast" class="fixed bottom-6 right-6 bg-green-600 text-white px-6 py-3 rounded-xl shadow-lg flex items-center transform translate-y-10 opacity-0 transition-all duration-300 z-50"> | |
| <i class="fas fa-check-circle mr-3"></i> | |
| <span>Export file saved successfully!</span> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // DOM Elements | |
| const scanBtn = document.getElementById('scanBtn'); | |
| const exportBtn = document.getElementById('exportBtn'); | |
| const progressText = document.getElementById('progressText'); | |
| const progressCircle = document.getElementById('progressCircle'); | |
| const progressStatus = document.getElementById('progressStatus'); | |
| const resultsContainer = document.getElementById('resultsContainer'); | |
| const walletsFound = document.getElementById('walletsFound'); | |
| const walletsWithBalance = document.getElementById('walletsWithBalance'); | |
| const encryptedWallets = document.getElementById('encryptedWallets'); | |
| const totalBalance = document.getElementById('totalBalance'); | |
| const walletsList = document.getElementById('walletsList'); | |
| const fileCount = document.getElementById('fileCount'); | |
| const encryptModal = document.getElementById('encryptModal'); | |
| const modalContent = document.getElementById('modalContent'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const cancelEncrypt = document.getElementById('cancelEncrypt'); | |
| const confirmEncrypt = document.getElementById('confirmEncrypt'); | |
| const togglePass1 = document.getElementById('togglePass1'); | |
| const togglePass2 = document.getElementById('togglePass2'); | |
| const encryptionPass = document.getElementById('encryptionPass'); | |
| const confirmPass = document.getElementById('confirmPass'); | |
| const successToast = document.getElementById('successToast'); | |
| // Sample wallet data for demonstration | |
| const sampleWallets = [ | |
| { | |
| name: 'wallet.dat', | |
| path: 'C:/Users/Documents/Bitcoin/wallet.dat', | |
| type: 'wallet.dat', | |
| balance: 0.42, | |
| encrypted: false, | |
| date: '2023-05-15' | |
| }, | |
| { | |
| name: 'My Backup Wallet', | |
| path: 'C:/Users/Desktop/backup_seed.txt', | |
| type: 'seed phrase', | |
| balance: 1.85, | |
| encrypted: true, | |
| date: '2023-06-22' | |
| }, | |
| { | |
| name: 'Old Wallet', | |
| path: 'C:/Users/Downloads/old_wallet.json', | |
| type: 'private key', | |
| balance: 0, | |
| encrypted: false, | |
| date: '2022-11-05' | |
| }, | |
| { | |
| name: 'Trading Wallet', | |
| path: 'C:/Users/AppData/Roaming/Bitcoin/wallet.dat', | |
| type: 'wallet.dat', | |
| balance: 3.21, | |
| encrypted: true, | |
| date: '2023-07-10' | |
| } | |
| ]; | |
| // Toggle password visibility | |
| togglePass1.addEventListener('click', function() { | |
| const type = encryptionPass.getAttribute('type') === 'password' ? 'text' : 'password'; | |
| encryptionPass.setAttribute('type', type); | |
| togglePass1.innerHTML = type === 'password' ? '<i class="fas fa-eye"></i>' : '<i class="fas fa-eye-slash"></i>'; | |
| }); | |
| togglePass2.addEventListener('click', function() { | |
| const type = confirmPass.getAttribute('type') === 'password' ? 'text' : 'password'; | |
| confirmPass.setAttribute('type', type); | |
| togglePass2.innerHTML = type === 'password' ? '<i class="fas fa-eye"></i>' : '<i class="fas fa-eye-slash"></i>'; | |
| }); | |
| // Scan button click handler | |
| scanBtn.addEventListener('click', function() { | |
| // Reset UI | |
| resultsContainer.innerHTML = ` | |
| <div class="flex flex-col items-center justify-center py-10"> | |
| <div class="w-20 h-20 mb-4 rounded-full bg-blue-900/20 flex items-center justify-center scan-pulse"> | |
| <i class="fas fa-search text-3xl text-blue-400"></i> | |
| </div> | |
| <h4 class="text-lg font-medium mb-1">Scanning directories</h4> | |
| <p class="text-gray-400">Please wait while we search for wallet files</p> | |
| </div> | |
| `; | |
| walletsList.innerHTML = ` | |
| <div class="flex flex-col items-center justify-center py-10"> | |
| <div class="w-16 h-16 mb-4 rounded-full bg-gray-800 flex items-center justify-center"> | |
| <i class="fas fa-spinner fa-spin text-2xl text-purple-400"></i> | |
| </div> | |
| <h4 class="text-lg font-medium mb-1">Scanning for wallets</h4> | |
| <p class="text-gray-400">This may take a few moments</p> | |
| </div> | |
| `; | |
| walletsFound.textContent = '0'; | |
| walletsWithBalance.textContent = '0'; | |
| encryptedWallets.textContent = '0'; | |
| totalBalance.textContent = '0.00 BTC'; | |
| scanBtn.disabled = true; | |
| scanBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Scanning...'; | |
| // Simulate scan progress | |
| let progress = 0; | |
| const circumference = 2 * Math.PI * 40; | |
| const progressInterval = setInterval(() => { | |
| progress += Math.random() * 8; | |
| if (progress > 100) progress = 100; | |
| progressText.textContent = Math.floor(progress) + '%'; | |
| const offset = circumference - (progress / 100) * circumference; | |
| progressCircle.style.strokeDashoffset = offset; | |
| // Update status text | |
| if (progress < 30) { | |
| progressStatus.textContent = 'Indexing files...'; | |
| } else if (progress < 70) { | |
| progressStatus.textContent = 'Analyzing potential wallets...'; | |
| fileCount.textContent = `${Math.floor(progress * 35)} files scanned`; | |
| } else { | |
| progressStatus.textContent = 'Finalizing scan...'; | |
| fileCount.textContent = `${Math.floor(progress * 35)} files scanned`; | |
| } | |
| if (progress === 100) { | |
| clearInterval(progressInterval); | |
| setTimeout(showScanResults, 800); | |
| } | |
| }, 300); | |
| }); | |
| // Show scan results with animation | |
| function showScanResults() { | |
| // Update results container | |
| let resultsHTML = ` | |
| <div class="space-y-4 fade-in"> | |
| <div class="flex items-center p-4 bg-gray-800 rounded-xl"> | |
| <div class="w-12 h-12 rounded-full bg-green-900/20 flex items-center justify-center mr-4"> | |
| <i class="fas fa-check-circle text-green-400"></i> | |
| </div> | |
| <div> | |
| <h4 class="font-medium mb-1">Scan completed successfully</h4> | |
| <p class="text-sm text-gray-400">${new Date().toLocaleString()}</p> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 sm:grid-cols-2 gap-4"> | |
| <div class="p-4 bg-gray-800 rounded-xl"> | |
| <div class="flex items-center mb-2"> | |
| <i class="fas fa-file-alt text-blue-400 mr-3"></i> | |
| <span class="font-medium">Files Scanned</span> | |
| </div> | |
| <p class="text-2xl font-bold">3,452</p> | |
| </div> | |
| <div class="p-4 bg-gray-800 rounded-xl"> | |
| <div class="flex items-center mb-2"> | |
| <i class="fas fa-wallet text-purple-400 mr-3"></i> | |
| <span class="font-medium">Wallets Found</span> | |
| </div> | |
| <p class="text-2xl font-bold">${sampleWallets.length}</p> | |
| </div> | |
| </div> | |
| <div class="mt-4 text-center"> | |
| <button id="downloadLink" class="inline-flex items-center bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 px-5 py-2.5 rounded-xl font-medium shadow-lg"> | |
| <i class="fas fa-download mr-2"></i> Download Export File | |
| </button> | |
| </div> | |
| </div> | |
| `; | |
| resultsContainer.innerHTML = resultsHTML; | |
| // Update wallet list | |
| updateWalletList(); | |
| // Reset scan button | |
| scanBtn.disabled = false; | |
| scanBtn.innerHTML = '<i class="fas fa-search mr-2"></i> Scan Now'; | |
| exportBtn.disabled = false; | |
| // Update progress status | |
| progressStatus.textContent = 'Scan completed'; | |
| fileCount.textContent = '3,452 files scanned'; | |
| } | |
| // Update wallet list with sample data | |
| function updateWalletList() { | |
| let walletsHTML = ''; | |
| let withBalance = 0; | |
| let encryptedCount = 0; | |
| let balanceTotal = 0; | |
| sampleWallets.forEach((wallet, index) => { | |
| withBalance += wallet.balance > 0 ? 1 : 0; | |
| encryptedCount += wallet.encrypted ? 1 : 0; | |
| balanceTotal += wallet.balance; | |
| // Format balance with commas | |
| const formattedBalance = wallet.balance > 0 ? | |
| wallet.balance.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 8 }) : | |
| '0.00'; | |
| walletsHTML += ` | |
| <div class="wallet-card bg-gray-800 rounded-xl p-5 fade-in" style="animation-delay: ${index * 0.1}s"> | |
| <div class="flex justify-between items-start mb-3"> | |
| <div> | |
| <h4 class="font-semibold truncate">${wallet.name}</h4> | |
| <p class="text-xs text-gray-400">${wallet.date}</p> | |
| </div> | |
| <span class="text-xs bg-gray-700 px-2 py-1 rounded-full">${wallet.type}</span> | |
| </div> | |
| <p class="text-xs text-gray-400 truncate mb-4">${wallet.path}</p> | |
| <div class="flex justify-between items-center"> | |
| <div> | |
| <span class="text-sm text-gray-400">Balance:</span> | |
| <span class="font-bold ml-1 ${wallet.balance > 0 ? 'text-green-400' : 'text-gray-400'}"> | |
| ${wallet.balance > 0 ? formattedBalance + ' BTC' : 'Empty'} | |
| </span> | |
| </div> | |
| <div class="flex items-center space-x-2"> | |
| ${wallet.encrypted ? '<span class="text-xs bg-green-900/30 text-green-400 px-2 py-1 rounded-full"><i class="fas fa-lock mr-1"></i> Encrypted</span>' : ''} | |
| <button class="text-blue-400 hover:text-blue-300 text-sm"> | |
| <i class="fas fa-ellipsis-h"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| }); | |
| walletsList.innerHTML = walletsHTML; | |
| walletsFound.textContent = sampleWallets.length; | |
| walletsWithBalance.textContent = withBalance; | |
| encryptedWallets.textContent = encryptedCount; | |
| totalBalance.textContent = balanceTotal.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 8 }) + ' BTC'; | |
| } | |
| // Export button click handler | |
| exportBtn.addEventListener('click', function() { | |
| encryptModal.classList.remove('hidden'); | |
| setTimeout(() => { | |
| modalContent.classList.remove('scale-95'); | |
| modalContent.classList.remove('opacity-0'); | |
| }, 10); | |
| }); | |
| // Modal close handlers | |
| function closeModalHandler() { | |
| modalContent.classList.add('scale-95'); | |
| modalContent.classList.add('opacity-0'); | |
| setTimeout(() => { | |
| encryptModal.classList.add('hidden'); | |
| }, 300); | |
| } | |
| closeModal.addEventListener('click', closeModalHandler); | |
| cancelEncrypt.addEventListener('click', closeModalHandler); | |
| // Confirm encryption | |
| confirmEncrypt.addEventListener('click', function() { | |
| const pass = encryptionPass.value; | |
| const confirm = confirmPass.value; | |
| if (!pass || !confirm) { | |
| alert('Please enter and confirm your passphrase'); | |
| return; | |
| } | |
| if (pass !== confirm) { | |
| alert('Passphrases do not match'); | |
| return; | |
| } | |
| if (pass.length < 8) { | |
| alert('Passphrase must be at least 8 characters'); | |
| return; | |
| } | |
| // Simulate encryption process | |
| modalContent.innerHTML = ` | |
| <div class="flex flex-col items-center justify-center py-10"> | |
| <div class="w-20 h-20 mb-6 rounded-full bg-purple-900/20 flex items-center justify-center"> | |
| <i class="fas fa-spinner fa-spin text-3xl text-purple-400"></i> | |
| </div> | |
| <h4 class="text-lg font-medium mb-2">Encrypting wallet data</h4> | |
| <p class="text-gray-400 text-center">Securing your wallets with AES-256 encryption</p> | |
| </div> | |
| `; | |
| setTimeout(() => { | |
| // Create export data | |
| const exportData = { | |
| wallets: sampleWallets.filter(w => w.balance > 0), | |
| timestamp: new Date().toISOString(), | |
| version: "1.0" | |
| }; | |
| // Create download link | |
| const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(exportData, null, 2)); | |
| const downloadLink = document.getElementById('downloadLink'); | |
| if (downloadLink) { | |
| downloadLink.setAttribute("href", dataStr); | |
| downloadLink.setAttribute("download", `bitvault_export_${new Date().getTime()}.json`); | |
| } | |
| // Close modal | |
| closeModalHandler(); | |
| // Show success toast | |
| successToast.classList.remove('translate-y-10'); | |
| successToast.classList.remove('opacity-0'); | |
| setTimeout(() => { | |
| successToast.classList.add('translate-y-10'); | |
| successToast.classList.add('opacity-0'); | |
| }, 3000); | |
| // Reset modal for next use | |
| setTimeout(() => { | |
| modalContent.innerHTML = ` | |
| <div class="flex justify-between items-center mb-6"> | |
| <h3 class="text-xl font-semibold">Secure Export</h3> | |
| <button id="closeModal" class="text-gray-400 hover:text-white p-1 rounded-full hover:bg-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <p class="mb-6 text-gray-400"> | |
| Protect your wallet data with AES-256 encryption before exporting. Choose a strong passphrase. | |
| </p> | |
| <div class="space-y-5"> | |
| <div> | |
| <label class="block text-gray-300 mb-2 text-sm font-medium">Passphrase</label> | |
| <div class="relative"> | |
| <input type="password" id="encryptionPass" class="w-full bg-gray-800 border border-gray-700 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Enter passphrase"> | |
| <button class="absolute right-3 top-3 text-gray-400 hover:text-gray-300" id="togglePass1"> | |
| <i class="fas fa-eye"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-gray-300 mb-2 text-sm font-medium">Confirm Passphrase</label> | |
| <div class="relative"> | |
| <input type="password" id="confirmPass" class="w-full bg-gray-800 border border-gray-700 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Confirm passphrase"> | |
| <button class="absolute right-3 top-3 text-gray-400 hover:text-gray-300" id="togglePass2"> | |
| <i class="fas fa-eye"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-400"> | |
| <i class="fas fa-info-circle mr-2 text-blue-400"></i> | |
| <span>Remember this passphrase - it cannot be recovered</span> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3 mt-8"> | |
| <button id="cancelEncrypt" class="px-5 py-2.5 rounded-xl border border-gray-600 hover:bg-gray-700 font-medium"> | |
| Cancel | |
| </button> | |
| <button id="confirmEncrypt" class="bg-gradient-to-r from-blue-500 to-blue-600 hover:from-blue-600 hover:to-blue-700 px-5 py-2.5 rounded-xl font-medium shadow-lg"> | |
| Encrypt & Export | |
| </button> | |
| </div> | |
| `; | |
| // Re-attach event listeners | |
| document.getElementById('closeModal').addEventListener('click', closeModalHandler); | |
| document.getElementById('cancelEncrypt').addEventListener('click', closeModalHandler); | |
| document.getElementById('confirmEncrypt').addEventListener('click', confirmEncrypt); | |
| document.getElementById('togglePass1').addEventListener('click', function() { | |
| const type = document.getElementById('encryptionPass').getAttribute('type') === 'password' ? 'text' : 'password'; | |
| document.getElementById('encryptionPass').setAttribute('type', type); | |
| this.innerHTML = type === 'password' ? '<i class="fas fa-eye"></i>' : '<i class="fas fa-eye-slash"></i>'; | |
| }); | |
| document.getElementById('togglePass2').addEventListener('click', function() { | |
| const type = document.getElementById('confirmPass').getAttribute('type') === 'password' ? 'text' : 'password'; | |
| document.getElementById('confirmPass').setAttribute('type', type); | |
| this.innerHTML = type === 'password' ? '<i class="fas fa-eye"></i>' : '<i class="fas fa-eye-slash"></i>'; | |
| }); | |
| }, 500); | |
| }, 1500); | |
| }); | |
| // Initialize toggle switches | |
| document.querySelectorAll('.toggle-checkbox').forEach(checkbox => { | |
| checkbox.addEventListener('change', function() { | |
| const label = this.nextElementSibling; | |
| if (this.checked) { | |
| label.classList.remove('bg-gray-600'); | |
| label.classList.add('bg-blue-500'); | |
| } else { | |
| label.classList.remove('bg-blue-500'); | |
| label.classList.add('bg-gray-600'); | |
| } | |
| }); | |
| // Initialize state | |
| if (checkbox.checked) { | |
| const label = checkbox.nextElementSibling; | |
| label.classList.remove('bg-gray-600'); | |
| label.classList.add('bg-blue-500'); | |
| } | |
| }); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=libby055404/btcme" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |