Core: add internal flag for invoice creation to use FakeWallet (#646)

* add internal flag for invoice creation to use FakeWallet
This commit is contained in:
calle 2022-07-17 14:34:25 +02:00 committed by GitHub
parent d4c30a1091
commit 6646fce549
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 12 deletions

View File

@ -14,7 +14,7 @@ from lnbits import bolt11
from lnbits.db import Connection from lnbits.db import Connection
from lnbits.helpers import url_for, urlsafe_short_hash from lnbits.helpers import url_for, urlsafe_short_hash
from lnbits.requestvars import g 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 lnbits.wallets.base import PaymentResponse, PaymentStatus
from . import db from . import db
@ -49,15 +49,19 @@ async def create_invoice(
description_hash: Optional[bytes] = None, description_hash: Optional[bytes] = None,
extra: Optional[Dict] = None, extra: Optional[Dict] = None,
webhook: Optional[str] = None, webhook: Optional[str] = None,
internal: Optional[bool] = False,
conn: Optional[Connection] = None, conn: Optional[Connection] = None,
) -> Tuple[str, str]: ) -> Tuple[str, str]:
invoice_memo = None if description_hash else memo 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 amount=amount, memo=invoice_memo, description_hash=description_hash
) )
if not ok: if not ok:
raise InvoiceFailure(error_message or "Unexpected backend error.") raise InvoiceFailure(error_message or "unexpected backend error.")
invoice = bolt11.decode(payment_request) invoice = bolt11.decode(payment_request)

View File

@ -49,7 +49,8 @@
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5> <h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<code <code
>{"out": false, "amount": &lt;int&gt;, "memo": &lt;string&gt;, "unit": >{"out": false, "amount": &lt;int&gt;, "memo": &lt;string&gt;, "unit":
&lt;string&gt;, "webhook": &lt;url:string&gt;}</code &lt;string&gt;, "webhook": &lt;url:string&gt;, "internal":
&lt;bool&gt;}</code
> >
<h5 class="text-caption q-mt-sm q-mb-none"> <h5 class="text-caption q-mt-sm q-mb-none">
Returns 201 CREATED (application/json) Returns 201 CREATED (application/json)

View File

@ -147,6 +147,7 @@ class CreateInvoiceData(BaseModel):
lnurl_balance_check: Optional[str] = None lnurl_balance_check: Optional[str] = None
extra: Optional[dict] = None extra: Optional[dict] = None
webhook: Optional[str] = None webhook: Optional[str] = None
internal: Optional[bool] = False
bolt11: Optional[str] = None bolt11: Optional[str] = None
@ -173,6 +174,7 @@ async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
description_hash=description_hash, description_hash=description_hash,
extra=data.extra, extra=data.extra,
webhook=data.webhook, webhook=data.webhook,
internal=data.internal,
conn=conn, conn=conn,
) )
except InvoiceFailure as e: except InvoiceFailure as e:

View File

@ -51,6 +51,7 @@ LNBITS_THEME_OPTIONS: List[str] = env.list(
LNBITS_CUSTOM_LOGO = env.str("LNBITS_CUSTOM_LOGO", default="") LNBITS_CUSTOM_LOGO = env.str("LNBITS_CUSTOM_LOGO", default="")
WALLET = wallet_class() WALLET = wallet_class()
FAKE_WALLET = getattr(wallets_module, "FakeWallet")()
DEFAULT_WALLET_NAME = env.str("LNBITS_DEFAULT_WALLET_NAME", default="LNbits wallet") DEFAULT_WALLET_NAME = env.str("LNBITS_DEFAULT_WALLET_NAME", default="LNbits wallet")
PREFER_SECURE_URLS = env.bool("LNBITS_FORCE_HTTPS", default=True) PREFER_SECURE_URLS = env.bool("LNBITS_FORCE_HTTPS", default=True)

View File

@ -5,6 +5,7 @@ from datetime import datetime
from os import getenv from os import getenv
from typing import AsyncGenerator, Dict, Optional from typing import AsyncGenerator, Dict, Optional
from environs import Env # type: ignore
from loguru import logger from loguru import logger
from lnbits.helpers import urlsafe_short_hash from lnbits.helpers import urlsafe_short_hash
@ -18,6 +19,9 @@ from .base import (
Wallet, Wallet,
) )
env = Env()
env.read_env()
class FakeWallet(Wallet): class FakeWallet(Wallet):
async def status(self) -> StatusResponse: async def status(self) -> StatusResponse:
@ -32,7 +36,9 @@ class FakeWallet(Wallet):
memo: Optional[str] = None, memo: Optional[str] = None,
description_hash: Optional[bytes] = None, description_hash: Optional[bytes] = None,
) -> InvoiceResponse: ) -> 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 = { data: Dict = {
"out": False, "out": False,
"amount": amount, "amount": amount,

View File

@ -25,13 +25,32 @@ async def test_create_invoice(client, inkey_headers_to):
response = await client.post( response = await client.post(
"/api/v1/payments", json=data, headers=inkey_headers_to "/api/v1/payments", json=data, headers=inkey_headers_to
) )
assert response.status_code < 300 assert response.status_code == 201
assert "payment_hash" in response.json() invoice = response.json()
assert len(response.json()["payment_hash"]) == 64 assert "payment_hash" in invoice
assert "payment_request" in response.json() assert len(invoice["payment_hash"]) == 64
assert "checking_id" in response.json() assert "payment_request" in invoice
assert len(response.json()["checking_id"]) assert "checking_id" in invoice
return response.json() 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 # check POST /api/v1/payments: make payment