basic invoice listeners.
This commit is contained in:
@@ -131,6 +131,19 @@ def get_wallet_for_key(key: str, key_type: str = "invoice") -> Optional[Wallet]:
|
||||
# ---------------
|
||||
|
||||
|
||||
def get_standalone_payment(checking_id: str) -> Optional[Payment]:
|
||||
row = g.db.fetchone(
|
||||
"""
|
||||
SELECT *
|
||||
FROM apipayments
|
||||
WHERE checking_id = ?
|
||||
""",
|
||||
(checking_id,),
|
||||
)
|
||||
|
||||
return Payment.from_row(row) if row else None
|
||||
|
||||
|
||||
def get_wallet_payment(wallet_id: str, payment_hash: str) -> Optional[Payment]:
|
||||
row = g.db.fetchone(
|
||||
"""
|
||||
|
||||
@@ -2,6 +2,8 @@ import json
|
||||
from typing import List, NamedTuple, Optional, Dict
|
||||
from sqlite3 import Row
|
||||
|
||||
from lnbits.settings import WALLET
|
||||
|
||||
|
||||
class User(NamedTuple):
|
||||
id: str
|
||||
@@ -113,6 +115,17 @@ class Payment(NamedTuple):
|
||||
|
||||
update_payment_status(self.checking_id, pending)
|
||||
|
||||
def check_pending(self) -> None:
|
||||
if self.is_uncheckable:
|
||||
return
|
||||
|
||||
if self.is_out:
|
||||
pending = WALLET.get_payment_status(self.checking_id)
|
||||
else:
|
||||
pending = WALLET.get_invoice_status(self.checking_id)
|
||||
|
||||
self.set_pending(pending.pending)
|
||||
|
||||
def delete(self) -> None:
|
||||
from .crud import delete_payment
|
||||
|
||||
|
||||
+40
-2
@@ -1,9 +1,13 @@
|
||||
import asyncio
|
||||
from typing import Optional, Awaitable
|
||||
from typing import Optional, List, Awaitable, Tuple, Callable
|
||||
from quart import Quart, Request, g
|
||||
from werkzeug.datastructures import Headers
|
||||
|
||||
from lnbits.db import open_db
|
||||
from lnbits.db import open_db, open_ext_db
|
||||
from lnbits.settings import WALLET
|
||||
|
||||
from .models import Payment
|
||||
from .crud import get_standalone_payment
|
||||
|
||||
main_app: Optional[Quart] = None
|
||||
|
||||
@@ -31,3 +35,37 @@ def run_on_pseudo_request(awaitable: Awaitable):
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(run(awaitable))
|
||||
|
||||
|
||||
invoice_listeners: List[Tuple[str, Callable[[Payment], Awaitable[None]]]] = []
|
||||
|
||||
|
||||
def register_invoice_listener(ext_name: str, callback: Callable[[Payment], Awaitable[None]]):
|
||||
"""
|
||||
A method intended for extensions to call when they want to be notified about
|
||||
new invoice payments incoming.
|
||||
"""
|
||||
print("registering callback", callback)
|
||||
invoice_listeners.append((ext_name, callback))
|
||||
|
||||
|
||||
async def webhook_handler():
|
||||
handler = getattr(WALLET, "webhook_listener", None)
|
||||
if handler:
|
||||
await handler()
|
||||
|
||||
|
||||
async def invoice_listener(app):
|
||||
run_on_pseudo_request(_invoice_listener())
|
||||
|
||||
|
||||
async def _invoice_listener():
|
||||
async for checking_id in WALLET.paid_invoices_stream():
|
||||
# do this just so the g object is available
|
||||
g.db = await open_db()
|
||||
payment = await get_standalone_payment(checking_id)
|
||||
if payment.is_in:
|
||||
await payment.set_pending(False)
|
||||
for ext_name, cb in invoice_listeners:
|
||||
g.ext_db = await open_ext_db(ext_name)
|
||||
cb(payment)
|
||||
|
||||
@@ -7,7 +7,6 @@ from lnbits.core import core_app
|
||||
from lnbits.core.services import create_invoice, pay_invoice
|
||||
from lnbits.core.crud import delete_expired_invoices
|
||||
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
|
||||
from lnbits.settings import WALLET
|
||||
|
||||
|
||||
@core_app.route("/api/v1/wallet", methods=["GET"])
|
||||
@@ -32,10 +31,7 @@ async def api_payments():
|
||||
delete_expired_invoices()
|
||||
|
||||
for payment in g.wallet.get_payments(complete=False, pending=True, exclude_uncheckable=True):
|
||||
if payment.is_out:
|
||||
payment.set_pending(WALLET.get_payment_status(payment.checking_id).pending)
|
||||
else:
|
||||
payment.set_pending(WALLET.get_invoice_status(payment.checking_id).pending)
|
||||
payment.check_pending()
|
||||
|
||||
return jsonify(g.wallet.get_payments(pending=True)), HTTPStatus.OK
|
||||
|
||||
@@ -123,17 +119,8 @@ async def api_payment(payment_hash):
|
||||
return jsonify({"paid": True}), HTTPStatus.OK
|
||||
|
||||
try:
|
||||
if payment.is_uncheckable:
|
||||
pass
|
||||
elif payment.is_out:
|
||||
is_paid = not WALLET.get_payment_status(payment.checking_id).pending
|
||||
elif payment.is_in:
|
||||
is_paid = not WALLET.get_invoice_status(payment.checking_id).pending
|
||||
payment.check_pending()
|
||||
except Exception:
|
||||
return jsonify({"paid": False}), HTTPStatus.OK
|
||||
|
||||
if is_paid:
|
||||
payment.set_pending(False)
|
||||
return jsonify({"paid": True}), HTTPStatus.OK
|
||||
|
||||
return jsonify({"paid": False}), HTTPStatus.OK
|
||||
return jsonify({"paid": not payment.pending}), HTTPStatus.OK
|
||||
|
||||
Reference in New Issue
Block a user