|
|
@ -26,6 +26,7 @@ |
|
|
|
|
|
|
|
import threading |
|
|
|
from functools import partial |
|
|
|
from typing import TYPE_CHECKING, Union, Optional, Callable, Any |
|
|
|
|
|
|
|
from PyQt5.QtCore import QObject, pyqtSignal |
|
|
|
from PyQt5.QtWidgets import QVBoxLayout, QLineEdit, QHBoxLayout, QLabel |
|
|
@ -33,12 +34,18 @@ from PyQt5.QtWidgets import QVBoxLayout, QLineEdit, QHBoxLayout, QLabel |
|
|
|
from electrum.gui.qt.password_dialog import PasswordLayout, PW_PASSPHRASE |
|
|
|
from electrum.gui.qt.util import (read_QIcon, WWLabel, OkButton, WindowModalDialog, |
|
|
|
Buttons, CancelButton, TaskThread, char_width_in_lineedit) |
|
|
|
from electrum.gui.qt.main_window import StatusBarButton, ElectrumWindow |
|
|
|
|
|
|
|
from electrum.i18n import _ |
|
|
|
from electrum.logging import Logger |
|
|
|
from electrum.util import parse_URI, InvalidBitcoinURI |
|
|
|
from electrum.util import parse_URI, InvalidBitcoinURI, UserCancelled |
|
|
|
from electrum.plugin import hook, DeviceUnpairableError |
|
|
|
|
|
|
|
from .plugin import OutdatedHwFirmwareException |
|
|
|
from .plugin import OutdatedHwFirmwareException, HW_PluginBase |
|
|
|
|
|
|
|
if TYPE_CHECKING: |
|
|
|
from electrum.wallet import Abstract_Wallet |
|
|
|
from electrum.keystore import Hardware_KeyStore |
|
|
|
|
|
|
|
|
|
|
|
# The trickiest thing about this handler was getting windows properly |
|
|
@ -190,15 +197,10 @@ class QtHandlerBase(QObject, Logger): |
|
|
|
self.done.set() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from electrum.plugin import hook |
|
|
|
from electrum.util import UserCancelled |
|
|
|
from electrum.gui.qt.main_window import StatusBarButton |
|
|
|
|
|
|
|
class QtPluginBase(object): |
|
|
|
|
|
|
|
@hook |
|
|
|
def load_wallet(self, wallet, window): |
|
|
|
def load_wallet(self: Union['QtPluginBase', HW_PluginBase], wallet: 'Abstract_Wallet', window: ElectrumWindow): |
|
|
|
for keystore in wallet.get_keystores(): |
|
|
|
if not isinstance(keystore, self.keystore_class): |
|
|
|
continue |
|
|
@ -220,7 +222,8 @@ class QtPluginBase(object): |
|
|
|
# Trigger a pairing |
|
|
|
keystore.thread.add(partial(self.get_client, keystore)) |
|
|
|
|
|
|
|
def on_task_thread_error(self, window, keystore, exc_info): |
|
|
|
def on_task_thread_error(self: Union['QtPluginBase', HW_PluginBase], window: ElectrumWindow, |
|
|
|
keystore: 'Hardware_KeyStore', exc_info): |
|
|
|
e = exc_info[1] |
|
|
|
if isinstance(e, OutdatedHwFirmwareException): |
|
|
|
if window.question(e.text_ignore_old_fw_and_continue(), title=_("Outdated device firmware")): |
|
|
@ -236,7 +239,8 @@ class QtPluginBase(object): |
|
|
|
else: |
|
|
|
window.on_error(exc_info) |
|
|
|
|
|
|
|
def choose_device(self, window, keystore): |
|
|
|
def choose_device(self: Union['QtPluginBase', HW_PluginBase], window: ElectrumWindow, |
|
|
|
keystore: 'Hardware_KeyStore') -> Optional[str]: |
|
|
|
'''This dialog box should be usable even if the user has |
|
|
|
forgotten their PIN or it is in bootloader mode.''' |
|
|
|
device_id = self.device_manager().xpub_id(keystore.xpub) |
|
|
@ -248,10 +252,12 @@ class QtPluginBase(object): |
|
|
|
device_id = info.device.id_ |
|
|
|
return device_id |
|
|
|
|
|
|
|
def show_settings_dialog(self, window, keystore): |
|
|
|
def show_settings_dialog(self, window: ElectrumWindow, keystore: 'Hardware_KeyStore') -> None: |
|
|
|
device_id = self.choose_device(window, keystore) |
|
|
|
|
|
|
|
def add_show_address_on_hw_device_button_for_receive_addr(self, wallet, keystore, main_window): |
|
|
|
def add_show_address_on_hw_device_button_for_receive_addr(self, wallet: 'Abstract_Wallet', |
|
|
|
keystore: 'Hardware_KeyStore', |
|
|
|
main_window: ElectrumWindow): |
|
|
|
plugin = keystore.plugin |
|
|
|
receive_address_e = main_window.receive_address_e |
|
|
|
|
|
|
@ -267,3 +273,6 @@ class QtPluginBase(object): |
|
|
|
keystore.thread.add(partial(plugin.show_address, wallet, addr, keystore)) |
|
|
|
dev_name = f"{plugin.device} ({keystore.label})" |
|
|
|
receive_address_e.addButton("eye1.png", show_address, _("Show on {}").format(dev_name)) |
|
|
|
|
|
|
|
def create_handler(self, window: ElectrumWindow) -> 'QtHandlerBase': |
|
|
|
raise NotImplementedError() |
|
|
|