1
0

hardware wallets: show address on device also from tx dialog

This commit is contained in:
ThomasV
2025-04-17 10:05:11 +02:00
committed by SomberNight
parent 4640384b91
commit b86be552e7
10 changed files with 79 additions and 65 deletions

View File

@@ -397,6 +397,7 @@ class TxInOutWidget(QWidget):
for item in copy_list: for item in copy_list:
menu.addAction(*item) menu.addAction(*item)
run_hook('transaction_dialog_address_menu', menu, addr, self.wallet)
menu.addSeparator() menu.addSeparator()
std_menu = o_text.createStandardContextMenu() std_menu = o_text.createStandardContextMenu()
menu.addActions(std_menu.actions()) menu.addActions(std_menu.actions())

View File

@@ -43,6 +43,7 @@ from electrum.i18n import _
from electrum.logging import Logger from electrum.logging import Logger
from electrum.util import UserCancelled, UserFacingException, ChoiceItem from electrum.util import UserCancelled, UserFacingException, ChoiceItem
from electrum.plugin import hook, DeviceUnpairableError from electrum.plugin import hook, DeviceUnpairableError
from electrum.wallet import Standard_Wallet
from .plugin import OutdatedHwFirmwareException, HW_PluginBase, HardwareHandlerBase from .plugin import OutdatedHwFirmwareException, HW_PluginBase, HardwareHandlerBase
@@ -299,3 +300,14 @@ class QtPluginBase(object):
def create_handler(self, window: Union['ElectrumWindow', 'QENewWalletWizard']) -> 'QtHandlerBase': def create_handler(self, window: Union['ElectrumWindow', 'QENewWalletWizard']) -> 'QtHandlerBase':
raise NotImplementedError() 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)

View File

@@ -30,19 +30,13 @@ class Plugin(BitBox02Plugin, QtPluginBase):
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
# Context menu on each address in the Addresses Tab, right click... if len(addrs) == 1:
if len(addrs) != 1: self._add_menu_action(menu, addrs[0], wallet)
return
for keystore in wallet.get_keystores():
if type(keystore) == self.keystore_class:
def show_address(keystore=keystore): @only_hook_if_libraries_available
keystore.thread.add( @hook
partial(self.show_address, wallet, addrs[0], keystore=keystore) def transaction_dialog_address_menu(self, menu, addr, wallet):
) self._add_menu_action(menu, addr, wallet)
device_name = "{} ({})".format(self.device, keystore.label)
menu.addAction(_("Show on {}").format(device_name), show_address)
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook

View File

@@ -38,15 +38,14 @@ class Plugin(ColdcardPlugin, QtPluginBase):
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
# Context menu on each address in the Addresses Tab, right click...
if len(addrs) != 1: if len(addrs) != 1:
return return
for keystore in wallet.get_keystores(): self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class:
def show_address(keystore=keystore): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore=keystore)) @hook
device_name = "{} ({})".format(self.device, keystore.label) def transaction_dialog_address_menu(self, menu, addr, wallet):
menu.addAction(_("Show on {}").format(device_name), show_address) self._add_menu_action(menu, addr, wallet)
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook

View File

@@ -29,26 +29,23 @@ class Plugin(DigitalBitboxPlugin, QtPluginBase):
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet: Abstract_Wallet): def receive_menu(self, menu, addrs, wallet):
if type(wallet) is not Standard_Wallet:
return
keystore = wallet.get_keystore()
if type(keystore) is not self.keystore_class:
return
if not self.is_mobile_paired(): if not self.is_mobile_paired():
return 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: @only_hook_if_libraries_available
addr = addrs[0] @hook
if wallet.get_txin_type(addr) != 'p2pkh': def transaction_dialog_address_menu(self, menu, addr, wallet):
return if not self.is_mobile_paired():
return
def show_address(): if wallet.get_txin_type(addr) != 'p2pkh':
keystore.thread.add(partial(self.show_address, wallet, addr, keystore)) return
self._add_menu_action(menu, addr, wallet)
menu.addAction(_("Show on {}").format(self.device), show_address)
@hook @hook
def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): def init_wallet_wizard(self, wizard: 'QENewWalletWizard'):

View File

@@ -9,6 +9,7 @@ from electrum.wallet import Standard_Wallet
from electrum.hw_wallet.qt import QtHandlerBase, QtPluginBase from electrum.hw_wallet.qt import QtHandlerBase, QtPluginBase
from electrum.hw_wallet import plugin 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 electrum.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWXPub, WCHWUninitialized
from .jade import JadePlugin from .jade import JadePlugin
@@ -24,16 +25,21 @@ class Plugin(JadePlugin, QtPluginBase):
def create_handler(self, window): def create_handler(self, window):
return Jade_Handler(window) return Jade_Handler(window)
@plugin.only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if len(addrs) != 1:
return
if type(wallet) is not Standard_Wallet: if type(wallet) is not Standard_Wallet:
return return
keystore = wallet.get_keystore() self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class and len(addrs) == 1:
def show_address(): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0])) @hook
menu.addAction(_("Show on Jade"), show_address) 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 @hook
def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): def init_wallet_wizard(self, wizard: 'QENewWalletWizard'):

View File

@@ -207,12 +207,12 @@ class QtPlugin(QtPluginBase):
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if len(addrs) != 1: if len(addrs) != 1:
return return
for keystore in wallet.get_keystores(): self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class:
def show_address(keystore=keystore): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) @hook
device_name = "{} ({})".format(self.device, keystore.label) def transaction_dialog_address_menu(self, menu, addr, wallet):
menu.addAction(_("Show on {}").format(device_name), show_address) self._add_menu_action(menu, addr, wallet)
def show_settings_dialog(self, window, keystore): def show_settings_dialog(self, window, keystore):
def connect(): def connect():

View File

@@ -27,13 +27,18 @@ class Plugin(LedgerPlugin, QtPluginBase):
@only_hook_if_libraries_available @only_hook_if_libraries_available
@hook @hook
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if len(addrs) != 1:
return
if type(wallet) is not Standard_Wallet: if type(wallet) is not Standard_Wallet:
return return
keystore = wallet.get_keystore() self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class and len(addrs) == 1:
def show_address(): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore=keystore)) @hook
menu.addAction(_("Show on Ledger"), show_address) 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 @hook
def init_wallet_wizard(self, wizard: 'QENewWalletWizard'): def init_wallet_wizard(self, wizard: 'QENewWalletWizard'):

View File

@@ -84,12 +84,12 @@ class QtPlugin(QtPluginBase):
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if len(addrs) != 1: if len(addrs) != 1:
return return
for keystore in wallet.get_keystores(): self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class:
def show_address(keystore=keystore): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) @hook
device_name = "{} ({})".format(self.device, keystore.label) def transaction_dialog_address_menu(self, menu, addr, wallet):
menu.addAction(_("Show on {}").format(device_name), show_address) self._add_menu_action(menu, addr, wallet)
def show_settings_dialog(self, window, keystore): def show_settings_dialog(self, window, keystore):
def connect(): def connect():

View File

@@ -248,12 +248,12 @@ class QtPlugin(QtPluginBase):
def receive_menu(self, menu, addrs, wallet): def receive_menu(self, menu, addrs, wallet):
if len(addrs) != 1: if len(addrs) != 1:
return return
for keystore in wallet.get_keystores(): self._add_menu_action(menu, addrs[0], wallet)
if type(keystore) == self.keystore_class:
def show_address(keystore=keystore): @only_hook_if_libraries_available
keystore.thread.add(partial(self.show_address, wallet, addrs[0], keystore)) @hook
device_name = "{} ({})".format(self.device, keystore.label) def transaction_dialog_address_menu(self, menu, addr, wallet):
menu.addAction(_("Show on {}").format(device_name), show_address) self._add_menu_action(menu, addr, wallet)
def show_settings_dialog(self, window, keystore): def show_settings_dialog(self, window, keystore):
def connect(): def connect():