mirror of
https://github.com/lnbits/lnbits-legend.git
synced 2025-02-26 15:42:30 +01:00
158 lines
4.2 KiB
Python
158 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)
|