Browse Source

coldcard: rebase #7682 and fix CC bugs

master
avirgovi 1 year ago committed by Sander van Grieken
parent
commit
572252abcd
No known key found for this signature in database
GPG Key ID: 9BCF8209EA402EBA
  1. 2
      electrum/gui/qt/wallet_info_dialog.py
  2. 55
      electrum/plugins/coldcard/qt.py

2
electrum/gui/qt/wallet_info_dialog.py

@ -162,6 +162,6 @@ class WalletInfoDialog(WindowModalDialog):
vbox.addStretch(1)
btn_export_info = run_hook('wallet_info_buttons', window, self)
btn_close = CloseButton(self)
btns = Buttons(btn_export_info, btn_close)
btns = Buttons(*btn_export_info, btn_close)
vbox.addLayout(btns)
self.setLayout(vbox)

55
electrum/plugins/coldcard/qt.py

@ -29,6 +29,10 @@ class Plugin(ColdcardPlugin, QtPluginBase):
def create_handler(self, window):
return Coldcard_Handler(window)
@staticmethod
def trim_file_suffix(path):
return path.rsplit('.', 1)[0]
@only_hook_if_libraries_available
@hook
def receive_menu(self, menu, addrs, wallet):
@ -48,23 +52,59 @@ class Plugin(ColdcardPlugin, QtPluginBase):
# user is about to see the "Wallet Information" dialog
# - add a button if multisig wallet, and a Coldcard is a cosigner.
assert isinstance(main_window, ElectrumWindow), f"{type(main_window)}"
buttons = []
wallet = main_window.wallet
if type(wallet) is not Multisig_Wallet:
return
if not any(type(ks) == self.keystore_class for ks in wallet.get_keystores()):
coldcard_keystores = [
ks
for ks in wallet.get_keystores()
if type(ks) == self.keystore_class
]
if not coldcard_keystores:
# doesn't involve a Coldcard wallet, hide feature
return
btn = QPushButton(_("Export for Coldcard"))
btn.clicked.connect(lambda unused: self.export_multisig_setup(main_window, wallet))
btn_export = QPushButton(_("Export multisig for Coldcard as file"))
btn_export.clicked.connect(lambda unused: self.export_multisig_setup(main_window, wallet))
buttons.append(btn_export)
btn_import_usb = QPushButton(_("Export multisig to Coldcard via USB"))
btn_import_usb.clicked.connect(lambda unused: self.import_multisig_wallet_to_cc(main_window, coldcard_keystores))
buttons.append(btn_import_usb)
return buttons
return btn
def import_multisig_wallet_to_cc(self, main_window, coldcard_keystores):
from io import StringIO
from ckcc.protocol import CCProtocolPacker
def export_multisig_setup(self, main_window, wallet):
index = main_window.query_choice(
_("Please select which {} device to use:").format(self.device),
[(i, ks.label) for i, ks in enumerate(coldcard_keystores)]
)
if index is not None:
selected_keystore = coldcard_keystores[index]
client = self.get_client(selected_keystore, force_pair=True, allow_user_interaction=False)
if client is None:
main_window.show_error("{} not connected.").format(selected_keystore.label)
return
basename = wallet.basename().rsplit('.', 1)[0] # trim .json
wallet = main_window.wallet
sio = StringIO()
basename = self.trim_file_suffix(wallet.basename())
ColdcardPlugin.export_ms_wallet(wallet, sio, basename)
sio.seek(0)
file_len, sha = client.dev.upload_file(sio.read().encode("utf-8"), verify=True)
client.dev.send_recv(CCProtocolPacker.multisig_enroll(file_len, sha))
main_window.show_message('\n'.join([
_("Wallet setup file '{}' imported successfully.").format(basename),
_("Confirm import on your {} device.").format(selected_keystore.label)
]))
def export_multisig_setup(self, main_window, wallet):
basename = self.trim_file_suffix(wallet.basename())
name = f'{basename}-cc-export.txt'.replace(' ', '-')
fileName = getSaveFileName(
parent=main_window,
@ -76,7 +116,7 @@ class Plugin(ColdcardPlugin, QtPluginBase):
if fileName:
with open(fileName, "wt") as f:
ColdcardPlugin.export_ms_wallet(wallet, f, basename)
main_window.show_message(_("Wallet setup file exported successfully"))
main_window.show_message(_("Wallet setup file '{}' exported successfully").format(name))
def show_settings_dialog(self, window, keystore):
# When they click on the icon for CC we come here.
@ -220,7 +260,6 @@ class CKCCSettingsDialog(WindowModalDialog):
from ckcc.utils import dfu_parse
from ckcc.sigheader import FW_HEADER_SIZE, FW_HEADER_OFFSET, FW_HEADER_MAGIC
from ckcc.protocol import CCProtocolPacker
from hashlib import sha256
import struct
try:

Loading…
Cancel
Save