Merge pull request #1304 from lnbits/fix/mypy-lnurldevices

fix mypy lnurldevices
This commit is contained in:
Arc 2023-01-09 16:44:23 +00:00 committed by GitHub
commit c439732f9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 80 deletions

View File

@ -7,8 +7,6 @@ from lnbits.helpers import urlsafe_short_hash
from . import db
from .models import createLnurldevice, lnurldevicepayment, lnurldevices
###############lnurldeviceS##########################
async def create_lnurldevice(
data: createLnurldevice,
@ -69,10 +67,12 @@ async def create_lnurldevice(
data.pin4,
),
)
return await get_lnurldevice(lnurldevice_id)
device = await get_lnurldevice(lnurldevice_id)
assert device
return device
async def update_lnurldevice(lnurldevice_id: str, **kwargs) -> Optional[lnurldevices]:
async def update_lnurldevice(lnurldevice_id: str, **kwargs) -> lnurldevices:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(
f"UPDATE lnurldevice.lnurldevices SET {q} WHERE id = ?",
@ -81,19 +81,18 @@ async def update_lnurldevice(lnurldevice_id: str, **kwargs) -> Optional[lnurldev
row = await db.fetchone(
"SELECT * FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
)
return lnurldevices(**row) if row else None
return lnurldevices(**row)
async def get_lnurldevice(lnurldevice_id: str) -> lnurldevices:
async def get_lnurldevice(lnurldevice_id: str) -> Optional[lnurldevices]:
row = await db.fetchone(
"SELECT * FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
)
return lnurldevices(**row) if row else None
async def get_lnurldevices(wallet_ids: Union[str, List[str]]) -> List[lnurldevices]:
wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids[0]))
async def get_lnurldevices(wallet_ids: List[str]) -> List[lnurldevices]:
q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall(
f"""
SELECT * FROM lnurldevice.lnurldevices WHERE wallet IN ({q})
@ -102,7 +101,7 @@ async def get_lnurldevices(wallet_ids: Union[str, List[str]]) -> List[lnurldevic
(*wallet_ids,),
)
return [lnurldevices(**row) if row else None for row in rows]
return [lnurldevices(**row) for row in rows]
async def delete_lnurldevice(lnurldevice_id: str) -> None:
@ -110,8 +109,6 @@ async def delete_lnurldevice(lnurldevice_id: str) -> None:
"DELETE FROM lnurldevice.lnurldevices WHERE id = ?", (lnurldevice_id,)
)
########################lnuldevice payments###########################
async def create_lnurldevicepayment(
deviceid: str,
@ -121,6 +118,7 @@ async def create_lnurldevicepayment(
sats: Optional[int] = 0,
) -> lnurldevicepayment:
device = await get_lnurldevice(deviceid)
assert device
if device.device == "atm":
lnurldevicepayment_id = shortuuid.uuid(name=payload)
else:
@ -139,7 +137,9 @@ async def create_lnurldevicepayment(
""",
(lnurldevicepayment_id, deviceid, payload, pin, payhash, sats),
)
return await get_lnurldevicepayment(lnurldevicepayment_id)
dpayment = await get_lnurldevicepayment(lnurldevicepayment_id)
assert dpayment
return dpayment
async def update_lnurldevicepayment(
@ -157,7 +157,9 @@ async def update_lnurldevicepayment(
return lnurldevicepayment(**row) if row else None
async def get_lnurldevicepayment(lnurldevicepayment_id: str) -> lnurldevicepayment:
async def get_lnurldevicepayment(
lnurldevicepayment_id: str,
) -> Optional[lnurldevicepayment]:
row = await db.fetchone(
"SELECT * FROM lnurldevice.lnurldevicepayment WHERE id = ?",
(lnurldevicepayment_id,),
@ -165,7 +167,9 @@ async def get_lnurldevicepayment(lnurldevicepayment_id: str) -> lnurldevicepayme
return lnurldevicepayment(**row) if row else None
async def get_lnurlpayload(lnurldevicepayment_payload: str) -> lnurldevicepayment:
async def get_lnurlpayload(
lnurldevicepayment_payload: str,
) -> Optional[lnurldevicepayment]:
row = await db.fetchone(
"SELECT * FROM lnurldevice.lnurldevicepayment WHERE payload = ?",
(lnurldevicepayment_payload,),

View File

@ -1,16 +1,11 @@
import base64
import hashlib
import hmac
from http import HTTPStatus
from io import BytesIO
from typing import Optional
import shortuuid
from embit import bech32, compact
from fastapi import Request
from fastapi.param_functions import Query
from loguru import logger
from starlette.exceptions import HTTPException
from fastapi import HTTPException, Query, Request
from lnbits import bolt11
from lnbits.core.services import create_invoice
@ -44,7 +39,9 @@ def bech32_decode(bech):
encoding = bech32.bech32_verify_checksum(hrp, data)
if encoding is None:
return
return bytes(bech32.convertbits(data[:-6], 5, 8, False))
bits = bech32.convertbits(data[:-6], 5, 8, False)
assert bits
return bytes(bits)
def xor_decrypt(key, blob):
@ -105,6 +102,8 @@ async def lnurl_v1_params(
"reason": f"lnurldevice {device_id} not found on this server",
}
if device.device == "switch":
# TODO: AMOUNT IN CENT was never reference here
amount_in_cent = 0
price_msat = (
await fiat_amount_as_satoshis(float(profit), device.currency)
if device.currency != "sat"
@ -160,23 +159,18 @@ async def lnurl_v1_params(
if device.device != "atm":
return {"status": "ERROR", "reason": "Not ATM device."}
price_msat = int(price_msat * (1 - (device.profit / 100)) / 1000)
lnurldevicepayment = await get_lnurldevicepayment(shortuuid.uuid(name=p))
if lnurldevicepayment:
logger.debug("lnurldevicepayment")
logger.debug(lnurldevicepayment)
logger.debug("lnurldevicepayment")
if lnurldevicepayment.payload == lnurldevicepayment.payhash:
return {"status": "ERROR", "reason": f"Payment already claimed"}
else:
try:
lnurldevicepayment = await create_lnurldevicepayment(
deviceid=device.id,
payload=p,
sats=price_msat * 1000,
pin=pin,
pin=str(pin),
payhash="payment_hash",
)
except:
return {"status": "ERROR", "reason": "Could not create ATM payment."}
if not lnurldevicepayment:
return {"status": "ERROR", "reason": "Could not create payment."}
return {"status": "ERROR", "reason": "Could not create ATM payment."}
return {
"tag": "withdrawRequest",
"callback": request.url_for(
@ -193,7 +187,7 @@ async def lnurl_v1_params(
deviceid=device.id,
payload=p,
sats=price_msat * 1000,
pin=pin,
pin=str(pin),
payhash="payment_hash",
)
if not lnurldevicepayment:
@ -221,6 +215,10 @@ async def lnurl_callback(
k1: str = Query(None),
):
lnurldevicepayment = await get_lnurldevicepayment(paymentid)
if not lnurldevicepayment:
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="lnurldevicepayment not found."
)
device = await get_lnurldevice(lnurldevicepayment.deviceid)
if not device:
raise HTTPException(
@ -241,13 +239,17 @@ async def lnurl_callback(
else:
if lnurldevicepayment.payload != k1:
return {"status": "ERROR", "reason": "Bad K1"}
lnurldevicepayment = await update_lnurldevicepayment(
if lnurldevicepayment.payhash != "payment_hash":
return {"status": "ERROR", "reason": f"Payment already claimed"}
lnurldevicepayment_updated = await update_lnurldevicepayment(
lnurldevicepayment_id=paymentid, payhash=lnurldevicepayment.payload
)
assert lnurldevicepayment_updated
await pay_invoice(
wallet_id=device.wallet,
payment_request=pr,
max_sat=lnurldevicepayment.sats / 1000,
max_sat=int(lnurldevicepayment_updated.sats / 1000),
extra={"tag": "withdraw"},
)
return {"status": "OK"}

View File

@ -3,13 +3,9 @@ from sqlite3 import Row
from typing import List, Optional
from fastapi import Request
from lnurl import Lnurl
from lnurl import encode as lnurl_encode # type: ignore
from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore
from lnurl.types import LnurlPayMetadata # type: ignore
from loguru import logger
from lnurl import encode as lnurl_encode
from lnurl.types import LnurlPayMetadata
from pydantic import BaseModel
from pydantic.main import BaseModel
class createLnurldevice(BaseModel):
@ -58,6 +54,7 @@ class lnurldevices(BaseModel):
pin4: int
timestamp: str
@classmethod
def from_row(cls, row: Row) -> "lnurldevices":
return cls(**dict(row))

View File

@ -1,18 +1,11 @@
import asyncio
import json
from http import HTTPStatus
from urllib.parse import urlparse
import httpx
from fastapi import HTTPException
from lnbits import bolt11
from lnbits.core.models import Payment
from lnbits.core.services import pay_invoice, websocketUpdater
from lnbits.core.services import websocketUpdater
from lnbits.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener
from .crud import get_lnurldevice, get_lnurldevicepayment, update_lnurldevicepayment
from .crud import get_lnurldevicepayment, update_lnurldevicepayment
async def wait_for_paid_invoices():
@ -27,14 +20,15 @@ async def wait_for_paid_invoices():
async def on_invoice_paid(payment: Payment) -> None:
# (avoid loops)
if "Switch" == payment.extra.get("tag"):
lnurldevicepayment = await get_lnurldevicepayment(payment.extra.get("id"))
lnurldevicepayment = await get_lnurldevicepayment(payment.extra["id"])
if not lnurldevicepayment:
return
if lnurldevicepayment.payhash == "used":
return
lnurldevicepayment = await update_lnurldevicepayment(
lnurldevicepayment_id=payment.extra.get("id"), payhash="used"
lnurldevicepayment_id=payment.extra["id"], payhash="used"
)
assert lnurldevicepayment
return await websocketUpdater(
lnurldevicepayment.deviceid,
str(lnurldevicepayment.pin) + "-" + str(lnurldevicepayment.payload),

View File

@ -1,12 +1,7 @@
from http import HTTPStatus
from io import BytesIO
import pyqrcode
from fastapi import Request
from fastapi.param_functions import Query
from fastapi.params import Depends
from fastapi import Depends, HTTPException, Query, Request
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse, StreamingResponse
from lnbits.core.crud import update_payment_status
@ -62,4 +57,6 @@ async def img(request: Request, lnurldevice_id):
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="LNURLDevice does not exist."
)
return lnurldevice.lnurl(request)
# error: "lnurldevices" has no attribute "lnurl"
# return lnurldevice.lnurl(request)
return None

View File

@ -1,9 +1,6 @@
from http import HTTPStatus
from fastapi import Request
from fastapi.param_functions import Query
from fastapi.params import Depends
from starlette.exceptions import HTTPException
from fastapi import Depends, HTTPException, Query, Request
from lnbits.core.crud import get_user
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
@ -26,9 +23,6 @@ async def api_list_currencies_available():
return list(currencies.keys())
#######################lnurldevice##########################
@lnurldevice_ext.post("/api/v1/lnurlpos")
@lnurldevice_ext.put("/api/v1/lnurlpos/{lnurldevice_id}")
async def api_lnurldevice_create_or_update(
@ -41,7 +35,7 @@ async def api_lnurldevice_create_or_update(
lnurldevice = await create_lnurldevice(data)
return {**lnurldevice.dict(), **{"switches": lnurldevice.switches(req)}}
else:
lnurldevice = await update_lnurldevice(data, lnurldevice_id=lnurldevice_id)
lnurldevice = await update_lnurldevice(lnurldevice_id, **data.dict())
return {**lnurldevice.dict(), **{"switches": lnurldevice.switches(req)}}
@ -49,7 +43,8 @@ async def api_lnurldevice_create_or_update(
async def api_lnurldevices_retrieve(
req: Request, wallet: WalletTypeInfo = Depends(get_key_type)
):
wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids
user = await get_user(wallet.wallet.user)
wallet_ids = user.wallet_ids if user else []
try:
return [
{**lnurldevice.dict(), **{"switches": lnurldevice.switches(req)}}
@ -65,10 +60,11 @@ async def api_lnurldevices_retrieve(
return ""
@lnurldevice_ext.get("/api/v1/lnurlpos/{lnurldevice_id}")
@lnurldevice_ext.get(
"/api/v1/lnurlpos/{lnurldevice_id}", dependencies=[Depends(get_key_type)]
)
async def api_lnurldevice_retrieve(
req: Request,
wallet: WalletTypeInfo = Depends(get_key_type),
lnurldevice_id: str = Query(None),
):
lnurldevice = await get_lnurldevice(lnurldevice_id)
@ -76,23 +72,18 @@ async def api_lnurldevice_retrieve(
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="lnurldevice does not exist"
)
if not lnurldevice.lnurl_toggle:
return {**lnurldevice.dict()}
return {**lnurldevice.dict(), **{"switches": lnurldevice.switches(req)}}
@lnurldevice_ext.delete("/api/v1/lnurlpos/{lnurldevice_id}")
async def api_lnurldevice_delete(
wallet: WalletTypeInfo = Depends(require_admin_key),
lnurldevice_id: str = Query(None),
):
@lnurldevice_ext.delete(
"/api/v1/lnurlpos/{lnurldevice_id}", dependencies=[Depends(require_admin_key)]
)
async def api_lnurldevice_delete(lnurldevice_id: str = Query(None)):
lnurldevice = await get_lnurldevice(lnurldevice_id)
if not lnurldevice:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Wallet link does not exist."
)
await delete_lnurldevice(lnurldevice_id)
return "", HTTPStatus.NO_CONTENT

View File

@ -92,7 +92,6 @@ exclude = """(?x)(
^lnbits/extensions/bleskomat.
| ^lnbits/extensions/boltz.
| ^lnbits/extensions/livestream.
| ^lnbits/extensions/lnurldevice.
| ^lnbits/wallets/lnd_grpc_files.
)"""