Compare commits

...
4 Commits
Author SHA1 Message Date
dni ⚡andGitHub dbb689c5c5 chore: update version to 0.12.10 (#2597) 2024-07-23 14:06:55 +02:00
dni ⚡andGitHub 2167aa398f fix: annotations for models.py (#2595) 2024-07-23 14:03:27 +02:00
dni ⚡andGitHub eb8d2f312f fix: install extensions async (#2596)
so it does not block webserver start on saas instances and comes up
faster if extensions are reinstalled
2024-07-23 14:01:34 +02:00
jackstar12andGitHub f9133760fc fix: proper status check in invoice paid callback (#2592)
status fields like preimage and fee_msat are never updated otherwise
2024-07-22 16:59:26 +02:00
4 changed files with 26 additions and 22 deletions
+13 -11
View File
@@ -63,6 +63,7 @@ from .middleware import (
from .requestvars import g from .requestvars import g
from .tasks import ( from .tasks import (
check_pending_payments, check_pending_payments,
create_task,
internal_invoice_listener, internal_invoice_listener,
invoice_listener, invoice_listener,
) )
@@ -93,13 +94,8 @@ async def startup(app: FastAPI):
# register core routes # register core routes
init_core_routers(app) init_core_routers(app)
# check extensions after restart
if not settings.lnbits_extensions_deactivate_all:
await check_installed_extensions(app)
register_all_ext_routes(app)
# initialize tasks # initialize tasks
register_async_tasks() register_async_tasks(app)
async def shutdown(): async def shutdown():
@@ -399,22 +395,28 @@ def register_ext_routes(app: FastAPI, ext: Extension) -> None:
app.include_router(router=ext_route, prefix=prefix) app.include_router(router=ext_route, prefix=prefix)
def register_all_ext_routes(app: FastAPI): async def check_and_register_extensions(app: FastAPI):
await check_installed_extensions(app)
for ext in get_valid_extensions(False): for ext in get_valid_extensions(False):
try: try:
register_ext_routes(app, ext) register_ext_routes(app, ext)
except Exception as e: except Exception as exc:
logger.error(f"Could not load extension `{ext.code}`: {e!s}") logger.error(f"Could not load extension `{ext.code}`: {exc!s}")
def register_async_tasks(): def register_async_tasks(app: FastAPI):
# check extensions after restart
if not settings.lnbits_extensions_deactivate_all:
create_task(check_and_register_extensions(app))
create_permanent_task(check_pending_payments) create_permanent_task(check_pending_payments)
create_permanent_task(invoice_listener) create_permanent_task(invoice_listener)
create_permanent_task(internal_invoice_listener) create_permanent_task(internal_invoice_listener)
create_permanent_task(cache.invalidate_forever) create_permanent_task(cache.invalidate_forever)
# core invoice listener # core invoice listener
invoice_queue = asyncio.Queue(5) invoice_queue: asyncio.Queue = asyncio.Queue(5)
register_invoice_listener(invoice_queue, "core") register_invoice_listener(invoice_queue, "core")
create_permanent_task(lambda: wait_for_paid_invoices(invoice_queue)) create_permanent_task(lambda: wait_for_paid_invoices(invoice_queue))
+10 -8
View File
@@ -1,3 +1,5 @@
from __future__ import annotations
import datetime import datetime
import hashlib import hashlib
import hmac import hmac
@@ -6,7 +8,7 @@ import time
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum from enum import Enum
from sqlite3 import Row from sqlite3 import Row
from typing import Callable, Dict, List, Optional from typing import Callable, Optional
from ecdsa import SECP256k1, SigningKey from ecdsa import SECP256k1, SigningKey
from fastapi import Query from fastapi import Query
@@ -62,7 +64,7 @@ class Wallet(BaseWallet):
linking_key, curve=SECP256k1, hashfunc=hashlib.sha256 linking_key, curve=SECP256k1, hashfunc=hashlib.sha256
) )
async def get_payment(self, payment_hash: str) -> Optional["Payment"]: async def get_payment(self, payment_hash: str) -> Optional[Payment]:
from .crud import get_standalone_payment from .crud import get_standalone_payment
return await get_standalone_payment(payment_hash) return await get_standalone_payment(payment_hash)
@@ -132,8 +134,8 @@ class User(BaseModel):
id: str id: str
email: Optional[str] = None email: Optional[str] = None
username: Optional[str] = None username: Optional[str] = None
extensions: List[str] = [] extensions: list[str] = []
wallets: List[Wallet] = [] wallets: list[Wallet] = []
admin: bool = False admin: bool = False
super_user: bool = False super_user: bool = False
has_password: bool = False has_password: bool = False
@@ -142,10 +144,10 @@ class User(BaseModel):
updated_at: Optional[int] = None updated_at: Optional[int] = None
@property @property
def wallet_ids(self) -> List[str]: def wallet_ids(self) -> list[str]:
return [wallet.id for wallet in self.wallets] return [wallet.id for wallet in self.wallets]
def get_wallet(self, wallet_id: str) -> Optional["Wallet"]: def get_wallet(self, wallet_id: str) -> Optional[Wallet]:
w = [wallet for wallet in self.wallets if wallet.id == wallet_id] w = [wallet for wallet in self.wallets if wallet.id == wallet_id]
return w[0] if w else None return w[0] if w else None
@@ -208,7 +210,7 @@ class Payment(FromRowModel):
preimage: str preimage: str
payment_hash: str payment_hash: str
expiry: Optional[float] expiry: Optional[float]
extra: Dict = {} extra: dict = {}
wallet_id: str wallet_id: str
webhook: Optional[str] webhook: Optional[str]
webhook_status: Optional[int] webhook_status: Optional[int]
@@ -349,7 +351,7 @@ class PaymentFilters(FilterModel):
preimage: str preimage: str
payment_hash: str payment_hash: str
expiry: Optional[datetime.datetime] expiry: Optional[datetime.datetime]
extra: Dict = {} extra: dict = {}
wallet_id: str wallet_id: str
webhook: Optional[str] webhook: Optional[str]
webhook_status: Optional[int] webhook_status: Optional[int]
+2 -2
View File
@@ -175,7 +175,7 @@ async def check_pending_payments():
async def invoice_callback_dispatcher(checking_id: str): async def invoice_callback_dispatcher(checking_id: str):
""" """
Takes incoming payments, sets pending=False, and dispatches them to Takes an incoming payment, checks its status, and dispatches it to
invoice_listeners from core and extensions. invoice_listeners from core and extensions.
""" """
payment = await get_standalone_payment(checking_id, incoming=True) payment = await get_standalone_payment(checking_id, incoming=True)
@@ -183,7 +183,7 @@ async def invoice_callback_dispatcher(checking_id: str):
logger.trace( logger.trace(
f"invoice listeners: sending invoice callback for payment {checking_id}" f"invoice listeners: sending invoice callback for payment {checking_id}"
) )
await payment.set_pending(False) await payment.check_status()
for name, send_chan in invoice_listeners.items(): for name, send_chan in invoice_listeners.items():
logger.trace(f"invoice listeners: sending to `{name}`") logger.trace(f"invoice listeners: sending to `{name}`")
await send_chan.put(payment) await send_chan.put(payment)
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "lnbits" name = "lnbits"
version = "0.12.9" version = "0.12.10"
description = "LNbits, free and open-source Lightning wallet and accounts system." description = "LNbits, free and open-source Lightning wallet and accounts system."
authors = ["Alan Bits <alan@lnbits.com>"] authors = ["Alan Bits <alan@lnbits.com>"]
readme = "README.md" readme = "README.md"