diff --git a/electrum/gui/qml/components/Wallets.qml b/electrum/gui/qml/components/Wallets.qml index b131953fe..1e6156a32 100644 --- a/electrum/gui/qml/components/Wallets.qml +++ b/electrum/gui/qml/components/Wallets.qml @@ -30,8 +30,8 @@ Pane { Label { text: 'Wallet'; Layout.columnSpan: 2 } Label { text: Daemon.currentWallet.name; Layout.columnSpan: 2; color: Material.accentColor } - Label { text: 'derivation path (BIP32)'; visible: Daemon.currentWallet.isDeterministic; Layout.columnSpan: 2 } - Label { text: Daemon.currentWallet.derivationPath; visible: Daemon.currentWallet.isDeterministic; color: Material.accentColor; Layout.columnSpan: 2 } + Label { text: 'derivation prefix (BIP32)'; visible: Daemon.currentWallet.isDeterministic; Layout.columnSpan: 2 } + Label { text: Daemon.currentWallet.derivationPrefix; visible: Daemon.currentWallet.isDeterministic; color: Material.accentColor; Layout.columnSpan: 2 } Label { text: 'txinType' } Label { text: Daemon.currentWallet.txinType; color: Material.accentColor } @@ -69,9 +69,6 @@ Pane { delegate: AbstractButton { width: ListView.view.width height: row.height - onClicked: { - wallet_db.path = model.path - } RowLayout { id: row @@ -83,8 +80,8 @@ Pane { id: walleticon source: "../../icons/wallet.png" fillMode: Image.PreserveAspectFit - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 + Layout.preferredWidth: constants.iconSizeLarge + Layout.preferredHeight: constants.iconSizeLarge } Label { @@ -129,7 +126,4 @@ Pane { } } - WalletDB { - id: wallet_db - } } diff --git a/electrum/gui/qml/qeaddressdetails.py b/electrum/gui/qml/qeaddressdetails.py index 422aed402..9bf20cb37 100644 --- a/electrum/gui/qml/qeaddressdetails.py +++ b/electrum/gui/qml/qeaddressdetails.py @@ -109,4 +109,5 @@ class QEAddressDetails(QObject): self._balance = QEAmount(amount_sat=c + u + x) self._pubkeys = self._wallet.wallet.get_public_keys(self._address) self._derivationPath = self._wallet.wallet.get_address_path_str(self._address) + self._derivationPath = self._derivationPath.replace('m', self._wallet.derivationPrefix) self.detailsChanged.emit() diff --git a/electrum/gui/qml/qedaemon.py b/electrum/gui/qml/qedaemon.py index 113baf938..8d049b31a 100644 --- a/electrum/gui/qml/qedaemon.py +++ b/electrum/gui/qml/qedaemon.py @@ -8,8 +8,10 @@ from electrum.util import register_callback, get_new_wallet_name, WalletFileExce from electrum.logging import get_logger from electrum.wallet import Wallet, Abstract_Wallet from electrum.storage import WalletStorage, StorageReadWriteError +from electrum.wallet_db import WalletDB from .qewallet import QEWallet +from .qewalletdb import QEWalletDB from .qefx import QEFX # wallet list model. supports both wallet basenames (wallet file basenames) @@ -87,6 +89,8 @@ class QEDaemon(QObject): super().__init__(parent) self.daemon = daemon self.qefx = QEFX(daemon.fx, daemon.config) + self._walletdb = QEWalletDB() + self._walletdb.invalidPasswordChanged.connect(self.passwordValidityCheck) _logger = get_logger(__name__) _loaded_wallets = QEWalletListModel() @@ -94,6 +98,7 @@ class QEDaemon(QObject): _current_wallet = None _path = None + walletLoaded = pyqtSignal() walletRequiresPassword = pyqtSignal() activeWalletsChanged = pyqtSignal() @@ -101,6 +106,11 @@ class QEDaemon(QObject): walletOpenError = pyqtSignal([str], arguments=["error"]) fxChanged = pyqtSignal() + @pyqtSlot() + def passwordValidityCheck(self): + if self._walletdb._invalidPassword: + self.walletRequiresPassword.emit() + @pyqtSlot() @pyqtSlot(str) @pyqtSlot(str, str) @@ -113,14 +123,13 @@ class QEDaemon(QObject): return self._logger.debug('load wallet ' + str(self._path)) - try: - storage = WalletStorage(self._path) - if not storage.file_exists(): - self.walletOpenError.emit('File not found') + + if path not in self.daemon._wallets: + # pre-checks, let walletdb trigger any necessary user interactions + self._walletdb.path = self._path + self._walletdb.password = password + if not self._walletdb.ready: return - except StorageReadWriteError as e: - self.walletOpenError.emit('Storage read/write error') - return try: wallet = self.daemon.load_wallet(self._path, password) @@ -130,8 +139,8 @@ class QEDaemon(QObject): self.walletLoaded.emit() self.daemon.config.save_last_wallet(wallet) else: - self._logger.info('password required but unset or incorrect') - self.walletRequiresPassword.emit() + self._logger.info('could not open wallet') + self.walletOpenError.emit('could not open wallet') except WalletFileException as e: self._logger.error(str(e)) self.walletOpenError.emit(str(e)) @@ -159,4 +168,3 @@ class QEDaemon(QObject): @pyqtProperty(QEFX, notify=fxChanged) def fx(self): return self.qefx - diff --git a/electrum/gui/qml/qetransactionlistmodel.py b/electrum/gui/qml/qetransactionlistmodel.py index dca90bf9a..22ec81643 100644 --- a/electrum/gui/qml/qetransactionlistmodel.py +++ b/electrum/gui/qml/qetransactionlistmodel.py @@ -85,8 +85,10 @@ class QETransactionListModel(QAbstractListModel): 'lastweek': '%a, %H:%M:%S', 'lastmonth': '%a %d, %H:%M:%S', 'older': '%G-%m-%d %H:%M:%S' - }[section] - return date.strftime(dfmt) + } + if section not in dfmt: + section = 'older' + return date.strftime(dfmt[section]) # initial model data def init_model(self): diff --git a/electrum/gui/qml/qewallet.py b/electrum/gui/qml/qewallet.py index 93c17471f..ddf6138d5 100644 --- a/electrum/gui/qml/qewallet.py +++ b/electrum/gui/qml/qewallet.py @@ -139,7 +139,7 @@ class QEWallet(QObject): self._logger.debug('queue empty, stopping wallet notification timer') self.notification_timer.stop() return - if not self.wallet.up_to_date: + if not self.wallet.is_up_to_date(): return # no notifications while syncing now = time.time() rate_limit = 20 # seconds @@ -218,7 +218,7 @@ class QEWallet(QObject): return self.wallet.storage.is_encrypted_with_hw_device() @pyqtProperty('QString', notify=dataChanged) - def derivationPath(self): + def derivationPrefix(self): keystores = self.wallet.get_keystores() if len(keystores) > 1: self._logger.debug('multiple keystores not supported yet') diff --git a/electrum/gui/qml/qewalletdb.py b/electrum/gui/qml/qewalletdb.py index 34000d77a..d3dae8e16 100644 --- a/electrum/gui/qml/qewalletdb.py +++ b/electrum/gui/qml/qewalletdb.py @@ -9,8 +9,6 @@ from electrum.bip32 import normalize_bip32_derivation from electrum.util import InvalidPassword from electrum import keystore -from .qedaemon import QEDaemon - class QEWalletDB(QObject): def __init__(self, parent=None): super().__init__(parent) @@ -116,6 +114,12 @@ class QEWalletDB(QObject): def invalidPassword(self): return self._invalidPassword + @invalidPassword.setter + def invalidPassword(self, invalidPassword): + if self._invalidPassword != invalidPassword: + self._invalidPassword = invalidPassword + self.invalidPasswordChanged.emit() + @pyqtProperty(bool, notify=readyChanged) def ready(self): return self._ready @@ -143,11 +147,10 @@ class QEWalletDB(QObject): self.needsPassword = True try: - self._storage.decrypt(self._password) - self._invalidPassword = False + self._storage.decrypt('' if not self._password else self._password) + self.invalidPassword = False except InvalidPassword as e: - self._invalidPassword = True - self.invalidPasswordChanged.emit() + self.invalidPassword = True if not self._storage.is_past_initial_decryption(): self._storage = None