def __init__(
        self,
        tx: Transaction,
        *,
        parent: 'ElectrumWindow',
        prompt_if_unsaved: bool,
        external_keypairs: Mapping[bytes, bytes] = None,
        invoice: 'Invoice' = None,
        on_closed: Callable[[], None] = None,
    ):
        '''Transactions in the wallet will show their description.
        Pass desc to give a description for txs not yet in the wallet.
        '''
        # We want to be a top-level window
        QDialog.__init__(self, parent=None)
        self.tx = None  # type: Optional[Transaction]
        self.external_keypairs = external_keypairs
        self.main_window = parent
        self.config = parent.config
        self.wallet = parent.wallet
        self.invoice = invoice
        self.prompt_if_unsaved = prompt_if_unsaved
        self.on_closed = on_closed
        self.saved = False
        self.desc = None
        if txid := tx.txid():
            self.desc = self.wallet.get_label_for_txid(txid) or None
        if not self.desc and self.invoice:
            self.desc = self.invoice.get_message()
        self.setMinimumWidth(640)

        self.psbt_only_widgets = []  # type: List[Union[QWidget, QAction]]

        vbox = QVBoxLayout()
        self.setLayout(vbox)
        toolbar, menu = create_toolbar_with_menu(self.config, '')
        menu.addConfig(
            self.config.cv.GUI_QT_TX_DIALOG_FETCH_TXIN_DATA,
            callback=self.maybe_fetch_txin_data)
        vbox.addLayout(toolbar)

        vbox.addWidget(QLabel(_("Transaction ID:")))
        self.tx_hash_e = ShowQRLineEdit('', self.config, title=_('Transaction ID'))
        vbox.addWidget(self.tx_hash_e)
        self.tx_desc_label = QLabel(_("Description:"))
        vbox.addWidget(self.tx_desc_label)
        self.tx_desc = ButtonsLineEdit('')

        self.tx_desc.editingFinished.connect(self.store_tx_label)
        self.tx_desc.addCopyButton()
        vbox.addWidget(self.tx_desc)

        self.add_tx_stats(vbox)

        vbox.addSpacing(10)

        self.io_widget = TxInOutWidget(self.main_window, self.wallet)
        vbox.addWidget(self.io_widget)

        self.sign_button = b = QPushButton(_("Sign"))
        b.clicked.connect(self.sign)

        self.broadcast_button = b = QPushButton(_("Broadcast"))
        b.clicked.connect(self.do_broadcast)

        self.save_button = b = QPushButton(_("Add to History"))
        b.clicked.connect(self.save)

        self.cancel_button = b = QPushButton(_("Close"))
        b.clicked.connect(self.close)
        b.setDefault(True)

        self.export_actions_menu = export_actions_menu = QMenuWithConfig(config=self.config)
        self.add_export_actions_to_menu(export_actions_menu)
        export_actions_menu.addSeparator()
        export_option = export_actions_menu.addConfig(
            self.config.cv.GUI_QT_TX_DIALOG_EXPORT_STRIP_SENSITIVE_METADATA)
        self.psbt_only_widgets.append(export_option)
        export_option = export_actions_menu.addConfig(
            self.config.cv.GUI_QT_TX_DIALOG_EXPORT_INCLUDE_GLOBAL_XPUBS)
        self.psbt_only_widgets.append(export_option)
        if self.wallet.has_support_for_slip_19_ownership_proofs():
            export_option = export_actions_menu.addAction(
                _('Include SLIP-19 ownership proofs'),
                self._add_slip_19_ownership_proofs_to_tx)
            export_option.setToolTip(_("Some cosigners (e.g. Trezor) might require this for coinjoins."))
            self._export_option_slip19 = export_option
            export_option.setCheckable(True)
            export_option.setChecked(False)
            self.psbt_only_widgets.append(export_option)

        self.export_actions_button = QToolButton()
        self.export_actions_button.setText(_("Share"))
        self.export_actions_button.setMenu(export_actions_menu)
        self.export_actions_button.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)

        partial_tx_actions_menu = QMenu()
        ptx_merge_sigs_action = QAction(_("Merge signatures from"), self)
        ptx_merge_sigs_action.triggered.connect(self.merge_sigs)
        partial_tx_actions_menu.addAction(ptx_merge_sigs_action)
        self._ptx_join_txs_action = QAction(_("Join inputs/outputs"), self)
        self._ptx_join_txs_action.triggered.connect(self.join_tx_with_another)
        partial_tx_actions_menu.addAction(self._ptx_join_txs_action)
        self.partial_tx_actions_button = QToolButton()
        self.partial_tx_actions_button.setText(_("Combine"))
        self.partial_tx_actions_button.setMenu(partial_tx_actions_menu)
        self.partial_tx_actions_button.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
        self.psbt_only_widgets.append(self.partial_tx_actions_button)

        # Action buttons
        self.buttons = [self.partial_tx_actions_button, self.sign_button, self.broadcast_button, self.cancel_button]
        # Transaction sharing buttons
        self.sharing_buttons = [self.export_actions_button, self.save_button]
        run_hook('transaction_dialog', self)
        self.hbox = hbox = QHBoxLayout()
        hbox.addLayout(Buttons(*self.sharing_buttons))
        hbox.addStretch(1)
        hbox.addLayout(Buttons(*self.buttons))
        vbox.addLayout(hbox)
        dialogs.append(self)

        self._fetch_txin_data_fut = None  # type: Optional[concurrent.futures.Future]
        self._fetch_txin_data_progress = None  # type: Optional[TxinDataFetchProgress]
        self.throttled_update_sig.connect(self._throttled_update, Qt.ConnectionType.QueuedConnection)

        self.set_tx(tx)
        self.update()
        self.set_title()
Transactions in the wallet will show their description.
        Pass desc to give a description for txs not yet in the wallet.
        
electrum/gui/qt/transaction_dialog.py