basic invoice listeners.

This commit is contained in:
fiatjaf
2020-10-04 12:04:47 -03:00
parent e2f6c20e3b
commit 04222f1f01
12 changed files with 193 additions and 26 deletions
+13
View File
@@ -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(
"""
+13
View File
@@ -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
View File
@@ -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)
+3 -16
View File
@@ -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