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