electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 200f547a07f77e2edf04cd544a1bf954fb7c9b1c
parent 59f7d4b02dfc5fe92073b1f4e89de4bdb836f195
Author: SomberNight <somber.night@protonmail.com>
Date:   Sat, 24 Oct 2020 23:32:18 +0200

ledger: fix compat with hw.1 - signing flow deadlocked

broke in 8a1b46d839ac24f77bfa5e3a1eed0cb7284b59eac5b685854c517f224c98dc44

Diffstat:
Melectrum/plugins/ledger/auth2fa.py | 8++++++--
Melectrum/plugins/ledger/ledger.py | 16++++++++++------
Melectrum/plugins/ledger/qt.py | 12++++++------
3 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/electrum/plugins/ledger/auth2fa.py b/electrum/plugins/ledger/auth2fa.py @@ -1,4 +1,5 @@ import copy +from typing import TYPE_CHECKING from PyQt5.QtWidgets import (QDialog, QLineEdit, QTextEdit, QVBoxLayout, QLabel, QWidget, QHBoxLayout, QComboBox) @@ -11,6 +12,9 @@ from electrum.i18n import _ from electrum import constants, bitcoin from electrum.logging import get_logger +if TYPE_CHECKING: + from .ledger import Ledger_Client + _logger = get_logger(__name__) @@ -27,7 +31,7 @@ helpTxt = [_("Your Ledger Wallet wants to tell you a one-time PIN code.<br><br>" ] class LedgerAuthDialog(QDialog): - def __init__(self, handler, data): + def __init__(self, handler, data, *, client: 'Ledger_Client'): '''Ask user for 2nd factor authentication. Support text and security card methods. Use last method from settings, but support downgrade. ''' @@ -38,7 +42,7 @@ class LedgerAuthDialog(QDialog): self.setMinimumWidth(650) self.setWindowTitle(_("Ledger Wallet Authentication")) self.cfg = copy.deepcopy(self.handler.win.wallet.get_keystore().cfg) - self.dongle = self.handler.win.wallet.get_keystore().get_client().dongle + self.dongle = client.dongleObject.dongle self.pin = '' self.devmode = self.getDevice2FAMode() diff --git a/electrum/plugins/ledger/ledger.py b/electrum/plugins/ledger/ledger.py @@ -300,18 +300,20 @@ class Ledger_KeyStore(Hardware_KeyStore): message = message.encode('utf8') message_hash = hashlib.sha256(message).hexdigest().upper() # prompt for the PIN before displaying the dialog if necessary - client = self.get_client() + client_ledger = self.get_client() + client_electrum = self.get_client_electrum() address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence self.handler.show_message("Signing message ...\r\nMessage hash: "+message_hash) try: - info = self.get_client().signMessagePrepare(address_path, message) + info = client_ledger.signMessagePrepare(address_path, message) pin = "" if info['confirmationNeeded']: - pin = self.handler.get_auth( info ) # does the authenticate dialog and returns pin + # do the authenticate dialog and get pin: + pin = self.handler.get_auth(info, client=client_electrum) if not pin: raise UserWarning(_('Cancelled by user')) pin = str(pin).encode() - signature = self.get_client().signMessageSign(pin) + signature = client_ledger.signMessageSign(pin) except BTChipException as e: if e.sw == 0x6a80: self.give_error("Unfortunately, this message cannot be signed by the Ledger wallet. Only alphanumerical messages shorter than 140 characters are supported. Please remove any extra characters (tab, carriage return) and retry.") @@ -484,7 +486,8 @@ class Ledger_KeyStore(Hardware_KeyStore): if outputData['confirmationNeeded']: outputData['address'] = output self.handler.finished() - pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin + # do the authenticate dialog and get pin: + pin = self.handler.get_auth(outputData, client=client_electrum) if not pin: raise UserWarning() self.handler.show_message(_("Confirmed. Signing Transaction...")) @@ -510,7 +513,8 @@ class Ledger_KeyStore(Hardware_KeyStore): if outputData['confirmationNeeded']: outputData['address'] = output self.handler.finished() - pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin + # do the authenticate dialog and get pin: + pin = self.handler.get_auth(outputData, client=client_electrum) if not pin: raise UserWarning() self.handler.show_message(_("Confirmed. Signing Transaction...")) diff --git a/electrum/plugins/ledger/qt.py b/electrum/plugins/ledger/qt.py @@ -8,7 +8,7 @@ from electrum.plugin import hook from electrum.wallet import Standard_Wallet from electrum.gui.qt.util import WindowModalDialog -from .ledger import LedgerPlugin +from .ledger import LedgerPlugin, Ledger_Client from ..hw_wallet.qt import QtHandlerBase, QtPluginBase from ..hw_wallet.plugin import only_hook_if_libraries_available @@ -33,7 +33,7 @@ class Plugin(LedgerPlugin, QtPluginBase): class Ledger_Handler(QtHandlerBase): setup_signal = pyqtSignal() - auth_signal = pyqtSignal(object) + auth_signal = pyqtSignal(object, object) def __init__(self, win): super(Ledger_Handler, self).__init__(win, 'Ledger') @@ -56,20 +56,20 @@ class Ledger_Handler(QtHandlerBase): vbox.addWidget(l) dialog.show() - def auth_dialog(self, data): + def auth_dialog(self, data, client: 'Ledger_Client'): try: from .auth2fa import LedgerAuthDialog except ImportError as e: self.message_dialog(repr(e)) return - dialog = LedgerAuthDialog(self, data) + dialog = LedgerAuthDialog(self, data, client=client) dialog.exec_() self.word = dialog.pin self.done.set() - def get_auth(self, data): + def get_auth(self, data, *, client: 'Ledger_Client'): self.done.clear() - self.auth_signal.emit(data) + self.auth_signal.emit(data, client) self.done.wait() return self.word