qt tx dialog: show_qr to warn if QR code is missing data
When exporting a tx as qr code, the prev txs are omitted to save space. This causes problems with offline signers: software electrum signers will just warn and then proceed, but hw devices will typically error.
This commit is contained in:
@@ -332,7 +332,7 @@ class TxDialog(Factory.Popup):
|
||||
|
||||
def show_qr(self):
|
||||
original_raw_tx = str(self.tx)
|
||||
qr_data = self.tx.to_qr_data()
|
||||
qr_data = self.tx.to_qr_data()[0]
|
||||
self.app.qr_dialog(_("Raw Transaction"), qr_data, text_for_clipboard=original_raw_tx)
|
||||
|
||||
def remove_local_tx(self):
|
||||
|
||||
@@ -5,7 +5,7 @@ from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
||||
from electrum.i18n import _
|
||||
from electrum.logging import get_logger
|
||||
from electrum.util import format_time, AddTransactionException, TxMinedInfo
|
||||
from electrum.transaction import tx_from_any
|
||||
from electrum.transaction import tx_from_any, Transaction
|
||||
from electrum.network import Network
|
||||
|
||||
from .qewallet import QEWallet
|
||||
@@ -31,7 +31,7 @@ class QETxDetails(QObject, QtEventListener):
|
||||
self._rawtx = ''
|
||||
self._label = ''
|
||||
|
||||
self._tx = None
|
||||
self._tx = None # type: Optional[Transaction]
|
||||
|
||||
self._status = ''
|
||||
self._amount = QEAmount()
|
||||
@@ -396,6 +396,6 @@ class QETxDetails(QObject, QtEventListener):
|
||||
def getSerializedTx(self, for_qr=False):
|
||||
tx = self._tx
|
||||
if for_qr:
|
||||
return tx.to_qr_data()
|
||||
return tx.to_qr_data()[0]
|
||||
else:
|
||||
return str(tx)
|
||||
|
||||
@@ -733,6 +733,6 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
|
||||
def getSerializedTx(self, txid, for_qr=False):
|
||||
tx = self.wallet.db.get_transaction(txid)
|
||||
if for_qr:
|
||||
return tx.to_qr_data()
|
||||
return tx.to_qr_data()[0]
|
||||
else:
|
||||
return str(tx)
|
||||
|
||||
@@ -595,9 +595,15 @@ class TxDialog(QDialog, MessageBoxMixin):
|
||||
def show_qr(self, *, tx: Transaction = None):
|
||||
if tx is None:
|
||||
tx = self.tx
|
||||
qr_data = tx.to_qr_data()
|
||||
qr_data, is_complete = tx.to_qr_data()
|
||||
help_text = None
|
||||
if not is_complete:
|
||||
help_text = _(
|
||||
"""Warning: Some data (prev txs / "full utxos") was left """
|
||||
"""out of the QR code as it would not fit. This might cause issues if signing offline. """
|
||||
"""As a workaround, try exporting the tx as file or text instead.""")
|
||||
try:
|
||||
self.main_window.show_qrcode(qr_data, 'Transaction', parent=self)
|
||||
self.main_window.show_qrcode(qr_data, 'Transaction', parent=self, help_text=help_text)
|
||||
except qrcode.exceptions.DataOverflowError:
|
||||
self.show_error(_('Failed to display QR code.') + '\n' +
|
||||
_('Transaction is too large in size.'))
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -938,14 +938,19 @@ class Transaction:
|
||||
else:
|
||||
return nVersion + txins + txouts + nLocktime
|
||||
|
||||
def to_qr_data(self) -> str:
|
||||
"""Returns tx as data to be put into a QR code. No side-effects."""
|
||||
def to_qr_data(self) -> Tuple[str, bool]:
|
||||
"""Returns (serialized_tx, is_complete). The tx is serialized to be put inside a QR code. No side-effects.
|
||||
As space in a QR code is limited, some data might have to be omitted. This is signalled via is_complete=False.
|
||||
"""
|
||||
is_complete = True
|
||||
tx = copy.deepcopy(self) # make copy as we mutate tx
|
||||
if isinstance(tx, PartialTransaction):
|
||||
# this makes QR codes a lot smaller (or just possible in the first place!)
|
||||
# note: will not apply if all inputs are taproot, due to new sighash.
|
||||
tx.convert_all_utxos_to_witness_utxos()
|
||||
is_complete = False
|
||||
tx_bytes = tx.serialize_as_bytes()
|
||||
return base_encode(tx_bytes, base=43)
|
||||
return base_encode(tx_bytes, base=43), is_complete
|
||||
|
||||
def txid(self) -> Optional[str]:
|
||||
if self._cached_txid is None:
|
||||
|
||||
Reference in New Issue
Block a user