Browse Source

qml: add support for ln address and openalias, fix lnurl finalize step,

avoid overloading invoiceParser with new payment identifiers while potentially long-running
resolve/finalize steps are ongoing, show errors inresolve/finalize steps to user.
master
Sander van Grieken 2 years ago committed by accumulator
parent
commit
03dd38bfb8
  1. 2
      electrum/gui/qml/components/WalletMainView.qml
  2. 58
      electrum/gui/qml/qeinvoice.py

2
electrum/gui/qml/components/WalletMainView.qml

@ -309,6 +309,7 @@ Item {
Layout.preferredWidth: 1
icon.source: '../../icons/tab_send.png'
text: qsTr('Send')
enabled: !invoiceParser.busy
onClicked: openSendDialog()
onPressAndHold: {
Config.userKnowsPressAndHold = true
@ -329,6 +330,7 @@ Item {
wallet: Daemon.currentWallet
onValidationError: (code, message) => {
var dialog = app.messageDialog.createObject(app, {
title: qsTr('Error'),
text: message
})
dialog.closed.connect(function() {

58
electrum/gui/qml/qeinvoice.py

@ -327,9 +327,9 @@ class QEInvoice(QObject, QtEventListener):
self.userinfo = {
PR_EXPIRED: _('This invoice has expired'),
PR_PAID: _('This invoice was already paid'),
PR_BROADCASTING: _('Payment in progress...') + ' (' + _('broadcasting') + ')',
PR_BROADCAST: _('Payment in progress...') + ' (' + _('broadcast successfully') + ')',
PR_UNCONFIRMED: _('Payment in progress...') + ' (' + _('waiting for confirmation') + ')',
PR_BROADCASTING: _('Payment in progress...') + ' (' + _('broadcasting') + ')',
PR_BROADCAST: _('Payment in progress...') + ' (' + _('broadcast successfully') + ')',
PR_UNCONFIRMED: _('Payment in progress...') + ' (' + _('waiting for confirmation') + ')',
PR_UNKNOWN: _('Invoice has unknown status'),
}[self.status]
@ -395,13 +395,15 @@ class QEInvoiceParser(QEInvoice):
_logger = get_logger(__name__)
validationSuccess = pyqtSignal()
validationWarning = pyqtSignal([str,str], arguments=['code', 'message'])
validationError = pyqtSignal([str,str], arguments=['code', 'message'])
validationWarning = pyqtSignal([str, str], arguments=['code', 'message'])
validationError = pyqtSignal([str, str], arguments=['code', 'message'])
invoiceCreateError = pyqtSignal([str,str], arguments=['code', 'message'])
invoiceCreateError = pyqtSignal([str, str], arguments=['code', 'message'])
lnurlRetrieved = pyqtSignal()
lnurlError = pyqtSignal([str,str], arguments=['code', 'message'])
lnurlError = pyqtSignal([str, str], arguments=['code', 'message'])
busyChanged = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
@ -409,6 +411,7 @@ class QEInvoiceParser(QEInvoice):
self._recipient = ''
self._pi = None
self._lnurlData = None
self._busy = False
self.clear()
@ -434,6 +437,10 @@ class QEInvoiceParser(QEInvoice):
def isLnurlPay(self):
return self._lnurlData is not None
@pyqtProperty(bool, notify=busyChanged)
def busy(self):
return self._busy
@pyqtSlot()
def clear(self):
self.recipient = ''
@ -492,7 +499,9 @@ class QEInvoiceParser(QEInvoice):
self._pi = PaymentIdentifier(self._wallet.wallet, recipient)
if not self._pi.is_valid() or self._pi.type not in [PaymentIdentifierType.SPK, PaymentIdentifierType.BIP21,
PaymentIdentifierType.BIP70, PaymentIdentifierType.BOLT11,
PaymentIdentifierType.LNURLP]:
PaymentIdentifierType.LNURLP,
PaymentIdentifierType.EMAILLIKE,
PaymentIdentifierType.DOMAINLIKE]:
self.validationError.emit('unknown', _('Unknown invoice'))
return
@ -509,7 +518,7 @@ class QEInvoiceParser(QEInvoice):
self.resolve_pi()
return
if self._pi.type == PaymentIdentifierType.LNURLP:
if self._pi.type in [PaymentIdentifierType.LNURLP, PaymentIdentifierType.LNADDR]:
self.on_lnurl(self._pi.lnurl_data)
return
@ -518,7 +527,7 @@ class QEInvoiceParser(QEInvoice):
return
if self._pi.is_available():
if self._pi.type == PaymentIdentifierType.SPK:
if self._pi.type in [PaymentIdentifierType.SPK, PaymentIdentifierType.OPENALIAS]:
outputs = [PartialTxOutput(scriptpubkey=self._pi.spk, value=0)]
invoice = self.create_onchain_invoice(outputs, None, None, None)
self._logger.debug(repr(invoice))
@ -563,11 +572,25 @@ class QEInvoiceParser(QEInvoice):
assert self._pi.need_resolve()
def on_finished(pi):
self._busy = False
self.busyChanged.emit()
if pi.is_error():
pass
if pi.type in [PaymentIdentifierType.EMAILLIKE, PaymentIdentifierType.DOMAINLIKE]:
msg = _('Could not resolve address')
elif pi.type == PaymentIdentifierType.LNURLP:
msg = _('Could not resolve LNURL')
elif pi.type == PaymentIdentifierType.BIP70:
msg = _('Could not resolve BIP70 payment request: {}').format(pi.error)
else:
msg = _('Could not resolve')
self.validationError.emit('resolve', msg)
else:
self._update_from_payment_identifier()
self._busy = True
self.busyChanged.emit()
self._pi.resolve(on_finished=on_finished)
def on_lnurl(self, lnurldata):
@ -576,7 +599,7 @@ class QEInvoiceParser(QEInvoice):
self._lnurlData = {
'domain': urlparse(lnurldata.callback_url).netloc,
'callback_url' : lnurldata.callback_url,
'callback_url': lnurldata.callback_url,
'min_sendable_sat': lnurldata.min_sendable_sat,
'max_sendable_sat': lnurldata.max_sendable_sat,
'metadata_plaintext': lnurldata.metadata_plaintext,
@ -598,6 +621,9 @@ class QEInvoiceParser(QEInvoice):
comment = None
def on_finished(pi):
self._busy = False
self.busyChanged.emit()
if pi.is_error():
if pi.state == PaymentIdentifierState.INVALID_AMOUNT:
self.lnurlError.emit('amount', pi.get_error())
@ -606,6 +632,9 @@ class QEInvoiceParser(QEInvoice):
else:
self.on_lnurl_invoice(self.amountOverride.satsInt, pi.bolt11)
self._busy = True
self.busyChanged.emit()
self._pi.finalize(amount_sat=amount, comment=comment, on_finished=on_finished)
def on_lnurl_invoice(self, orig_amount, invoice):
@ -613,11 +642,10 @@ class QEInvoiceParser(QEInvoice):
self._logger.debug(f'{repr(invoice)}')
# assure no shenanigans with the bolt11 invoice we get back
lninvoice = Invoice.from_bech32(invoice)
if orig_amount * 1000 != lninvoice.amount_msat: # TODO msat precision can cause trouble here
if orig_amount * 1000 != invoice.amount_msat: # TODO msat precision can cause trouble here
raise Exception('Unexpected amount in invoice, differs from lnurl-pay specified amount')
self.recipient = invoice
self.recipient = invoice.lightning_invoice
@pyqtSlot()
def saveInvoice(self):

Loading…
Cancel
Save