From 21b2fcbe85b1acf12c46ecdf83461538a925931f Mon Sep 17 00:00:00 2001 From: ThomasV Date: Sat, 18 Apr 2015 14:59:46 +0200 Subject: [PATCH] always_hook. fix trezor handler. fixes #1146 --- gui/qt/__init__.py | 6 ++++-- gui/qt/installwizard.py | 6 +++--- lib/plugins.py | 16 +++++++++------- plugins/trezor.py | 36 ++++++++++++++++++++++-------------- plugins/trustedcoin.py | 4 ---- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/gui/qt/__init__.py b/gui/qt/__init__.py index c282e1e31..a11bd21dc 100644 --- a/gui/qt/__init__.py +++ b/gui/qt/__init__.py @@ -36,7 +36,7 @@ import PyQt4.QtCore as QtCore from electrum.i18n import _, set_language from electrum.util import print_error, print_msg -from electrum.plugins import run_hook +from electrum.plugins import run_hook, always_hook from electrum import WalletStorage, Wallet from electrum.bitcoin import MIN_RELAY_TX_FEE @@ -73,6 +73,8 @@ class ElectrumGui: if app is None: self.app = QApplication(sys.argv) self.app.installEventFilter(self.efilter) + # let plugins know that we are using the qt gui + always_hook('init_qt_app', self.app) def build_tray_menu(self): @@ -222,7 +224,7 @@ class ElectrumGui: else: self.go_full() - # plugins that need to change the GUI do it here + # plugins interact with main window run_hook('init_qt', self) w.load_wallet(wallet) diff --git a/gui/qt/installwizard.py b/gui/qt/installwizard.py index 35b9bd9d9..06a823c59 100644 --- a/gui/qt/installwizard.py +++ b/gui/qt/installwizard.py @@ -15,7 +15,7 @@ from amountedit import AmountEdit import sys import threading -from electrum.plugins import run_hook +from electrum.plugins import always_hook from electrum.mnemonic import prepare_seed MSG_ENTER_ANYTHING = _("Please enter a wallet seed, a master public key, a list of Bitcoin addresses, or a list of private keys") @@ -385,7 +385,7 @@ class InstallWizard(QDialog): self.waiting_dialog(wallet.synchronize) else: - f = run_hook('get_wizard_action', self, wallet, action) + f = always_hook('get_wizard_action', self, wallet, action) if not f: raise BaseException('unknown wizard action', action) r = f(wallet, self) @@ -452,7 +452,7 @@ class InstallWizard(QDialog): else: self.storage.put('wallet_type', t) - wallet = run_hook('installwizard_restore', self, self.storage) + wallet = always_hook('installwizard_restore', self, self.storage) if not wallet: return diff --git a/lib/plugins.py b/lib/plugins.py index 580b94df5..4c0b0ac4b 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -33,23 +33,25 @@ hook_names = set() hooks = {} def hook(func): - n = func.func_name - if n not in hook_names: - hook_names.add(n) + hook_names.add(func.func_name) return func - def run_hook(name, *args): - SPECIAL_HOOKS = ['get_wizard_action','installwizard_restore'] + return _run_hook(name, False, *args) + +def always_hook(name, *args): + return _run_hook(name, True, *args) + +def _run_hook(name, always, *args): results = [] - f_list = hooks.get(name,[]) + f_list = hooks.get(name, []) for p, f in f_list: if name == 'load_wallet': p.wallet = args[0] if name == 'init_qt': gui = args[0] p.window = gui.main_window - if name in SPECIAL_HOOKS or p.is_enabled(): + if always or p.is_enabled(): try: r = f(*args) except Exception: diff --git a/plugins/trezor.py b/plugins/trezor.py index 7578879aa..88cec3146 100644 --- a/plugins/trezor.py +++ b/plugins/trezor.py @@ -12,7 +12,7 @@ import electrum from electrum.account import BIP32_Account from electrum.bitcoin import EncodeBase58Check, public_key_to_bc_address, bc_address_to_hash_160 from electrum.i18n import _ -from electrum.plugins import BasePlugin, hook +from electrum.plugins import BasePlugin, hook, always_hook, run_hook from electrum.transaction import deserialize from electrum.wallet import BIP32_HD_Wallet from electrum.util import print_error @@ -90,17 +90,25 @@ class Plugin(BasePlugin): return False return True + @hook + def add_plugin(self, wallet): + wallet.plugin = self + @hook def close_wallet(self): print_error("trezor: clear session") if self.wallet and self.wallet.client: self.wallet.client.clear_session() self.wallet.client.transport.close() + self.wallet = None + + @hook + def init_qt_app(self, app): + self.handler = TrezorQtHandler(app) @hook def load_wallet(self, wallet): - self.twd = TrezorQtHandler(self.window) - self.wallet.twd = self.twd + self.wallet = wallet if self.trezor_is_connected(): if not self.wallet.check_proper_device(): QMessageBox.information(self.window, _('Error'), _("This wallet does not match your Trezor device"), _('OK')) @@ -118,7 +126,7 @@ class Plugin(BasePlugin): return wallet = TrezorWallet(storage) self.wallet = wallet - passphrase = self.twd.get_passphrase(_("Please enter your Trezor passphrase.") + '\n' + _("Press OK if you do not use one.")) + passphrase = self.handler.get_passphrase(_("Please enter your Trezor passphrase.") + '\n' + _("Press OK if you do not use one.")) if passphrase is None: return password = wizard.password_dialog() @@ -152,9 +160,9 @@ class Plugin(BasePlugin): if not response[1]: return new_label = str(response[0]) - self.twd.show_message("Please confirm label change on Trezor") + self.handler.show_message("Please confirm label change on Trezor") status = self.wallet.get_client().apply_settings(label=new_label) - self.twd.stop() + self.handler.stop() update_label() current_label_label = QLabel() @@ -182,6 +190,7 @@ class TrezorWallet(BIP32_HD_Wallet): self.mpk = None self.device_checked = False self.force_watching_only = False + always_hook('add_plugin', self) def get_action(self): if not self.accounts: @@ -192,7 +201,6 @@ class TrezorWallet(BIP32_HD_Wallet): def can_sign_xpubkey(self, x_pubkey): xpub, sequence = BIP32_Account.parse_xpubkey(x_pubkey) - print "z", xpub return xpub in self.master_public_keys.values() def can_export(self): @@ -218,7 +226,7 @@ class TrezorWallet(BIP32_HD_Wallet): except: give_error('Could not connect to your Trezor. Please verify the cable is connected and that no other app is using it.') self.client = QtGuiTrezorClient(self.transport) - self.client.twd = self.twd + self.client.handler = self.plugin.handler self.client.set_tx_api(self) #self.client.clear_session()# TODO Doesn't work with firmware 1.1, returns proto.Failure self.client.bad = False @@ -305,7 +313,7 @@ class TrezorWallet(BIP32_HD_Wallet): except Exception, e: give_error(e) finally: - self.twd.stop() + self.plugin.handler.stop() def sign_message(self, address, message, password): if not self.check_proper_device(): @@ -320,7 +328,7 @@ class TrezorWallet(BIP32_HD_Wallet): except Exception, e: give_error(e) finally: - self.twd.stop() + self.plugin.handler.stop() b64_msg_sig = b64encode(msg_sig.signature) return str(b64_msg_sig) @@ -337,7 +345,7 @@ class TrezorWallet(BIP32_HD_Wallet): except Exception, e: give_error(e) finally: - self.twd.stop() + self.plugin.handler.stop() #values = [i['value'] for i in tx.inputs] raw = signed_tx.encode('hex') tx.update(raw) @@ -455,7 +463,7 @@ class TrezorGuiMixin(object): message = "Confirm address on Trezor device to continue" else: message = "Check Trezor device to continue" - self.twd.show_message(message) + self.handler.show_message(message) return proto.ButtonAck() def callback_PinMatrixRequest(self, msg): @@ -467,14 +475,14 @@ class TrezorGuiMixin(object): desc = 'new PIN again' else: desc = 'PIN' - pin = self.twd.get_pin("Please enter Trezor %s" % desc) + pin = self.handler.get_pin("Please enter Trezor %s" % desc) if not pin: return proto.Cancel() return proto.PinMatrixAck(pin=pin) def callback_PassphraseRequest(self, req): msg = _("Please enter your Trezor passphrase.") - passphrase = self.twd.get_passphrase(msg) + passphrase = self.handler.get_passphrase(msg) if passphrase is None: return proto.Cancel() return proto.PassphraseAck(passphrase=passphrase) diff --git a/plugins/trustedcoin.py b/plugins/trustedcoin.py index ba6e108ec..e5d5ab6c1 100644 --- a/plugins/trustedcoin.py +++ b/plugins/trustedcoin.py @@ -329,10 +329,6 @@ class Plugin(BasePlugin): xpub3 = self.make_xpub(signing_xpub, long_user_id) wallet.add_master_public_key('x3/', xpub3) - @hook - def init_qt(self, gui): - self.window = gui.main_window - @hook def do_clear(self): self.is_billing = False