From b86be552e7b28a0a810251c3ecfd29eb9725480a Mon Sep 17 00:00:00 2001 From: ThomasV Date: Thu, 17 Apr 2025 10:05:11 +0200 Subject: [PATCH] hardware wallets: show address on device also from tx dialog --- electrum/gui/qt/transaction_dialog.py | 1 + electrum/hw_wallet/qt.py | 12 +++++++++++ electrum/plugins/bitbox02/qt.py | 18 ++++++---------- electrum/plugins/coldcard/qt.py | 13 ++++++----- electrum/plugins/digitalbitbox/qt.py | 31 ++++++++++++--------------- electrum/plugins/jade/qt.py | 18 ++++++++++------ electrum/plugins/keepkey/qt.py | 12 +++++------ electrum/plugins/ledger/qt.py | 15 ++++++++----- electrum/plugins/safe_t/qt.py | 12 +++++------ electrum/plugins/trezor/qt.py | 12 +++++------ 10 files changed, 79 insertions(+), 65 deletions(-) diff --git a/electrum/gui/qt/transaction_dialog.py b/electrum/gui/qt/transaction_dialog.py index 47d86d60c..70c2a6b7d 100644 --- a/electrum/gui/qt/transaction_dialog.py +++ b/electrum/gui/qt/transaction_dialog.py @@ -397,6 +397,7 @@ class TxInOutWidget(QWidget): for item in copy_list: menu.addAction(*item) + run_hook('transaction_dialog_address_menu', menu, addr, self.wallet) menu.addSeparator() std_menu = o_text.createStandardContextMenu() menu.addActions(std_menu.actions()) diff --git a/electrum/hw_wallet/qt.py b/electrum/hw_wallet/qt.py index a48311be6..057a95171 100644 --- a/electrum/hw_wallet/qt.py +++ b/electrum/hw_wallet/qt.py @@ -43,6 +43,7 @@ from electrum.i18n import _ from electrum.logging import Logger from electrum.util import UserCancelled, UserFacingException, ChoiceItem from electrum.plugin import hook, DeviceUnpairableError +from electrum.wallet import Standard_Wallet from .plugin import OutdatedHwFirmwareException, HW_PluginBase, HardwareHandlerBase @@ -299,3 +300,14 @@ class QtPluginBase(object): def create_handler(self, window: Union['ElectrumWindow', 'QENewWalletWizard']) -> 'QtHandlerBase': raise NotImplementedError() + + def _add_menu_action(self, menu, address, wallet): + keystore = wallet.get_keystore() + if type(keystore) != self.keystore_class: + return + if not wallet.is_mine(address): + return + def show_address(): + keystore.thread.add(partial(self.show_address, wallet, address, keystore=keystore)) + device_name = "{} ({})".format(self.device, keystore.label) + menu.addAction(read_QIcon("eye1.png"), _("Show address on {}").format(device_name), show_address) diff --git a/electrum/plugins/bitbox02/qt.py b/electrum/plugins/bitbox02/qt.py index 089063a7e..e62ad93e0 100644 --- a/electrum/plugins/bitbox02/qt.py +++ b/electrum/plugins/bitbox02/qt.py @@ -30,19 +30,13 @@ class Plugin(BitBox02Plugin, QtPluginBase): @only_hook_if_libraries_available @hook def receive_menu(self, menu, addrs, wallet): - # Context menu on each address in the Addresses Tab, right click... - if len(addrs) != 1: - return - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class: + if len(addrs) == 1: + self._add_menu_action(menu, addrs[0], wallet) - def show_address(keystore=keystore): - keystore.thread.add( - partial(self.show_address, wallet, addrs[0], keystore=keystore) - ) - - device_name = "{} ({})".format(self.device, keystore.label) - menu.addAction(_("Show on {}").format(device_name), show_address) + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + self._add_menu_action(menu, addr, wallet) @only_hook_if_libraries_available @hook diff --git a/electrum/plugins/coldcard/qt.py b/electrum/plugins/coldcard/qt.py index 5956ae7f8..0a235f76a 100644 --- a/electrum/plugins/coldcard/qt.py +++ b/electrum/plugins/coldcard/qt.py @@ -38,15 +38,14 @@ class Plugin(ColdcardPlugin, QtPluginBase): @only_hook_if_libraries_available @hook def receive_menu(self, menu, addrs, wallet): - # Context menu on each address in the Addresses Tab, right click... if len(addrs) != 1: return - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class: - def show_address(keystore=keystore): - keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore=keystore)) - device_name = "{} ({})".format(self.device, keystore.label) - menu.addAction(_("Show on {}").format(device_name), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + self._add_menu_action(menu, addr, wallet) @only_hook_if_libraries_available @hook diff --git a/electrum/plugins/digitalbitbox/qt.py b/electrum/plugins/digitalbitbox/qt.py index 3fad9b6ec..5bb50b46c 100644 --- a/electrum/plugins/digitalbitbox/qt.py +++ b/electrum/plugins/digitalbitbox/qt.py @@ -29,26 +29,23 @@ class Plugin(DigitalBitboxPlugin, QtPluginBase): @only_hook_if_libraries_available @hook - def receive_menu(self, menu, addrs, wallet: Abstract_Wallet): - if type(wallet) is not Standard_Wallet: - return - - keystore = wallet.get_keystore() - if type(keystore) is not self.keystore_class: - return - + def receive_menu(self, menu, addrs, wallet): if not self.is_mobile_paired(): return + if len(addrs) != 1: + return + if wallet.get_txin_type(addrs[0]) != 'p2pkh': + return + self._add_menu_action(menu, addrs[0], wallet) - if len(addrs) == 1: - addr = addrs[0] - if wallet.get_txin_type(addr) != 'p2pkh': - return - - def show_address(): - keystore.thread.add(partial(self.show_address, wallet, addr, keystore)) - - menu.addAction(_("Show on {}").format(self.device), show_address) + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + if not self.is_mobile_paired(): + return + if wallet.get_txin_type(addr) != 'p2pkh': + return + self._add_menu_action(menu, addr, wallet) @hook def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): diff --git a/electrum/plugins/jade/qt.py b/electrum/plugins/jade/qt.py index 034e28e20..50bf9e938 100644 --- a/electrum/plugins/jade/qt.py +++ b/electrum/plugins/jade/qt.py @@ -9,6 +9,7 @@ from electrum.wallet import Standard_Wallet from electrum.hw_wallet.qt import QtHandlerBase, QtPluginBase from electrum.hw_wallet import plugin +from electrum.hw_wallet.plugin import only_hook_if_libraries_available from electrum.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWXPub, WCHWUninitialized from .jade import JadePlugin @@ -24,16 +25,21 @@ class Plugin(JadePlugin, QtPluginBase): def create_handler(self, window): return Jade_Handler(window) - @plugin.only_hook_if_libraries_available + @only_hook_if_libraries_available @hook def receive_menu(self, menu, addrs, wallet): + if len(addrs) != 1: + return if type(wallet) is not Standard_Wallet: return - keystore = wallet.get_keystore() - if type(keystore) == self.keystore_class and len(addrs) == 1: - def show_address(): - keystore.thread.add(partial(self.show_address, wallet, addrs[0])) - menu.addAction(_("Show on Jade"), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + if type(wallet) is not Standard_Wallet: + return + self._add_menu_action(menu, addr, wallet) @hook def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): diff --git a/electrum/plugins/keepkey/qt.py b/electrum/plugins/keepkey/qt.py index 401afba3a..97ce728c2 100644 --- a/electrum/plugins/keepkey/qt.py +++ b/electrum/plugins/keepkey/qt.py @@ -207,12 +207,12 @@ class QtPlugin(QtPluginBase): def receive_menu(self, menu, addrs, wallet): if len(addrs) != 1: return - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class: - def show_address(keystore=keystore): - keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) - device_name = "{} ({})".format(self.device, keystore.label) - menu.addAction(_("Show on {}").format(device_name), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + self._add_menu_action(menu, addr, wallet) def show_settings_dialog(self, window, keystore): def connect(): diff --git a/electrum/plugins/ledger/qt.py b/electrum/plugins/ledger/qt.py index 950d51345..5583e1ac8 100644 --- a/electrum/plugins/ledger/qt.py +++ b/electrum/plugins/ledger/qt.py @@ -27,13 +27,18 @@ class Plugin(LedgerPlugin, QtPluginBase): @only_hook_if_libraries_available @hook def receive_menu(self, menu, addrs, wallet): + if len(addrs) != 1: + return if type(wallet) is not Standard_Wallet: return - keystore = wallet.get_keystore() - if type(keystore) == self.keystore_class and len(addrs) == 1: - def show_address(): - keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore=keystore)) - menu.addAction(_("Show on Ledger"), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + if type(wallet) is not Standard_Wallet: + return + self._add_menu_action(menu, addr, wallet) @hook def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): diff --git a/electrum/plugins/safe_t/qt.py b/electrum/plugins/safe_t/qt.py index 58ff70019..3111a03b2 100644 --- a/electrum/plugins/safe_t/qt.py +++ b/electrum/plugins/safe_t/qt.py @@ -84,12 +84,12 @@ class QtPlugin(QtPluginBase): def receive_menu(self, menu, addrs, wallet): if len(addrs) != 1: return - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class: - def show_address(keystore=keystore): - keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) - device_name = "{} ({})".format(self.device, keystore.label) - menu.addAction(_("Show on {}").format(device_name), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + self._add_menu_action(menu, addr, wallet) def show_settings_dialog(self, window, keystore): def connect(): diff --git a/electrum/plugins/trezor/qt.py b/electrum/plugins/trezor/qt.py index 471aae59a..31e572ef1 100644 --- a/electrum/plugins/trezor/qt.py +++ b/electrum/plugins/trezor/qt.py @@ -248,12 +248,12 @@ class QtPlugin(QtPluginBase): def receive_menu(self, menu, addrs, wallet): if len(addrs) != 1: return - for keystore in wallet.get_keystores(): - if type(keystore) == self.keystore_class: - def show_address(keystore=keystore): - keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) - device_name = "{} ({})".format(self.device, keystore.label) - menu.addAction(_("Show on {}").format(device_name), show_address) + self._add_menu_action(menu, addrs[0], wallet) + + @only_hook_if_libraries_available + @hook + def transaction_dialog_address_menu(self, menu, addr, wallet): + self._add_menu_action(menu, addr, wallet) def show_settings_dialog(self, window, keystore): def connect():