From a5c0a2bb5078da5d767a27ed1bb3cebecd03e3cc Mon Sep 17 00:00:00 2001 From: Stefan Stammberger Date: Sun, 19 Sep 2021 13:34:31 +0200 Subject: [PATCH] fix: offlineshop ext lnurl handling --- lnbits/extensions/offlineshop/lnurl.py | 13 +++++++------ lnbits/extensions/offlineshop/models.py | 8 +++++++- lnbits/extensions/offlineshop/views.py | 17 ++++++++++------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lnbits/extensions/offlineshop/lnurl.py b/lnbits/extensions/offlineshop/lnurl.py index 72ef2a42..b04d8512 100644 --- a/lnbits/extensions/offlineshop/lnurl.py +++ b/lnbits/extensions/offlineshop/lnurl.py @@ -1,4 +1,5 @@ import hashlib +from lnbits.extensions.offlineshop.models import Item from fastapi.params import Query from starlette.requests import Request @@ -13,8 +14,8 @@ from .crud import get_shop, get_item @offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response") -async def lnurl_response(item_id: int = Query(...)): - item = await get_item(item_id) +async def lnurl_response(req: Request, item_id: int = Query(...)): + item = await get_item(item_id) # type: Item if not item: return {"status": "ERROR", "reason": "Item not found."} @@ -28,7 +29,7 @@ async def lnurl_response(item_id: int = Query(...)): ) * 1000 resp = LnurlPayResponse( - callback=url_for("offlineshop.lnurl_callback", item_id=item.id, _external=True), + callback=req.url_for("offlineshop.lnurl_callback", item_id=item.id), min_sendable=price_msat, max_sendable=price_msat, metadata=await item.lnurlpay_metadata(), @@ -37,9 +38,9 @@ async def lnurl_response(item_id: int = Query(...)): return resp.dict() -@offlineshop_ext.get("/lnurl/cb/") +@offlineshop_ext.get("/lnurl/cb/{item_id}", name="offlineshop.lnurl_callback") async def lnurl_callback(request: Request, item_id: int): - item = await get_item(item_id) + item = await get_item(item_id) # type: Item if not item: return {"status": "ERROR", "reason": "Couldn't find item."} @@ -52,7 +53,7 @@ async def lnurl_callback(request: Request, item_id: int): min = price * 995 max = price * 1010 - amount_received = int(request.args.get("amount") or 0) + amount_received = int(request.query_params.get("amount") or 0) if amount_received < min: return LnurlErrorResponse( reason=f"Amount {amount_received} is smaller than minimum {min}." diff --git a/lnbits/extensions/offlineshop/models.py b/lnbits/extensions/offlineshop/models.py index 53fdb845..12616022 100644 --- a/lnbits/extensions/offlineshop/models.py +++ b/lnbits/extensions/offlineshop/models.py @@ -14,7 +14,8 @@ from .helpers import totp shop_counters: Dict = {} -class ShopCounter(BaseModel): +class ShopCounter(): + wordlist: List[str] fulfilled_payments: OrderedDict counter: int @@ -88,6 +89,11 @@ class Item(BaseModel): price: int unit: str + def lnurl(self, req: Request) -> str: + return lnurl_encode( + req.url_for("offlineshop.lnurl_response", item_id=self.id) + ) + def values(self, req: Request): values = self.dict() values["lnurl"] = lnurl_encode( diff --git a/lnbits/extensions/offlineshop/views.py b/lnbits/extensions/offlineshop/views.py index 80870b27..e8bea173 100644 --- a/lnbits/extensions/offlineshop/views.py +++ b/lnbits/extensions/offlineshop/views.py @@ -1,8 +1,9 @@ import time from datetime import datetime from http import HTTPStatus +from typing import List -from fastapi.params import Depends +from fastapi.params import Depends, Query from starlette.responses import HTMLResponse from lnbits.decorators import check_user_exists @@ -10,6 +11,7 @@ from lnbits.core.models import Payment, User from lnbits.core.crud import get_standalone_payment from . import offlineshop_ext, offlineshop_renderer +from .models import Item from .crud import get_item, get_shop from fastapi import Request, HTTPException @@ -20,14 +22,14 @@ async def index(request: Request, user: User = Depends(check_user_exists)): @offlineshop_ext.get("/print", response_class=HTMLResponse) -async def print_qr_codes(request: Request): +async def print_qr_codes(request: Request, items: List[int] = None): items = [] - for item_id in request.args.get("items").split(","): - item = await get_item(item_id) + for item_id in request.query_params.get("items").split(","): + item = await get_item(item_id) # type: Item if item: items.append( { - "lnurl": item.lnurl, + "lnurl": item.lnurl(request), "name": item.name, "price": f"{item.price} {item.unit}", } @@ -36,8 +38,9 @@ async def print_qr_codes(request: Request): return offlineshop_renderer().TemplateResponse("offlineshop/print.html", {"request": request,"items":items}) -@offlineshop_ext.get("/confirmation") -async def confirmation_code(p: str): +@offlineshop_ext.get("/confirmation/{p}", name="offlineshop.confirmation_code", + response_class=HTMLResponse) +async def confirmation_code(p: str = Query(...)): style = "" payment_hash = p