From 6646fce549fe0123bd1fbf0e6adb8ea9e3676b8a Mon Sep 17 00:00:00 2001 From: calle <93376500+callebtc@users.noreply.github.com> Date: Sun, 17 Jul 2022 14:34:25 +0200 Subject: [PATCH] Core: add internal flag for invoice creation to use FakeWallet (#646) * add internal flag for invoice creation to use FakeWallet --- lnbits/core/services.py | 10 ++++--- lnbits/core/templates/core/_api_docs.html | 3 ++- lnbits/core/views/api.py | 2 ++ lnbits/settings.py | 1 + lnbits/wallets/fake.py | 8 +++++- tests/core/views/test_api.py | 33 ++++++++++++++++++----- 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/lnbits/core/services.py b/lnbits/core/services.py index 84bc98e3b..da0e5a446 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -14,7 +14,7 @@ from lnbits import bolt11 from lnbits.db import Connection from lnbits.helpers import url_for, urlsafe_short_hash from lnbits.requestvars import g -from lnbits.settings import WALLET +from lnbits.settings import FAKE_WALLET, WALLET from lnbits.wallets.base import PaymentResponse, PaymentStatus from . import db @@ -49,15 +49,19 @@ async def create_invoice( description_hash: Optional[bytes] = None, extra: Optional[Dict] = None, webhook: Optional[str] = None, + internal: Optional[bool] = False, conn: Optional[Connection] = None, ) -> Tuple[str, str]: invoice_memo = None if description_hash else memo - ok, checking_id, payment_request, error_message = await WALLET.create_invoice( + # use the fake wallet if the invoice is for internal use only + wallet = FAKE_WALLET if internal else WALLET + + ok, checking_id, payment_request, error_message = await wallet.create_invoice( amount=amount, memo=invoice_memo, description_hash=description_hash ) if not ok: - raise InvoiceFailure(error_message or "Unexpected backend error.") + raise InvoiceFailure(error_message or "unexpected backend error.") invoice = bolt11.decode(payment_request) diff --git a/lnbits/core/templates/core/_api_docs.html b/lnbits/core/templates/core/_api_docs.html index 271568d44..383f2b121 100644 --- a/lnbits/core/templates/core/_api_docs.html +++ b/lnbits/core/templates/core/_api_docs.html @@ -49,7 +49,8 @@
Body (application/json)
{"out": false, "amount": <int>, "memo": <string>, "unit": - <string>, "webhook": <url:string>}
Returns 201 CREATED (application/json) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index f5b580414..198b00098 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -147,6 +147,7 @@ class CreateInvoiceData(BaseModel): lnurl_balance_check: Optional[str] = None extra: Optional[dict] = None webhook: Optional[str] = None + internal: Optional[bool] = False bolt11: Optional[str] = None @@ -173,6 +174,7 @@ async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet): description_hash=description_hash, extra=data.extra, webhook=data.webhook, + internal=data.internal, conn=conn, ) except InvoiceFailure as e: diff --git a/lnbits/settings.py b/lnbits/settings.py index efa0b8d50..5778b9e23 100644 --- a/lnbits/settings.py +++ b/lnbits/settings.py @@ -51,6 +51,7 @@ LNBITS_THEME_OPTIONS: List[str] = env.list( LNBITS_CUSTOM_LOGO = env.str("LNBITS_CUSTOM_LOGO", default="") WALLET = wallet_class() +FAKE_WALLET = getattr(wallets_module, "FakeWallet")() DEFAULT_WALLET_NAME = env.str("LNBITS_DEFAULT_WALLET_NAME", default="LNbits wallet") PREFER_SECURE_URLS = env.bool("LNBITS_FORCE_HTTPS", default=True) diff --git a/lnbits/wallets/fake.py b/lnbits/wallets/fake.py index ff64bd613..9dd5556bd 100644 --- a/lnbits/wallets/fake.py +++ b/lnbits/wallets/fake.py @@ -5,6 +5,7 @@ from datetime import datetime from os import getenv from typing import AsyncGenerator, Dict, Optional +from environs import Env # type: ignore from loguru import logger from lnbits.helpers import urlsafe_short_hash @@ -18,6 +19,9 @@ from .base import ( Wallet, ) +env = Env() +env.read_env() + class FakeWallet(Wallet): async def status(self) -> StatusResponse: @@ -32,7 +36,9 @@ class FakeWallet(Wallet): memo: Optional[str] = None, description_hash: Optional[bytes] = None, ) -> InvoiceResponse: - secret = getenv("FAKE_WALLET_SECRET") + # we set a default secret since FakeWallet is used for internal=True invoices + # and the user might not have configured a secret yet + secret = env.str("FAKE_WALLET_SECTRET", default="ToTheMoon1") data: Dict = { "out": False, "amount": amount, diff --git a/tests/core/views/test_api.py b/tests/core/views/test_api.py index 726709022..10e659aa4 100644 --- a/tests/core/views/test_api.py +++ b/tests/core/views/test_api.py @@ -25,13 +25,32 @@ async def test_create_invoice(client, inkey_headers_to): response = await client.post( "/api/v1/payments", json=data, headers=inkey_headers_to ) - assert response.status_code < 300 - assert "payment_hash" in response.json() - assert len(response.json()["payment_hash"]) == 64 - assert "payment_request" in response.json() - assert "checking_id" in response.json() - assert len(response.json()["checking_id"]) - return response.json() + assert response.status_code == 201 + invoice = response.json() + assert "payment_hash" in invoice + assert len(invoice["payment_hash"]) == 64 + assert "payment_request" in invoice + assert "checking_id" in invoice + assert len(invoice["checking_id"]) + return invoice + + +# check POST /api/v1/payments: invoice creation for internal payments only +@pytest.mark.asyncio +async def test_create_internal_invoice(client, inkey_headers_to): + data = await get_random_invoice_data() + data["internal"] = True + response = await client.post( + "/api/v1/payments", json=data, headers=inkey_headers_to + ) + invoice = response.json() + assert response.status_code == 201 + assert "payment_hash" in invoice + assert len(invoice["payment_hash"]) == 64 + assert "payment_request" in invoice + assert "checking_id" in invoice + assert len(invoice["checking_id"]) + return invoice # check POST /api/v1/payments: make payment