mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-08-23 17:47:31 +00:00
qt tx dialog: add export options for coinjoins and for coldcard
This commit is contained in:
parent
d872be7f6b
commit
c8c1ea9c86
2 changed files with 77 additions and 27 deletions
|
@ -28,7 +28,7 @@ import copy
|
|||
import datetime
|
||||
import traceback
|
||||
import time
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
from PyQt5.QtCore import QSize, Qt
|
||||
from PyQt5.QtGui import QTextCharFormat, QBrush, QFont
|
||||
|
@ -144,16 +144,13 @@ class TxDialog(QDialog, MessageBoxMixin):
|
|||
b.clicked.connect(self.close)
|
||||
b.setDefault(True)
|
||||
|
||||
export_actions_menu = QMenu()
|
||||
action = QAction(_("Copy to clipboard"), self)
|
||||
action.triggered.connect(lambda: parent.app.clipboard().setText((lambda: str(self.tx))()))
|
||||
export_actions_menu.addAction(action)
|
||||
action = QAction(read_QIcon(qr_icon), _("Show as QR code"), self)
|
||||
action.triggered.connect(self.show_qr)
|
||||
export_actions_menu.addAction(action)
|
||||
action = QAction(_("Export to file"), self)
|
||||
action.triggered.connect(self.export)
|
||||
export_actions_menu.addAction(action)
|
||||
self.export_actions_menu = export_actions_menu = QMenu()
|
||||
self.add_export_actions_to_menu(export_actions_menu)
|
||||
export_actions_menu.addSeparator()
|
||||
if isinstance(tx, PartialTransaction):
|
||||
export_for_coinjoin_submenu = export_actions_menu.addMenu(_("For CoinJoin; strip privates"))
|
||||
self.add_export_actions_to_menu(export_for_coinjoin_submenu, gettx=self._gettx_for_coinjoin)
|
||||
|
||||
self.export_actions_button = QToolButton()
|
||||
self.export_actions_button.setText(_("Export"))
|
||||
self.export_actions_button.setMenu(export_actions_menu)
|
||||
|
@ -167,7 +164,7 @@ class TxDialog(QDialog, MessageBoxMixin):
|
|||
ptx_join_txs_action.triggered.connect(self.join_tx_with_another)
|
||||
partial_tx_actions_menu.addAction(ptx_join_txs_action)
|
||||
self.partial_tx_actions_button = QToolButton()
|
||||
self.partial_tx_actions_button.setText(_("Combine with other"))
|
||||
self.partial_tx_actions_button.setText(_("Combine"))
|
||||
self.partial_tx_actions_button.setMenu(partial_tx_actions_menu)
|
||||
self.partial_tx_actions_button.setPopupMode(QToolButton.InstantPopup)
|
||||
|
||||
|
@ -212,8 +209,39 @@ class TxDialog(QDialog, MessageBoxMixin):
|
|||
# Override escape-key to close normally (and invoke closeEvent)
|
||||
self.close()
|
||||
|
||||
def show_qr(self):
|
||||
text = self.tx.serialize_as_bytes()
|
||||
def add_export_actions_to_menu(self, menu: QMenu, *, gettx: Callable[[], Transaction] = None) -> None:
|
||||
if gettx is None:
|
||||
gettx = lambda: None
|
||||
|
||||
action = QAction(_("Copy to clipboard"), self)
|
||||
action.triggered.connect(lambda: self.copy_to_clipboard(tx=gettx()))
|
||||
menu.addAction(action)
|
||||
|
||||
qr_icon = "qrcode_white.png" if ColorScheme.dark_scheme else "qrcode.png"
|
||||
action = QAction(read_QIcon(qr_icon), _("Show as QR code"), self)
|
||||
action.triggered.connect(lambda: self.show_qr(tx=gettx()))
|
||||
menu.addAction(action)
|
||||
|
||||
action = QAction(_("Export to file"), self)
|
||||
action.triggered.connect(lambda: self.export_to_file(tx=gettx()))
|
||||
menu.addAction(action)
|
||||
|
||||
def _gettx_for_coinjoin(self) -> PartialTransaction:
|
||||
if not isinstance(self.tx, PartialTransaction):
|
||||
raise Exception("Can only export partial transactions for coinjoins.")
|
||||
tx = copy.deepcopy(self.tx)
|
||||
tx.prepare_for_export_for_coinjoin()
|
||||
return tx
|
||||
|
||||
def copy_to_clipboard(self, *, tx: Transaction = None):
|
||||
if tx is None:
|
||||
tx = self.tx
|
||||
self.main_window.app.clipboard().setText(str(tx))
|
||||
|
||||
def show_qr(self, *, tx: Transaction = None):
|
||||
if tx is None:
|
||||
tx = self.tx
|
||||
text = tx.serialize_as_bytes()
|
||||
text = base_encode(text, base=43)
|
||||
try:
|
||||
self.main_window.show_qrcode(text, 'Transaction', parent=self)
|
||||
|
@ -245,24 +273,26 @@ class TxDialog(QDialog, MessageBoxMixin):
|
|||
self.saved = True
|
||||
self.main_window.pop_top_level_window(self)
|
||||
|
||||
def export(self):
|
||||
if isinstance(self.tx, PartialTransaction):
|
||||
self.tx.finalize_psbt()
|
||||
if self.tx.is_complete():
|
||||
name = 'signed_%s.txn' % (self.tx.txid()[0:8])
|
||||
def export_to_file(self, *, tx: Transaction = None):
|
||||
if tx is None:
|
||||
tx = self.tx
|
||||
if isinstance(tx, PartialTransaction):
|
||||
tx.finalize_psbt()
|
||||
if tx.is_complete():
|
||||
name = 'signed_%s.txn' % (tx.txid()[0:8])
|
||||
else:
|
||||
name = self.wallet.basename() + time.strftime('-%Y%m%d-%H%M.psbt')
|
||||
fileName = self.main_window.getSaveFileName(_("Select where to save your signed transaction"), name, "*.txn;;*.psbt")
|
||||
if not fileName:
|
||||
return
|
||||
if self.tx.is_complete(): # network tx hex
|
||||
if tx.is_complete(): # network tx hex
|
||||
with open(fileName, "w+") as f:
|
||||
network_tx_hex = self.tx.serialize_to_network()
|
||||
network_tx_hex = tx.serialize_to_network()
|
||||
f.write(network_tx_hex + '\n')
|
||||
else: # if partial: PSBT bytes
|
||||
assert isinstance(self.tx, PartialTransaction)
|
||||
assert isinstance(tx, PartialTransaction)
|
||||
with open(fileName, "wb+") as f:
|
||||
f.write(self.tx.serialize_as_bytes())
|
||||
f.write(tx.serialize_as_bytes())
|
||||
|
||||
self.show_message(_("Transaction exported successfully"))
|
||||
self.saved = True
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import time, os
|
||||
from functools import partial
|
||||
import copy
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSignal
|
||||
from PyQt5.QtWidgets import QPushButton, QLabel, QVBoxLayout, QWidget, QGridLayout
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
|
||||
from electrum.gui.qt.util import WindowModalDialog, CloseButton, get_parent_main_window, Buttons
|
||||
from electrum.gui.qt.transaction_dialog import TxDialog
|
||||
|
||||
from electrum.i18n import _
|
||||
from electrum.plugin import hook
|
||||
from electrum.wallet import Standard_Wallet, Multisig_Wallet
|
||||
from electrum.gui.qt.util import WindowModalDialog, CloseButton, get_parent_main_window, Buttons
|
||||
from electrum.transaction import Transaction
|
||||
from electrum.wallet import Multisig_Wallet
|
||||
from electrum.transaction import PartialTransaction
|
||||
|
||||
from .coldcard import ColdcardPlugin, xfp2str
|
||||
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
|
||||
|
@ -68,6 +70,24 @@ class Plugin(ColdcardPlugin, QtPluginBase):
|
|||
ColdcardPlugin.export_ms_wallet(wallet, f, basename)
|
||||
main_window.show_message(_("Wallet setup file exported successfully"))
|
||||
|
||||
@hook
|
||||
def transaction_dialog(self, dia: TxDialog):
|
||||
# if not a Coldcard wallet, hide feature
|
||||
if not any(type(ks) == self.keystore_class for ks in dia.wallet.get_keystores()):
|
||||
return
|
||||
|
||||
def gettx_for_coldcard_export() -> PartialTransaction:
|
||||
if not isinstance(dia.tx, PartialTransaction):
|
||||
raise Exception("Can only export partial transactions for coinjoins.")
|
||||
tx = copy.deepcopy(dia.tx)
|
||||
tx.add_info_from_wallet(dia.wallet, include_xpubs_and_full_paths=True)
|
||||
return tx
|
||||
|
||||
# add a new "export" option
|
||||
if isinstance(dia.tx, PartialTransaction):
|
||||
export_submenu = dia.export_actions_menu.addMenu(_("For {}; include xpubs").format(self.device))
|
||||
dia.add_export_actions_to_menu(export_submenu, gettx=gettx_for_coldcard_export)
|
||||
|
||||
def show_settings_dialog(self, window, keystore):
|
||||
# When they click on the icon for CC we come here.
|
||||
# - doesn't matter if device not connected, continue
|
||||
|
|
Loading…
Add table
Reference in a new issue