From 79c3d7526e1bd6bb8329624a0baa49f7021993d2 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Fri, 19 Jun 2026 18:02:54 +0300 Subject: [PATCH] feat: partial work --- lnbits/core/services/payments.py | 16 ++++++++++++++++ lnbits/wallets/base.py | 1 + lnbits/wallets/lnbits.py | 22 ++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lnbits/core/services/payments.py b/lnbits/core/services/payments.py index 52574028c..a2a7dd6db 100644 --- a/lnbits/core/services/payments.py +++ b/lnbits/core/services/payments.py @@ -129,6 +129,15 @@ async def create_fiat_invoice( if not fiat_provider_name: raise ValueError("Fiat provider is required for fiat invoices.") if not settings.is_fiat_provider_enabled(fiat_provider_name): + funding_source = get_funding_source() + if funding_source.__class__.__name__ == "LNbitsWallet": + fiat_invoice = await create_wallet_invoice(wallet_id, invoice_data) + fiat_invoice.fiat_provider = fiat_provider_name + fiat_invoice.extra["fiat_checking_id"] = fiat_invoice.checking_id + # TODO: move to payment + fiat_invoice.extra["fiat_payment_request"] = fiat_invoice.payment_request + + return fiat_invoice raise ValueError( f"Fiat provider '{fiat_provider_name}' is not enabled.", ) @@ -219,6 +228,7 @@ async def create_wallet_invoice(wallet_id: str, data: CreateInvoice) -> Payment: payment_hash=data.payment_hash, labels=data.labels, external_id=data.external_id, + fiat_provider=data.fiat_provider, conn=conn, ) @@ -261,6 +271,7 @@ async def create_invoice( payment_hash: str | None = None, labels: list[str] | None = None, external_id: str | None = None, + fiat_provider: str | None = None, conn: Connection | None = None, ) -> Payment: if not amount > 0: @@ -321,6 +332,9 @@ async def create_invoice( description_hash=description_hash, unhashed_description=unhashed_description, expiry=expiry or settings.lightning_invoice_expiry, + fiat_provider=fiat_provider, + currency=currency if currency != "sat" else None, + fiat_amount=amount if currency != "sat" else None, ) if ( not invoice_response.ok @@ -332,6 +346,8 @@ async def create_invoice( status="pending", ) invoice = bolt11_decode(invoice_response.payment_request) + extra["fiat_provider"] = fiat_provider + extra["fiat_payment_request"] = invoice_response.fiat_payment_request create_payment_model = CreatePayment( wallet_id=user_wallet.source_wallet_id, diff --git a/lnbits/wallets/base.py b/lnbits/wallets/base.py index 4d1d81b95..980f47850 100644 --- a/lnbits/wallets/base.py +++ b/lnbits/wallets/base.py @@ -30,6 +30,7 @@ class InvoiceResponse(NamedTuple): ok: bool checking_id: str | None = None # payment_hash, rpc_id payment_request: str | None = None + fiat_payment_request: str | None = None error_message: str | None = None preimage: str | None = None fee_msat: int | None = None diff --git a/lnbits/wallets/lnbits.py b/lnbits/wallets/lnbits.py index c14a41706..5a7428786 100644 --- a/lnbits/wallets/lnbits.py +++ b/lnbits/wallets/lnbits.py @@ -78,17 +78,28 @@ class LNbitsWallet(Wallet): data: dict = {"out": False, "amount": amount, "memo": memo or ""} if kwargs.get("expiry"): data["expiry"] = kwargs["expiry"] + if kwargs.get("fiat_provider"): + if "currency" not in kwargs or "fiat_amount" not in kwargs: + return InvoiceResponse( + ok=False, + error_message="Fiat provider requires " + "'currency' and 'fiat_amount' parameters.", + ) + data["amount"] = kwargs["fiat_amount"] + data["unit"] = kwargs["currency"] + data["fiat_provider"] = kwargs["fiat_provider"] + if description_hash: data["description_hash"] = description_hash.hex() if unhashed_description: data["unhashed_description"] = unhashed_description.hex() try: - r = await self.client.post(url="/api/v1/payments", json=data) + print(f"Creating invoice with data: {data}") + r = await self.client.post(url="/api/v1/payments", json=data, timeout=30) r.raise_for_status() data = r.json() - # Backwards compatibility for pre-v1 which used the key "payment_request" payment_str = data.get("bolt11") or data.get("payment_request") if r.is_error or not payment_str: error_message = data["detail"] if "detail" in data else r.text @@ -100,6 +111,7 @@ class LNbitsWallet(Wallet): ok=True, checking_id=data["checking_id"], payment_request=payment_str, + fiat_payment_request=data.get("payment_request"), preimage=data.get("preimage"), ) except json.JSONDecodeError: @@ -111,6 +123,11 @@ class LNbitsWallet(Wallet): return InvoiceResponse( ok=False, error_message="Server error: 'missing required fields'" ) + except httpx.HTTPStatusError as exc: + logger.warning(exc.response.text) + return InvoiceResponse( + ok=False, error_message=f"Unable to connect to {self.endpoint}." + ) except Exception as exc: logger.warning(exc) return InvoiceResponse( @@ -213,6 +230,7 @@ class LNbitsWallet(Wallet): logger.info("connected to LNbits fundingsource websocket.") while settings.lnbits_running: message = await ws.recv() + print(f"### Received message from websocket: {message}") message_dict = json.loads(message) if ( message_dict