Move wallet Lightning Address lookups into CRUD

This commit is contained in:
blackcoffeexbt 2026-07-28 10:59:04 +01:00
parent 078a2c724a
commit f2b89db92c
3 changed files with 56 additions and 48 deletions

View file

@ -1,5 +1,6 @@
from datetime import datetime, timezone
from time import time
from typing import Any
from uuid import uuid4
from lnbits.core.db import db
@ -229,6 +230,50 @@ async def get_wallets_count():
return row.get("count", 0)
async def wallet_lightning_address_exists(
local_part: str, conn: Connection | None = None
) -> bool:
row: Any = await (conn or db).fetchone(
"""
SELECT id FROM wallets
WHERE lightning_address = :lightning_address
""",
{"lightning_address": local_part},
)
return bool(row)
async def wallet_lightning_address_exists_for_other_wallet(
local_part: str, wallet_id: str, conn: Connection | None = None
) -> bool:
row: Any = await (conn or db).fetchone(
"""
SELECT id FROM wallets
WHERE lightning_address = :lightning_address
AND id != :wallet_id
""",
{"lightning_address": local_part, "wallet_id": wallet_id},
)
return bool(row)
async def get_wallet_by_lightning_address(local_part: str) -> Wallet | None:
return await db.fetchone(
"""
SELECT wallets.*, COALESCE((
SELECT balance FROM balances WHERE wallet_id = wallets.id
), 0) AS balance_msat FROM wallets
INNER JOIN accounts ON wallets.user = accounts.id
WHERE lightning_address = :lightning_address
AND wallet_type = 'lightning'
AND deleted = false
AND accounts.activated = true
""",
{"lightning_address": local_part.lower()},
Wallet,
)
async def get_wallet_for_key(
key: str,
conn: Connection | None = None,

View file

@ -16,6 +16,11 @@ from lnurl import (
from pydantic import parse_obj_as
from sqlalchemy.exc import OperationalError
from lnbits.core.crud.wallets import (
get_wallet_by_lightning_address,
wallet_lightning_address_exists,
wallet_lightning_address_exists_for_other_wallet,
)
from lnbits.core.db import db
from lnbits.core.models.wallets import Wallet
from lnbits.db import Connection, Database
@ -91,31 +96,6 @@ def _generate_local_part() -> str:
return f"{participle}.{noun}.{suffix:03d}"
async def _core_address_exists(local_part: str, conn: Connection | None = None) -> bool:
row: Any = await (conn or db).fetchone(
"""
SELECT id FROM wallets
WHERE lightning_address = :lightning_address
""",
{"lightning_address": local_part},
)
return bool(row)
async def _core_address_exists_for_other_wallet(
local_part: str, wallet_id: str, conn: Connection | None = None
) -> bool:
row: Any = await (conn or db).fetchone(
"""
SELECT id FROM wallets
WHERE lightning_address = :lightning_address
AND id != :wallet_id
""",
{"lightning_address": local_part, "wallet_id": wallet_id},
)
return bool(row)
async def legacy_lnurlp_address_exists(local_part: str) -> bool:
try:
row: Any = await _LEGACY_LNURLP_DB.fetchone(
@ -138,7 +118,7 @@ async def generate_lightning_address_local_part(
) -> str:
for _ in range(100):
local_part = _generate_local_part()
if await _core_address_exists(local_part, conn):
if await wallet_lightning_address_exists(local_part, conn):
continue
if await legacy_lnurlp_address_exists(local_part):
continue
@ -187,7 +167,9 @@ async def validate_lightning_address_local_part(
)
if not allow_blacklisted and _uses_blacklisted_word(local_part):
raise ValueError("Lightning Address contains a reserved word.")
if await _core_address_exists_for_other_wallet(local_part, wallet.id, conn):
if await wallet_lightning_address_exists_for_other_wallet(
local_part, wallet.id, conn
):
raise ValueError("Lightning Address is already taken.")
if await legacy_lnurlp_address_exists(local_part):
raise ValueError("Lightning Address is already taken.")
@ -288,23 +270,6 @@ async def ensure_wallet_lightning_address(
return wallet
async def get_wallet_by_lightning_address(local_part: str) -> Wallet | None:
return await db.fetchone(
"""
SELECT wallets.*, COALESCE((
SELECT balance FROM balances WHERE wallet_id = wallets.id
), 0) AS balance_msat FROM wallets
INNER JOIN accounts ON wallets.user = accounts.id
WHERE lightning_address = :lightning_address
AND wallet_type = 'lightning'
AND deleted = false
AND accounts.activated = true
""",
{"lightning_address": local_part.lower()},
Wallet,
)
def lightning_address_for_request(request: Request, local_part: str) -> str:
return f"{local_part}@{request.url.netloc}"

View file

@ -123,10 +123,8 @@ class ExtensionsRedirectMiddleware:
username = path_parts[2].lower()
base_username = username.partition("+")[0]
from lnbits.core.services.lightning_address import (
get_wallet_by_lightning_address,
legacy_lnurlp_address_exists,
)
from lnbits.core.crud.wallets import get_wallet_by_lightning_address
from lnbits.core.services.lightning_address import legacy_lnurlp_address_exists
if await legacy_lnurlp_address_exists(username):
return False