From 25d59e4142c7d8a0263ea69aea710fe9a76859c5 Mon Sep 17 00:00:00 2001 From: jackstar12 <62219658+jackstar12@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:37:28 +0100 Subject: [PATCH] feat: emulate behaviour of paid_invoices_stream for wallets that dont support it (#2071) --- lnbits/wallets/base.py | 22 +++++++++++++++++++--- lnbits/wallets/lnpay.py | 4 +++- lnbits/wallets/opennode.py | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lnbits/wallets/base.py b/lnbits/wallets/base.py index 2abc16cb..c416224f 100644 --- a/lnbits/wallets/base.py +++ b/lnbits/wallets/base.py @@ -1,8 +1,11 @@ from __future__ import annotations +import asyncio from abc import ABC, abstractmethod from typing import TYPE_CHECKING, AsyncGenerator, Coroutine, NamedTuple, Optional +from loguru import logger + if TYPE_CHECKING: from lnbits.nodes.base import Node @@ -93,6 +96,9 @@ class Wallet(ABC): __node_cls__: Optional[type[Node]] = None + def __init__(self) -> None: + self.pending_invoices: list[str] = [] + @abstractmethod async def cleanup(self): pass @@ -130,9 +136,19 @@ class Wallet(ABC): ) -> Coroutine[None, None, PaymentStatus]: pass - @abstractmethod - def paid_invoices_stream(self) -> AsyncGenerator[str, None]: - pass + async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: + while True: + for invoice in self.pending_invoices: + try: + status = await self.get_invoice_status(invoice) + if status.paid: + yield invoice + self.pending_invoices.remove(invoice) + elif status.failed: + self.pending_invoices.remove(invoice) + except Exception as exc: + logger.error(f"could not get status of invoice {invoice}: '{exc}' ") + await asyncio.sleep(5) def normalize_endpoint(self, endpoint: str, add_proto=True) -> str: endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint diff --git a/lnbits/wallets/lnpay.py b/lnbits/wallets/lnpay.py index 28842fcb..7d2cd559 100644 --- a/lnbits/wallets/lnpay.py +++ b/lnbits/wallets/lnpay.py @@ -28,6 +28,7 @@ class LNPayWallet(Wallet): if not settings.lnpay_api_key: raise ValueError("cannot initialize LNPayWallet: missing lnpay_api_key") + super().__init__() wallet_key = settings.lnpay_wallet_key or settings.lnpay_admin_key if not wallet_key: raise ValueError( @@ -35,7 +36,6 @@ class LNPayWallet(Wallet): "missing lnpay_wallet_key or lnpay_admin_key" ) self.wallet_key = wallet_key - self.endpoint = self.normalize_endpoint(settings.lnpay_api_endpoint) headers = { @@ -102,6 +102,8 @@ class LNPayWallet(Wallet): data = r.json() checking_id, payment_request = data["id"], data["payment_request"] + self.pending_invoices.append(checking_id) + return InvoiceResponse(ok, checking_id, payment_request, error_message) async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse: diff --git a/lnbits/wallets/opennode.py b/lnbits/wallets/opennode.py index 4e8f3a85..e4ac8936 100644 --- a/lnbits/wallets/opennode.py +++ b/lnbits/wallets/opennode.py @@ -25,6 +25,7 @@ class OpenNodeWallet(Wallet): raise ValueError( "cannot initialize OpenNodeWallet: missing opennode_api_endpoint" ) + super().__init__() key = ( settings.opennode_key or settings.opennode_admin_key @@ -92,6 +93,7 @@ class OpenNodeWallet(Wallet): data = r.json()["data"] checking_id = data["id"] payment_request = data["lightning_invoice"]["payreq"] + self.pending_invoices.append(checking_id) return InvoiceResponse(True, checking_id, payment_request, None) async def pay_invoice(self, bolt11: str, fee_limit_msat: int) -> PaymentResponse: