|
|
|
|
@ -17,14 +17,13 @@ from electrum.util import NotEnoughFunds, NoDynamicFeeEstimates, parse_max_spend
|
|
|
|
|
from electrum.invoices import PR_PAID, Invoice, PR_BROADCASTING, PR_BROADCAST |
|
|
|
|
from electrum.transaction import Transaction, PartialTxInput, PartialTxOutput |
|
|
|
|
from electrum.network import TxBroadcastError, BestEffortRequestFailed |
|
|
|
|
from electrum.payment_identifier import PaymentIdentifierState, PaymentIdentifierType, PaymentIdentifier, \ |
|
|
|
|
invoice_from_payment_identifier, payment_identifier_from_invoice |
|
|
|
|
from electrum.payment_identifier import (PaymentIdentifierType, PaymentIdentifier, invoice_from_payment_identifier, |
|
|
|
|
payment_identifier_from_invoice) |
|
|
|
|
|
|
|
|
|
from .amountedit import AmountEdit, BTCAmountEdit, SizedFreezableLineEdit |
|
|
|
|
from .paytoedit import InvalidPaymentIdentifier |
|
|
|
|
from .util import (WaitingDialog, HelpLabel, MessageBoxMixin, EnterButton, |
|
|
|
|
char_width_in_lineedit, get_iconname_camera, get_iconname_qrcode, |
|
|
|
|
read_QIcon, ColorScheme, icon_path) |
|
|
|
|
from .util import (WaitingDialog, HelpLabel, MessageBoxMixin, EnterButton, char_width_in_lineedit, |
|
|
|
|
get_iconname_camera, read_QIcon, ColorScheme, icon_path) |
|
|
|
|
from .confirm_tx_dialog import ConfirmTxDialog |
|
|
|
|
from .invoice_list import InvoiceList |
|
|
|
|
|
|
|
|
|
@ -216,7 +215,8 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
pi_error = pi.is_error() if pi.is_valid() else False |
|
|
|
|
is_spk_script = pi.type == PaymentIdentifierType.SPK and not pi.spk_is_address |
|
|
|
|
valid_amount = is_spk_script or bool(self.amount_e.get_amount()) |
|
|
|
|
self.send_button.setEnabled(pi.is_valid() and not pi_error and valid_amount) |
|
|
|
|
ready_to_finalize = not pi.need_resolve() |
|
|
|
|
self.send_button.setEnabled(pi.is_valid() and not pi_error and valid_amount and ready_to_finalize) |
|
|
|
|
|
|
|
|
|
def do_paste(self): |
|
|
|
|
self.logger.debug('do_paste') |
|
|
|
|
@ -393,7 +393,8 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
if validated is not None: |
|
|
|
|
w.setStyleSheet(ColorScheme.GREEN.as_stylesheet(True) if validated else ColorScheme.RED.as_stylesheet(True)) |
|
|
|
|
|
|
|
|
|
def lock_fields(self, *, |
|
|
|
|
def lock_fields( |
|
|
|
|
self, *, |
|
|
|
|
lock_recipient: Optional[bool] = None, |
|
|
|
|
lock_amount: Optional[bool] = None, |
|
|
|
|
lock_max: Optional[bool] = None, |
|
|
|
|
@ -417,7 +418,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
|
|
|
|
|
if pi.is_multiline(): |
|
|
|
|
self.lock_fields(lock_recipient=False, lock_amount=True, lock_max=True, lock_description=False) |
|
|
|
|
self.set_field_validated(self.payto_e, validated=pi.is_valid()) # TODO: validated used differently here than openalias |
|
|
|
|
self.set_field_validated(self.payto_e, validated=pi.is_valid()) # TODO: validated used differently here than openalias |
|
|
|
|
self.save_button.setEnabled(pi.is_valid()) |
|
|
|
|
self.send_button.setEnabled(pi.is_valid()) |
|
|
|
|
self.payto_e.setToolTip(pi.get_error() if not pi.is_valid() else '') |
|
|
|
|
@ -453,13 +454,13 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
for w in [self.comment_e, self.comment_label]: |
|
|
|
|
w.setVisible(bool(fields.comment)) |
|
|
|
|
if fields.comment: |
|
|
|
|
self.comment_e.setToolTip(_('Max comment length: %d characters') % fields.comment) |
|
|
|
|
self.comment_e.setToolTip(_('Max comment length: {} characters').format(fields.comment)) |
|
|
|
|
self.set_field_validated(self.payto_e, validated=fields.validated) |
|
|
|
|
|
|
|
|
|
# LNURLp amount range |
|
|
|
|
if fields.amount_range: |
|
|
|
|
amin, amax = fields.amount_range |
|
|
|
|
self.amount_e.setToolTip(_('Amount must be between %d and %d sat.') % (amin, amax)) |
|
|
|
|
self.amount_e.setToolTip(_('Amount must be between {} and {} sat.').format(amin, amax)) |
|
|
|
|
else: |
|
|
|
|
self.amount_e.setToolTip('') |
|
|
|
|
|
|
|
|
|
@ -467,7 +468,10 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
if not lock_max and self.amount_e.text() == '!': |
|
|
|
|
self.spend_max() |
|
|
|
|
|
|
|
|
|
pi_unusable = pi.is_error() or (not self.wallet.has_lightning() and not pi.is_onchain()) |
|
|
|
|
pi_unusable = pi.is_error() \ |
|
|
|
|
or (not self.wallet.has_lightning() and not pi.is_onchain()) \ |
|
|
|
|
or pi.need_resolve() |
|
|
|
|
self.logger.debug(f'usable? {not pi_unusable}') |
|
|
|
|
is_spk_script = pi.type == PaymentIdentifierType.SPK and not pi.spk_is_address |
|
|
|
|
|
|
|
|
|
amount_valid = is_spk_script or bool(self.amount_e.get_amount()) |
|
|
|
|
@ -821,7 +825,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger):
|
|
|
|
|
total = 0 |
|
|
|
|
for output in outputs: |
|
|
|
|
if parse_max_spend(output.value): |
|
|
|
|
self.max_button.setChecked(True) # TODO: remove and let spend_max set this? |
|
|
|
|
self.max_button.setChecked(True) # TODO: remove and let spend_max set this? |
|
|
|
|
self.spend_max() |
|
|
|
|
return |
|
|
|
|
else: |
|
|
|
|
|