fix: several more API calls restored
This commit is contained in:
+76
-89
@@ -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())
|
||||
|
||||
@@ -2,12 +2,14 @@ from http import HTTPStatus
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import Request, status
|
||||
from fastapi.exceptions import HTTPException
|
||||
from fastapi.param_functions import Body
|
||||
from fastapi.params import Depends, Query
|
||||
from fastapi.responses import FileResponse, RedirectResponse
|
||||
from fastapi.routing import APIRouter
|
||||
from pydantic.types import UUID4
|
||||
from starlette.responses import HTMLResponse
|
||||
import trio
|
||||
|
||||
from lnbits.core import db
|
||||
from lnbits.helpers import template_renderer, url_for
|
||||
@@ -40,9 +42,7 @@ async def extensions(request: Request, enable: str, disable: str):
|
||||
extension_to_disable = disable
|
||||
|
||||
if extension_to_enable and extension_to_disable:
|
||||
abort(
|
||||
HTTPStatus.BAD_REQUEST, "You can either `enable` or `disable` an extension."
|
||||
)
|
||||
raise HTTPException(HTTPStatus.BAD_REQUEST, "You can either `enable` or `disable` an extension.")
|
||||
|
||||
if extension_to_enable:
|
||||
await update_user_extension(
|
||||
@@ -142,7 +142,8 @@ async def lnurl_full_withdraw_callback(request: Request):
|
||||
except:
|
||||
pass
|
||||
|
||||
current_app.nursery.start_soon(pay)
|
||||
async with trio.open_nursery() as n:
|
||||
n.start_soon(pay)
|
||||
|
||||
balance_notify = request.args.get("balanceNotify")
|
||||
if balance_notify:
|
||||
@@ -159,7 +160,7 @@ async def deletewallet(request: Request):
|
||||
user_wallet_ids = g().user.wallet_ids
|
||||
|
||||
if wallet_id not in user_wallet_ids:
|
||||
abort(HTTPStatus.FORBIDDEN, "Not your wallet.")
|
||||
raise HTTPException(HTTPStatus.FORBIDDEN, "Not your wallet.")
|
||||
else:
|
||||
await delete_wallet(user_id=g().user.id, wallet_id=wallet_id)
|
||||
user_wallet_ids.remove(wallet_id)
|
||||
@@ -186,16 +187,17 @@ async def lnurlwallet(request: Request):
|
||||
user = await get_user(account.id, conn=conn)
|
||||
wallet = await create_wallet(user_id=user.id, conn=conn)
|
||||
|
||||
current_app.nursery.start_soon(
|
||||
redeem_lnurl_withdraw,
|
||||
wallet.id,
|
||||
request.args.get("lightning"),
|
||||
"LNbits initial funding: voucher redeem.",
|
||||
{"tag": "lnurlwallet"},
|
||||
5, # wait 5 seconds before sending the invoice to the service
|
||||
async with trio.open_nursery() as n:
|
||||
n.start_soon(
|
||||
redeem_lnurl_withdraw,
|
||||
wallet.id,
|
||||
request.args.get("lightning"),
|
||||
"LNbits initial funding: voucher redeem.",
|
||||
{"tag": "lnurlwallet"},
|
||||
5, # wait 5 seconds before sending the invoice to the service
|
||||
)
|
||||
|
||||
return redirect(url_for("core.wallet", usr=user.id, wal=wallet.id))
|
||||
return RedirectResponse(f"/wallet?usr={user.id}&wal={wallet.id}", status_code=status.HTTP_307_TEMPORARY_REDIRECT)
|
||||
|
||||
|
||||
@core_html_routes.get("/manifest/{usr}.webmanifest")
|
||||
|
||||
Reference in New Issue
Block a user