diff --git a/electrum/gui/qml/qeinvoice.py b/electrum/gui/qml/qeinvoice.py index fcf475865..fa92706aa 100644 --- a/electrum/gui/qml/qeinvoice.py +++ b/electrum/gui/qml/qeinvoice.py @@ -17,7 +17,7 @@ from electrum.lnurl import decode_lnurl, request_lnurl, callback_lnurl from electrum.bitcoin import COIN from electrum.paymentrequest import PaymentRequest from electrum.payment_identifier import (parse_bip21_URI, InvalidBitcoinURI, maybe_extract_lightning_payment_identifier, - PaymentIdentifier, PaymentIdentifierState) + PaymentIdentifier, PaymentIdentifierState, PaymentIdentifierType) from .qetypes import QEAmount from .qewallet import QEWallet @@ -491,7 +491,8 @@ class QEInvoiceParser(QEInvoice): return self._pi = PaymentIdentifier(self._wallet.wallet, recipient) - if not self._pi.is_valid() or self._pi.type not in ['spk', 'bip21', 'bip70', 'bolt11', 'lnurl']: + if not self._pi.is_valid() or self._pi.type not in [PaymentIdentifierType.SPK, PaymentIdentifierType.BIP21, + PaymentIdentifierType.BIP70, PaymentIdentifierType.BOLT11, PaymentIdentifierType.LNURLP]: self.validationError.emit('unknown', _('Unknown invoice')) return @@ -502,23 +503,23 @@ class QEInvoiceParser(QEInvoice): self.resolve_pi() return - if self._pi.type == 'lnurl': + if self._pi.type == PaymentIdentifierType.LNURLP: self.on_lnurl(self._pi.lnurl_data) return - if self._pi.type == 'bip70': + if self._pi.type == PaymentIdentifierType.BIP70: self._bip70_payment_request_resolved(self._pi.bip70_data) return if self._pi.is_available(): - if self._pi.type == 'spk': + if self._pi.type == PaymentIdentifierType.SPK: outputs = [PartialTxOutput(scriptpubkey=self._pi.spk, value=0)] invoice = self.create_onchain_invoice(outputs, None, None, None) self._logger.debug(repr(invoice)) self.setValidOnchainInvoice(invoice) self.validationSuccess.emit() return - elif self._pi.type == 'bolt11': + elif self._pi.type == PaymentIdentifierType.BOLT11: lninvoice = Invoice.from_bech32(self._pi.bolt11) if not self._wallet.wallet.has_lightning() and not lninvoice.get_address(): self.validationError.emit('no_lightning', @@ -530,7 +531,7 @@ class QEInvoiceParser(QEInvoice): self.setValidLightningInvoice(lninvoice) self.validationSuccess.emit() - elif self._pi.type == 'bip21': + elif self._pi.type == PaymentIdentifierType.BIP21: if self._wallet.wallet.has_lightning() and self._wallet.wallet.lnworker.channels and self._pi.bolt11: lninvoice = Invoice.from_bech32(self._pi.bolt11) self.setValidLightningInvoice(lninvoice) diff --git a/electrum/gui/qt/send_tab.py b/electrum/gui/qt/send_tab.py index 9c8b4bc49..7ee6cfcf8 100644 --- a/electrum/gui/qt/send_tab.py +++ b/electrum/gui/qt/send_tab.py @@ -16,7 +16,7 @@ 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 +from electrum.payment_identifier import PaymentIdentifierState, PaymentIdentifierType from .amountedit import AmountEdit, BTCAmountEdit, SizedFreezableLineEdit from .paytoedit import InvalidPaymentIdentifier @@ -206,7 +206,7 @@ class SendTab(QWidget, MessageBoxMixin, Logger): def spend_max(self): assert self.payto_e.payment_identifier is not None - assert self.payto_e.payment_identifier.type in ['spk', 'multiline'] + assert self.payto_e.payment_identifier.type in [PaymentIdentifierType.SPK, PaymentIdentifierType.MULTILINE] if run_hook('abort_send', self): return outputs = self.payto_e.payment_identifier.get_onchain_outputs('!') @@ -383,10 +383,10 @@ class SendTab(QWidget, MessageBoxMixin, Logger): self.send_button.setEnabled(False) return - lock_recipient = pi.type != 'spk' \ - and not (pi.type == 'emaillike' and pi.is_state(PaymentIdentifierState.NOT_FOUND)) + lock_recipient = pi.type != PaymentIdentifierType.SPK \ + and not (pi.type == PaymentIdentifierType.EMAILLIKE and pi.is_state(PaymentIdentifierState.NOT_FOUND)) lock_max = pi.is_amount_locked() \ - or pi.type in ['bolt11', 'lnurl', 'lightningaddress'] + or pi.type in [PaymentIdentifierType.BOLT11, PaymentIdentifierType.LNURLP, PaymentIdentifierType.LNADDR] self.lock_fields(lock_recipient=lock_recipient, lock_amount=pi.is_amount_locked(), lock_max=lock_max, diff --git a/electrum/payment_identifier.py b/electrum/payment_identifier.py index 4b9733b66..0f348809f 100644 --- a/electrum/payment_identifier.py +++ b/electrum/payment_identifier.py @@ -182,6 +182,17 @@ class PaymentIdentifierState(IntEnum): MERCHANT_ERROR = 52 # PI failed notifying the merchant after broadcasting onchain TX INVALID_AMOUNT = 53 # Specified amount not accepted +class PaymentIdentifierType(IntEnum): + UNKNOWN = 0 + SPK = 1 + BIP21 = 2 + BIP70 = 3 + MULTILINE = 4 + BOLT11 = 5 + LNURLP = 6 + EMAILLIKE = 7 + OPENALIAS = 8 + LNADDR = 9 class PaymentIdentifier(Logger): """ @@ -203,7 +214,7 @@ class PaymentIdentifier(Logger): self.contacts = wallet.contacts if wallet is not None else None self.config = wallet.config if wallet is not None else None self.text = text.strip() - self._type = None + self._type = PaymentIdentifierType.UNKNOWN self.error = None # if set, GUI should show error and stop self.warning = None # if set, GUI should ask user if they want to proceed # more than one of those may be set @@ -262,16 +273,16 @@ class PaymentIdentifier(Logger): return self.is_multiline() and self._is_max def is_amount_locked(self): - if self._type == 'spk': + if self._type == PaymentIdentifierType.SPK: return False - elif self._type == 'bip21': + elif self._type == PaymentIdentifierType.BIP21: return bool(self.bip21.get('amount')) - elif self._type == 'bip70': + elif self._type == PaymentIdentifierType.BIP70: return True # TODO always given? - elif self._type == 'bolt11': + elif self._type == PaymentIdentifierType.BOLT11: lnaddr = lndecode(self.bolt11) return bool(lnaddr.amount) - elif self._type == 'lnurl' or self._type == 'lightningaddress': + elif self._type in [PaymentIdentifierType.LNURLP, PaymentIdentifierType.LNADDR]: # amount limits known after resolve, might be specific amount or locked to range if self.need_resolve(): return True @@ -279,11 +290,11 @@ class PaymentIdentifier(Logger): self.logger.debug(f'lnurl f {self.lnurl_data.min_sendable_sat}-{self.lnurl_data.max_sendable_sat}') return not (self.lnurl_data.min_sendable_sat < self.lnurl_data.max_sendable_sat) return True - elif self._type == 'multiline': + elif self._type == PaymentIdentifierType.MULTILINE: return True - elif self._type == 'emaillike': + elif self._type == PaymentIdentifierType.EMAILLIKE: return False - elif self._type == 'openalias': + elif self._type == PaymentIdentifierType.OPENALIAS: return False def is_error(self) -> bool: @@ -298,7 +309,7 @@ class PaymentIdentifier(Logger): if not text: return if outputs := self._parse_as_multiline(text): - self._type = 'multiline' + self._type = PaymentIdentifierType.MULTILINE self.multiline_outputs = outputs if self.error: self.set_state(PaymentIdentifierState.INVALID) @@ -306,7 +317,7 @@ class PaymentIdentifier(Logger): self.set_state(PaymentIdentifierState.AVAILABLE) elif invoice_or_lnurl := maybe_extract_lightning_payment_identifier(text): if invoice_or_lnurl.startswith('lnurl'): - self._type = 'lnurl' + self._type = PaymentIdentifierType.LNURLP try: self.lnurl = decode_lnurl(invoice_or_lnurl) self.set_state(PaymentIdentifierState.NEED_RESOLVE) @@ -315,7 +326,7 @@ class PaymentIdentifier(Logger): self.set_state(PaymentIdentifierState.INVALID) return else: - self._type = 'bolt11' + self._type = PaymentIdentifierType.BOLT11 try: lndecode(invoice_or_lnurl) except LnInvoiceException as e: @@ -338,10 +349,10 @@ class PaymentIdentifier(Logger): self.bip21 = out self.bip70 = out.get('r') if self.bip70: - self._type = 'bip70' + self._type = PaymentIdentifierType.BIP70 self.set_state(PaymentIdentifierState.NEED_RESOLVE) else: - self._type = 'bip21' + self._type = PaymentIdentifierType.BIP21 # check optional lightning in bip21, set self.bolt11 if valid bolt11 = out.get('lightning') if bolt11: @@ -355,11 +366,11 @@ class PaymentIdentifier(Logger): self.logger.debug(_("Invoice requires unknown or incompatible Lightning feature") + f":\n{e!r}") self.set_state(PaymentIdentifierState.AVAILABLE) elif scriptpubkey := self.parse_output(text): - self._type = 'spk' + self._type = PaymentIdentifierType.SPK self.spk = scriptpubkey self.set_state(PaymentIdentifierState.AVAILABLE) elif re.match(RE_EMAIL, text): - self._type = 'emaillike' + self._type = PaymentIdentifierType.EMAILLIKE self.emaillike = text self.set_state(PaymentIdentifierState.NEED_RESOLVE) elif self.error is None: @@ -390,7 +401,7 @@ class PaymentIdentifier(Logger): 'security check, DNSSEC, and thus may not be correct.').format(self.emaillike) try: scriptpubkey = self.parse_output(address) - self._type = 'openalias' + self._type = PaymentIdentifierType.OPENALIAS self.spk = scriptpubkey self.set_state(PaymentIdentifierState.AVAILABLE) except Exception as e: @@ -400,7 +411,7 @@ class PaymentIdentifier(Logger): lnurl = lightning_address_to_url(self.emaillike) try: data = await request_lnurl(lnurl) - self._type = 'lightningaddress' + self._type = PaymentIdentifierType.LNADDR self.lnurl = lnurl self.lnurl_data = data self.set_state(PaymentIdentifierState.LNURLP_FINALIZE) diff --git a/electrum/x509.py b/electrum/x509.py index f0da646f6..68cf92b94 100644 --- a/electrum/x509.py +++ b/electrum/x509.py @@ -308,8 +308,7 @@ class X509(object): raise CertificateError('Certificate has not entered its valid date range. (%s)' % self.get_common_name()) if self.notAfter <= now: dt = datetime.utcfromtimestamp(time.mktime(self.notAfter)) - # for testnet - #raise CertificateError(f'Certificate ({self.get_common_name()}) has expired (at {dt} UTC).') + raise CertificateError(f'Certificate ({self.get_common_name()}) has expired (at {dt} UTC).') def getFingerprint(self): return hashlib.sha1(self.bytes).digest()