fix: offlineshop ext lnurl handling

This commit is contained in:
Stefan Stammberger 2021-09-19 13:34:31 +02:00
parent c5d96d21e9
commit a5c0a2bb50
No known key found for this signature in database
GPG key ID: 645FA807E935D9D5
3 changed files with 24 additions and 14 deletions

View file

@ -1,4 +1,5 @@
import hashlib import hashlib
from lnbits.extensions.offlineshop.models import Item
from fastapi.params import Query from fastapi.params import Query
from starlette.requests import Request 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") @offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response")
async def lnurl_response(item_id: int = Query(...)): async def lnurl_response(req: Request, item_id: int = Query(...)):
item = await get_item(item_id) item = await get_item(item_id) # type: Item
if not item: if not item:
return {"status": "ERROR", "reason": "Item not found."} return {"status": "ERROR", "reason": "Item not found."}
@ -28,7 +29,7 @@ async def lnurl_response(item_id: int = Query(...)):
) * 1000 ) * 1000
resp = LnurlPayResponse( 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, min_sendable=price_msat,
max_sendable=price_msat, max_sendable=price_msat,
metadata=await item.lnurlpay_metadata(), metadata=await item.lnurlpay_metadata(),
@ -37,9 +38,9 @@ async def lnurl_response(item_id: int = Query(...)):
return resp.dict() return resp.dict()
@offlineshop_ext.get("/lnurl/cb/<item_id>") @offlineshop_ext.get("/lnurl/cb/{item_id}", name="offlineshop.lnurl_callback")
async def lnurl_callback(request: Request, item_id: int): 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: if not item:
return {"status": "ERROR", "reason": "Couldn't find 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 min = price * 995
max = price * 1010 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: if amount_received < min:
return LnurlErrorResponse( return LnurlErrorResponse(
reason=f"Amount {amount_received} is smaller than minimum {min}." reason=f"Amount {amount_received} is smaller than minimum {min}."

View file

@ -14,7 +14,8 @@ from .helpers import totp
shop_counters: Dict = {} shop_counters: Dict = {}
class ShopCounter(BaseModel): class ShopCounter():
wordlist: List[str]
fulfilled_payments: OrderedDict fulfilled_payments: OrderedDict
counter: int counter: int
@ -88,6 +89,11 @@ class Item(BaseModel):
price: int price: int
unit: str 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): def values(self, req: Request):
values = self.dict() values = self.dict()
values["lnurl"] = lnurl_encode( values["lnurl"] = lnurl_encode(

View file

@ -1,8 +1,9 @@
import time import time
from datetime import datetime from datetime import datetime
from http import HTTPStatus 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 starlette.responses import HTMLResponse
from lnbits.decorators import check_user_exists 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 lnbits.core.crud import get_standalone_payment
from . import offlineshop_ext, offlineshop_renderer from . import offlineshop_ext, offlineshop_renderer
from .models import Item
from .crud import get_item, get_shop from .crud import get_item, get_shop
from fastapi import Request, HTTPException 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) @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 = [] items = []
for item_id in request.args.get("items").split(","): for item_id in request.query_params.get("items").split(","):
item = await get_item(item_id) item = await get_item(item_id) # type: Item
if item: if item:
items.append( items.append(
{ {
"lnurl": item.lnurl, "lnurl": item.lnurl(request),
"name": item.name, "name": item.name,
"price": f"{item.price} {item.unit}", "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}) return offlineshop_renderer().TemplateResponse("offlineshop/print.html", {"request": request,"items":items})
@offlineshop_ext.get("/confirmation") @offlineshop_ext.get("/confirmation/{p}", name="offlineshop.confirmation_code",
async def confirmation_code(p: str): response_class=HTMLResponse)
async def confirmation_code(p: str = Query(...)):
style = "<style>* { font-size: 100px}</style>" style = "<style>* { font-size: 100px}</style>"
payment_hash = p payment_hash = p