Ejemplo n.º 1
0
    def sign_transaction(self, tx: Transaction, password):
        # Build a PSBT in memory, upload it for signing.
        # - we can also work offline (without paired device present)
        if tx.is_complete():
            return

        assert self.my_wallet, "Not clear which wallet associated with this Coldcard"

        client = self.get_client()

        assert client.dev.master_fingerprint == self.ckcc_xfp

        # makes PSBT required
        raw_psbt = build_psbt(tx, self.my_wallet)

        cc_finalize = not (type(self.my_wallet) is Multisig_Wallet)

        try:
            try:
                self.handler.show_message("Authorize Transaction...")

                client.sign_transaction_start(raw_psbt, cc_finalize)

                while 1:
                    # How to kill some time, without locking UI?
                    time.sleep(0.250)

                    resp = client.sign_transaction_poll()
                    if resp is not None:
                        break

                rlen, rsha = resp
            
                # download the resulting txn.
                raw_resp = client.download_file(rlen, rsha)

            finally:
                self.handler.finished()

        except (CCUserRefused, CCBusyError) as exc:
            self.logger.info(f'Did not sign: {exc}')
            self.handler.show_error(str(exc))
            return
        except BaseException as e:
            self.logger.exception('')
            self.give_error(e, True)
            return

        if cc_finalize:
            # We trust the coldcard to re-serialize final transaction ready to go
            tx.update(bh2u(raw_resp))
        else:
            # apply partial signatures back into txn
            psbt = BasicPSBT()
            psbt.parse(raw_resp, client.label())

            merge_sigs_from_psbt(tx, psbt)