/**
* Simple Litecoin Paper Wallet Generator
* Entropy Collection Module - Keyboard Only Version (Cleaned v2)
*/
const EntropyCollector = (function() {
// Private variables
let entropyProgress = 0;
let entropyData = [];
let keyPresses = 0;
let isCollecting = false;
let entropyPoolSize = 50; // Target number of key presses
let callbackFunction = null;
// DOM elements
let progressBar, progressText;
let entropyInput;
// Initialize the entropy collector
function init() {
// Get references to DOM elements needed
progressBar = document.getElementById('entropy-progress-bar');
progressText = document.getElementById('entropy-percent');
entropyInput = document.getElementById('entropy-text');
// Check if all required elements were found
if (!progressBar || !progressText || !entropyInput) {
console.error('Required entropy UI elements (progress bar, text, or input) not found!');
// Prevent further initialization if UI elements are missing
return;
}
// Add event listeners for entropy collection - keyboard only
entropyInput.addEventListener('keypress', collectKeyboardEntropy);
// Add some initial entropy from browser environment
collectBrowserEntropy();
console.log('Entropy collector initialized (keyboard only, no canvas)');
}
// Start entropy collection
function start(callback) {
entropyProgress = 0;
entropyData = [];
keyPresses = 0; // Reset key presses on start
isCollecting = true;
callbackFunction = callback;
// Reset progress UI elements
updateProgress(); // Update to show 0% or initial browser %
console.log('Entropy collection started');
}
// Collect entropy from keyboard input
function collectKeyboardEntropy(event) {
if (!isCollecting) return;
// --- Visual Feedback Start ---
if (entropyInput) {
// Add the class to trigger the CSS style
entropyInput.classList.add('entropy-input-active');
// Set a timer to remove the class after a short duration (e.g., 150ms)
setTimeout(() => {
if (entropyInput) { // Check if entropyInput still exists
entropyInput.classList.remove('entropy-input-active');
}
}, 120); // Adjust timing if needed
}
// --- Visual Feedback End ---
// Add keyboard data to entropy pool
// Using key, timestamp, and Math.random() provides good seeding data
const keyData = event.key + event.timeStamp + Math.random();
addEntropy(keyData);
keyPresses++; // Increment counter for actual key presses
updateProgress();
// console.log('Keyboard entropy collected: ' + keyPresses + ', Progress: ' + entropyProgress + '%'); // Keep commented out unless debugging
}
// Collect entropy from browser environment - REVISED to focus on time/randomness
function collectBrowserEntropy() {
try {
// Gather dynamic time data and basic randomness
const browserData = [
Date.now(), // Milliseconds since epoch - dynamic
performance.now(), // High-resolution time since navigation start - dynamic
new Date().toString(), // Includes current time string - dynamic element
Math.random().toString(), // Add multiple Math.random() calls for simple stirring
Math.random().toString(),
Math.random().toString()
].join('|'); // Use a separator
addEntropy(browserData); // Add this combined data to the pool
console.log('Time/Random-based browser entropy collected');
} catch (e) {
console.error("Error collecting browser entropy:", e);
// Still allow the process to continue, relying on keyboard entropy
}
}
// Add data to entropy pool and update progress
function addEntropy(data) {
entropyData.push(data);
// Update progress based purely on keyboard key presses relative to the target size
// Ensure keyPresses doesn't exceed pool size for calculation
let currentKeyPresses = Math.min(keyPresses, entropyPoolSize);
entropyProgress = Math.min(100, Math.floor((currentKeyPresses / entropyPoolSize) * 100));
// updateProgress is called after keyPresses is incremented in collectKeyboardEntropy
}
// Update progress bar and text
function updateProgress() {
// Ensure elements exist before trying to update them
if (progressBar) {
progressBar.style.width = entropyProgress + '%';
}
if (progressText) {
progressText.textContent = entropyProgress + '% Complete';
}
// Enable continue button when enough keyboard entropy is collected
const continueButton = document.getElementById('entropy-continue');
if (continueButton) {
// Button enabled only when keyboard progress reaches 100%
continueButton.disabled = entropyProgress < 100;
}
// If we've reached 100% from keyboard input, finalize entropy collection
// Check isCollecting to prevent multiple finalizations if user keeps typing
if (entropyProgress >= 100 && isCollecting) {
finalizeEntropy();
}
}
// Finalize entropy collection and generate seed
function finalizeEntropy() {
// Prevent finalizeEntropy from running again if user keeps typing after 100%
if (!isCollecting) return;
isCollecting = false;
// Combine all entropy data
const combinedEntropy = entropyData.join('');
// The 'seed' here is the raw collected data string.
// The actual cryptographic strength comes from how this seed
// is processed by SecureRandom or bitcoinjs-lib later.
const seed = combinedEntropy;
console.log('Entropy collection finalized. Raw seed length:', seed.length);
// Call the callback function with the raw seed string
if (typeof callbackFunction === 'function') {
callbackFunction(seed);
} else {
console.error("Entropy collection finished, but no callback function was provided or it's not a function.");
}
}
// Public API (Removed 'skip')
return {
init: init,
start: start
};
})(); // End of IIFE