qml: disable 'Create Wallet' before first unlock
What changed, and why it matters
This commit changes the Electrum mobile/QML wallet interface so that users cannot create a new wallet until they have first unlocked an existing wallet. The goal is to prevent a frustrating situation where a user goes through the entire new-wallet setup (for example, writing down a recovery seed) and only afterward discovers they must enter an existing wallet password they have forgotten. The change also fixes a related state issue where the single-password setting was not being updated after a password change. There is no direct evidence in the commit that this fixes an active security vulnerability; it reads as a usability and defensive hardening improvement.
Treat as a low-risk usability/hardening change. Reviewers may want to confirm that numWalletsWithPassword cannot be bypassed and that the singlePassword setter is not reachable from untrusted QML bindings. No urgent security response is indicated by the commit alone.
Security signals we found
Precondition check added before wallet creation flow
Password state synchronization added for single-password mode
Setter asserts single-password config before mutating internal password state
No cryptographic changes, memory-zeroing, or authentication bypass fixes visible
Evidence from the diff
The patch modifies three QML GUI files. In Wallets.qml, the ‘Create Wallet’ button now checks whether any wallets exist, whether single-password mode is enabled, and whether the stored singlePassword has been verified against at least one loaded wallet (via Daemon.numWalletsWithPassword). If wallets exist but none are unlocked, a dialog blocks creation. In WalletDetails.qml, after a successful password change, if single-password mode is active the new password is propagated to Daemon.singlePassword. In qedaemon.py, a setter for singlePassword is added, gated by WALLET_SHOULD_USE_SINGLE_PASSWORD, and the getter’s docstring clarifies that _password may hold the last loaded wallet’s password even when true single-password unification has not yet been achieved. The change is defensive UX hardening rather than a clear-cut vulnerability fix.
Changed components
electrum/gui/qml/components/Wallets.qmlelectrum/gui/qml/components/WalletDetails.qmlelectrum/gui/qml/qedaemon.pyInspect captured patch +31 / −1
diff --git a/electrum/gui/qml/components/WalletDetails.qml b/electrum/gui/qml/components/WalletDetails.qml
index ea10520..85da196 100644
--- a/electrum/gui/qml/components/WalletDetails.qml
+++ b/electrum/gui/qml/components/WalletDetails.qml
@@ -528,6 +528,9 @@ Pane {
})
dialog.accepted.connect(function() {
var success = Daemon.currentWallet.setPassword(dialog.password)
+ if (success && Config.walletShouldUseSinglePassword) {
+ Daemon.singlePassword = dialog.password
+ }
var done_dialog = app.messageDialog.createObject(app, {
title: success ? qsTr('Success') : qsTr('Error'),
iconSource: success
diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml
index 52dc317..f9c9f84 100644
--- a/electrum/gui/qml/components/Wallets.qml
+++ b/electrum/gui/qml/components/Wallets.qml
@@ -121,7 +121,21 @@ Pane {
Layout.fillWidth: true
text: qsTr('Create Wallet')
icon.source: '../../icons/add.png'
- onClicked: rootItem.createWallet()
+ onClicked: {
+ if (Daemon.availableWallets.rowCount() > 0 && Config.walletShouldUseSinglePassword
+ && (!Daemon.singlePassword || Daemon.numWalletsWithPassword(Daemon.singlePassword) < 1)) {
+ // if the user has wallets but hasn't unlocked any wallet yet force them to do so.
+ // this ensures they know at least one wallets password and can complete the wizard
+ // where they will need to enter the password of an existing wallet.
+ var dialog = app.messageDialog.createObject(app, {
+ title: qsTr('Wallet unlock required'),
+ text: qsTr("You have to unlock any existing wallet first before creating a new wallet."),
+ })
+ dialog.open()
+ } else {
+ rootItem.createWallet()
+ }
+ }
}
}
diff --git a/electrum/gui/qml/qedaemon.py b/electrum/gui/qml/qedaemon.py
index c31937d..72e618b 100644
--- a/electrum/gui/qml/qedaemon.py
+++ b/electrum/gui/qml/qedaemon.py
@@ -356,8 +356,21 @@ class QEDaemon(AuthMixin, QObject):
@pyqtProperty(str, notify=singlePasswordChanged)
def singlePassword(self):
+ """
+ self._password is also set to the last loaded wallet password if we WANT a single password,
+ but don't actually have a single password yet. So singlePassword being set doesn't strictly
+ mean all wallets use the same password.
+ """
return self._password
+ @singlePassword.setter
+ def singlePassword(self, password: str):
+ assert password
+ assert self.daemon.config.WALLET_SHOULD_USE_SINGLE_PASSWORD
+ if self._password != password:
+ self._password = password
+ self.singlePasswordChanged.emit()
+
@pyqtSlot(result=str)
def suggestWalletName(self):
# FIXME why not use util.get_new_wallet_name ?
Why this scored 30/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.