payment identifier types as enum
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user