electrum

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

commit 8589c1b0bb79c3c6a8506d5ef875bd1e2bb055e6
parent 5e5134b76ffec8ed9702f5661a1d16e9e52a24c8
Author: SomberNight <somber.night@protonmail.com>
Date:   Wed, 14 Mar 2018 15:18:26 +0100

ledger: don't throw exception if user cancels signing

Used to show "Exception : Invalid status 6985", which is not really user-friendly. This now mimics the behaviour with Trezor where we silently ignore cancellation (not showing any popup).

Diffstat:
Mplugins/ledger/ledger.py | 30++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py @@ -229,6 +229,16 @@ class Ledger_KeyStore(Hardware_KeyStore): self.client = None raise Exception(message) + def set_and_unset_signing(func): + """Function decorator to set and unset self.signing.""" + def wrapper(self, *args, **kwargs): + try: + self.signing = True + return func(self, *args, **kwargs) + finally: + self.signing = False + return wrapper + def address_id_stripped(self, address): # Strip the leading "m/" change, index = self.get_address_index(address) @@ -239,8 +249,8 @@ class Ledger_KeyStore(Hardware_KeyStore): def decrypt_message(self, pubkey, message, password): raise RuntimeError(_('Encryption and decryption are currently not supported for {}').format(self.device)) + @set_and_unset_signing def sign_message(self, sequence, message, password): - self.signing = True message = message.encode('utf8') message_hash = hashlib.sha256(message).hexdigest().upper() # prompt for the PIN before displaying the dialog if necessary @@ -259,16 +269,17 @@ class Ledger_KeyStore(Hardware_KeyStore): 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.") + elif e.sw == 0x6985: # cancelled by user + return b'' else: self.give_error(e, True) except UserWarning: self.handler.show_error(_('Cancelled by user')) - return '' + return b'' except Exception as e: self.give_error(e, True) finally: self.handler.finished() - self.signing = False # Parse the ASN.1 signature rLength = signature[3] r = signature[4 : 4 + rLength] @@ -281,12 +292,11 @@ class Ledger_KeyStore(Hardware_KeyStore): # And convert it return bytes([27 + 4 + (signature[0] & 0x01)]) + r + s - + @set_and_unset_signing def sign_transaction(self, tx, password): if tx.is_complete(): return client = self.get_client() - self.signing = True inputs = [] inputsPaths = [] pubKeys = [] @@ -446,6 +456,12 @@ class Ledger_KeyStore(Hardware_KeyStore): except UserWarning: self.handler.show_error(_('Cancelled by user')) return + except BTChipException as e: + if e.sw == 0x6985: # cancelled by user + return + else: + traceback.print_exc(file=sys.stderr) + self.give_error(e, True) except BaseException as e: traceback.print_exc(file=sys.stdout) self.give_error(e, True) @@ -456,10 +472,9 @@ class Ledger_KeyStore(Hardware_KeyStore): signingPos = inputs[i][4] txin['signatures'][signingPos] = bh2u(signatures[i]) tx.raw = tx.serialize() - self.signing = False + @set_and_unset_signing def show_address(self, sequence, txin_type): - self.signing = True client = self.get_client() address_path = self.get_derivation()[2:] + "/%d/%d"%sequence self.handler.show_message(_("Showing address ...")) @@ -478,7 +493,6 @@ class Ledger_KeyStore(Hardware_KeyStore): self.handler.show_error(e) finally: self.handler.finished() - self.signing = False class LedgerPlugin(HW_PluginBase): libraries_available = BTCHIP