Browse Source

Qt: add bolt11_fallback and bip21_lightning options to preferences

patch-4
ThomasV 3 years ago
parent
commit
ba018c707f
  1. 15
      electrum/gui/qt/main_window.py
  2. 19
      electrum/gui/qt/settings_dialog.py
  3. 13
      electrum/invoices.py
  4. 12
      electrum/util.py
  5. 3
      electrum/wallet.py

15
electrum/gui/qt/main_window.py

@ -1268,11 +1268,11 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
def show_receive_request(self, req):
addr = req.get_address() or ''
URI = req.get_bip21_URI() if addr else ''
lnaddr = req.lightning_invoice or ''
can_receive_lightning = self.wallet.lnworker and req.get_amount_sat() <= self.wallet.lnworker.num_sats_can_receive()
if not can_receive_lightning:
lnaddr = ''
lnaddr = req.lightning_invoice if can_receive_lightning else None
bip21_lightning = lnaddr if self.config.get('bip21_lightning', False) else None
URI = req.get_bip21_URI(lightning=bip21_lightning)
lnaddr = lnaddr or ''
icon_name = "lightning.png" if can_receive_lightning else "lightning_disconnected.png"
self.receive_tabs.setTabIcon(2, read_QIcon(icon_name))
# encode lightning invoices as uppercase so QR encoding can use
@ -1673,7 +1673,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
choices = {}
if can_pay_onchain:
msg = ''.join([
_('Pay this invoice onchain'), '\n',
_('Pay onchain'), '\n',
_('Funds will be sent to the invoice fallback address.')
])
choices[0] = msg
@ -1694,7 +1694,6 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
msg = _('You cannot pay that invoice using Lightning.')
if self.wallet.lnworker.channels:
msg += '\n' + _('Your channels can send {}.').format(self.format_amount(num_sats_can_send) + self.base_unit())
r = self.query_choice(msg, choices)
if r is not None:
self.save_pending_invoice()
@ -2162,6 +2161,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
amount = out.get('amount')
label = out.get('label')
message = out.get('message')
lightning = out.get('lightning')
if lightning:
self.set_ln_invoice(lightning)
return
# use label as description (not BIP21 compliant)
if label and not message:
message = label

19
electrum/gui/qt/settings_dialog.py

@ -97,6 +97,21 @@ class SettingsDialog(WindowModalDialog):
self.window.refresh_tabs()
nz.valueChanged.connect(on_nz)
# invoices
bolt11_fallback_cb = QCheckBox(_('Add on-chain fallback to lightning invoices'))
bolt11_fallback_cb.setChecked(bool(self.config.get('bolt11_fallback', True)))
bolt11_fallback_cb.setToolTip(_('Add fallback addresses to BOLT11 lightning invoices.'))
def on_bolt11_fallback(x):
self.config.set_key('bolt11_fallback', bool(x))
bolt11_fallback_cb.stateChanged.connect(on_bolt11_fallback)
bip21_lightning_cb = QCheckBox(_('Add lightning invoice to bitcoin URIs'))
bip21_lightning_cb.setChecked(bool(self.config.get('bip21_lightning', False)))
bip21_lightning_cb.setToolTip(_('This may create larger qr codes.'))
def on_bip21_lightning(x):
self.config.set_key('bip21_lightning', bool(x))
bip21_lightning_cb.stateChanged.connect(on_bip21_lightning)
use_rbf = bool(self.config.get('use_rbf', True))
use_rbf_cb = QCheckBox(_('Use Replace-By-Fee'))
use_rbf_cb.setChecked(use_rbf)
@ -483,6 +498,9 @@ class SettingsDialog(WindowModalDialog):
gui_widgets.append((nz_label, nz))
gui_widgets.append((msat_cb, None))
gui_widgets.append((thousandsep_cb, None))
invoices_widgets = []
invoices_widgets.append((bolt11_fallback_cb, None))
invoices_widgets.append((bip21_lightning_cb, None))
tx_widgets = []
tx_widgets.append((usechange_cb, None))
tx_widgets.append((use_rbf_cb, None))
@ -513,6 +531,7 @@ class SettingsDialog(WindowModalDialog):
tabs_info = [
(gui_widgets, _('Appearance')),
(invoices_widgets, _('Invoices')),
(tx_widgets, _('Transactions')),
(lightning_widgets, _('Lightning')),
(fiat_widgets, _('Fiat')),

13
electrum/invoices.py

@ -157,12 +157,21 @@ class Invoice(StoredObject):
return None
return int(amount_msat / 1000)
def get_bip21_URI(self):
def get_bip21_URI(self, lightning=None):
from electrum.util import create_bip21_uri
addr = self.get_address()
amount = int(self.get_amount_sat())
message = self.message
uri = create_bip21_uri(addr, amount, message)
extra = {}
if self.time and self.exp:
extra['time'] = str(self.time)
extra['exp'] = str(self.exp)
# only if we can receive
if lightning:
extra['lightning'] = lightning
if not addr and lightning:
return "bitcoin:?lightning="+lightning
uri = create_bip21_uri(addr, amount, message, extra_query_params=extra)
return str(uri)
@lightning_invoice.validator

12
electrum/util.py

@ -942,6 +942,7 @@ def parse_URI(uri: str, on_pr: Callable = None, *, loop=None) -> dict:
"""Raises InvalidBitcoinURI on malformed URI."""
from . import bitcoin
from .bitcoin import COIN, TOTAL_COIN_SUPPLY_LIMIT_IN_BTC
from .lnaddr import lndecode
if not isinstance(uri, str):
raise InvalidBitcoinURI(f"expected string, not {repr(uri)}")
@ -1004,6 +1005,17 @@ def parse_URI(uri: str, on_pr: Callable = None, *, loop=None) -> dict:
out['sig'] = bh2u(bitcoin.base_decode(out['sig'], base=58))
except Exception as e:
raise InvalidBitcoinURI(f"failed to parse 'sig' field: {repr(e)}") from e
if 'lightning' in out:
try:
lnaddr = lndecode(out['lightning'])
amount_sat = out.get('amount')
if amount:
assert int(lnaddr.get_amount_sat()) == amount_sat
address = out.get('address')
if address:
assert lnaddr.get_fallback_address() == address
except Exception as e:
raise InvalidBitcoinURI(f"Inconsistent lightning field: {repr(e)}") from e
r = out.get('r')
sig = out.get('sig')

3
electrum/wallet.py

@ -2348,7 +2348,8 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
amount_sat = amount_sat or 0
exp_delay = exp_delay or 0
timestamp = int(time.time())
lightning_invoice = self.lnworker.add_request(amount_sat, message, exp_delay) if lightning else None
fallback_address = address if self.config.get('bolt11_fallback', True) else None
lightning_invoice = self.lnworker.add_request(amount_sat, message, exp_delay, fallback_address) if lightning else None
outputs = [ PartialTxOutput.from_address_and_value(address, amount_sat)] if address else []
height = self.get_local_height()
req = Invoice(

Loading…
Cancel
Save