From b5d3f1458a7403c3cd75c2689f3134cfe50f42a3 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Fri, 3 Jun 2022 15:29:25 +0200 Subject: [PATCH] hww: impl get_client in Hardware_KeyStore instead of subclasses --- electrum/keystore.py | 22 +++++++++++++++++----- electrum/plugin.py | 6 ++---- electrum/plugins/bitbox02/bitbox02.py | 3 --- electrum/plugins/coldcard/coldcard.py | 10 +++++----- electrum/plugins/jade/jade.py | 3 --- electrum/plugins/keepkey/keepkey.py | 3 --- electrum/plugins/ledger/ledger.py | 24 +++++++++++------------- electrum/plugins/safe_t/safe_t.py | 3 --- electrum/plugins/trezor/trezor.py | 3 --- 9 files changed, 35 insertions(+), 42 deletions(-) diff --git a/electrum/keystore.py b/electrum/keystore.py index c1c1bff65..ec7cc79b0 100644 --- a/electrum/keystore.py +++ b/electrum/keystore.py @@ -50,6 +50,7 @@ if TYPE_CHECKING: from .gui.qt.util import TaskThread from .plugins.hw_wallet import HW_PluginBase, HardwareClientBase, HardwareHandlerBase from .wallet_db import WalletDB + from .plugin import Device class CannotDerivePubkey(Exception): pass @@ -840,17 +841,28 @@ class Hardware_KeyStore(Xpub, KeyStore): assert not self.has_seed() return False + def get_client( + self, + force_pair: bool = True, + *, + devices: Sequence['Device'] = None, + allow_user_interaction: bool = True, + ) -> Optional['HardwareClientBase']: + return self.plugin.get_client( + self, + force_pair=force_pair, + devices=devices, + allow_user_interaction=allow_user_interaction, + ) + def get_password_for_storage_encryption(self) -> str: - client = self.plugin.get_client(self) + client = self.get_client() return client.get_password_for_storage_encryption() def has_usable_connection_with_device(self) -> bool: - if not hasattr(self, 'plugin'): - return False # we try to create a client even if there isn't one already, # but do not prompt the user if auto-select fails: - client = self.plugin.get_client( - self, + client = self.get_client( force_pair=True, allow_user_interaction=False, ) diff --git a/electrum/plugin.py b/electrum/plugin.py index 3ac957f59..f328cf9c5 100644 --- a/electrum/plugin.py +++ b/electrum/plugin.py @@ -808,8 +808,7 @@ class DeviceMgr(ThreadJob): # first pair with all devices that can be auto-selected for ks in keystores: try: - ks.plugin.get_client( - keystore=ks, + ks.get_client( force_pair=True, allow_user_interaction=False, devices=devices, @@ -820,8 +819,7 @@ class DeviceMgr(ThreadJob): # now do manual selections for ks in keystores: try: - ks.plugin.get_client( - keystore=ks, + ks.get_client( force_pair=True, allow_user_interaction=True, devices=devices, diff --git a/electrum/plugins/bitbox02/bitbox02.py b/electrum/plugins/bitbox02/bitbox02.py index 278b70008..8f720e5f6 100644 --- a/electrum/plugins/bitbox02/bitbox02.py +++ b/electrum/plugins/bitbox02/bitbox02.py @@ -561,9 +561,6 @@ class BitBox02_KeyStore(Hardware_KeyStore): super().__init__(d) self.ux_busy = False - def get_client(self) -> Optional['BitBox02Client']: - return self.plugin.get_client(self) - def give_error(self, message: Exception): self.logger.info(message) if not self.ux_busy: diff --git a/electrum/plugins/coldcard/coldcard.py b/electrum/plugins/coldcard/coldcard.py index a4ea2ed76..7a9dd4ab0 100644 --- a/electrum/plugins/coldcard/coldcard.py +++ b/electrum/plugins/coldcard/coldcard.py @@ -269,16 +269,16 @@ class Coldcard_KeyStore(Hardware_KeyStore): assert xfp is not None return xfp_int_from_xfp_bytes(bfh(xfp)) - def get_client(self): + def get_client(self, *args, **kwargs): # called when user tries to do something like view address, sign somthing. # - not called during probing/setup # - will fail if indicated device can't produce the xpub (at derivation) expected - rv = self.plugin.get_client(self) - if rv: + client = super().get_client(*args, **kwargs) # type: Optional[CKCCClient] + if client: xfp_int = self.get_xfp_int() - rv.verify_connection(xfp_int, self.ckcc_xpub) + client.verify_connection(xfp_int, self.ckcc_xpub) - return rv + return client def give_error(self, message): self.logger.info(message) diff --git a/electrum/plugins/jade/jade.py b/electrum/plugins/jade/jade.py index 7c1e0f946..0869cee41 100644 --- a/electrum/plugins/jade/jade.py +++ b/electrum/plugins/jade/jade.py @@ -237,9 +237,6 @@ class Jade_KeyStore(Hardware_KeyStore): plugin: 'JadePlugin' - def get_client(self): - return self.plugin.get_client(self) - def decrypt_message(self, sequence, message, password): raise UserFacingException(_('Encryption and decryption are not implemented by {}').format(self.device)) diff --git a/electrum/plugins/keepkey/keepkey.py b/electrum/plugins/keepkey/keepkey.py index 4a3141793..33ede8f6d 100644 --- a/electrum/plugins/keepkey/keepkey.py +++ b/electrum/plugins/keepkey/keepkey.py @@ -31,9 +31,6 @@ class KeepKey_KeyStore(Hardware_KeyStore): plugin: 'KeepKeyPlugin' - def get_client(self, force_pair=True): - return self.plugin.get_client(self, force_pair) - def decrypt_message(self, sequence, message, password): raise UserFacingException(_('Encryption and decryption are not implemented by {}').format(self.device)) diff --git a/electrum/plugins/ledger/ledger.py b/electrum/plugins/ledger/ledger.py index 1f0bcd0b5..b131905f5 100644 --- a/electrum/plugins/ledger/ledger.py +++ b/electrum/plugins/ledger/ledger.py @@ -143,7 +143,7 @@ class Ledger_Client(HardwareClientBase): fingerprint=fingerprint_bytes, child_number=childnum_bytes).to_xpub() - def has_detached_pin_support(self, client): + def has_detached_pin_support(self, client: 'btchip'): try: client.getVerifyPinRemainingAttempts() return True @@ -152,7 +152,7 @@ class Ledger_Client(HardwareClientBase): return False raise e - def is_pin_validated(self, client): + def is_pin_validated(self, client: 'btchip'): try: # Invalid SET OPERATION MODE to verify the PIN status client.dongle.exchange(bytearray([0xe0, 0x26, 0x00, 0x00, 0x01, 0xAB])) @@ -254,11 +254,9 @@ class Ledger_KeyStore(Hardware_KeyStore): obj['cfg'] = self.cfg return obj - def get_client(self): - return self.plugin.get_client(self).dongleObject - - def get_client_electrum(self) -> Optional[Ledger_Client]: - return self.plugin.get_client(self) + def get_client_dongle_object(self) -> 'btchip': + client_electrum = self.get_client() + return client_electrum.dongleObject def give_error(self, message): _logger.info(message) @@ -288,8 +286,8 @@ 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_ledger = self.get_client() - client_electrum = self.get_client_electrum() + client_ledger = self.get_client_dongle_object() + client_electrum = self.get_client() address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence self.handler.show_message("Signing message ...\r\nMessage hash: "+message_hash) try: @@ -352,8 +350,8 @@ class Ledger_KeyStore(Hardware_KeyStore): p2shTransaction = False segwitTransaction = False pin = "" - client_ledger = self.get_client() # prompt for the PIN before displaying the dialog if necessary - client_electrum = self.get_client_electrum() + client_ledger = self.get_client_dongle_object() # prompt for the PIN before displaying the dialog if necessary + client_electrum = self.get_client() assert client_electrum # Fetch inputs of the transaction to sign @@ -552,13 +550,13 @@ class Ledger_KeyStore(Hardware_KeyStore): @test_pin_unlocked @set_and_unset_signing def show_address(self, sequence, txin_type): - client = self.get_client() + client_ledger = self.get_client_dongle_object() address_path = self.get_derivation_prefix()[2:] + "/%d/%d"%sequence self.handler.show_message(_("Showing address ...")) segwit = is_segwit_script_type(txin_type) segwitNative = txin_type == 'p2wpkh' try: - client.getWalletPublicKey(address_path, showOnScreen=True, segwit=segwit, segwitNative=segwitNative) + client_ledger.getWalletPublicKey(address_path, showOnScreen=True, segwit=segwit, segwitNative=segwitNative) except BTChipException as e: if e.sw == 0x6985: # cancelled by user pass diff --git a/electrum/plugins/safe_t/safe_t.py b/electrum/plugins/safe_t/safe_t.py index e52c55d59..62af36bc0 100644 --- a/electrum/plugins/safe_t/safe_t.py +++ b/electrum/plugins/safe_t/safe_t.py @@ -29,9 +29,6 @@ class SafeTKeyStore(Hardware_KeyStore): plugin: 'SafeTPlugin' - def get_client(self, force_pair=True): - return self.plugin.get_client(self, force_pair) - def decrypt_message(self, sequence, message, password): raise UserFacingException(_('Encryption and decryption are not implemented by {}').format(self.device)) diff --git a/electrum/plugins/trezor/trezor.py b/electrum/plugins/trezor/trezor.py index 9a8b483b2..d7e165a1e 100644 --- a/electrum/plugins/trezor/trezor.py +++ b/electrum/plugins/trezor/trezor.py @@ -71,9 +71,6 @@ class TrezorKeyStore(Hardware_KeyStore): plugin: 'TrezorPlugin' - def get_client(self, force_pair=True): - return self.plugin.get_client(self, force_pair) - def decrypt_message(self, sequence, message, password): raise UserFacingException(_('Encryption and decryption are not implemented by {}').format(self.device))