wizard: fix missing 'wallet_password' and 'wallet_password_hardware' views on abstract KeystoreWizard (these were implicitly defined by the Qt subclass) and test wallet keystore enable.
What changed, and why it matters
This commit fixes a bug in Electrum's wallet setup wizard where two password-related screens ('wallet_password' and 'wallet_password_hardware') were accidentally only defined in the Qt desktop version, not in the shared wizard logic. The fix adds those missing view definitions to the abstract KeystoreWizard so non-Qt interfaces (like command-line or mobile builds) can complete wallet creation properly. It also adds tests verifying that a hardware wallet keystore can be enabled after setup. There is no direct evidence in the commit of a security vulnerability; it appears to be a correctness/robustness fix for wizard flow.
Treat as a normal bug-fix commit. Reviewers using non-Qt Electrum frontends should verify wallet creation and password-entry flows complete correctly. No urgent security response is indicated by the diff itself.
Security signals we found
Fixes missing wizard view definitions that could cause incomplete wallet creation flow in non-Qt builds
Adds regression test for hardware keystore enablement
No explicit security claim by vendor or researcher in commit or references
Evidence from the diff
The patch adds ‘wallet_password’ and ‘wallet_password_hardware’ entries to KeystoreWizard.viewmap in electrum/wizard.py, marking them as ‘last’: True. Previously these views were implicitly defined only by the Qt subclass (NewWalletWizard in Qt), so the abstract wizard could not navigate to or terminate on those views for non-Qt frontends. The test changes update a hardware wallet test vector to use a valid zpub with a root fingerprint and soft_device_id, then exercise resolve_next, _result, and wallet.enable_keystore() to confirm the keystore transitions from watching-only to a Hardware_KeyStore. No cryptographic, authentication, or privilege changes are present.
Changed components
electrum/wizard.py: KeystoreWizard.viewmaptests/test_wizard.py: KeystoreWizardTestCaseInspect captured patch +20 / −4
diff --git a/electrum/wizard.py b/electrum/wizard.py
index 08b65db..ae624a1 100644
--- a/electrum/wizard.py
+++ b/electrum/wizard.py
@@ -226,6 +226,12 @@ class KeystoreWizard(AbstractWizard):
'choose_hardware_device': {
'next': self.on_hardware_device,
},
+ 'wallet_password': {
+ 'last': True
+ },
+ 'wallet_password_hardware': {
+ 'last': True
+ },
}
def maybe_master_pubkey(self, wizard_data):
diff --git a/tests/test_wizard.py b/tests/test_wizard.py
index 82a2fae..203e37e 100644
--- a/tests/test_wizard.py
+++ b/tests/test_wizard.py
@@ -2,7 +2,7 @@ import os
from electrum import SimpleConfig
from electrum.interface import ServerAddr
-from electrum.keystore import bip44_derivation
+from electrum.keystore import bip44_derivation, Hardware_KeyStore
from electrum.network import NetworkParameters, ProxySettings
from electrum.plugin import Plugins, DeviceInfo, Device
from electrum.wizard import ServerConnectWizard, NewWalletWizard, WizardViewState, KeystoreWizard
@@ -266,12 +266,22 @@ class KeystoreWizardTestCase(WizardTestCase):
self.assertEqual('trezor_xpub', v.view)
d.update({
'hw_type': 'trezor',
- 'master_key': 'zpub6jftahH18ngZwMBBp7epRdBwPMPphfdy9gM6P4n5zFUXdfQJmsYfMNZoBnQMkAoBAiQYRyDQKdpxLYp6QuTrWbgmt6v1cxnFdesyiDSocAs',
- 'root_fingerprint': '',
+ 'master_key': 'zpub6rakEaM5ps5UiQ2yhbWiEkd6ceJfmuzegwc62G4itMz8L7rRFRqh6y8bTCScXV6NfTMUhANYQnfqfBd9dYfBRKf4LD1Yyfc8UvwY1MtNKWs',
+ 'root_fingerprint': 'b3569ff0',
'label': 'test',
- 'soft_device_id': '',
+ 'soft_device_id': '1',
})
self.assertTrue(w.is_last_view(v.view, d))
+ v = w.resolve_next(v.view, d)
+
+ ks, ishww = w._result
+ self.assertTrue(ishww)
+
+ wallet = self._create_xpub_keystore_wallet(xpub='zpub6rakEaM5ps5UiQ2yhbWiEkd6ceJfmuzegwc62G4itMz8L7rRFRqh6y8bTCScXV6NfTMUhANYQnfqfBd9dYfBRKf4LD1Yyfc8UvwY1MtNKWs')
+ self.assertTrue(wallet.get_keystore().is_watching_only())
+ wallet.enable_keystore(ks, ishww, None)
+ self.assertFalse(wallet.get_keystore().is_watching_only())
+ self.assertTrue(isinstance(wallet.get_keystore(), Hardware_KeyStore))
class WalletWizardTestCase(WizardTestCase):
Why this scored 23/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.