- {% for row in page %}
-
- {% for one in row %}
-
-
-
+
+ {% for threes in page %}
+
+ {% for one in threes %}
+ |
+
+
+
+ |
{% endfor %}
-
+
{% endfor %}
-
+
{% endfor %}
diff --git a/templates/withdraw/print_qr_custom.html b/templates/withdraw/print_qr_custom.html
index c144a9f..8e34097 100644
--- a/templates/withdraw/print_qr_custom.html
+++ b/templates/withdraw/print_qr_custom.html
@@ -11,8 +11,7 @@
@@ -62,10 +61,9 @@
.wrapper .lnurlw {
display: block;
position: absolute;
- top: calc(3mm + 1rem);
- left: calc(6mm + 1rem);
+ top: calc(7.3mm + 1rem);
+ left: calc(7.5mm + 1rem);
transform: rotate(45deg);
- width: 27mm;
}
@media print {
@@ -85,8 +83,8 @@
.wrapper .lnurlw {
display: block;
position: absolute;
- top: 3mm;
- left: 6mm;
+ top: 7.3mm;
+ left: 7.5mm;
transform: rotate(45deg);
}
}
diff --git a/views.py b/views.py
index 7313a87..1a77d40 100644
--- a/views.py
+++ b/views.py
@@ -1,8 +1,7 @@
-import io
from http import HTTPStatus
from fastapi import APIRouter, Depends, HTTPException, Request
-from fastapi.responses import HTMLResponse, StreamingResponse
+from fastapi.responses import HTMLResponse
from lnbits.core.models import User
from lnbits.decorators import check_user_exists
from lnbits.helpers import template_renderer
@@ -45,9 +44,9 @@ async def display(request: Request, link_id):
"withdraw/display.html",
{
"request": request,
- "spent": link.is_spent,
- "lnurl_url": str(lnurl.url),
- "enabled": link.enabled,
+ "link": link.json(),
+ "lnurl": lnurl,
+ "unique": True,
},
)
@@ -59,8 +58,11 @@ async def print_qr(request: Request, link_id):
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
)
+ # response.status_code = HTTPStatus.NOT_FOUND
+ # return "Withdraw link does not exist."
if link.uses == 0:
+
return withdraw_renderer().TemplateResponse(
"withdraw/print_qr.html",
{"request": request, "link": link.json(), "unique": False},
@@ -81,7 +83,7 @@ async def print_qr(request: Request, link_id):
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail=str(exc),
) from exc
- links.append(str(lnurl.bech32))
+ links.append(str(lnurl))
count = count + 1
page_link = list(chunks(links, 2))
linked = list(chunks(page_link, 5))
@@ -112,12 +114,14 @@ async def csv(request: Request, link_id):
)
if link.uses == 0:
- raise HTTPException(
- status_code=HTTPStatus.BAD_REQUEST, detail="Withdraw is spent."
- )
- buffer = io.StringIO()
+ return withdraw_renderer().TemplateResponse(
+ "withdraw/csv.html",
+ {"request": request, "link": link.json(), "unique": False},
+ )
+ links = []
count = 0
+
for _ in link.usescsv.split(","):
linkk = await get_withdraw_link(link_id, count)
if not linkk:
@@ -131,16 +135,11 @@ async def csv(request: Request, link_id):
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail=str(exc),
) from exc
- buffer.write(f"{lnurl.bech32!s}\n")
- count += 1
+ links.append(str(lnurl))
+ count = count + 1
+ page_link = list(chunks(links, 2))
+ linked = list(chunks(page_link, 5))
- # Move buffer cursor to the beginning
- buffer.seek(0)
-
- return StreamingResponse(
- buffer,
- media_type="text/csv",
- headers={
- "Content-Disposition": f"attachment; filename=withdraw-links-{link_id}.csv"
- },
+ return withdraw_renderer().TemplateResponse(
+ "withdraw/csv.html", {"request": request, "link": linked, "unique": True}
)
diff --git a/views_api.py b/views_api.py
index 514372d..8c4063c 100644
--- a/views_api.py
+++ b/views_api.py
@@ -3,7 +3,7 @@ from http import HTTPStatus
from fastapi import APIRouter, Depends, HTTPException, Query, Request
from lnbits.core.crud import get_user
-from lnbits.core.models import SimpleStatus, WalletTypeInfo
+from lnbits.core.models import WalletTypeInfo
from lnbits.decorators import require_admin_key, require_invoice_key
from .crud import (
@@ -15,7 +15,7 @@ from .crud import (
update_withdraw_link,
)
from .helpers import create_lnurl
-from .models import CreateWithdrawData, HashCheck, PaginatedWithdraws, WithdrawLink
+from .models import CreateWithdrawData, HashCheck
withdraw_ext_api = APIRouter(prefix="/api/v1")
@@ -27,35 +27,38 @@ async def api_links(
all_wallets: bool = Query(False),
offset: int = Query(0),
limit: int = Query(0),
-) -> PaginatedWithdraws:
+):
wallet_ids = [key_info.wallet.id]
if all_wallets:
user = await get_user(key_info.wallet.user)
wallet_ids = user.wallet_ids if user else []
- links = await get_withdraw_links(wallet_ids, limit, offset)
+ links, total = await get_withdraw_links(wallet_ids, limit, offset)
- for linkk in links.data:
+ data = []
+ for link in links:
try:
- lnurl = create_lnurl(linkk, request)
+ lnurl = create_lnurl(link, request)
except ValueError as exc:
raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail=str(exc),
) from exc
- linkk.lnurl = str(lnurl.bech32)
- linkk.lnurl_url = str(lnurl.url)
+ data.append({**link.dict(), **{"lnurl": lnurl}})
- return links
+ return {
+ "data": data,
+ "total": total,
+ }
@withdraw_ext_api.get("/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_retrieve(
- request: Request,
link_id: str,
+ request: Request,
key_info: WalletTypeInfo = Depends(require_invoice_key),
-) -> WithdrawLink:
+):
link = await get_withdraw_link(link_id, 0)
if not link:
@@ -67,7 +70,6 @@ async def api_link_retrieve(
raise HTTPException(
detail="Not your withdraw link.", status_code=HTTPStatus.FORBIDDEN
)
-
try:
lnurl = create_lnurl(link, request)
except ValueError as exc:
@@ -75,19 +77,17 @@ async def api_link_retrieve(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail=str(exc),
) from exc
- link.lnurl = str(lnurl.bech32)
- link.lnurl_url = str(lnurl.url)
- return link
+ return {**link.dict(), **{"lnurl": lnurl}}
@withdraw_ext_api.post("/links", status_code=HTTPStatus.CREATED)
-@withdraw_ext_api.put("/links/{link_id}")
+@withdraw_ext_api.put("/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_create_or_update(
request: Request,
data: CreateWithdrawData,
link_id: str | None = None,
key_info: WalletTypeInfo = Depends(require_admin_key),
-) -> WithdrawLink:
+):
if data.uses > 250:
raise HTTPException(detail="250 uses max.", status_code=HTTPStatus.BAD_REQUEST)
@@ -159,6 +159,7 @@ async def api_link_create_or_update(
link = await update_withdraw_link(link)
else:
link = await create_withdraw_link(wallet_id=key_info.wallet.id, data=data)
+
try:
lnurl = create_lnurl(link, request)
except ValueError as exc:
@@ -167,16 +168,13 @@ async def api_link_create_or_update(
detail=str(exc),
) from exc
- link.lnurl = str(lnurl.bech32)
- link.lnurl_url = str(lnurl.url)
-
- return link
+ return {**link.dict(), **{"lnurl": lnurl}}
-@withdraw_ext_api.delete("/links/{link_id}")
+@withdraw_ext_api.delete("/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_delete(
link_id: str, key_info: WalletTypeInfo = Depends(require_admin_key)
-) -> SimpleStatus:
+):
link = await get_withdraw_link(link_id)
if not link:
@@ -190,7 +188,7 @@ async def api_link_delete(
)
await delete_withdraw_link(link_id)
- return SimpleStatus(success=True, message="Withdraw link deleted.")
+ return {"success": True}
@withdraw_ext_api.get(
diff --git a/views_lnurl.py b/views_lnurl.py
index f893427..d62b21d 100644
--- a/views_lnurl.py
+++ b/views_lnurl.py
@@ -3,7 +3,6 @@ from datetime import datetime
import httpx
import shortuuid
-from bolt11 import decode as decode_bolt11
from fastapi import APIRouter, Request
from fastapi.responses import JSONResponse
from lnbits.core.crud import update_payment
@@ -44,9 +43,6 @@ async def api_lnurl_response(
if not link:
return LnurlErrorResponse(reason="Withdraw link does not exist.")
- if not link.enabled:
- return LnurlErrorResponse(reason="Withdraw link is disabled.")
-
if link.is_spent:
return LnurlErrorResponse(reason="Withdraw is spent.")
@@ -90,23 +86,11 @@ async def api_lnurl_callback(
pr: str,
id_unique_hash: str | None = None,
) -> LnurlErrorResponse | LnurlSuccessResponse:
+
link = await get_withdraw_link_by_hash(unique_hash)
if not link:
return LnurlErrorResponse(reason="withdraw link not found.")
- if not link.enabled:
- return LnurlErrorResponse(reason="Withdraw link is disabled.")
-
- bolt11 = decode_bolt11(pr)
- if not bolt11.amount_msat:
- return LnurlErrorResponse(reason="0 amount invoices are not supported.")
-
- if (
- link.min_withdrawable * 1000 > bolt11.amount_msat
- or bolt11.amount_msat > link.max_withdrawable * 1000
- ):
- return LnurlErrorResponse(reason="Amount not within limits.")
-
if link.is_spent:
return LnurlErrorResponse(reason="withdraw is spent.")
@@ -115,9 +99,9 @@ async def api_lnurl_callback(
now = int(datetime.now().timestamp())
- if now < link.open_time + link.wait_time:
+ if now < link.open_time:
return LnurlErrorResponse(
- reason=f"Wait {link.open_time + link.wait_time - now} seconds."
+ reason=f"wait link open_time {link.open_time - now} seconds."
)
if not id_unique_hash and link.is_unique:
@@ -210,9 +194,6 @@ async def api_lnurl_multi_response(
if not link:
return LnurlErrorResponse(reason="Withdraw link does not exist.")
- if not link.enabled:
- return LnurlErrorResponse(reason="Withdraw link is disabled.")
-
if link.is_spent:
return LnurlErrorResponse(reason="Withdraw is spent.")