bitbox02: fix pairing_dialog

This commit is contained in:
SomberNight 2020-04-06 16:13:13 +02:00 committed by TheCharlatan
parent 5f5a1e96ab
commit 15102855c1
No known key found for this signature in database
GPG key ID: 9B79B45691DB4173
2 changed files with 30 additions and 37 deletions

View file

@ -4,7 +4,7 @@
import hid import hid
import hashlib import hashlib
from typing import TYPE_CHECKING, Dict, Tuple, Optional, List, Any from typing import TYPE_CHECKING, Dict, Tuple, Optional, List, Any, Callable
from electrum import bip32, constants from electrum import bip32, constants
from electrum.i18n import _ from electrum.i18n import _
@ -84,16 +84,22 @@ class BitBox02Client(HardwareClientBase):
def has_usable_connection_with_device(self) -> bool: def has_usable_connection_with_device(self) -> bool:
if self.bitbox_hid_info is None: if self.bitbox_hid_info is None:
return False return False
return True return True
def pairing_dialog(self, wizard: bool = True): def pairing_dialog(self, wizard: bool = True):
def pairing_step(code): def pairing_step(code: str, device_response: Callable[[], bool]) -> bool:
msg = "Please compare and confirm the pairing code on your BitBox02:\n" msg = "Please compare and confirm the pairing code on your BitBox02:\n" + code
choice = [code] self.handler.show_message(msg)
if wizard == True: try:
return self.handler.win.query_choice(msg, choice) res = device_response()
self.handler.pairing_code_dialog(code) except:
# Close the hid device on exception
hid_device.close()
raise
finally:
self.handler.finished()
return res
def exists_remote_static_pubkey(pubkey: bytes) -> bool: def exists_remote_static_pubkey(pubkey: bytes) -> bool:
bitbox02_config = self.config.get("bitbox02") bitbox02_config = self.config.get("bitbox02")
@ -132,15 +138,8 @@ class BitBox02Client(HardwareClientBase):
class NoiseConfig(bitbox_api_protocol.BitBoxNoiseConfig): class NoiseConfig(bitbox_api_protocol.BitBoxNoiseConfig):
"""NoiseConfig extends BitBoxNoiseConfig""" """NoiseConfig extends BitBoxNoiseConfig"""
def show_pairing(self, code: str) -> bool: def show_pairing(self, code: str, device_response: Callable[[], bool]) -> bool:
choice = [code] return pairing_step(code, device_response)
try:
reply = pairing_step(code)
except:
# Close the hid device on exception
hid_device.close()
raise
return True
def attestation_check(self, result: bool) -> None: def attestation_check(self, result: bool) -> None:
if not result: if not result:
@ -168,6 +167,10 @@ class BitBox02Client(HardwareClientBase):
noise_config=NoiseConfig(), noise_config=NoiseConfig(),
) )
self.fail_if_not_initialized()
def fail_if_not_initialized(self) -> None:
assert self.bitbox02_device
if not self.bitbox02_device.device_info()["initialized"]: if not self.bitbox02_device.device_info()["initialized"]:
raise Exception( raise Exception(
"Please initialize the BitBox02 using the BitBox app first before using the BitBox02 in electrum" "Please initialize the BitBox02 using the BitBox app first before using the BitBox02 in electrum"
@ -201,10 +204,7 @@ class BitBox02Client(HardwareClientBase):
"Need to setup communication first before attempting any BitBox02 calls" "Need to setup communication first before attempting any BitBox02 calls"
) )
if not self.bitbox02_device.device_info()["initialized"]: self.fail_if_not_initialized()
raise UserFacingException(
"Please initialize the BitBox02 using the BitBox app first before using the BitBox02 in electrum"
)
xpub_keypath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path) xpub_keypath = bip32.convert_bip32_path_to_list_of_uint32(bip32_path)
coin_network = self.coin_network_from_electrum_network() coin_network = self.coin_network_from_electrum_network()
@ -502,11 +502,12 @@ class BitBox02_KeyStore(Hardware_KeyStore):
if tx.is_complete(): if tx.is_complete():
return return
client = self.get_client() client = self.get_client()
assert isinstance(client, BitBox02Client)
try: try:
try: try:
self.handler.show_message("Authorize Transaction...") self.handler.show_message("Authorize Transaction...")
client.sign_transaction(self, tx, self.handler.win.wallet) client.sign_transaction(self, tx, self.handler.get_wallet())
finally: finally:
self.handler.finished() self.handler.finished()
@ -535,7 +536,7 @@ class BitBox02_KeyStore(Hardware_KeyStore):
class BitBox02Plugin(HW_PluginBase): class BitBox02Plugin(HW_PluginBase):
keystore_class = BitBox02_KeyStore keystore_class = BitBox02_KeyStore
minimum_library = (2, 0, 2)
DEVICE_IDS = [(0x03EB, 0x2403)] DEVICE_IDS = [(0x03EB, 0x2403)]
SUPPORTED_XTYPES = ("p2wpkh-p2sh", "p2wpkh", "p2wsh") SUPPORTED_XTYPES = ("p2wpkh-p2sh", "p2wpkh", "p2wsh")
@ -571,8 +572,11 @@ class BitBox02Plugin(HW_PluginBase):
): ):
device_id = device_info.device.id_ device_id = device_info.device.id_
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
assert isinstance(client, BitBox02Client)
if client.bitbox02_device is None: if client.bitbox02_device is None:
client.pairing_dialog() wizard.run_task_without_blocking_gui(
task=lambda client=client: client.pairing_dialog())
client.fail_if_not_initialized()
return client return client
def get_xpub( def get_xpub(
@ -583,8 +587,8 @@ class BitBox02Plugin(HW_PluginBase):
_("This type of script is not supported with {}.").format(self.device) _("This type of script is not supported with {}.").format(self.device)
) )
client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard) client = self.scan_and_create_client_for_device(device_id=device_id, wizard=wizard)
if client.bitbox02_device is None: assert isinstance(client, BitBox02Client)
client.pairing_dialog() assert client.bitbox02_device is not None
return client.get_xpub(derivation, xtype) return client.get_xpub(derivation, xtype)
def get_client(self, keystore: BitBox02_KeyStore, force_pair: bool = True): def get_client(self, keystore: BitBox02_KeyStore, force_pair: bool = True):

View file

@ -117,17 +117,6 @@ class BitBox02_Handler(QtHandlerBase):
dialog.exec_() dialog.exec_()
return return
def pairing_code_dialog(self, code):
self.clear_dialog()
self.dialog = dialog = WindowModalDialog(None, "BitBox02 Pairing Code")
l = QLabel(code)
vbox = QVBoxLayout(dialog)
vbox.addWidget(l)
vbox.addLayout(Buttons(CancelButton(dialog), OkButton(dialog)))
dialog.setLayout(vbox)
dialog.exec_()
return
def get_setup(self): def get_setup(self):
self.done.clear() self.done.clear()
self.setup_signal.emit() self.setup_signal.emit()