diff --git a/lnbits/extensions/lnurlp/tasks.py b/lnbits/extensions/lnurlp/tasks.py index b8da5e436..38485f74f 100644 --- a/lnbits/extensions/lnurlp/tasks.py +++ b/lnbits/extensions/lnurlp/tasks.py @@ -4,7 +4,6 @@ import json import httpx from loguru import logger -from lnbits.core import db as core_db from lnbits.core.crud import update_payment_extra from lnbits.core.models import Payment from lnbits.helpers import get_current_extension_name @@ -22,9 +21,8 @@ async def wait_for_paid_invoices(): await on_invoice_paid(payment) -async def on_invoice_paid(payment: Payment) -> None: - if payment.extra.get("tag") != "lnurlp": - # not an lnurlp invoice +async def on_invoice_paid(payment: Payment): + if not payment.extra or payment.extra.get("tag") != "lnurlp": return if payment.extra.get("wh_status"): @@ -35,22 +33,24 @@ async def on_invoice_paid(payment: Payment) -> None: if pay_link and pay_link.webhook_url: async with httpx.AsyncClient() as client: try: - kwargs = { - "json": { + r: httpx.Response = await client.post( + pay_link.webhook_url, + json={ "payment_hash": payment.payment_hash, "payment_request": payment.bolt11, "amount": payment.amount, "comment": payment.extra.get("comment"), "lnurlp": pay_link.id, + "lnurlp": pay_link.id, + "body": json.loads(pay_link.webhook_body) + if pay_link.webhook_body + else "", }, - "timeout": 40, - } - if pay_link.webhook_body: - kwargs["json"]["body"] = json.loads(pay_link.webhook_body) - if pay_link.webhook_headers: - kwargs["headers"] = json.loads(pay_link.webhook_headers) - - r: httpx.Response = await client.post(pay_link.webhook_url, **kwargs) + headers=json.loads(pay_link.webhook_headers) + if pay_link.webhook_headers + else None, + timeout=40, + ) await mark_webhook_sent( payment.payment_hash, r.status_code, diff --git a/lnbits/extensions/lnurlp/views.py b/lnbits/extensions/lnurlp/views.py index 4e9f487ca..9bc78056f 100644 --- a/lnbits/extensions/lnurlp/views.py +++ b/lnbits/extensions/lnurlp/views.py @@ -1,7 +1,6 @@ from http import HTTPStatus -from fastapi import Request -from fastapi.params import Depends +from fastapi import Depends, Request from fastapi.templating import Jinja2Templates from starlette.exceptions import HTTPException from starlette.responses import HTMLResponse diff --git a/lnbits/extensions/lnurlp/views_api.py b/lnbits/extensions/lnurlp/views_api.py index d5966bf67..0fa739b08 100644 --- a/lnbits/extensions/lnurlp/views_api.py +++ b/lnbits/extensions/lnurlp/views_api.py @@ -1,9 +1,7 @@ import json from http import HTTPStatus -from fastapi import Request -from fastapi.param_functions import Query -from fastapi.params import Depends +from fastapi import Depends, Query, Request from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore from starlette.exceptions import HTTPException @@ -36,7 +34,8 @@ async def api_links( wallet_ids = [wallet.wallet.id] if all_wallets: - wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids + user = await get_user(wallet.wallet.user) + wallet_ids = user.wallet_ids if user else [] try: return [ @@ -137,6 +136,7 @@ async def api_link_create_or_update( link = await update_pay_link(**data.dict(), link_id=link_id) else: link = await create_pay_link(data, wallet_id=wallet.wallet.id) + assert link return {**link.dict(), "lnurl": link.lnurl(request)} diff --git a/lnbits/extensions/lnurlpayout/crud.py b/lnbits/extensions/lnurlpayout/crud.py index 0f9f98acb..ccbca1204 100644 --- a/lnbits/extensions/lnurlpayout/crud.py +++ b/lnbits/extensions/lnurlpayout/crud.py @@ -53,7 +53,7 @@ async def get_lnurlpayouts(wallet_ids: Union[str, List[str]]) -> List[lnurlpayou f"SELECT * FROM lnurlpayout.lnurlpayouts WHERE wallet IN ({q})", (*wallet_ids,) ) - return [lnurlpayout(**row) if row else None for row in rows] + return [lnurlpayout(**row) for row in rows] async def delete_lnurlpayout(lnurlpayout_id: str) -> None: diff --git a/lnbits/extensions/lnurlpayout/tasks.py b/lnbits/extensions/lnurlpayout/tasks.py index 71f299be5..7de26d15d 100644 --- a/lnbits/extensions/lnurlpayout/tasks.py +++ b/lnbits/extensions/lnurlpayout/tasks.py @@ -2,14 +2,13 @@ import asyncio from http import HTTPStatus import httpx +from lnurl import decode as lnurl_decode from loguru import logger from starlette.exceptions import HTTPException -from lnbits.core import db as core_db from lnbits.core.crud import get_wallet from lnbits.core.models import Payment from lnbits.core.services import pay_invoice -from lnbits.core.views.api import api_payments_decode from lnbits.helpers import get_current_extension_name from lnbits.tasks import register_invoice_listener @@ -35,6 +34,7 @@ async def on_invoice_paid(payment: Payment) -> None: # Check the wallet balance is more than the threshold wallet = await get_wallet(lnurlpayout_link.wallet) + assert wallet threshold = lnurlpayout_link.threshold + (lnurlpayout_link.threshold * 0.02) if wallet.balance < threshold: @@ -42,14 +42,10 @@ async def on_invoice_paid(payment: Payment) -> None: # Get the invoice from the LNURL to pay async with httpx.AsyncClient() as client: try: - url = await api_payments_decode({"data": lnurlpayout_link.lnurlpay}) - if str(url["domain"])[0:4] != "http": - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="LNURL broken" - ) + url = lnurl_decode(lnurlpayout_link.lnurlpay) try: - r = await client.get(str(url["domain"]), timeout=40) + r = await client.get(str(url), timeout=40) res = r.json() try: r = await client.get( diff --git a/lnbits/extensions/lnurlpayout/views.py b/lnbits/extensions/lnurlpayout/views.py index 454a33328..c3c00c5b9 100644 --- a/lnbits/extensions/lnurlpayout/views.py +++ b/lnbits/extensions/lnurlpayout/views.py @@ -1,16 +1,13 @@ from http import HTTPStatus -from fastapi import Request -from fastapi.params import Depends +from fastapi import Depends, Request from fastapi.templating import Jinja2Templates -from starlette.exceptions import HTTPException from starlette.responses import HTMLResponse from lnbits.core.models import User from lnbits.decorators import check_user_exists from . import lnurlpayout_ext, lnurlpayout_renderer -from .crud import get_lnurlpayout templates = Jinja2Templates(directory="templates") diff --git a/lnbits/extensions/lnurlpayout/views_api.py b/lnbits/extensions/lnurlpayout/views_api.py index 324eb5dd5..02feba157 100644 --- a/lnbits/extensions/lnurlpayout/views_api.py +++ b/lnbits/extensions/lnurlpayout/views_api.py @@ -1,13 +1,10 @@ from http import HTTPStatus -from fastapi import Query -from fastapi.params import Depends +from fastapi import Depends, Query +from lnurl import decode as lnurl_decode from starlette.exceptions import HTTPException -from lnbits.core.crud import get_payments, get_user -from lnbits.core.models import Payment -from lnbits.core.services import create_invoice -from lnbits.core.views.api import api_payment, api_payments_decode +from lnbits.core.crud import get_user from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key from . import lnurlpayout_ext @@ -18,8 +15,9 @@ from .crud import ( get_lnurlpayout_from_wallet, get_lnurlpayouts, ) -from .models import CreateLnurlPayoutData, lnurlpayout -from .tasks import on_invoice_paid +from .models import CreateLnurlPayoutData + +# from .tasks import on_invoice_paid @lnurlpayout_ext.get("/api/v1/lnurlpayouts", status_code=HTTPStatus.OK) @@ -28,7 +26,8 @@ async def api_lnurlpayouts( ): wallet_ids = [wallet.wallet.id] if all_wallets: - wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids + user = await get_user(wallet.wallet.user) + wallet_ids = user.wallet_ids if user else [] return [lnurlpayout.dict() for lnurlpayout in await get_lnurlpayouts(wallet_ids)] @@ -42,24 +41,16 @@ async def api_lnurlpayout_create( status_code=HTTPStatus.FORBIDDEN, detail="Wallet already has lnurlpayout set", ) - return - url = await api_payments_decode({"data": data.lnurlpay}) - if "domain" not in url: - raise HTTPException( - status_code=HTTPStatus.FORBIDDEN, detail="LNURL could not be decoded" - ) - return - if str(url["domain"])[0:4] != "http": - raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not valid LNURL") - return + _ = lnurl_decode(data.lnurlpay) lnurlpayout = await create_lnurlpayout( wallet_id=wallet.wallet.id, admin_key=wallet.wallet.adminkey, data=data ) + if not lnurlpayout: raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="Failed to save LNURLPayout" ) - return + return lnurlpayout.dict() @@ -83,36 +74,29 @@ async def api_lnurlpayout_delete( return "", HTTPStatus.NO_CONTENT -@lnurlpayout_ext.get("/api/v1/lnurlpayouts/{lnurlpayout_id}", status_code=HTTPStatus.OK) -async def api_lnurlpayout_check( - lnurlpayout_id: str, wallet: WalletTypeInfo = Depends(get_key_type) -): - lnurlpayout = await get_lnurlpayout(lnurlpayout_id) - ## THIS - mock_payment = Payment( - checking_id="mock", - pending=False, - amount=1, - fee=1, - time=0000, - bolt11="mock", - preimage="mock", - payment_hash="mock", - wallet_id=lnurlpayout.wallet, - ) - ## INSTEAD OF THIS - # payments = await get_payments( - # wallet_id=lnurlpayout.wallet, complete=True, pending=False, outgoing=True, incoming=True - # ) +# TODO: what is this?! - result = await on_invoice_paid(mock_payment) - return +# @lnurlpayout_ext.get("/api/v1/lnurlpayouts/{lnurlpayout_id}", status_code=HTTPStatus.OK) +# async def api_lnurlpayout_check( +# lnurlpayout_id: str, wallet: WalletTypeInfo = Depends(get_key_type) +# ): +# lnurlpayout = await get_lnurlpayout(lnurlpayout_id) +# ## THIS +# mock_payment = Payment( +# checking_id="mock", +# pending=False, +# amount=1, +# fee=1, +# time=0000, +# bolt11="mock", +# preimage="mock", +# payment_hash="mock", +# wallet_id=lnurlpayout.wallet, +# ) +# ## INSTEAD OF THIS +# # payments = await get_payments( +# # wallet_id=lnurlpayout.wallet, complete=True, pending=False, outgoing=True, incoming=True +# # ) - -# get payouts func -# lnurlpayouts = await get_lnurlpayouts(wallet_ids) -# for lnurlpayout in lnurlpayouts: -# payments = await get_payments( -# wallet_id=lnurlpayout.wallet, complete=True, pending=False, outgoing=True, incoming=True -# ) -# await on_invoice_paid(payments[0]) +# result = await on_invoice_paid(mock_payment) +# return diff --git a/pyproject.toml b/pyproject.toml index 186e2123a..626b3dfd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,7 +98,6 @@ exclude = """(?x)( | ^lnbits/extensions/lnaddress. | ^lnbits/extensions/lndhub. | ^lnbits/extensions/lnurldevice. - | ^lnbits/extensions/lnurlp. | ^lnbits/extensions/offlineshop. | ^lnbits/extensions/satspay. | ^lnbits/extensions/streamalerts.