Merge pull request #311 from arcbtc/FastAPI

Most extensions done
This commit is contained in:
Arc 2021-08-22 11:41:18 +01:00 committed by GitHub
commit 064994d67e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 186 additions and 132 deletions

View file

@ -1,4 +1,4 @@
from pydantic.types import constr from pydantic import BaseModel
import trio import trio
import json import json
import httpx import httpx
@ -7,8 +7,6 @@ from urllib.parse import urlparse, urlunparse, urlencode, parse_qs, ParseResult
from quart import g, current_app, make_response, url_for from quart import g, current_app, make_response, url_for
from fastapi import Query from fastapi import Query
from fastapi.encoders import jsonable_encoder
from http import HTTPStatus from http import HTTPStatus
from binascii import unhexlify from binascii import unhexlify
@ -440,7 +438,7 @@ async def api_lnurlscan(code: str):
return params return params
@core_app.post("/api/v1/lnurlauth", methods=["POST"]) @core_app.post("/api/v1/lnurlauth")
@api_check_wallet_key("admin") @api_check_wallet_key("admin")
async def api_perform_lnurlauth(callback: str): async def api_perform_lnurlauth(callback: str):
err = await perform_lnurlauth(callback) err = await perform_lnurlauth(callback)

View file

@ -65,12 +65,13 @@ async def extensions():
return await templates.TemplateResponse("core/extensions.html", {"request": request, "user": get_user(g.user.id)}) return await templates.TemplateResponse("core/extensions.html", {"request": request, "user": get_user(g.user.id)})
@core_app.get("/wallet") @core_app.get("/wallet{usr}{wal}{nme}")
#Not sure how to validate
@validate_uuids(["usr", "wal"]) @validate_uuids(["usr", "wal"])
async def wallet(): async def wallet(request: Request, usr: Optional[str], wal: Optional[str], nme: Optional[str]):
user_id = request.args.get("usr", type=str) user_id = usr
wallet_id = request.args.get("wal", type=str) wallet_id = wal
wallet_name = request.args.get("nme", type=str) wallet_name = nme
service_fee = int(SERVICE_FEE) if int(SERVICE_FEE) == SERVICE_FEE else SERVICE_FEE service_fee = int(SERVICE_FEE) if int(SERVICE_FEE) == SERVICE_FEE else SERVICE_FEE
# just wallet_name: create a new user, then create a new wallet for user with wallet_name # just wallet_name: create a new user, then create a new wallet for user with wallet_name
@ -102,8 +103,8 @@ async def wallet():
if not wallet: if not wallet:
abort(HTTPStatus.FORBIDDEN, "Not your wallet.") abort(HTTPStatus.FORBIDDEN, "Not your wallet.")
return await render_template( return await templates.TemplateResponse(
"core/wallet.html", user=user, wallet=wallet, service_fee=service_fee "core/wallet.html", {"request":request,"user":user, "wallet":wallet, "service_fee":service_fee}
) )

View file

@ -7,6 +7,7 @@ from . import bleskomat_ext
from .exchange_rates import exchange_rate_providers_serializable, fiat_currencies from .exchange_rates import exchange_rate_providers_serializable, fiat_currencies
from .helpers import get_callback_url from .helpers import get_callback_url
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from fastapi import Request
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")

View file

@ -1,3 +1,6 @@
from typing import Union
from fastapi.param_functions import Query
from pydantic import BaseModel
from quart import g, jsonify, request from quart import g, jsonify, request
from http import HTTPStatus from http import HTTPStatus
@ -50,9 +53,9 @@ async def api_bleskomat_retrieve(bleskomat_id):
class CreateData(BaseModel): class CreateData(BaseModel):
name: str name: str
fiat_currency: str = fiat_currencies.keys() fiat_currency: str = "EUR" # TODO: fix this
exchange_rate_provider: str = exchange_rate_providers.keys() exchange_rate_provider: str = "bitfinex"
fee: Optional[str, int, float] = Query(...) fee: Union[str, int, float] = Query(...)
@bleskomat_ext.post("/api/v1/bleskomat") @bleskomat_ext.post("/api/v1/bleskomat")
@bleskomat_ext.put("/api/v1/bleskomat/<bleskomat_id>") @bleskomat_ext.put("/api/v1/bleskomat/<bleskomat_id>")

View file

@ -1,7 +1,9 @@
from typing import NamedTuple from sqlite3 import Row
from pydantic import BaseModel
#from typing import NamedTuple
class Events(NamedTuple): class Events(BaseModel):
id: str id: str
wallet: str wallet: str
name: str name: str
@ -15,7 +17,7 @@ class Events(NamedTuple):
time: int time: int
class Tickets(NamedTuple): class Tickets(BaseModel):
id: str id: str
wallet: str wallet: str
event: str event: str
@ -23,4 +25,4 @@ class Tickets(NamedTuple):
email: str email: str
registered: bool registered: bool
paid: bool paid: bool
time: int time: int

View file

@ -2,6 +2,11 @@ import re
from quart import g, jsonify, request from quart import g, jsonify, request
from http import HTTPStatus from http import HTTPStatus
from fastapi import FastAPI, Query
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from lnbits.core.crud import get_user, get_wallet from lnbits.core.crud import get_user, get_wallet
from lnbits.core.services import create_invoice, check_invoice_status from lnbits.core.services import create_invoice, check_invoice_status
from lnbits.decorators import api_check_wallet_key, api_validate_post_request from lnbits.decorators import api_check_wallet_key, api_validate_post_request
@ -24,7 +29,7 @@ from .crud import (
# FORMS # FORMS
@lnticket_ext.route("/api/v1/forms", methods=["GET"]) @lnticket_ext.get("/api/v1/forms")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_forms(): async def api_forms():
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
@ -33,50 +38,57 @@ async def api_forms():
wallet_ids = (await get_user(g.wallet.user)).wallet_ids wallet_ids = (await get_user(g.wallet.user)).wallet_ids
return ( return (
jsonify([form._asdict() for form in await get_forms(wallet_ids)]), [form._asdict() for form in await get_forms(wallet_ids)],
HTTPStatus.OK, HTTPStatus.OK,
) )
class CreateData(BaseModel):
wallet: str = Query(...)
name: str = Query(...)
webhook: str = Query(None)
description: str = Query(..., min_length=0)
amount: int = Query(..., ge=0)
flatrate: int = Query(...)
@lnticket_ext.route("/api/v1/forms", methods=["POST"]) @lnticket_ext.post("/api/v1/forms")
@lnticket_ext.route("/api/v1/forms/<form_id>", methods=["PUT"]) @lnticket_ext.put("/api/v1/forms/{form_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"wallet": {"type": "string", "empty": False, "required": True}, # "wallet": {"type": "string", "empty": False, "required": True},
"name": {"type": "string", "empty": False, "required": True}, # "name": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string", "required": False}, # "webhook": {"type": "string", "required": False},
"description": {"type": "string", "min": 0, "required": True}, # "description": {"type": "string", "min": 0, "required": True},
"amount": {"type": "integer", "min": 0, "required": True}, # "amount": {"type": "integer", "min": 0, "required": True},
"flatrate": {"type": "integer", "required": True}, # "flatrate": {"type": "integer", "required": True},
} # }
) # )
async def api_form_create(form_id=None): async def api_form_create(data: CreateData, form_id=None):
if form_id: if form_id:
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != g.wallet.id: if form.wallet != g.wallet.id:
return jsonify({"message": "Not your form."}), HTTPStatus.FORBIDDEN return jsonify{"message": "Not your form."}, HTTPStatus.FORBIDDEN
form = await update_form(form_id, **g.data) form = await update_form(form_id, **data)
else: else:
form = await create_form(**g.data) form = await create_form(**data)
return jsonify(form._asdict()), HTTPStatus.CREATED return form._asdict(), HTTPStatus.CREATED
@lnticket_ext.route("/api/v1/forms/<form_id>", methods=["DELETE"]) @lnticket_ext.delete("/api/v1/forms/{form_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_form_delete(form_id): async def api_form_delete(form_id):
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != g.wallet.id: if form.wallet != g.wallet.id:
return jsonify({"message": "Not your form."}), HTTPStatus.FORBIDDEN return {"message": "Not your form."}, HTTPStatus.FORBIDDEN
await delete_form(form_id) await delete_form(form_id)
@ -86,37 +98,43 @@ async def api_form_delete(form_id):
#########tickets########## #########tickets##########
@lnticket_ext.route("/api/v1/tickets", methods=["GET"]) @lnticket_ext.get("/api/v1/tickets")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_tickets(): async def api_tickets(all_wallets: bool = Query(None)):
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
if "all_wallets" in request.args: if all_wallets:
wallet_ids = (await get_user(g.wallet.user)).wallet_ids wallet_ids = (await get_user(g.wallet.user)).wallet_ids
return ( return (
jsonify([form._asdict() for form in await get_tickets(wallet_ids)]), [form._asdict() for form in await get_tickets(wallet_ids)],
HTTPStatus.OK, HTTPStatus.OK,
) )
class CreateTicketData(BaseModel):
form: str = Query(...)
name: str = Query(...)
email: str = Query("")
ltext: str = Query(...)
sats: int = Query(..., ge=0)
@lnticket_ext.route("/api/v1/tickets/<form_id>", methods=["POST"]) @lnticket_ext.post("/api/v1/tickets/{form_id}")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"form": {"type": "string", "empty": False, "required": True}, # "form": {"type": "string", "empty": False, "required": True},
"name": {"type": "string", "empty": False, "required": True}, # "name": {"type": "string", "empty": False, "required": True},
"email": {"type": "string", "empty": True, "required": True}, # "email": {"type": "string", "empty": True, "required": True},
"ltext": {"type": "string", "empty": False, "required": True}, # "ltext": {"type": "string", "empty": False, "required": True},
"sats": {"type": "integer", "min": 0, "required": True}, # "sats": {"type": "integer", "min": 0, "required": True},
} # }
) # )
async def api_ticket_make_ticket(form_id): async def api_ticket_make_ticket(data: CreateTicketData, form_id):
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "LNTicket does not exist."}), HTTPStatus.NOT_FOUND return {"message": "LNTicket does not exist."}, HTTPStatus.NOT_FOUND
nwords = len(re.split(r"\s+", g.data["ltext"])) nwords = len(re.split(r"\s+", data["ltext"]))
sats = g.data["sats"] sats = data["sats"]
try: try:
payment_hash, payment_request = await create_invoice( payment_hash, payment_request = await create_invoice(
@ -126,53 +144,52 @@ async def api_ticket_make_ticket(form_id):
extra={"tag": "lnticket"}, extra={"tag": "lnticket"},
) )
except Exception as e: except Exception as e:
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR return {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR
ticket = await create_ticket( ticket = await create_ticket(
payment_hash=payment_hash, wallet=form.wallet, **g.data payment_hash=payment_hash, wallet=form.wallet, **data
) )
if not ticket: if not ticket:
return ( return (
jsonify({"message": "LNTicket could not be fetched."}), {"message": "LNTicket could not be fetched."},
HTTPStatus.NOT_FOUND, HTTPStatus.NOT_FOUND,
) )
return ( return
jsonify({"payment_hash": payment_hash, "payment_request": payment_request}), {"payment_hash": payment_hash, "payment_request": payment_request},
HTTPStatus.OK, HTTPStatus.OK
)
@lnticket_ext.route("/api/v1/tickets/<payment_hash>", methods=["GET"]) @lnticket_ext.get("/api/v1/tickets/{payment_hash}")
async def api_ticket_send_ticket(payment_hash): async def api_ticket_send_ticket(payment_hash):
ticket = await get_ticket(payment_hash) ticket = await get_ticket(payment_hash)
try: try:
status = await check_invoice_status(ticket.wallet, payment_hash) status = await check_invoice_status(ticket.wallet, payment_hash)
is_paid = not status.pending is_paid = not status.pending
except Exception: except Exception:
return jsonify({"paid": False}), HTTPStatus.OK return {"paid": False}, HTTPStatus.OK
if is_paid: if is_paid:
wallet = await get_wallet(ticket.wallet) wallet = await get_wallet(ticket.wallet)
payment = await wallet.get_payment(payment_hash) payment = await wallet.get_payment(payment_hash)
await payment.set_pending(False) await payment.set_pending(False)
ticket = await set_ticket_paid(payment_hash=payment_hash) ticket = await set_ticket_paid(payment_hash=payment_hash)
return jsonify({"paid": True}), HTTPStatus.OK return {"paid": True}, HTTPStatus.OK
return jsonify({"paid": False}), HTTPStatus.OK return {"paid": False}, HTTPStatus.OK
@lnticket_ext.route("/api/v1/tickets/<ticket_id>", methods=["DELETE"]) @lnticket_ext.delete("/api/v1/tickets/{ticket_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_ticket_delete(ticket_id): async def api_ticket_delete(ticket_id):
ticket = await get_ticket(ticket_id) ticket = await get_ticket(ticket_id)
if not ticket: if not ticket:
return jsonify({"message": "Paywall does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Paywall does not exist."}, HTTPStatus.NOT_FOUND
if ticket.wallet != g.wallet.id: if ticket.wallet != g.wallet.id:
return jsonify({"message": "Not your ticket."}), HTTPStatus.FORBIDDEN return {"message": "Not your ticket."}, HTTPStatus.FORBIDDEN
await delete_ticket(ticket_id) await delete_ticket(ticket_id)

View file

@ -1,3 +1,6 @@
from typing import Optional
from fastapi.param_functions import Query
from pydantic.main import BaseModel
from quart import g, jsonify, request from quart import g, jsonify, request
from http import HTTPStatus from http import HTTPStatus
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore
@ -60,10 +63,10 @@ async def api_link_retrieve(link_id):
class CreateData(BaseModel): class CreateData(BaseModel):
description: str description: str
min: int = Query(ge=0.01) min: int = Query(0.01, ge=0.01)
max: int = Query(ge=0.01) max: int = Query(0.01, ge=0.01)
currency: Optional[str] currency: Optional[str]
comment_chars: int = Query(ge=0, lt=800) comment_chars: int = Query(0, ge=0, lt=800)
webhook_url: Optional[str] webhook_url: Optional[str]
success_text: Optional[str] success_text: Optional[str]
success_url: Optional[str] success_url: Optional[str]

View file

@ -1,3 +1,5 @@
from typing import Optional
from pydantic.main import BaseModel
from quart import g, jsonify from quart import g, jsonify
from http import HTTPStatus from http import HTTPStatus
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore

View file

@ -3,6 +3,10 @@ from quart import g, jsonify, url_for
from http import HTTPStatus from http import HTTPStatus
import httpx import httpx
from fastapi import FastAPI, Query
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from lnbits.core.crud import get_user from lnbits.core.crud import get_user
from lnbits.decorators import api_check_wallet_key, api_validate_post_request from lnbits.decorators import api_check_wallet_key, api_validate_post_request
@ -19,37 +23,46 @@ from .crud import (
#############################CHARGES########################## #############################CHARGES##########################
class CreateData(BaseModel):
onchainwallet: str
lnbitswallet: str
description: str = Query(...)
webhook: str
completelink: str
completelinktext: str
time: int = Query(..., ge=1)
amount: int = Query(..., ge=1)
@satspay_ext.route("/api/v1/charge", methods=["POST"]) @satspay_ext.post("/api/v1/charge")
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["PUT"]) @satspay_ext.put("/api/v1/charge/{charge_id}")
@api_check_wallet_key("admin") @api_check_wallet_key("admin")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"onchainwallet": {"type": "string"}, # "onchainwallet": {"type": "string"},
"lnbitswallet": {"type": "string"}, # "lnbitswallet": {"type": "string"},
"description": {"type": "string", "empty": False, "required": True}, # "description": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string"}, # "webhook": {"type": "string"},
"completelink": {"type": "string"}, # "completelink": {"type": "string"},
"completelinktext": {"type": "string"}, # "completelinktext": {"type": "string"},
"time": {"type": "integer", "min": 1, "required": True}, # "time": {"type": "integer", "min": 1, "required": True},
"amount": {"type": "integer", "min": 1, "required": True}, # "amount": {"type": "integer", "min": 1, "required": True},
} # }
) # )
async def api_charge_create_or_update(charge_id=None): async def api_charge_create_or_update(data: CreateData, charge_id=None):
if not charge_id: if not charge_id:
charge = await create_charge(user=g.wallet.user, **g.data) charge = await create_charge(user=g.wallet.user, **data)
return jsonify(charge._asdict()), HTTPStatus.CREATED return charge._asdict(), HTTPStatus.CREATED
else: else:
charge = await update_charge(charge_id=charge_id, **g.data) charge = await update_charge(charge_id=charge_id, **data)
return jsonify(charge._asdict()), HTTPStatus.OK return charge._asdict(), HTTPStatus.OK
@satspay_ext.route("/api/v1/charges", methods=["GET"]) @satspay_ext.get("/api/v1/charges")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charges_retrieve(): async def api_charges_retrieve():
try: try:
return ( return (
jsonify(
[ [
{ {
**charge._asdict(), **charge._asdict(),
@ -58,40 +71,40 @@ async def api_charges_retrieve():
} }
for charge in await get_charges(g.wallet.user) for charge in await get_charges(g.wallet.user)
] ]
), ,
HTTPStatus.OK, HTTPStatus.OK,
) )
except: except:
return "" return ""
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["GET"]) @satspay_ext.get("/api/v1/charge/{charge_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charge_retrieve(charge_id): async def api_charge_retrieve(charge_id: str):
charge = await get_charge(charge_id) charge = await get_charge(charge_id)
if not charge: if not charge:
return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND return {"message": "charge does not exist"}, HTTPStatus.NOT_FOUND
return ( return (
jsonify(
{ {
**charge._asdict(), **charge._asdict(),
**{"time_elapsed": charge.time_elapsed}, **{"time_elapsed": charge.time_elapsed},
**{"paid": charge.paid}, **{"paid": charge.paid},
} }
), ,
HTTPStatus.OK, HTTPStatus.OK,
) )
@satspay_ext.route("/api/v1/charge/<charge_id>", methods=["DELETE"]) @satspay_ext.delete("/api/v1/charge/{charge_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_charge_delete(charge_id): async def api_charge_delete(charge_id: str):
charge = await get_charge(charge_id) charge = await get_charge(charge_id)
if not charge: if not charge:
return jsonify({"message": "Wallet link does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Wallet link does not exist."}, HTTPStatus.NOT_FOUND
await delete_charge(charge_id) await delete_charge(charge_id)
@ -101,13 +114,13 @@ async def api_charge_delete(charge_id):
#############################BALANCE########################## #############################BALANCE##########################
@satspay_ext.route("/api/v1/charges/balance/<charge_id>", methods=["GET"]) @satspay_ext.get("/api/v1/charges/balance/{charge_id}")
async def api_charges_balance(charge_id): async def api_charges_balance(charge_id: str):
charge = await check_address_balance(charge_id) charge = await check_address_balance(charge_id)
if not charge: if not charge:
return jsonify({"message": "charge does not exist"}), HTTPStatus.NOT_FOUND return {"message": "charge does not exist"}, HTTPStatus.NOT_FOUND
if charge.paid and charge.webhook: if charge.paid and charge.webhook:
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
try: try:
@ -130,28 +143,28 @@ async def api_charges_balance(charge_id):
) )
except AssertionError: except AssertionError:
charge.webhook = None charge.webhook = None
return jsonify(charge._asdict()), HTTPStatus.OK return charge._asdict(), HTTPStatus.OK
#############################MEMPOOL########################## #############################MEMPOOL##########################
@satspay_ext.route("/api/v1/mempool", methods=["PUT"]) @satspay_ext.put("/api/v1/mempool")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"endpoint": {"type": "string", "empty": False, "required": True}, # "endpoint": {"type": "string", "empty": False, "required": True},
} # }
) # )
async def api_update_mempool(): async def api_update_mempool(endpoint: str = Query(...)):
mempool = await update_mempool(user=g.wallet.user, **g.data) mempool = await update_mempool(user=g.wallet.user, endpoint)
return jsonify(mempool._asdict()), HTTPStatus.OK return mempool._asdict(), HTTPStatus.OK
@satspay_ext.route("/api/v1/mempool", methods=["GET"]) @satspay_ext.get("/api/v1/mempool")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_get_mempool(): async def api_get_mempool():
mempool = await get_mempool(g.wallet.user) mempool = await get_mempool(g.wallet.user)
if not mempool: if not mempool:
mempool = await create_mempool(user=g.wallet.user) mempool = await create_mempool(user=g.wallet.user)
return jsonify(mempool._asdict()), HTTPStatus.OK return mempool._asdict(), HTTPStatus.OK

View file

@ -1,3 +1,5 @@
from typing import List, Optional
from pydantic import BaseModel
from quart import g, jsonify from quart import g, jsonify
from http import HTTPStatus from http import HTTPStatus
@ -22,7 +24,8 @@ class SchemaData(BaseModel):
@splitpayments_ext.put("/api/v1/targets") @splitpayments_ext.put("/api/v1/targets")
@api_check_wallet_key("admin") @api_check_wallet_key("admin")
async def api_targets_set(targets: Optional(list[SchemaData]) = None): async def api_targets_set(targets: Optional[List[SchemaData]]
= None):
targets = [] targets = []
for entry in targets: for entry in targets:

View file

@ -1,3 +1,5 @@
from typing import Optional
from pydantic.main import BaseModel
from quart import g, redirect, request, jsonify from quart import g, redirect, request, jsonify
from http import HTTPStatus from http import HTTPStatus
@ -34,7 +36,7 @@ class CreateServicesData(BaseModel):
@streamalerts_ext.post("/api/v1/services") @streamalerts_ext.post("/api/v1/services")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_create_service(data: CreateData): async def api_create_service(data: CreateServicesData):
"""Create a service, which holds data about how/where to post donations""" """Create a service, which holds data about how/where to post donations"""
try: try:
service = await create_service(**data) service = await create_service(**data)

View file

@ -1,3 +1,6 @@
from typing import Optional
from fastapi.param_functions import Query
from pydantic.main import BaseModel
from quart import g, jsonify, request from quart import g, jsonify, request
from http import HTTPStatus from http import HTTPStatus
@ -42,7 +45,7 @@ class CreateDomainsData(BaseModel):
domain: str domain: str
cf_token: str cf_token: str
cf_zone_id: str cf_zone_id: str
webhook: optional[str] webhook: Optional[str]
description: str description: str
cost: int cost: int
allowed_record_types: str allowed_record_types: str
@ -103,7 +106,7 @@ class CreateDomainsData(BaseModel):
subdomain: str subdomain: str
email: str email: str
ip: str ip: str
sats: int = Query(ge=0) sats: int = Query(0, ge=0)
duration: int duration: int
record_type: str record_type: str

View file

@ -3,7 +3,7 @@ from quart import g, render_template
from lnbits.decorators import check_user_exists, validate_uuids from lnbits.decorators import check_user_exists, validate_uuids
from . import usermanager_ext from . import usermanager_ext
from fastapi import FastAPI, Request from fastapi import Request
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")

View file

@ -1,9 +1,15 @@
from typing import Optional
from quart import g, jsonify from quart import g, jsonify
from http import HTTPStatus from http import HTTPStatus
from lnbits.core.crud import get_user from lnbits.core.crud import get_user
from lnbits.decorators import api_check_wallet_key, api_validate_post_request from lnbits.decorators import api_check_wallet_key, api_validate_post_request
from fastapi import FastAPI, Query
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from . import usermanager_ext from . import usermanager_ext
from .crud import ( from .crud import (
create_usermanager_user, create_usermanager_user,
@ -32,7 +38,7 @@ async def api_usermanager_users():
) )
@usermanager_ext.get("/api/v1/users/<user_id>") @usermanager_ext.get("/api/v1/users/{user_id}")
@api_check_wallet_key(key_type="invoice") @api_check_wallet_key(key_type="invoice")
async def api_usermanager_user(user_id): async def api_usermanager_user(user_id):
user = await get_usermanager_user(user_id) user = await get_usermanager_user(user_id)
@ -56,12 +62,12 @@ async def api_usermanager_users_create(data: CreateUsersData):
return jsonify(full), HTTPStatus.CREATED return jsonify(full), HTTPStatus.CREATED
@usermanager_ext.delete("/api/v1/users/<user_id>") @usermanager_ext.delete("/api/v1/users/{user_id}")
@api_check_wallet_key(key_type="invoice") @api_check_wallet_key(key_type="invoice")
async def api_usermanager_users_delete(user_id): async def api_usermanager_users_delete(user_id):
user = await get_usermanager_user(user_id) user = await get_usermanager_user(user_id)
if not user: if not user:
return jsonify({"message": "User does not exist."}), HTTPStatus.NOT_FOUND return {"message": "User does not exist."}, HTTPStatus.NOT_FOUND
await delete_usermanager_user(user_id) await delete_usermanager_user(user_id)
return "", HTTPStatus.NO_CONTENT return "", HTTPStatus.NO_CONTENT
@ -112,13 +118,13 @@ async def api_usermanager_wallets():
) )
@usermanager_ext.get("/api/v1/wallets<wallet_id>") @usermanager_ext.get("/api/v1/wallets/{wallet_id}")
@api_check_wallet_key(key_type="invoice") @api_check_wallet_key(key_type="invoice")
async def api_usermanager_wallet_transactions(wallet_id): async def api_usermanager_wallet_transactions(wallet_id):
return await get_usermanager_wallet_transactions(wallet_id), HTTPStatus.OK return await get_usermanager_wallet_transactions(wallet_id), HTTPStatus.OK
@usermanager_ext.get("/api/v1/wallets/<user_id>") @usermanager_ext.get("/api/v1/wallets/{user_id}")
@api_check_wallet_key(key_type="invoice") @api_check_wallet_key(key_type="invoice")
async def api_usermanager_users_wallets(user_id): async def api_usermanager_users_wallets(user_id):
wallet = await get_usermanager_users_wallets(user_id) wallet = await get_usermanager_users_wallets(user_id)
@ -131,7 +137,7 @@ async def api_usermanager_users_wallets(user_id):
) )
@usermanager_ext.delete("/api/v1/wallets/<wallet_id>") @usermanager_ext.delete("/api/v1/wallets/{wallet_id}")
@api_check_wallet_key(key_type="invoice") @api_check_wallet_key(key_type="invoice")
async def api_usermanager_wallets_delete(wallet_id): async def api_usermanager_wallets_delete(wallet_id):
wallet = await get_usermanager_wallet(wallet_id) wallet = await get_usermanager_wallet(wallet_id)