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:
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