diff --git a/electrum/commands.py b/electrum/commands.py index a71acde91..bb85fe370 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -58,6 +58,7 @@ from .lnpeer import channel_id_from_funding_tx from .plugin import run_hook from .version import ELECTRUM_VERSION from .simple_config import SimpleConfig +from .lnaddr import parse_lightning_invoice if TYPE_CHECKING: @@ -981,6 +982,10 @@ class Commands: password=password) return chan.funding_outpoint.to_str() + @command('') + async def decode_invoice(self, invoice): + return parse_lightning_invoice(invoice) + @command('wn') async def lnpay(self, invoice, attempts=1, timeout=10, wallet: Abstract_Wallet = None): lnworker = wallet.lnworker diff --git a/electrum/gui/kivy/uix/screens.py b/electrum/gui/kivy/uix/screens.py index 75de262e4..3bc6927a7 100644 --- a/electrum/gui/kivy/uix/screens.py +++ b/electrum/gui/kivy/uix/screens.py @@ -33,7 +33,7 @@ from electrum.util import (parse_URI, InvalidBitcoinURI, PR_PAID, PR_UNKNOWN, PR from electrum.plugin import run_hook from electrum.wallet import InternalAddressCorruption from electrum import simple_config -from electrum.lnaddr import lndecode +from electrum.lnaddr import lndecode, parse_lightning_invoice from electrum.lnutil import RECEIVED, SENT, PaymentFailure from .dialogs.question import Question @@ -299,7 +299,7 @@ class SendScreen(CScreen): return message = self.message if self.is_lightning: - return self.app.wallet.lnworker.parse_bech32_invoice(address) + return parse_lightning_invoice(address) else: # on-chain if self.payment_request: outputs = self.payment_request.get_outputs() diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index 3db2bbb9f..eb9040d8f 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -76,6 +76,7 @@ from electrum.logging import Logger from electrum.util import PR_PAID, PR_FAILED from electrum.util import pr_expiration_values from electrum.lnutil import ln_dummy_address +from electrum.lnaddr import parse_lightning_invoice from .exception_window import Exception_Hook from .amountedit import AmountEdit, BTCAmountEdit, FreezableLineEdit, FeerateEdit @@ -1492,7 +1493,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger): if not self.wallet.lnworker: self.show_error(_('Lightning is disabled')) return - invoice_dict = self.wallet.lnworker.parse_bech32_invoice(invoice) + invoice_dict = parse_lightning_invoice(invoice) if invoice_dict.get('amount') is None: amount = self.amount_e.get_amount() if amount: diff --git a/electrum/lnaddr.py b/electrum/lnaddr.py index a10054055..ace941db7 100644 --- a/electrum/lnaddr.py +++ b/electrum/lnaddr.py @@ -13,6 +13,8 @@ from .bitcoin import hash160_to_b58_address, b58_address_to_hash160 from .segwit_addr import bech32_encode, bech32_decode, CHARSET from . import constants from . import ecc +from .util import PR_TYPE_LN +from .bitcoin import COIN # BOLT #11: @@ -307,6 +309,11 @@ class LnAddr(object): class LnDecodeException(Exception): pass +class SerializableKey: + def __init__(self, pubkey): + self.pubkey = pubkey + def serialize(self): + return self.pubkey.get_public_key_bytes(True) def lndecode(invoice: str, *, verbose=False, expected_hrp=None) -> LnAddr: if expected_hrp is None: @@ -460,11 +467,22 @@ def lndecode(invoice: str, *, verbose=False, expected_hrp=None) -> LnAddr: return addr -class SerializableKey: - def __init__(self, pubkey): - self.pubkey = pubkey - def serialize(self): - return self.pubkey.get_public_key_bytes(True) + + + +def parse_lightning_invoice(invoice): + lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP) + amount = int(lnaddr.amount * COIN) if lnaddr.amount else None + return { + 'type': PR_TYPE_LN, + 'invoice': invoice, + 'amount': amount, + 'message': lnaddr.get_description(), + 'time': lnaddr.date, + 'exp': lnaddr.get_expiry(), + 'pubkey': lnaddr.pubkey.serialize().hex(), + 'rhash': lnaddr.paymenthash.hex(), + } if __name__ == '__main__': # run using diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 709aaee95..e73ae7ebc 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -529,20 +529,6 @@ class LNWallet(LNWorker): out[k].append(v) return out - def parse_bech32_invoice(self, invoice): - lnaddr = lndecode(invoice, expected_hrp=constants.net.SEGWIT_HRP) - amount = int(lnaddr.amount * COIN) if lnaddr.amount else None - return { - 'type': PR_TYPE_LN, - 'invoice': invoice, - 'amount': amount, - 'message': lnaddr.get_description(), - 'time': lnaddr.date, - 'exp': lnaddr.get_expiry(), - 'pubkey': bh2u(lnaddr.pubkey.serialize()), - 'rhash': lnaddr.paymenthash.hex(), - } - def get_lightning_history(self): out = {} for key, plist in self.get_settled_payments().items():