2021-08-30 19:55:02 +02:00
|
|
|
import asyncio
|
2021-06-02 22:04:56 +02:00
|
|
|
import datetime
|
|
|
|
from http import HTTPStatus
|
|
|
|
|
|
|
|
from lnbits import bolt11
|
|
|
|
|
|
|
|
from .. import core_app
|
|
|
|
from ..crud import get_standalone_payment
|
|
|
|
from ..tasks import api_invoice_listeners
|
|
|
|
|
|
|
|
|
2021-08-23 00:05:39 +02:00
|
|
|
@core_app.get("/public/v1/payment/{payment_hash}")
|
2021-06-02 22:04:56 +02:00
|
|
|
async def api_public_payment_longpolling(payment_hash):
|
|
|
|
payment = await get_standalone_payment(payment_hash)
|
|
|
|
|
|
|
|
if not payment:
|
2021-08-20 22:31:01 +02:00
|
|
|
return {"message": "Payment does not exist."}, HTTPStatus.NOT_FOUND
|
2021-06-02 22:04:56 +02:00
|
|
|
elif not payment.pending:
|
2021-08-20 22:31:01 +02:00
|
|
|
return {"status": "paid"}, HTTPStatus.OK
|
2021-06-02 22:04:56 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
invoice = bolt11.decode(payment.bolt11)
|
|
|
|
expiration = datetime.datetime.fromtimestamp(invoice.date + invoice.expiry)
|
|
|
|
if expiration < datetime.datetime.now():
|
2021-08-20 22:31:01 +02:00
|
|
|
return {"status": "expired"}, HTTPStatus.OK
|
2021-06-02 22:04:56 +02:00
|
|
|
except:
|
2021-08-20 22:31:01 +02:00
|
|
|
return {"message": "Invalid bolt11 invoice."}, HTTPStatus.BAD_REQUEST
|
2021-06-02 22:04:56 +02:00
|
|
|
|
2021-08-30 19:55:02 +02:00
|
|
|
payment_queue = asyncio.Queue(0)
|
2021-06-02 22:04:56 +02:00
|
|
|
|
2021-08-30 19:55:02 +02:00
|
|
|
print("adding standalone invoice listener", payment_hash, payment_queue)
|
|
|
|
api_invoice_listeners.append(payment_queue)
|
2021-06-02 22:04:56 +02:00
|
|
|
|
2021-06-23 22:00:30 +02:00
|
|
|
response = None
|
|
|
|
|
|
|
|
async def payment_info_receiver(cancel_scope):
|
2021-08-30 19:55:02 +02:00
|
|
|
async for payment in payment_queue.get():
|
2021-06-23 22:00:30 +02:00
|
|
|
if payment.payment_hash == payment_hash:
|
|
|
|
nonlocal response
|
2021-08-20 22:31:01 +02:00
|
|
|
response = ({"status": "paid"}, HTTPStatus.OK)
|
2021-06-23 22:00:30 +02:00
|
|
|
cancel_scope.cancel()
|
|
|
|
|
|
|
|
async def timeouter(cancel_scope):
|
2021-08-30 19:55:02 +02:00
|
|
|
await asyncio.sleep(45)
|
2021-06-23 22:00:30 +02:00
|
|
|
cancel_scope.cancel()
|
|
|
|
|
2021-08-30 19:55:02 +02:00
|
|
|
|
|
|
|
asyncio.create_task(payment_info_receiver())
|
|
|
|
asyncio.create_task(timeouter())
|
2021-06-23 22:00:30 +02:00
|
|
|
|
|
|
|
if response:
|
|
|
|
return response
|
|
|
|
else:
|
2021-08-20 22:31:01 +02:00
|
|
|
return {"message": "timeout"}, HTTPStatus.REQUEST_TIMEOUT
|