From 0607cb1d6e05ecf59873822bc7a68910b78d5ff4 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Thu, 2 Feb 2023 12:58:10 +0000 Subject: [PATCH] fix pyright lnbits/core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dni ⚡ --- lnbits/core/crud.py | 15 +++++++++++---- lnbits/core/services.py | 29 +++++++++++++---------------- lnbits/core/views/api.py | 16 ++++++++++------ lnbits/core/views/public_api.py | 9 ++++----- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 1b807b788..73656c7c3 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -206,7 +206,7 @@ async def create_wallet( async def update_wallet( wallet_id: str, new_name: str, conn: Optional[Connection] = None ) -> Optional[Wallet]: - return await (conn or db).execute( + await (conn or db).execute( """ UPDATE wallets SET name = ? @@ -214,6 +214,9 @@ async def update_wallet( """, (new_name, wallet_id), ) + wallet = await get_wallet(wallet_id=wallet_id, conn=conn) + assert wallet, "updated created wallet couldn't be retrieved" + return wallet async def delete_wallet( @@ -712,15 +715,19 @@ async def update_admin_settings(data: EditableSettings): await db.execute("UPDATE settings SET editable_settings = ?", (json.dumps(data),)) -async def update_super_user(super_user: str): +async def update_super_user(super_user: str) -> SuperSettings: await db.execute("UPDATE settings SET super_user = ?", (super_user,)) - return await get_super_settings() + settings = await get_super_settings() + assert settings + return settings async def create_admin_settings(super_user: str, new_settings: dict): sql = "INSERT INTO settings (super_user, editable_settings) VALUES (?, ?)" await db.execute(sql, (super_user, json.dumps(new_settings))) - return await get_super_settings() + settings = await get_super_settings() + assert settings + return settings # db versions diff --git a/lnbits/core/services.py b/lnbits/core/services.py index 5322de778..5645f0a5d 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -1,7 +1,7 @@ import asyncio import json from io import BytesIO -from typing import Dict, List, Optional, Tuple +from typing import Dict, List, Optional, Tuple, TypedDict from urllib.parse import parse_qs, urlparse import httpx @@ -17,6 +17,7 @@ from lnbits.helpers import url_for from lnbits.settings import ( FAKE_WALLET, EditableSettings, + SuperSettings, get_wallet_class, readonly_variables, send_admin_user_to_saas, @@ -43,11 +44,6 @@ from .crud import ( ) from .models import Payment -try: - from typing import TypedDict -except ImportError: # pragma: nocover - from typing_extensions import TypedDict - class PaymentFailure(Exception): pass @@ -336,19 +332,19 @@ async def perform_lnurlauth( return b - def encode_strict_der(r_int, s_int, order): + def encode_strict_der(r, s, order): # if s > order/2 verification will fail sometimes # so we must fix it here (see https://github.com/indutny/elliptic/blob/e71b2d9359c5fe9437fbf46f1f05096de447de57/lib/elliptic/ec/index.js#L146-L147) - if s_int > order // 2: - s_int = order - s_int + if s > order // 2: + s = order - s # now we do the strict DER encoding copied from # https://github.com/KiriKiri/bip66 (without any checks) - r = int_to_bytes_suitable_der(r_int) - s = int_to_bytes_suitable_der(s_int) + r_temp = int_to_bytes_suitable_der(r) + s_temp = int_to_bytes_suitable_der(s) - r_len = len(r) - s_len = len(s) + r_len = len(r_temp) + s_len = len(s_temp) sign_len = 6 + r_len + s_len signature = BytesIO() @@ -356,16 +352,17 @@ async def perform_lnurlauth( signature.write((sign_len - 2).to_bytes(1, "big", signed=False)) signature.write(0x02.to_bytes(1, "big", signed=False)) signature.write(r_len.to_bytes(1, "big", signed=False)) - signature.write(r) + signature.write(r_temp) signature.write(0x02.to_bytes(1, "big", signed=False)) signature.write(s_len.to_bytes(1, "big", signed=False)) - signature.write(s) + signature.write(s_temp) return signature.getvalue() sig = key.sign_digest_deterministic(k1, sigencode=encode_strict_der) async with httpx.AsyncClient() as client: + assert key.verifying_key r = await client.get( callback, params={ @@ -469,7 +466,7 @@ def update_cached_settings(sets_dict: dict): setattr(settings, "super_user", sets_dict["super_user"]) -async def init_admin_settings(super_user: str = None): +async def init_admin_settings(super_user: Optional[str] = None) -> SuperSettings: account = None if super_user: account = await get_account(super_user) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 408bef590..e0555b379 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -411,8 +411,7 @@ async def subscribe_wallet_invoices(request: Request, wallet: Wallet): typ, data = await send_queue.get() if data: jdata = json.dumps(dict(data.dict(), pending=False)) - - yield dict(data=jdata, event=typ) + yield dict(data=jdata, event=typ) except asyncio.CancelledError: logger.debug(f"removing listener for wallet {uid}") api_invoice_listeners.pop(uid) @@ -431,11 +430,12 @@ async def api_payments_sse( ) +# TODO: refactor this route into a public and admin one @core_app.get("/api/v1/payments/{payment_hash}") async def api_payment(payment_hash, X_Api_Key: Optional[str] = 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 type(X_Api_Key) == str else None + wallet = await get_wallet_for_key(X_Api_Key) if type(X_Api_Key) == str else None # type: ignore # we have to specify the wallet id here, because postgres and sqlite return internal payments in different order # and get_standalone_payment otherwise just fetches the first one, causing unpredictable results @@ -505,6 +505,7 @@ async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type params.update(callback=url) # with k1 already in it lnurlauth_key = wallet.wallet.lnurlauth_key(domain) + assert lnurlauth_key.verifying_key params.update(pubkey=lnurlauth_key.verifying_key.to_string("compressed").hex()) else: async with httpx.AsyncClient() as client: @@ -693,7 +694,7 @@ async def api_auditor(): if not error_message: delta = node_balance - total_balance else: - node_balance, delta = None, None + node_balance, delta = 0, 0 return { "node_balance_msats": int(node_balance), @@ -745,6 +746,7 @@ async def api_install_extension( raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Release not found" ) + ext_info = InstallableExtension( id=data.ext_id, name=data.ext_id, installed_release=release, icon=release.icon ) @@ -824,8 +826,10 @@ async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin) ) -@core_app.get("/api/v1/extension/{ext_id}/releases") -async def get_extension_releases(ext_id: str, user: User = Depends(check_admin)): +@core_app.get( + "/api/v1/extension/{ext_id}/releases", dependencies=[Depends(check_admin)] +) +async def get_extension_releases(ext_id: str): try: extension_releases: List[ ExtensionRelease diff --git a/lnbits/core/views/public_api.py b/lnbits/core/views/public_api.py index 303929feb..934fc6179 100644 --- a/lnbits/core/views/public_api.py +++ b/lnbits/core/views/public_api.py @@ -40,19 +40,18 @@ async def api_public_payment_longpolling(payment_hash): response = None - async def payment_info_receiver(cancel_scope): - async for payment in payment_queue.get(): + async def payment_info_receiver(): + for payment in await payment_queue.get(): if payment.payment_hash == payment_hash: nonlocal response response = {"status": "paid"} - cancel_scope.cancel() async def timeouter(cancel_scope): await asyncio.sleep(45) cancel_scope.cancel() - asyncio.create_task(payment_info_receiver()) - asyncio.create_task(timeouter()) + cancel_scope = asyncio.create_task(payment_info_receiver()) + asyncio.create_task(timeouter(cancel_scope)) if response: return response