OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-wallet-desktop commits / df9fd1d

Fix prompt() not supported in Pear/Electron - use modal for password input
CRITICAL FIX: Pear/Electron blocks window.prompt() causing export mnemonic to fail with "prompt() is and will not be supported" error. Root Cause: - exportWalletMnemonic() and exportIdentity() used prompt() for password - Electron security policy blocks synchronous prompts - Function failed before even calling the API Solution: - Created password-prompt-modal for async password input - Replaced all prompt() calls with promptForPasswordModal() - Modal supports Enter key submission and proper focus management Impact: - Users can now successfully export wallet and identity mnemonics - Password input works correctly in Pear desktop environment - Better UX with proper modal instead of browser prompt Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
df9fd1db9d64675e6b990ccc095df2fee6f48ce9
by plankatron <fleeky@gmail.com> · 2026-01-29T15:10:37.000Z

Changed files (2) +78 -4

desktop/index.html +18 -0
……@@ -995,6 +995,24 @@
995995 </div>
996996 </dialog>
997997
998 <!-- Password Prompt Modal -->
999 <dialog id="password-prompt-modal" class="modal-dialog">
1000 <div class="modal-header">
1001 <h3>🔒 Enter Password</h3>
1002 <button class="modal-close" onclick="closePasswordPrompt()">×</button>
1003 </div>
1004 <div class="modal-body">
1005 <p id="password-prompt-message">Enter your encryption password:</p>
1006 <div class="form-group">
1007 <input type="password" id="password-prompt-input" class="form-control" placeholder="Password" autocomplete="current-password" style="width: 100%; padding: 10px; font-size: 16px;">
1008 </div>
1009 <div class="form-actions">
1010 <button class="btn-secondary" onclick="closePasswordPrompt()">Cancel</button>
1011 <button class="btn-primary" onclick="submitPasswordPrompt()">Submit</button>
1012 </div>
1013 </div>
1014 </dialog>
1015
9981016 <!-- Mnemonic Display Modal -->
9991017 <dialog id="mnemonic-display-modal" class="modal-dialog">
10001018 <div class="modal-header">
desktop/wallet.js +60 -4
……@@ -595,8 +595,8 @@ async function exportIdentity() {
595595 return
596596 }
597597
598 // Prompt for password
599 const password = prompt('🔒 Enter your encryption password:')
598 // Use modal instead of prompt() which is blocked in Pear/Electron
599 const password = await promptForPasswordModal('Enter your encryption password to export identity mnemonic:')
600600 if (!password) {
601601 showError('Password required to export mnemonic')
602602 return
……@@ -637,8 +637,8 @@ async function exportWalletMnemonic() {
637637 return
638638 }
639639
640 // Prompt for password
641 const password = prompt('🔒 Enter your encryption password:')
640 // Use modal instead of prompt() which is blocked in Pear/Electron
641 const password = await promptForPasswordModal('Enter your encryption password to export wallet mnemonic:')
642642 if (!password) {
643643 showError('Password required to export mnemonic')
644644 return
……@@ -3653,6 +3653,62 @@ window.setWalletAddressCurrent = setWalletAddressCurrent
36533653window.showAddWallet = showAddWallet
36543654window.showTxDetails = showTxDetails
36553655
3656// Password prompt modal functions (replaces blocked prompt())
3657let passwordPromptResolver = null
3658
3659function promptForPasswordModal(message = 'Enter your password:') {
3660 return new Promise((resolve) => {
3661 const modal = document.getElementById('password-prompt-modal')
3662 const messageEl = document.getElementById('password-prompt-message')
3663 const inputEl = document.getElementById('password-prompt-input')
3664
3665 messageEl.textContent = message
3666 inputEl.value = ''
3667 passwordPromptResolver = resolve
3668
3669 modal.showModal()
3670 inputEl.focus()
3671
3672 // Allow Enter key to submit
3673 inputEl.onkeypress = (e) => {
3674 if (e.key === 'Enter') {
3675 submitPasswordPrompt()
3676 }
3677 }
3678 })
3679}
3680
3681function submitPasswordPrompt() {
3682 const modal = document.getElementById('password-prompt-modal')
3683 const inputEl = document.getElementById('password-prompt-input')
3684 const password = inputEl.value
3685
3686 if (passwordPromptResolver) {
3687 passwordPromptResolver(password)
3688 passwordPromptResolver = null
3689 }
3690
3691 inputEl.value = ''
3692 modal.close()
3693}
3694
3695function closePasswordPrompt() {
3696 const modal = document.getElementById('password-prompt-modal')
3697 const inputEl = document.getElementById('password-prompt-input')
3698
3699 if (passwordPromptResolver) {
3700 passwordPromptResolver(null)
3701 passwordPromptResolver = null
3702 }
3703
3704 inputEl.value = ''
3705 modal.close()
3706}
3707
3708window.promptForPasswordModal = promptForPasswordModal
3709window.submitPasswordPrompt = submitPasswordPrompt
3710window.closePasswordPrompt = closePasswordPrompt
3711
36563712// Mnemonic display modal functions
36573713let currentMnemonic = ''
36583714