feat: use uv instead of poetry for CI, docker and development (#3325)

Co-authored-by: arcbtc <ben@arc.wales>
This commit is contained in:
dni ⚡
2025-08-21 16:17:19 +02:00
committed by GitHub
co-authored by arcbtc
parent 15984fa49b
commit 5ba06d42d0
88 changed files with 4265 additions and 1303 deletions
+8 -10
View File
@@ -1,5 +1,3 @@
from typing import Optional
from lnbits.core.db import db
from lnbits.core.models import AuditEntry, AuditFilters
from lnbits.core.models.audit import AuditCountStat
@@ -8,14 +6,14 @@ from lnbits.db import Connection, Filters, Page
async def create_audit_entry(
entry: AuditEntry,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
await (conn or db).insert("audit", entry)
async def get_audit_entries(
filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None,
filters: Filters[AuditFilters] | None = None,
conn: Connection | None = None,
) -> Page[AuditEntry]:
return await (conn or db).fetch_page(
"SELECT * from audit",
@@ -27,7 +25,7 @@ async def get_audit_entries(
async def delete_expired_audit_entries(
conn: Optional[Connection] = None,
conn: Connection | None = None,
):
await (conn or db).execute(
# Timestamp placeholder is safe from SQL injection (not user input)
@@ -40,8 +38,8 @@ async def delete_expired_audit_entries(
async def get_count_stats(
field: str,
filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None,
filters: Filters[AuditFilters] | None = None,
conn: Connection | None = None,
) -> list[AuditCountStat]:
if field not in ["request_method", "component", "response_code"]:
return []
@@ -67,8 +65,8 @@ async def get_count_stats(
async def get_long_duration_stats(
filters: Optional[Filters[AuditFilters]] = None,
conn: Optional[Connection] = None,
filters: Filters[AuditFilters] | None = None,
conn: Connection | None = None,
) -> list[AuditCountStat]:
if not filters:
filters = Filters()
+4 -6
View File
@@ -1,5 +1,3 @@
from typing import Optional
from lnbits.core.db import db
from lnbits.db import Connection
@@ -7,8 +5,8 @@ from ..models import DbVersion
async def get_db_version(
ext_id: str, conn: Optional[Connection] = None
) -> Optional[DbVersion]:
ext_id: str, conn: Connection | None = None
) -> DbVersion | None:
return await (conn or db).fetchone(
"SELECT * FROM dbversions WHERE db = :ext_id",
{"ext_id": ext_id},
@@ -16,7 +14,7 @@ async def get_db_version(
)
async def get_db_versions(conn: Optional[Connection] = None) -> list[DbVersion]:
async def get_db_versions(conn: Connection | None = None) -> list[DbVersion]:
return await (conn or db).fetchall("SELECT * FROM dbversions", model=DbVersion)
@@ -30,7 +28,7 @@ async def update_migration_version(conn, db_name, version):
)
async def delete_dbversion(*, ext_id: str, conn: Optional[Connection] = None) -> None:
async def delete_dbversion(*, ext_id: str, conn: Connection | None = None) -> None:
await (conn or db).execute(
"""
DELETE FROM dbversions WHERE db = :ext
+15 -17
View File
@@ -1,5 +1,3 @@
from typing import Optional
from lnbits.core.db import db
from lnbits.core.models.extensions import (
InstallableExtension,
@@ -10,20 +8,20 @@ from lnbits.db import Connection, Database
async def create_installed_extension(
ext: InstallableExtension,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
await (conn or db).insert("installed_extensions", ext)
async def update_installed_extension(
ext: InstallableExtension,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
await (conn or db).update("installed_extensions", ext)
async def update_installed_extension_state(
*, ext_id: str, active: bool, conn: Optional[Connection] = None
*, ext_id: str, active: bool, conn: Connection | None = None
) -> None:
await (conn or db).execute(
"""
@@ -34,7 +32,7 @@ async def update_installed_extension_state(
async def delete_installed_extension(
*, ext_id: str, conn: Optional[Connection] = None
*, ext_id: str, conn: Connection | None = None
) -> None:
await (conn or db).execute(
"""
@@ -44,7 +42,7 @@ async def delete_installed_extension(
)
async def drop_extension_db(ext_id: str, conn: Optional[Connection] = None) -> None:
async def drop_extension_db(ext_id: str, conn: Connection | None = None) -> None:
row: dict = await (conn or db).fetchone(
"SELECT * FROM dbversions WHERE db = :id",
{"id": ext_id},
@@ -65,8 +63,8 @@ async def drop_extension_db(ext_id: str, conn: Optional[Connection] = None) -> N
async def get_installed_extension(
ext_id: str, conn: Optional[Connection] = None
) -> Optional[InstallableExtension]:
ext_id: str, conn: Connection | None = None
) -> InstallableExtension | None:
extension = await (conn or db).fetchone(
"SELECT * FROM installed_extensions WHERE id = :id",
{"id": ext_id},
@@ -76,8 +74,8 @@ async def get_installed_extension(
async def get_installed_extensions(
active: Optional[bool] = None,
conn: Optional[Connection] = None,
active: bool | None = None,
conn: Connection | None = None,
) -> list[InstallableExtension]:
query = "SELECT * FROM installed_extensions"
if active is not None:
@@ -93,8 +91,8 @@ async def get_installed_extensions(
async def get_user_extension(
user_id: str, extension: str, conn: Optional[Connection] = None
) -> Optional[UserExtension]:
user_id: str, extension: str, conn: Connection | None = None
) -> UserExtension | None:
return await (conn or db).fetchone(
"""
SELECT * FROM extensions
@@ -106,7 +104,7 @@ async def get_user_extension(
async def get_user_extensions(
user_id: str, conn: Optional[Connection] = None
user_id: str, conn: Connection | None = None
) -> list[UserExtension]:
return await (conn or db).fetchall(
"""SELECT * FROM extensions WHERE "user" = :user""",
@@ -116,20 +114,20 @@ async def get_user_extensions(
async def create_user_extension(
user_extension: UserExtension, conn: Optional[Connection] = None
user_extension: UserExtension, conn: Connection | None = None
) -> None:
await (conn or db).insert("extensions", user_extension)
async def update_user_extension(
user_extension: UserExtension, conn: Optional[Connection] = None
user_extension: UserExtension, conn: Connection | None = None
) -> None:
where = """WHERE extension = :extension AND "user" = :user"""
await (conn or db).update("extensions", user_extension, where)
async def get_user_active_extensions_ids(
user_id: str, conn: Optional[Connection] = None
user_id: str, conn: Connection | None = None
) -> list[str]:
exts = await (conn or db).fetchall(
"""
+40 -40
View File
@@ -1,5 +1,5 @@
from time import time
from typing import Any, Optional
from typing import Any
from lnbits.core.crud.wallets import get_total_balance, get_wallet, get_wallets_ids
from lnbits.core.db import db
@@ -23,7 +23,7 @@ def update_payment_extra():
pass
async def get_payment(checking_id: str, conn: Optional[Connection] = None) -> Payment:
async def get_payment(checking_id: str, conn: Connection | None = None) -> Payment:
return await (conn or db).fetchone(
"SELECT * FROM apipayments WHERE checking_id = :checking_id",
{"checking_id": checking_id},
@@ -33,10 +33,10 @@ async def get_payment(checking_id: str, conn: Optional[Connection] = None) -> Pa
async def get_standalone_payment(
checking_id_or_hash: str,
conn: Optional[Connection] = None,
incoming: Optional[bool] = False,
wallet_id: Optional[str] = None,
) -> Optional[Payment]:
conn: Connection | None = None,
incoming: bool | None = False,
wallet_id: str | None = None,
) -> Payment | None:
clause: str = "checking_id = :checking_id OR payment_hash = :hash"
values = {
"wallet_id": wallet_id,
@@ -64,8 +64,8 @@ async def get_standalone_payment(
async def get_wallet_payment(
wallet_id: str, payment_hash: str, conn: Optional[Connection] = None
) -> Optional[Payment]:
wallet_id: str, payment_hash: str, conn: Connection | None = None
) -> Payment | None:
payment = await (conn or db).fetchone(
"""
SELECT *
@@ -102,17 +102,17 @@ async def get_latest_payments_by_extension(
async def get_payments_paginated( # noqa: C901
*,
wallet_id: Optional[str] = None,
user_id: Optional[str] = None,
wallet_id: str | None = None,
user_id: str | None = None,
complete: bool = False,
pending: bool = False,
failed: bool = False,
outgoing: bool = False,
incoming: bool = False,
since: Optional[int] = None,
since: int | None = None,
exclude_uncheckable: bool = False,
filters: Optional[Filters[PaymentFilters]] = None,
conn: Optional[Connection] = None,
filters: Filters[PaymentFilters] | None = None,
conn: Connection | None = None,
) -> Page[Payment]:
"""
Filters payments to be returned by:
@@ -176,17 +176,17 @@ async def get_payments_paginated( # noqa: C901
async def get_payments(
*,
wallet_id: Optional[str] = None,
wallet_id: str | None = None,
complete: bool = False,
pending: bool = False,
outgoing: bool = False,
incoming: bool = False,
since: Optional[int] = None,
since: int | None = None,
exclude_uncheckable: bool = False,
filters: Optional[Filters[PaymentFilters]] = None,
conn: Optional[Connection] = None,
limit: Optional[int] = None,
offset: Optional[int] = None,
filters: Filters[PaymentFilters] | None = None,
conn: Connection | None = None,
limit: int | None = None,
offset: int | None = None,
) -> list[Payment]:
"""
Filters payments to be returned by complete | pending | outgoing | incoming.
@@ -230,7 +230,7 @@ async def get_payments_status_count() -> PaymentsStatusCount:
async def delete_expired_invoices(
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
# first we delete all invoices older than one month
@@ -259,7 +259,7 @@ async def create_payment(
checking_id: str,
data: CreatePayment,
status: PaymentState = PaymentState.PENDING,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Payment:
# we don't allow the creation of the same invoice twice
# note: this can be removed if the db uniqueness constraints are set appropriately
@@ -290,7 +290,7 @@ async def create_payment(
async def update_payment_checking_id(
checking_id: str, new_checking_id: str, conn: Optional[Connection] = None
checking_id: str, new_checking_id: str, conn: Connection | None = None
) -> None:
await (conn or db).execute(
"UPDATE apipayments SET checking_id = :new_id WHERE checking_id = :old_id",
@@ -300,8 +300,8 @@ async def update_payment_checking_id(
async def update_payment(
payment: Payment,
new_checking_id: Optional[str] = None,
conn: Optional[Connection] = None,
new_checking_id: str | None = None,
conn: Connection | None = None,
) -> None:
await (conn or db).update(
"apipayments", payment, "WHERE checking_id = :checking_id"
@@ -311,9 +311,9 @@ async def update_payment(
async def get_payments_history(
wallet_id: Optional[str] = None,
wallet_id: str | None = None,
group: DateTrunc = "day",
filters: Optional[Filters] = None,
filters: Filters | None = None,
) -> list[PaymentHistoryPoint]:
if not filters:
filters = Filters()
@@ -376,9 +376,9 @@ async def get_payments_history(
async def get_payment_count_stats(
field: PaymentCountField,
filters: Optional[Filters[PaymentFilters]] = None,
user_id: Optional[str] = None,
conn: Optional[Connection] = None,
filters: Filters[PaymentFilters] | None = None,
user_id: str | None = None,
conn: Connection | None = None,
) -> list[PaymentCountStat]:
if not filters:
@@ -409,9 +409,9 @@ async def get_payment_count_stats(
async def get_daily_stats(
filters: Optional[Filters[PaymentFilters]] = None,
user_id: Optional[str] = None,
conn: Optional[Connection] = None,
filters: Filters[PaymentFilters] | None = None,
user_id: str | None = None,
conn: Connection | None = None,
) -> tuple[list[PaymentDailyStats], list[PaymentDailyStats]]:
if not filters:
@@ -459,9 +459,9 @@ async def get_daily_stats(
async def get_wallets_stats(
filters: Optional[Filters[PaymentFilters]] = None,
user_id: Optional[str] = None,
conn: Optional[Connection] = None,
filters: Filters[PaymentFilters] | None = None,
user_id: str | None = None,
conn: Connection | None = None,
) -> list[PaymentWalletStats]:
if not filters:
@@ -508,7 +508,7 @@ async def get_wallets_stats(
async def delete_wallet_payment(
checking_id: str, wallet_id: str, conn: Optional[Connection] = None
checking_id: str, wallet_id: str, conn: Connection | None = None
) -> None:
await (conn or db).execute(
"DELETE FROM apipayments WHERE checking_id = :checking_id AND wallet = :wallet",
@@ -517,8 +517,8 @@ async def delete_wallet_payment(
async def check_internal(
payment_hash: str, conn: Optional[Connection] = None
) -> Optional[Payment]:
payment_hash: str, conn: Connection | None = None
) -> Payment | None:
"""
Returns the checking_id of the internal payment if it exists,
otherwise None
@@ -534,7 +534,7 @@ async def check_internal(
async def is_internal_status_success(
payment_hash: str, conn: Optional[Connection] = None
payment_hash: str, conn: Connection | None = None
) -> bool:
"""
Returns True if the internal payment was found and is successful,
@@ -563,7 +563,7 @@ async def mark_webhook_sent(payment_hash: str, status: str) -> None:
async def _only_user_wallets_statement(
user_id: str, conn: Optional[Connection] = None
user_id: str, conn: Connection | None = None
) -> str:
wallet_ids = await get_wallets_ids(user_id=user_id, conn=conn) or [
"no-wallets-for-user"
+9 -11
View File
@@ -1,5 +1,5 @@
import json
from typing import Any, Optional
from typing import Any
from loguru import logger
@@ -14,7 +14,7 @@ from lnbits.settings import (
)
async def get_super_settings() -> Optional[SuperSettings]:
async def get_super_settings() -> SuperSettings | None:
data = await get_settings_by_tag("core")
if data:
super_user = await get_settings_field("super_user")
@@ -24,7 +24,7 @@ async def get_super_settings() -> Optional[SuperSettings]:
return None
async def get_admin_settings(is_super_user: bool = False) -> Optional[AdminSettings]:
async def get_admin_settings(is_super_user: bool = False) -> AdminSettings | None:
sets = await get_super_settings()
if not sets:
return None
@@ -41,7 +41,7 @@ async def get_admin_settings(is_super_user: bool = False) -> Optional[AdminSetti
async def update_admin_settings(
data: EditableSettings, tag: Optional[str] = "core"
data: EditableSettings, tag: str | None = "core"
) -> None:
editable_settings = await get_settings_by_tag("core") or {}
editable_settings.update(data.dict(exclude_unset=True))
@@ -61,7 +61,7 @@ async def update_super_user(super_user: str) -> SuperSettings:
return settings
async def delete_admin_settings(tag: Optional[str] = "core") -> None:
async def delete_admin_settings(tag: str | None = "core") -> None:
await db.execute(
"DELETE FROM system_settings WHERE tag = :tag",
{"tag": tag},
@@ -93,8 +93,8 @@ async def create_admin_settings(super_user: str, new_settings: dict) -> SuperSet
async def get_settings_field(
id_: str, tag: Optional[str] = "core"
) -> Optional[SettingsField]:
id_: str, tag: str | None = "core"
) -> SettingsField | None:
row: dict = await db.fetchone(
"""
@@ -108,9 +108,7 @@ async def get_settings_field(
return SettingsField(id=row["id"], value=json.loads(row["value"]), tag=row["tag"])
async def set_settings_field(
id_: str, value: Optional[Any], tag: Optional[str] = "core"
):
async def set_settings_field(id_: str, value: Any | None, tag: str | None = "core"):
value = json.dumps(value) if value is not None else None
await db.execute(
"""
@@ -122,7 +120,7 @@ async def set_settings_field(
)
async def get_settings_by_tag(tag: str) -> Optional[dict[str, Any]]:
async def get_settings_by_tag(tag: str) -> dict[str, Any] | None:
rows: list[dict] = await db.fetchall(
"SELECT * FROM system_settings WHERE tag = :tag", {"tag": tag}
)
+1 -3
View File
@@ -1,5 +1,3 @@
from typing import Optional
import shortuuid
from lnbits.core.db import db
@@ -19,7 +17,7 @@ async def create_tinyurl(domain: str, endless: bool, wallet: str):
return await get_tinyurl(tinyurl_id)
async def get_tinyurl(tinyurl_id: str) -> Optional[TinyURL]:
async def get_tinyurl(tinyurl_id: str) -> TinyURL | None:
return await db.fetchone(
"SELECT * FROM tiny_url WHERE id = :tinyurl",
{"tinyurl": tinyurl_id},
+20 -22
View File
@@ -1,6 +1,6 @@
from datetime import datetime, timezone
from time import time
from typing import Any, Optional
from typing import Any
from uuid import uuid4
from lnbits.core.crud.extensions import get_user_active_extensions_ids
@@ -18,8 +18,8 @@ from ..models import (
async def create_account(
account: Optional[Account] = None,
conn: Optional[Connection] = None,
account: Account | None = None,
conn: Connection | None = None,
) -> Account:
if account:
account.validate_fields()
@@ -36,7 +36,7 @@ async def update_account(account: Account) -> Account:
return account
async def delete_account(user_id: str, conn: Optional[Connection] = None) -> None:
async def delete_account(user_id: str, conn: Connection | None = None) -> None:
await (conn or db).execute(
"DELETE from accounts WHERE id = :user",
{"user": user_id},
@@ -44,8 +44,8 @@ async def delete_account(user_id: str, conn: Optional[Connection] = None) -> Non
async def get_accounts(
filters: Optional[Filters[AccountFilters]] = None,
conn: Optional[Connection] = None,
filters: Filters[AccountFilters] | None = None,
conn: Connection | None = None,
) -> Page[AccountOverview]:
where_clauses = []
values: dict[str, Any] = {}
@@ -92,9 +92,7 @@ async def get_accounts(
)
async def get_account(
user_id: str, conn: Optional[Connection] = None
) -> Optional[Account]:
async def get_account(user_id: str, conn: Connection | None = None) -> Account | None:
if len(user_id) == 0:
return None
return await (conn or db).fetchone(
@@ -106,7 +104,7 @@ async def get_account(
async def delete_accounts_no_wallets(
time_delta: int,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
delta = int(time()) - time_delta
await (conn or db).execute(
@@ -125,8 +123,8 @@ async def delete_accounts_no_wallets(
async def get_account_by_username(
username: str, conn: Optional[Connection] = None
) -> Optional[Account]:
username: str, conn: Connection | None = None
) -> Account | None:
if len(username) == 0:
return None
return await (conn or db).fetchone(
@@ -137,8 +135,8 @@ async def get_account_by_username(
async def get_account_by_pubkey(
pubkey: str, conn: Optional[Connection] = None
) -> Optional[Account]:
pubkey: str, conn: Connection | None = None
) -> Account | None:
return await (conn or db).fetchone(
"SELECT * FROM accounts WHERE LOWER(pubkey) = :pubkey",
{"pubkey": pubkey.lower()},
@@ -147,8 +145,8 @@ async def get_account_by_pubkey(
async def get_account_by_email(
email: str, conn: Optional[Connection] = None
) -> Optional[Account]:
email: str, conn: Connection | None = None
) -> Account | None:
if len(email) == 0:
return None
return await (conn or db).fetchone(
@@ -159,8 +157,8 @@ async def get_account_by_email(
async def get_account_by_username_or_email(
username_or_email: str, conn: Optional[Connection] = None
) -> Optional[Account]:
username_or_email: str, conn: Connection | None = None
) -> Account | None:
return await (conn or db).fetchone(
"""
SELECT * FROM accounts
@@ -171,7 +169,7 @@ async def get_account_by_username_or_email(
)
async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[User]:
async def get_user(user_id: str, conn: Connection | None = None) -> User | None:
account = await get_account(user_id, conn)
if not account:
return None
@@ -179,8 +177,8 @@ async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[
async def get_user_from_account(
account: Account, conn: Optional[Connection] = None
) -> Optional[User]:
account: Account, conn: Connection | None = None
) -> User | None:
extensions = await get_user_active_extensions_ids(account.id, conn)
wallets = await get_wallets(account.id, False, conn=conn)
return User(
@@ -207,7 +205,7 @@ async def update_user_access_control_list(user_acls: UserAcls):
async def get_user_access_control_lists(
user_id: str, conn: Optional[Connection] = None
user_id: str, conn: Connection | None = None
) -> UserAcls:
user_acls = await (conn or db).fetchone(
"SELECT id, access_control_list FROM accounts WHERE id = :id",
+19 -22
View File
@@ -1,6 +1,5 @@
from datetime import datetime, timezone
from time import time
from typing import Optional
from uuid import uuid4
from lnbits.core.db import db
@@ -14,8 +13,8 @@ from ..models import Wallet
async def create_wallet(
*,
user_id: str,
wallet_name: Optional[str] = None,
conn: Optional[Connection] = None,
wallet_name: str | None = None,
conn: Connection | None = None,
) -> Wallet:
wallet_id = uuid4().hex
wallet = Wallet(
@@ -32,7 +31,7 @@ async def create_wallet(
async def update_wallet(
wallet: Wallet,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Wallet:
wallet.updated_at = datetime.now(timezone.utc)
await (conn or db).update("wallets", wallet)
@@ -44,7 +43,7 @@ async def delete_wallet(
user_id: str,
wallet_id: str,
deleted: bool = True,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
now = int(time())
await (conn or db).execute(
@@ -58,9 +57,7 @@ async def delete_wallet(
)
async def force_delete_wallet(
wallet_id: str, conn: Optional[Connection] = None
) -> None:
async def force_delete_wallet(wallet_id: str, conn: Connection | None = None) -> None:
await (conn or db).execute(
"DELETE FROM wallets WHERE id = :wallet",
{"wallet": wallet_id},
@@ -68,8 +65,8 @@ async def force_delete_wallet(
async def delete_wallet_by_id(
wallet_id: str, conn: Optional[Connection] = None
) -> Optional[int]:
wallet_id: str, conn: Connection | None = None
) -> int | None:
now = int(time())
result = await (conn or db).execute(
# Timestamp placeholder is safe from SQL injection (not user input)
@@ -83,13 +80,13 @@ async def delete_wallet_by_id(
return result.rowcount
async def remove_deleted_wallets(conn: Optional[Connection] = None) -> None:
async def remove_deleted_wallets(conn: Connection | None = None) -> None:
await (conn or db).execute("DELETE FROM wallets WHERE deleted = true")
async def delete_unused_wallets(
time_delta: int,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> None:
delta = int(time()) - time_delta
await (conn or db).execute(
@@ -107,8 +104,8 @@ async def delete_unused_wallets(
async def get_wallet(
wallet_id: str, deleted: Optional[bool] = None, conn: Optional[Connection] = None
) -> Optional[Wallet]:
wallet_id: str, deleted: bool | None = None, conn: Connection | None = None
) -> Wallet | None:
query = """
SELECT *, COALESCE((
SELECT balance FROM balances WHERE wallet_id = wallets.id
@@ -125,7 +122,7 @@ async def get_wallet(
async def get_wallets(
user_id: str, deleted: Optional[bool] = None, conn: Optional[Connection] = None
user_id: str, deleted: bool | None = None, conn: Connection | None = None
) -> list[Wallet]:
query = """
SELECT *, COALESCE((
@@ -144,9 +141,9 @@ async def get_wallets(
async def get_wallets_paginated(
user_id: str,
deleted: Optional[bool] = None,
filters: Optional[Filters[WalletsFilters]] = None,
conn: Optional[Connection] = None,
deleted: bool | None = None,
filters: Filters[WalletsFilters] | None = None,
conn: Connection | None = None,
) -> Page[Wallet]:
if deleted is None:
deleted = False
@@ -166,7 +163,7 @@ async def get_wallets_paginated(
async def get_wallets_ids(
user_id: str, deleted: Optional[bool] = None, conn: Optional[Connection] = None
user_id: str, deleted: bool | None = None, conn: Connection | None = None
) -> list[str]:
query = """SELECT id FROM wallets WHERE "user" = :user"""
if deleted is not None:
@@ -186,8 +183,8 @@ async def get_wallets_count():
async def get_wallet_for_key(
key: str,
conn: Optional[Connection] = None,
) -> Optional[Wallet]:
conn: Connection | None = None,
) -> Wallet | None:
return await (conn or db).fetchone(
"""
SELECT *, COALESCE((
@@ -201,7 +198,7 @@ async def get_wallet_for_key(
)
async def get_total_balance(conn: Optional[Connection] = None):
async def get_total_balance(conn: Connection | None = None):
result = await (conn or db).execute("SELECT SUM(balance) as balance FROM balances")
row = result.mappings().first()
return row.get("balance", 0) or 0
+1 -3
View File
@@ -1,5 +1,3 @@
from typing import Optional
from lnbits.core.db import db
from ..models import WebPushSubscription
@@ -7,7 +5,7 @@ from ..models import WebPushSubscription
async def get_webpush_subscription(
endpoint: str, user: str
) -> Optional[WebPushSubscription]:
) -> WebPushSubscription | None:
return await db.fetchone(
"""
SELECT * FROM webpush_subscriptions
+3 -3
View File
@@ -1,6 +1,6 @@
import importlib
import re
from typing import Any, Optional
from typing import Any
from urllib.parse import urlparse
from uuid import UUID
@@ -20,7 +20,7 @@ from lnbits.settings import settings
async def migrate_extension_database(
ext: InstallableExtension, current_version: Optional[DbVersion] = None
ext: InstallableExtension, current_version: DbVersion | None = None
):
try:
@@ -38,7 +38,7 @@ async def run_migration(
db: Connection,
migrations_module: Any,
db_name: str,
current_version: Optional[DbVersion] = None,
current_version: DbVersion | None = None,
):
matcher = re.compile(r"^m(\d\d\d)_")
+3 -4
View File
@@ -1,5 +1,4 @@
from time import time
from typing import Optional
from lnurl import LnAddress, Lnurl, LnurlPayResponse
from pydantic import BaseModel, Field
@@ -9,9 +8,9 @@ class CreateLnurlPayment(BaseModel):
res: LnurlPayResponse | None = None
lnurl: Lnurl | LnAddress | None = None
amount: int
comment: Optional[str] = None
unit: Optional[str] = None
internal_memo: Optional[str] = None
comment: str | None = None
unit: str | None = None
internal_memo: str | None = None
class CreateLnurlWithdraw(BaseModel):
+1 -1
View File
@@ -1,6 +1,6 @@
from __future__ import annotations
from typing import Callable
from collections.abc import Callable
from pydantic import BaseModel
+3 -4
View File
@@ -1,6 +1,5 @@
import asyncio
import importlib
from typing import Optional
from loguru import logger
@@ -145,7 +144,7 @@ async def start_extension_background_work(ext_id: str) -> bool:
async def get_valid_extensions(
include_deactivated: Optional[bool] = True,
include_deactivated: bool | None = True,
) -> list[Extension]:
installed_extensions = await get_installed_extensions()
valid_extensions = [Extension.from_installable_ext(e) for e in installed_extensions]
@@ -164,8 +163,8 @@ async def get_valid_extensions(
async def get_valid_extension(
ext_id: str, include_deactivated: Optional[bool] = True
) -> Optional[Extension]:
ext_id: str, include_deactivated: bool | None = True
) -> Extension | None:
ext = await get_installed_extension(ext_id)
if not ext:
return None
+5 -6
View File
@@ -1,7 +1,6 @@
import hashlib
import hmac
import time
from typing import Optional
from loguru import logger
@@ -15,7 +14,7 @@ from lnbits.settings import settings
async def handle_fiat_payment_confirmation(
payment: Payment, conn: Optional[Connection] = None
payment: Payment, conn: Connection | None = None
):
try:
await _credit_fiat_service_fee_wallet(payment, conn=conn)
@@ -29,7 +28,7 @@ async def handle_fiat_payment_confirmation(
async def _credit_fiat_service_fee_wallet(
payment: Payment, conn: Optional[Connection] = None
payment: Payment, conn: Connection | None = None
):
fiat_provider_name = payment.fiat_provider
if not fiat_provider_name:
@@ -66,7 +65,7 @@ async def _credit_fiat_service_fee_wallet(
async def _debit_fiat_service_faucet_wallet(
payment: Payment, conn: Optional[Connection] = None
payment: Payment, conn: Connection | None = None
):
fiat_provider_name = payment.fiat_provider
if not fiat_provider_name:
@@ -129,8 +128,8 @@ async def handle_stripe_event(event: dict):
def check_stripe_signature(
payload: bytes,
sig_header: Optional[str],
secret: Optional[str],
sig_header: str | None,
secret: str | None,
tolerance_seconds=300,
):
if not sig_header:
+3 -4
View File
@@ -4,7 +4,6 @@ import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from http import HTTPStatus
from typing import Optional
import httpx
from loguru import logger
@@ -71,7 +70,7 @@ async def process_next_notification() -> None:
async def send_admin_notification(
message: str,
message_type: Optional[str] = None,
message_type: str | None = None,
) -> None:
return await send_notification(
settings.lnbits_telegram_notifications_chat_id,
@@ -85,7 +84,7 @@ async def send_admin_notification(
async def send_user_notification(
user_notifications: UserNotifications,
message: str,
message_type: Optional[str] = None,
message_type: str | None = None,
) -> None:
email_address = (
@@ -110,7 +109,7 @@ async def send_notification(
nostr_identifiers: list[str] | None,
email_addresses: list[str] | None,
message: str,
message_type: Optional[str] = None,
message_type: str | None = None,
) -> None:
try:
if telegram_chat_id and settings.is_telegram_notifications_configured():
+31 -32
View File
@@ -1,7 +1,6 @@
import asyncio
import time
from datetime import datetime, timedelta, timezone
from typing import Optional
from bolt11 import Bolt11, MilliSatoshi, Tags
from bolt11 import decode as bolt11_decode
@@ -58,11 +57,11 @@ async def pay_invoice(
*,
wallet_id: str,
payment_request: str,
max_sat: Optional[int] = None,
extra: Optional[dict] = None,
max_sat: int | None = None,
extra: dict | None = None,
description: str = "",
tag: str = "",
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Payment:
if settings.lnbits_only_allow_incoming_payments:
raise PaymentError("Only incoming payments allowed.", status="failed")
@@ -110,7 +109,7 @@ async def create_payment_request(
async def create_fiat_invoice(
wallet_id: str, invoice_data: CreateInvoice, conn: Optional[Connection] = None
wallet_id: str, invoice_data: CreateInvoice, conn: Connection | None = None
):
fiat_provider_name = invoice_data.fiat_provider
if not fiat_provider_name:
@@ -231,16 +230,16 @@ async def create_invoice(
*,
wallet_id: str,
amount: float,
currency: Optional[str] = "sat",
currency: str | None = "sat",
memo: str,
description_hash: Optional[bytes] = None,
unhashed_description: Optional[bytes] = None,
expiry: Optional[int] = None,
extra: Optional[dict] = None,
webhook: Optional[str] = None,
internal: Optional[bool] = False,
description_hash: bytes | None = None,
unhashed_description: bytes | None = None,
expiry: int | None = None,
extra: dict | None = None,
webhook: str | None = None,
internal: bool | None = False,
payment_hash: str | None = None,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Payment:
if not amount > 0:
raise InvoiceError("Amountless invoices not supported.", status="failed")
@@ -427,7 +426,7 @@ def service_fee_fiat(amount_msat: int, fiat_provider_name: str) -> int:
async def update_wallet_balance(
wallet: Wallet,
amount: int,
conn: Optional[Connection] = None,
conn: Connection | None = None,
):
if amount == 0:
raise ValueError("Amount cannot be 0.")
@@ -486,14 +485,14 @@ async def update_wallet_balance(
async def check_wallet_limits(
wallet_id: str, amount_msat: int, conn: Optional[Connection] = None
wallet_id: str, amount_msat: int, conn: Connection | None = None
):
await check_time_limit_between_transactions(wallet_id, conn)
await check_wallet_daily_withdraw_limit(wallet_id, amount_msat, conn)
async def check_time_limit_between_transactions(
wallet_id: str, conn: Optional[Connection] = None
wallet_id: str, conn: Connection | None = None
):
limit = settings.lnbits_wallet_limit_secs_between_trans
if not limit or limit <= 0:
@@ -513,7 +512,7 @@ async def check_time_limit_between_transactions(
async def check_wallet_daily_withdraw_limit(
wallet_id: str, amount_msat: int, conn: Optional[Connection] = None
wallet_id: str, amount_msat: int, conn: Connection | None = None
):
limit = settings.lnbits_wallet_limit_daily_max_withdraw
if not limit:
@@ -546,8 +545,8 @@ async def check_wallet_daily_withdraw_limit(
async def calculate_fiat_amounts(
amount: float,
wallet: Wallet,
currency: Optional[str] = None,
extra: Optional[dict] = None,
currency: str | None = None,
extra: dict | None = None,
) -> tuple[int, dict]:
wallet_currency = wallet.currency or settings.lnbits_default_accounting_currency
fiat_amounts: dict = extra or {}
@@ -582,9 +581,9 @@ async def calculate_fiat_amounts(
async def check_transaction_status(
wallet_id: str, payment_hash: str, conn: Optional[Connection] = None
wallet_id: str, payment_hash: str, conn: Connection | None = None
) -> PaymentStatus:
payment: Optional[Payment] = await get_wallet_payment(
payment: Payment | None = await get_wallet_payment(
wallet_id, payment_hash, conn=conn
)
if not payment:
@@ -598,7 +597,7 @@ async def check_transaction_status(
async def get_payments_daily_stats(
filters: Filters[PaymentFilters],
user_id: Optional[str] = None,
user_id: str | None = None,
) -> list[PaymentDailyStats]:
data_in, data_out = await get_daily_stats(filters, user_id=user_id)
balance_total: float = 0
@@ -647,7 +646,7 @@ async def get_payments_daily_stats(
async def _pay_invoice(
wallet_id: str,
create_payment_model: CreatePayment,
conn: Optional[Connection] = None,
conn: Connection | None = None,
):
async with payment_lock:
if wallet_id not in wallets_payments_lock:
@@ -670,8 +669,8 @@ async def _pay_invoice(
async def _pay_internal_invoice(
wallet: Wallet,
create_payment_model: CreatePayment,
conn: Optional[Connection] = None,
) -> Optional[Payment]:
conn: Connection | None = None,
) -> Payment | None:
"""
Pay an internal payment.
returns None if the payment is not internal.
@@ -738,7 +737,7 @@ async def _pay_internal_invoice(
async def _pay_external_invoice(
wallet: Wallet,
create_payment_model: CreatePayment,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Payment:
checking_id = create_payment_model.payment_hash
amount_msat = create_payment_model.amount_msat
@@ -807,7 +806,7 @@ async def _pay_external_invoice(
async def update_payment_success_status(
payment: Payment,
status: PaymentStatus,
conn: Optional[Connection] = None,
conn: Connection | None = None,
) -> Payment:
if status.success:
service_fee_msat = service_fee(payment.amount, internal=False)
@@ -831,7 +830,7 @@ async def _fundingsource_pay_invoice(
async def _verify_external_payment(
payment: Payment, conn: Optional[Connection] = None
payment: Payment, conn: Connection | None = None
) -> Payment:
# fail on pending payments
if payment.pending:
@@ -862,7 +861,7 @@ async def _check_wallet_for_payment(
wallet_id: str,
tag: str,
amount_msat: int,
conn: Optional[Connection] = None,
conn: Connection | None = None,
):
wallet = await get_wallet(wallet_id, conn=conn)
if not wallet:
@@ -878,7 +877,7 @@ async def _check_wallet_for_payment(
def _validate_payment_request(
payment_request: str, max_sat: Optional[int] = None
payment_request: str, max_sat: int | None = None
) -> Bolt11:
try:
invoice = bolt11_decode(payment_request)
@@ -901,7 +900,7 @@ def _validate_payment_request(
async def _credit_service_fee_wallet(
wallet: Wallet, payment: Payment, conn: Optional[Connection] = None
wallet: Wallet, payment: Payment, conn: Connection | None = None
):
service_fee_msat = service_fee(payment.amount, internal=payment.is_internal)
if not settings.lnbits_service_fee_wallet or not service_fee_msat:
@@ -927,7 +926,7 @@ async def _credit_service_fee_wallet(
async def _check_fiat_invoice_limits(
amount_sat: int, fiat_provider_name: str, conn: Optional[Connection] = None
amount_sat: int, fiat_provider_name: str, conn: Connection | None = None
):
limits = settings.get_fiat_provider_limits(fiat_provider_name)
if not limits:
+6 -7
View File
@@ -1,5 +1,4 @@
from pathlib import Path
from typing import Optional
from uuid import uuid4
from loguru import logger
@@ -37,7 +36,7 @@ from .settings import update_cached_settings
async def create_user_account(
account: Optional[Account] = None, wallet_name: Optional[str] = None
account: Account | None = None, wallet_name: str | None = None
) -> User:
if not settings.new_accounts_allowed:
raise ValueError("Account creation is disabled.")
@@ -46,9 +45,9 @@ async def create_user_account(
async def create_user_account_no_ckeck(
account: Optional[Account] = None,
wallet_name: Optional[str] = None,
default_exts: Optional[list[str]] = None,
account: Account | None = None,
wallet_name: str | None = None,
default_exts: list[str] | None = None,
) -> User:
if account:
@@ -165,12 +164,12 @@ async def check_admin_settings():
settings.first_install = True
logger.success(
"✔️ Admin UI is enabled. run `poetry run lnbits-cli superuser` "
"✔️ Admin UI is enabled. run `uv run lnbits-cli superuser` "
"to get the superuser."
)
async def init_admin_settings(super_user: Optional[str] = None) -> SuperSettings:
async def init_admin_settings(super_user: str | None = None) -> SuperSettings:
account = None
if super_user:
account = await get_account(super_user)
+1 -2
View File
@@ -1,7 +1,6 @@
import asyncio
import traceback
from collections.abc import Coroutine
from typing import Callable
from collections.abc import Callable, Coroutine
from loguru import logger
+3 -3
View File
@@ -5,7 +5,7 @@ from pathlib import Path
from shutil import make_archive, move
from subprocess import Popen
from tempfile import NamedTemporaryFile
from typing import IO, Optional
from typing import IO
from urllib.parse import urlparse
import filetype
@@ -71,10 +71,10 @@ async def api_test_email():
)
@admin_router.get("/api/v1/settings", response_model=Optional[AdminSettings])
@admin_router.get("/api/v1/settings")
async def api_get_settings(
user: User = Depends(check_admin),
) -> Optional[AdminSettings]:
) -> AdminSettings | None:
admin_settings = await get_admin_settings(user.super_user)
return admin_settings
+12 -12
View File
@@ -1,9 +1,9 @@
import base64
import importlib
import json
from collections.abc import Callable
from http import HTTPStatus
from time import time
from typing import Callable, Optional
from uuid import uuid4
from fastapi import APIRouter, Depends, HTTPException, Request
@@ -238,7 +238,7 @@ async def api_delete_user_api_token(
@auth_router.get("/{provider}", description="SSO Provider")
async def login_with_sso_provider(
request: Request, provider: str, user_id: Optional[str] = None
request: Request, provider: str, user_id: str | None = None
):
provider_sso = _new_sso(provider)
if not provider_sso:
@@ -319,7 +319,7 @@ async def update_pubkey(
data: UpdateUserPubkey,
user: User = Depends(check_user_exists),
payload: AccessTokenPayload = Depends(access_token_payload),
) -> Optional[User]:
) -> User | None:
if data.user_id != user.id:
raise ValueError("Invalid user ID.")
@@ -345,7 +345,7 @@ async def update_password(
data: UpdateUserPassword,
user: User = Depends(check_user_exists),
payload: AccessTokenPayload = Depends(access_token_payload),
) -> Optional[User]:
) -> User | None:
_validate_auth_timeout(payload.auth_time)
if data.user_id != user.id:
raise ValueError("Invalid user ID.")
@@ -419,7 +419,7 @@ async def reset_password(data: ResetUserPassword) -> JSONResponse:
@auth_router.put("/update")
async def update(
data: UpdateUser, user: User = Depends(check_user_exists)
) -> Optional[User]:
) -> User | None:
if data.user_id != user.id:
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid user ID.")
if data.username and not is_valid_username(data.username):
@@ -461,7 +461,7 @@ async def first_install(data: UpdateSuperuserPassword) -> JSONResponse:
return _auth_success_response(account.username, account.id, account.email)
async def _handle_sso_login(userinfo: OpenID, verified_user_id: Optional[str] = None):
async def _handle_sso_login(userinfo: OpenID, verified_user_id: str | None = None):
email = userinfo.email
if not email or not is_valid_email_address(email):
raise HTTPException(HTTPStatus.BAD_REQUEST, "Invalid email.")
@@ -490,9 +490,9 @@ async def _handle_sso_login(userinfo: OpenID, verified_user_id: Optional[str] =
def _auth_success_response(
username: Optional[str] = None,
user_id: Optional[str] = None,
email: Optional[str] = None,
username: str | None = None,
user_id: str | None = None,
email: str | None = None,
) -> JSONResponse:
payload = AccessTokenPayload(
sub=username or "", usr=user_id, email=email, auth_time=int(time())
@@ -533,7 +533,7 @@ def _auth_redirect_response(path: str, email: str) -> RedirectResponse:
return response
def _new_sso(provider: str) -> Optional[SSOBase]:
def _new_sso(provider: str) -> SSOBase | None:
try:
if not settings.is_auth_method_allowed(AuthMethods(f"{provider}-auth")):
return None
@@ -610,7 +610,7 @@ def _nostr_nip98_event(request: Request) -> dict:
def _check_nostr_event_tags(event: dict):
method: Optional[str] = next((v for k, v in event["tags"] if k == "method"), None)
method: str | None = next((v for k, v in event["tags"] if k == "method"), None)
if not method:
raise ValueError("Tag 'method' is missing.")
if not method.upper() == "POST":
@@ -625,7 +625,7 @@ def _check_nostr_event_tags(event: dict):
raise ValueError(f"Invalid value for tag 'u': '{url}'.")
def _validate_auth_timeout(auth_time: Optional[int] = 0):
def _validate_auth_timeout(auth_time: int | None = 0):
if abs(time() - (auth_time or 0)) > settings.auth_credetials_update_threshold:
raise HTTPException(
HTTPStatus.BAD_REQUEST,
+3 -3
View File
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Annotated, Optional, Union
from typing import Annotated
from urllib.parse import urlencode, urlparse
import httpx
@@ -161,9 +161,9 @@ async def extensions(request: Request, user: User = Depends(check_user_exists)):
)
async def wallet(
request: Request,
lnbits_last_active_wallet: Annotated[Union[str, None], Cookie()] = None,
lnbits_last_active_wallet: Annotated[str | None, Cookie()] = None,
user: User = Depends(check_user_exists),
wal: Optional[UUID4] = Query(None),
wal: UUID4 | None = Query(None),
):
if wal:
wallet = await get_wallet(wal.hex)
+2 -2
View File
@@ -60,7 +60,7 @@ async def _handle(lnurl: str) -> LnurlResponseModel:
)
async def api_lnurlscan(code: str) -> LnurlResponseModel:
res = await _handle(code)
if isinstance(res, (LnurlPayResponse, LnurlWithdrawResponse, LnurlAuthResponse)):
if isinstance(res, LnurlPayResponse | LnurlWithdrawResponse | LnurlAuthResponse):
check_callback_url(res.callback)
return res
@@ -169,7 +169,7 @@ async def api_payment_pay_with_nfc(
except (LnurlResponseException, Exception) as exc:
logger.warning(exc)
return LnurlErrorResponse(reason=str(exc))
if not isinstance(res2, (LnurlSuccessResponse, LnurlErrorResponse)):
if not isinstance(res2, LnurlSuccessResponse | LnurlErrorResponse):
return LnurlErrorResponse(reason="Invalid LNURL-withdraw response.")
return res2
+19 -20
View File
@@ -1,5 +1,4 @@
from http import HTTPStatus
from typing import Optional
import httpx
from fastapi import APIRouter, Body, Depends, HTTPException
@@ -89,14 +88,14 @@ async def api_get_public_info(node: Node = Depends(require_node)) -> PublicNodeI
@node_router.get("/info")
async def api_get_info(
node: Node = Depends(require_node),
) -> Optional[NodeInfoResponse]:
) -> NodeInfoResponse | None:
return await node.get_info()
@node_router.get("/channels")
async def api_get_channels(
node: Node = Depends(require_node),
) -> Optional[list[NodeChannel]]:
) -> list[NodeChannel] | None:
return await node.get_channels()
@@ -104,7 +103,7 @@ async def api_get_channels(
async def api_get_channel(
channel_id: str,
node: Node = Depends(require_node),
) -> Optional[NodeChannel]:
) -> NodeChannel | None:
return await node.get_channel(channel_id)
@@ -113,20 +112,20 @@ async def api_create_channel(
node: Node = Depends(require_node),
peer_id: str = Body(),
funding_amount: int = Body(),
push_amount: Optional[int] = Body(None),
fee_rate: Optional[int] = Body(None),
push_amount: int | None = Body(None),
fee_rate: int | None = Body(None),
):
return await node.open_channel(peer_id, funding_amount, push_amount, fee_rate)
@super_node_router.delete("/channels")
async def api_delete_channel(
short_id: Optional[str],
funding_txid: Optional[str],
output_index: Optional[int],
short_id: str | None,
funding_txid: str | None,
output_index: int | None,
force: bool = False,
node: Node = Depends(require_node),
) -> Optional[list[NodeChannel]]:
) -> list[NodeChannel] | None:
return await node.close_channel(
short_id,
(
@@ -152,7 +151,7 @@ async def api_set_channel_fees(
async def api_get_payments(
node: Node = Depends(require_node),
filters: Filters = Depends(parse_filters(NodePaymentsFilters)),
) -> Optional[Page[NodePayment]]:
) -> Page[NodePayment] | None:
if not settings.lnbits_node_ui_transactions:
raise HTTPException(
HTTP_503_SERVICE_UNAVAILABLE,
@@ -165,7 +164,7 @@ async def api_get_payments(
async def api_get_invoices(
node: Node = Depends(require_node),
filters: Filters = Depends(parse_filters(NodeInvoiceFilters)),
) -> Optional[Page[NodeInvoice]]:
) -> Page[NodeInvoice] | None:
if not settings.lnbits_node_ui_transactions:
raise HTTPException(
HTTP_503_SERVICE_UNAVAILABLE,
@@ -192,25 +191,25 @@ async def api_disconnect_peer(peer_id: str, node: Node = Depends(require_node)):
class NodeRank(BaseModel):
capacity: Optional[int]
channelcount: Optional[int]
age: Optional[int]
growth: Optional[int]
availability: Optional[int]
capacity: int | None
channelcount: int | None
age: int | None
growth: int | None
availability: int | None
# Same for public and private api
@node_router.get(
"/rank",
description="Retrieve node ranks from https://1ml.com",
response_model=Optional[NodeRank],
response_model=NodeRank | None,
)
@public_node_router.get(
"/rank",
description="Retrieve node ranks from https://1ml.com",
response_model=Optional[NodeRank],
response_model=NodeRank | None,
)
async def api_get_1ml_stats(node: Node = Depends(require_node)) -> Optional[NodeRank]:
async def api_get_1ml_stats(node: Node = Depends(require_node)) -> NodeRank | None:
node_id = await node.get_id()
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
+1 -2
View File
@@ -1,6 +1,5 @@
from hashlib import sha256
from http import HTTPStatus
from typing import Optional
from fastapi import (
APIRouter,
@@ -275,7 +274,7 @@ async def api_payments_fee_reserve(invoice: str = Query("invoice")) -> JSONRespo
# TODO: refactor this route into a public and admin one
@payment_router.get("/{payment_hash}")
async def api_payment(payment_hash, x_api_key: Optional[str] = Header(None)):
async def api_payment(payment_hash, x_api_key: str | None = Header(None)):
# We use X_Api_Key here because we want this call to work with and without keys
# If a valid key is given, we also return the field "details", otherwise not
wallet = await get_wallet_for_key(x_api_key) if isinstance(x_api_key, str) else None
+1 -2
View File
@@ -2,7 +2,6 @@ import base64
import json
import time
from http import HTTPStatus
from typing import Optional
from uuid import uuid4
import shortuuid
@@ -223,7 +222,7 @@ async def api_users_get_user_wallet(user_id: str) -> list[Wallet]:
@users_router.post("/user/{user_id}/wallet", name="Create a new wallet for user")
async def api_users_create_user_wallet(
user_id: str, name: Optional[str] = Body(None), currency: Optional[str] = Body(None)
user_id: str, name: str | None = Body(None), currency: str | None = Body(None)
):
if currency and currency not in allowed_currencies():
raise ValueError(f"Currency '{currency}' not allowed.")
+5 -6
View File
@@ -1,5 +1,4 @@
from http import HTTPStatus
from typing import Optional
from uuid import uuid4
from fastapi import (
@@ -110,11 +109,11 @@ async def api_put_stored_paylinks(
@wallet_router.patch("")
async def api_update_wallet(
name: Optional[str] = Body(None),
icon: Optional[str] = Body(None),
color: Optional[str] = Body(None),
currency: Optional[str] = Body(None),
pinned: Optional[bool] = Body(None),
name: str | None = Body(None),
icon: str | None = Body(None),
color: str | None = Body(None),
currency: str | None = Body(None),
pinned: bool | None = Body(None),
key_info: WalletTypeInfo = Depends(require_admin_key),
) -> Wallet:
wallet = await get_wallet(key_info.wallet.id)