mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-02-26 15:42:30 +01:00
* feat: add shortcuts for insert_query and update_query into `Database` example: await db.insert("table_name", base_model) * remove where from argument * chore: code clean-up * extension manager * lnbits-qrcode components * parse date from dict * refactor: make `settings` a fixture * chore: remove verbose key names * fix: time column * fix: cast balance to `int` * extension toggle vue3 * vue3 @input migration * fix: payment extra and payment hash * fix dynamic fields and ext db migration * remove shadow on cards in dark theme * screwed up and made more css pushes to this branch * attempt to make chip component in settings dynamic fields * dynamic chips * qrscanner * clean init admin settings * make get_user better * add dbversion model * remove update_payment_status/extra/details * traces for value and assertion errors * refactor services * add PaymentFiatAmount * return Payment on api endpoints * rename to get_user_from_account * refactor: just refactor (#2740) * rc5 * Fix db cache (#2741) * [refactor] split services.py (#2742) * refactor: spit `core.py` (#2743) * refactor: make QR more customizable * fix: print.html * fix: qrcode options * fix: white shadow on dark theme * fix: datetime wasnt parsed in dict_to_model * add timezone for conversion * only parse timestamp for sqlite, postgres does it * log internal payment success * fix: export wallet to phone QR * Adding a customisable border theme, like gradient (#2746) * fixed mobile scan btn * fix test websocket * fix get_payments tests * dict_to_model skip none values * preimage none instead of defaulting to 0000... * fixup test real invoice tests * fixed pheonixd for wss * fix nodemanager test settings * fix lnbits funding * only insert extension when they dont exist --------- Co-authored-by: Vlad Stan <stan.v.vlad@gmail.com> Co-authored-by: Tiago Vasconcelos <talvasconcelos@gmail.com> Co-authored-by: Arc <ben@arc.wales> Co-authored-by: Arc <33088785+arcbtc@users.noreply.github.com>
157 lines
4.2 KiB
Python
157 lines
4.2 KiB
Python
from datetime import datetime, timezone
|
|
from time import time
|
|
from typing import Optional
|
|
from uuid import uuid4
|
|
|
|
from lnbits.core.db import db
|
|
from lnbits.db import Connection
|
|
from lnbits.settings import settings
|
|
|
|
from ..models import Wallet
|
|
|
|
|
|
async def create_wallet(
|
|
*,
|
|
user_id: str,
|
|
wallet_name: Optional[str] = None,
|
|
conn: Optional[Connection] = None,
|
|
) -> Wallet:
|
|
wallet_id = uuid4().hex
|
|
wallet = Wallet(
|
|
id=wallet_id,
|
|
name=wallet_name or settings.lnbits_default_wallet_name,
|
|
user=user_id,
|
|
adminkey=uuid4().hex,
|
|
inkey=uuid4().hex,
|
|
)
|
|
await (conn or db).insert("wallets", wallet)
|
|
return wallet
|
|
|
|
|
|
async def update_wallet(
|
|
wallet: Wallet,
|
|
conn: Optional[Connection] = None,
|
|
) -> Optional[Wallet]:
|
|
wallet.updated_at = datetime.now(timezone.utc)
|
|
await (conn or db).update("wallets", wallet)
|
|
return wallet
|
|
|
|
|
|
async def delete_wallet(
|
|
*,
|
|
user_id: str,
|
|
wallet_id: str,
|
|
deleted: bool = True,
|
|
conn: Optional[Connection] = None,
|
|
) -> None:
|
|
now = int(time())
|
|
await (conn or db).execute(
|
|
f"""
|
|
UPDATE wallets
|
|
SET deleted = :deleted, updated_at = {db.timestamp_placeholder('now')}
|
|
WHERE id = :wallet AND "user" = :user
|
|
""",
|
|
{"wallet": wallet_id, "user": user_id, "deleted": deleted, "now": now},
|
|
)
|
|
|
|
|
|
async def force_delete_wallet(
|
|
wallet_id: str, conn: Optional[Connection] = None
|
|
) -> None:
|
|
await (conn or db).execute(
|
|
"DELETE FROM wallets WHERE id = :wallet",
|
|
{"wallet": wallet_id},
|
|
)
|
|
|
|
|
|
async def delete_wallet_by_id(
|
|
wallet_id: str, conn: Optional[Connection] = None
|
|
) -> Optional[int]:
|
|
now = int(time())
|
|
result = await (conn or db).execute(
|
|
f"""
|
|
UPDATE wallets
|
|
SET deleted = true, updated_at = {db.timestamp_placeholder('now')}
|
|
WHERE id = :wallet
|
|
""",
|
|
{"wallet": wallet_id, "now": now},
|
|
)
|
|
return result.rowcount
|
|
|
|
|
|
async def remove_deleted_wallets(conn: Optional[Connection] = 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,
|
|
) -> None:
|
|
delta = int(time()) - time_delta
|
|
await (conn or db).execute(
|
|
"""
|
|
DELETE FROM wallets
|
|
WHERE (
|
|
SELECT COUNT(*) FROM apipayments WHERE wallet_id = wallets.id
|
|
) = 0 AND (
|
|
(updated_at is null AND created_at < :delta)
|
|
OR updated_at < :delta
|
|
)
|
|
""",
|
|
{"delta": delta},
|
|
)
|
|
|
|
|
|
async def get_wallet(
|
|
wallet_id: str, deleted: Optional[bool] = None, conn: Optional[Connection] = None
|
|
) -> Optional[Wallet]:
|
|
where = "AND deleted = :deleted" if deleted is not None else ""
|
|
return await (conn or db).fetchone(
|
|
f"""
|
|
SELECT *, COALESCE((
|
|
SELECT balance FROM balances WHERE wallet_id = wallets.id
|
|
), 0) AS balance_msat FROM wallets
|
|
WHERE id = :wallet {where}
|
|
""",
|
|
{"wallet": wallet_id, "deleted": deleted},
|
|
Wallet,
|
|
)
|
|
|
|
|
|
async def get_wallets(
|
|
user_id: str, deleted: Optional[bool] = None, conn: Optional[Connection] = None
|
|
) -> list[Wallet]:
|
|
where = "AND deleted = :deleted" if deleted is not None else ""
|
|
return await (conn or db).fetchall(
|
|
f"""
|
|
SELECT *, COALESCE((
|
|
SELECT balance FROM balances WHERE wallet_id = wallets.id
|
|
), 0) AS balance_msat FROM wallets
|
|
WHERE "user" = :user {where}
|
|
""",
|
|
{"user": user_id, "deleted": deleted},
|
|
Wallet,
|
|
)
|
|
|
|
|
|
async def get_wallet_for_key(
|
|
key: str,
|
|
conn: Optional[Connection] = None,
|
|
) -> Optional[Wallet]:
|
|
return await (conn or db).fetchone(
|
|
"""
|
|
SELECT *, COALESCE((
|
|
SELECT balance FROM balances WHERE wallet_id = wallets.id
|
|
), 0)
|
|
AS balance_msat FROM wallets
|
|
WHERE (adminkey = :key OR inkey = :key) AND deleted = false
|
|
""",
|
|
{"key": key},
|
|
Wallet,
|
|
)
|
|
|
|
|
|
async def get_total_balance(conn: Optional[Connection] = None):
|
|
result = await (conn or db).execute("SELECT SUM(balance) FROM balances")
|
|
row = result.mappings().first()
|
|
return row.get("balance", 0)
|