diff --git a/electrum/plugins/coldcard/build_psbt.py b/electrum/plugins/coldcard/build_psbt.py index 998da24fb..31b98b583 100644 --- a/electrum/plugins/coldcard/build_psbt.py +++ b/electrum/plugins/coldcard/build_psbt.py @@ -34,8 +34,7 @@ _logger = get_logger(__name__) def xfp2str(xfp): # Standardized way to show an xpub's fingerprint... it's a 4-byte string # and not really an integer. Used to show as '0x%08x' but that's wrong endian. - - return b2a_hex(pack('>I', xfp)).decode('ascii').upper() + return b2a_hex(pack(' Transaction: tx.is_partial_originally = True for idx, inp in enumerate(tx.inputs()): - scr = first.inputs[idx].redeem_script + scr = first.inputs[idx].redeem_script or first.inputs[idx].witness_script # XXX should use transaction.py parse_scriptSig() here! if scr: try: M, N, __, pubkeys, __ = parse_redeemScript_multisig(scr) except NotRecognizedRedeemScript: - # problem: we can only handle M-of-N multisig here + # limitation: we can only handle M-of-N multisig here raise ValueError("Cannot handle non M-of-N multisig input") inp['pubkeys'] = pubkeys @@ -344,6 +348,14 @@ def recover_tx_from_psbt(first: BasicPSBT, wallet: Wallet) -> Transaction: # bugfix: transaction.py:parse_input() puts empty dict here, but need a list inp['signatures'] = [None] * N + if 'prev_tx' not in inp: + # fetch info about inputs' previous txn + wallet.add_hw_info(tx) + + if 'value' not in inp: + # we'll need to know the value of the outpts used as part + # of the witness data, much later... + inp['value'] = inp['prev_tx'].outputs()[inp['prevout_n']].value return tx @@ -356,8 +368,10 @@ def merge_sigs_from_psbt(tx: Transaction, psbt: BasicPSBT): if not inp.part_sigs: continue + scr = inp.redeem_script or inp.witness_script + # need to map from pubkey to signing position in redeem script - M, N, _, pubkeys, _ = parse_redeemScript_multisig(inp.redeem_script) + M, N, _, pubkeys, _ = parse_redeemScript_multisig(scr) #assert (M, N) == (wallet.m, wallet.n) for sig_pk in inp.part_sigs: diff --git a/electrum/plugins/coldcard/qt.py b/electrum/plugins/coldcard/qt.py index bbca7f141..294c89f5b 100644 --- a/electrum/plugins/coldcard/qt.py +++ b/electrum/plugins/coldcard/qt.py @@ -21,6 +21,8 @@ from base64 import b64encode, b64decode from .basic_psbt import BasicPSBT from .build_psbt import build_psbt, merge_sigs_from_psbt, recover_tx_from_psbt +CC_DEBUG = False + class Plugin(ColdcardPlugin, QtPluginBase): icon_unpaired = "coldcard_unpaired.png" icon_paired = "coldcard.png" @@ -156,6 +158,7 @@ class Plugin(ColdcardPlugin, QtPluginBase): return warn = [] + if not psbts: return # user picked nothing # Consistency checks and warnings. try: @@ -187,6 +190,9 @@ class Plugin(ColdcardPlugin, QtPluginBase): try: tx = recover_tx_from_psbt(first, wallet) except BaseException as exc: + if CC_DEBUG: + from PyQt5.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook() + import pdb; pdb.post_mortem() window.show_critical(str(exc), title=_("Unable to understand PSBT file")) return @@ -195,9 +201,10 @@ class Plugin(ColdcardPlugin, QtPluginBase): try: merge_sigs_from_psbt(tx, p) except BaseException as exc: - #from PyQt5.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook() - #import pdb; pdb.post_mortem() - window.show_critical(str(exc), + if CC_DEBUG: + from PyQt5.QtCore import pyqtRemoveInputHook; pyqtRemoveInputHook() + import pdb; pdb.post_mortem() + window.show_critical("Unable to merge signatures: " + str(exc), title=_("Unable to combine PSBT file: ") + p.filename) return