lnbits-legend/lnbits/tasks.py
2021-06-20 21:17:32 -03:00

105 lines
2.7 KiB
Python

import time
import trio
from http import HTTPStatus
from typing import Optional, List, Callable
from quart_trio import QuartTrio
from lnbits.settings import WALLET
from lnbits.core.crud import (
get_payments,
get_standalone_payment,
delete_expired_invoices,
get_balance_checks,
)
from lnbits.core.services import redeem_lnurl_withdraw
deferred_async: List[Callable] = []
def record_async(func: Callable) -> Callable:
def recorder(state):
deferred_async.append(func)
return recorder
def run_deferred_async(nursery):
for func in deferred_async:
nursery.start_soon(func)
async def send_push_promise(a, b) -> None:
pass
invoice_listeners: List[trio.MemorySendChannel] = []
def register_invoice_listener(send_chan: trio.MemorySendChannel):
"""
A method intended for extensions to call when they want to be notified about
new invoice payments incoming.
"""
invoice_listeners.append(send_chan)
async def webhook_handler():
handler = getattr(WALLET, "webhook_listener", None)
if handler:
return await handler()
return "", HTTPStatus.NO_CONTENT
internal_invoice_paid, internal_invoice_received = trio.open_memory_channel(0)
async def internal_invoice_listener(nursery):
async for checking_id in internal_invoice_received:
nursery.start_soon(invoice_callback_dispatcher, checking_id)
async def invoice_listener(nursery):
async for checking_id in WALLET.paid_invoices_stream():
nursery.start_soon(invoice_callback_dispatcher, checking_id)
async def check_pending_payments():
await delete_expired_invoices()
outgoing = True
incoming = True
while True:
for payment in await get_payments(
since=(int(time.time()) - 60 * 60 * 24 * 15), # 15 days ago
complete=False,
pending=True,
outgoing=outgoing,
incoming=incoming,
exclude_uncheckable=True,
):
await payment.check_pending()
# after the first check we will only check outgoing, not incoming
# that will be handled by the global invoice listeners, hopefully
incoming = False
await trio.sleep(60 * 30) # every 30 minutes
async def perform_balance_checks():
while True:
for bc in await get_balance_checks():
redeem_lnurl_withdraw(bc.wallet, bc.url)
await trio.sleep(60 * 60 * 6) # every 6 hours
async def invoice_callback_dispatcher(checking_id: str):
payment = await get_standalone_payment(checking_id)
if payment and payment.is_in:
await payment.set_pending(False)
for send_chan in invoice_listeners:
await send_chan.send(payment)