2021-08-30 19:55:02 +02:00
|
|
|
import asyncio
|
2021-06-02 17:04:56 -03:00
|
|
|
from http import HTTPStatus
|
2021-10-29 16:43:26 +01:00
|
|
|
|
2023-09-12 12:25:05 +02:00
|
|
|
from fastapi import APIRouter, HTTPException
|
2022-07-16 14:23:03 +02:00
|
|
|
from loguru import logger
|
2021-10-29 16:43:26 +01:00
|
|
|
|
2021-06-02 17:04:56 -03:00
|
|
|
from lnbits import bolt11
|
|
|
|
|
|
|
|
from ..crud import get_standalone_payment
|
|
|
|
from ..tasks import api_invoice_listeners
|
|
|
|
|
2024-03-28 08:59:28 +01:00
|
|
|
public_router = APIRouter(tags=["Core"])
|
2021-06-02 17:04:56 -03:00
|
|
|
|
2023-09-12 12:25:05 +02:00
|
|
|
|
|
|
|
@public_router.get("/public/v1/payment/{payment_hash}")
|
2021-06-02 17:04:56 -03:00
|
|
|
async def api_public_payment_longpolling(payment_hash):
|
|
|
|
payment = await get_standalone_payment(payment_hash)
|
|
|
|
|
|
|
|
if not payment:
|
2021-09-11 11:02:48 +02:00
|
|
|
raise HTTPException(
|
2021-10-17 18:33:29 +01:00
|
|
|
status_code=HTTPStatus.NOT_FOUND, detail="Payment does not exist."
|
2021-09-11 11:02:48 +02:00
|
|
|
)
|
2021-06-02 17:04:56 -03:00
|
|
|
elif not payment.pending:
|
2021-09-11 11:02:48 +02:00
|
|
|
return {"status": "paid"}
|
2021-06-02 17:04:56 -03:00
|
|
|
|
|
|
|
try:
|
|
|
|
invoice = bolt11.decode(payment.bolt11)
|
2023-09-25 12:06:54 +02:00
|
|
|
if invoice.has_expired():
|
2021-09-11 11:02:48 +02:00
|
|
|
return {"status": "expired"}
|
2024-04-17 13:11:51 +02:00
|
|
|
except Exception as exc:
|
2021-09-11 11:02:48 +02:00
|
|
|
raise HTTPException(
|
2021-10-17 18:33:29 +01:00
|
|
|
status_code=HTTPStatus.BAD_REQUEST, detail="Invalid bolt11 invoice."
|
2024-04-17 13:11:51 +02:00
|
|
|
) from exc
|
2021-06-02 17:04:56 -03:00
|
|
|
|
2021-08-30 19:55:02 +02:00
|
|
|
payment_queue = asyncio.Queue(0)
|
2021-06-02 17:04:56 -03:00
|
|
|
|
2022-10-04 09:51:47 +02:00
|
|
|
logger.debug(f"adding standalone invoice listener for hash: {payment_hash}")
|
|
|
|
api_invoice_listeners[payment_hash] = payment_queue
|
2021-06-02 17:04:56 -03:00
|
|
|
|
2021-06-23 17:00:30 -03:00
|
|
|
response = None
|
|
|
|
|
2023-02-02 12:58:10 +00:00
|
|
|
async def payment_info_receiver():
|
|
|
|
for payment in await payment_queue.get():
|
2021-06-23 17:00:30 -03:00
|
|
|
if payment.payment_hash == payment_hash:
|
|
|
|
nonlocal response
|
2021-09-11 11:02:48 +02:00
|
|
|
response = {"status": "paid"}
|
2021-06-23 17:00:30 -03:00
|
|
|
|
|
|
|
async def timeouter(cancel_scope):
|
2021-08-30 19:55:02 +02:00
|
|
|
await asyncio.sleep(45)
|
2021-06-23 17:00:30 -03:00
|
|
|
cancel_scope.cancel()
|
|
|
|
|
2023-02-02 12:58:10 +00:00
|
|
|
cancel_scope = asyncio.create_task(payment_info_receiver())
|
2024-04-17 07:36:22 +02:00
|
|
|
asyncio.create_task(timeouter(cancel_scope)) # noqa: RUF006
|
2021-06-23 17:00:30 -03:00
|
|
|
|
|
|
|
if response:
|
|
|
|
return response
|
|
|
|
else:
|
2021-10-17 18:33:29 +01:00
|
|
|
raise HTTPException(status_code=HTTPStatus.REQUEST_TIMEOUT, detail="timeout")
|