fix: several more API calls restored

This commit is contained in:
Stefan Stammberger
2021-08-29 19:38:42 +02:00
parent 5ae124408e
commit fe79709698
5 changed files with 208 additions and 142 deletions
+76 -89
View File
@@ -1,69 +1,59 @@
from lnbits.helpers import url_for
from fastapi.param_functions import Depends
from lnbits.auth_bearer import AuthBearer
from pydantic import BaseModel
import trio
import json
import httpx
import hashlib
from urllib.parse import urlparse, urlunparse, urlencode, parse_qs, ParseResult
from fastapi import Query
from http import HTTPStatus
import json
from binascii import unhexlify
from typing import Dict, List, Optional, Union
from http import HTTPStatus
from typing import Dict, Optional, Union
from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
import httpx
import trio
from fastapi import Query, security
from fastapi.exceptions import HTTPException
from fastapi.param_functions import Depends
from fastapi.params import Body
from pydantic import BaseModel
from lnbits import bolt11, lnurl
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
from lnbits.utils.exchange_rates import currencies, fiat_amount_as_satoshis
from lnbits.core.models import Wallet
from lnbits.decorators import (WalletAdminKeyChecker, WalletInvoiceKeyChecker,
WalletTypeInfo, get_key_type)
from lnbits.helpers import url_for
from lnbits.requestvars import g
from lnbits.utils.exchange_rates import currencies, fiat_amount_as_satoshis
from .. import core_app, db
from ..crud import get_payments, save_balance_check, update_wallet
from ..services import (
PaymentFailure,
InvoiceFailure,
create_invoice,
pay_invoice,
perform_lnurlauth,
)
from ..services import (InvoiceFailure, PaymentFailure, create_invoice,
pay_invoice, perform_lnurlauth)
from ..tasks import api_invoice_listeners
@core_app.get(
"/api/v1/wallet",
# dependencies=[Depends(AuthBearer())]
)
# @api_check_wallet_key("invoice")
async def api_wallet():
@core_app.get("/api/v1/wallet")
async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)):
return (
{"id": g().wallet.id, "name": g().wallet.name, "balance": g().wallet.balance_msat},
{"id": wallet.wallet.id, "name": wallet.wallet.name, "balance": wallet.wallet.balance_msat},
HTTPStatus.OK,
)
@core_app.put("/api/v1/wallet/{new_name}")
@api_check_wallet_key("invoice")
async def api_update_wallet(new_name: str):
await update_wallet(g().wallet.id, new_name)
async def api_update_wallet(new_name: str, wallet: WalletTypeInfo = Depends(get_key_type)):
await update_wallet(wallet.wallet.id, new_name)
return (
{
"id": g().wallet.id,
"name": g().wallet.name,
"balance": g().wallet.balance_msat,
"id": wallet.wallet.id,
"name": wallet.wallet.name,
"balance": wallet.wallet.balance_msat,
},
HTTPStatus.OK,
)
@core_app.get("/api/v1/payments")
@api_check_wallet_key("invoice")
async def api_payments():
return (
await get_payments(wallet_id=g().wallet.id, pending=True, complete=True),
HTTPStatus.OK,
)
async def api_payments(wallet: WalletTypeInfo = Depends(get_key_type)):
return await get_payments(wallet_id=wallet.wallet.id, pending=True, complete=True)
class CreateInvoiceData(BaseModel):
amount: int = Query(None, ge=1)
@@ -75,9 +65,7 @@ class CreateInvoiceData(BaseModel):
extra: Optional[dict] = None
webhook: Optional[str] = None
@api_check_wallet_key("invoice")
# async def api_payments_create_invoice(amount: List[str] = Query([type: str = Query(None)])):
async def api_payments_create_invoice(data: CreateInvoiceData):
async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
if "description_hash" in data:
description_hash = unhexlify(data.description_hash)
memo = ""
@@ -94,7 +82,7 @@ async def api_payments_create_invoice(data: CreateInvoiceData):
async with db.connect() as conn:
try:
payment_hash, payment_request = await create_invoice(
wallet_id=g().wallet.id,
wallet_id=wallet.id,
amount=amount,
memo=memo,
description_hash=description_hash,
@@ -151,10 +139,7 @@ async def api_payments_create_invoice(data: CreateInvoiceData):
)
@api_check_wallet_key("admin")
async def api_payments_pay_invoice(
bolt11: str = Query(...), wallet: Optional[List[str]] = Query(None)
):
async def api_payments_pay_invoice(bolt11: str, wallet: Wallet):
try:
payment_hash = await pay_invoice(
wallet_id=wallet.id,
@@ -179,11 +164,20 @@ async def api_payments_pay_invoice(
)
@core_app.post("/api/v1/payments")
async def api_payments_create(out: bool = True):
if out is True:
return await api_payments_pay_invoice()
return await api_payments_create_invoice()
@core_app.post("/api/v1/payments", deprecated=True,
description="DEPRECATED. Use /api/v2/TBD and /api/v2/TBD instead")
async def api_payments_create(wallet: WalletTypeInfo = Depends(get_key_type), out: bool = True,
invoiceData: Optional[CreateInvoiceData] = Body(None),
bolt11: Optional[str] = Query(None)):
if wallet.wallet_type < 0 or wallet.wallet_type > 2:
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="Key is invalid")
if out is True and wallet.wallet_type == 0:
if not bolt11:
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail="BOLT11 string is invalid or not given")
return await api_payments_pay_invoice(bolt11, wallet.wallet) # admin key
return await api_payments_create_invoice(invoiceData, wallet.wallet) # invoice key
class CreateLNURLData(BaseModel):
description_hash: str
@@ -192,8 +186,7 @@ class CreateLNURLData(BaseModel):
comment: Optional[str] = None
description: Optional[str] = None
@core_app.post("/api/v1/payments/lnurl")
@api_check_wallet_key("admin")
@core_app.post("/api/v1/payments/lnurl", dependencies=[Depends(WalletAdminKeyChecker())])
async def api_payments_pay_lnurl(data: CreateLNURLData):
domain = urlparse(data.callback).netloc
@@ -258,32 +251,9 @@ async def api_payments_pay_lnurl(data: CreateLNURLData):
HTTPStatus.CREATED,
)
@core_app.get("/api/v1/payments/{payment_hash}")
@api_check_wallet_key("invoice")
async def api_payment(payment_hash):
payment = await g().wallet.get_payment(payment_hash)
if not payment:
return {"message": "Payment does not exist."}, HTTPStatus.NOT_FOUND
elif not payment.pending:
return {"paid": True, "preimage": payment.preimage}, HTTPStatus.OK
try:
await payment.check_pending()
except Exception:
return {"paid": False}, HTTPStatus.OK
return (
{"paid": not payment.pending, "preimage": payment.preimage},
HTTPStatus.OK,
)
@core_app.get("/api/v1/payments/sse")
@api_check_wallet_key("invoice", accept_querystring=True)
async def api_payments_sse():
this_wallet_id = g().wallet.id
async def api_payments_sse(wallet: WalletTypeInfo = Depends(get_key_type)):
this_wallet_id = wallet.wallet.id
send_payment, receive_payment = trio.open_memory_channel(0)
@@ -303,9 +273,10 @@ async def api_payments_sse():
await send_event.send(("keepalive", ""))
await trio.sleep(25)
current_app.nursery.start_soon(payment_received)
current_app.nursery.start_soon(repeat_keepalive)
async with trio.open_nursery() as nursery:
nursery.start_soon(payment_received)
nursery.start_soon(repeat_keepalive)
async def send_events():
try:
async for typ, data in event_to_send:
@@ -332,9 +303,26 @@ async def api_payments_sse():
response.timeout = None
return response
@core_app.get("/api/v1/payments/{payment_hash}")
async def api_payment(payment_hash, wallet: WalletTypeInfo = Depends(get_key_type)):
payment = await wallet.wallet.get_payment(payment_hash)
@core_app.get("/api/v1/lnurlscan/{code}")
@api_check_wallet_key("invoice")
if not payment:
return {"message": "Payment does not exist."}, HTTPStatus.NOT_FOUND
elif not payment.pending:
return {"paid": True, "preimage": payment.preimage}, HTTPStatus.OK
try:
await payment.check_pending()
except Exception:
return {"paid": False}, HTTPStatus.OK
return (
{"paid": not payment.pending, "preimage": payment.preimage},
HTTPStatus.OK,
)
@core_app.get("/api/v1/lnurlscan/{code}", dependencies=[Depends(WalletInvoiceKeyChecker())])
async def api_lnurlscan(code: str):
try:
url = lnurl.decode(code)
@@ -443,8 +431,7 @@ async def api_lnurlscan(code: str):
return params
@core_app.post("/api/v1/lnurlauth")
@api_check_wallet_key("admin")
@core_app.post("/api/v1/lnurlauth", dependencies=[Depends(WalletAdminKeyChecker())])
async def api_perform_lnurlauth(callback: str):
err = await perform_lnurlauth(callback)
if err:
@@ -452,6 +439,6 @@ async def api_perform_lnurlauth(callback: str):
return "", HTTPStatus.OK
@core_app.route("/api/v1/currencies", methods=["GET"])
@core_app.get("/api/v1/currencies")
async def api_list_currencies_available():
return list(currencies.keys())