invoice gets undefined
This commit is contained in:
parent
d9aaae7872
commit
683f138f1b
7 changed files with 127 additions and 79 deletions
|
|
@ -1,12 +1,26 @@
|
||||||
from quart import Blueprint
|
import asyncio
|
||||||
|
|
||||||
|
from fastapi import APIRouter
|
||||||
|
|
||||||
from lnbits.db import Database
|
from lnbits.db import Database
|
||||||
|
from lnbits.helpers import template_renderer
|
||||||
|
from lnbits.tasks import catch_everything_and_restart
|
||||||
|
|
||||||
db = Database("ext_tpos")
|
db = Database("ext_tpos")
|
||||||
|
|
||||||
tpos_ext: Blueprint = Blueprint(
|
tpos_ext: APIRouter = APIRouter(
|
||||||
"tpos", __name__, static_folder="static", template_folder="templates"
|
prefix="/tpos",
|
||||||
|
tags=["TPoS"]
|
||||||
|
# "tpos", __name__, static_folder="static", template_folder="templates"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def tpos_renderer():
|
||||||
|
return template_renderer(
|
||||||
|
[
|
||||||
|
"lnbits/extensions/tpos/templates",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
from .views_api import * # noqa
|
from .views_api import * # noqa
|
||||||
from .views import * # noqa
|
from .views import * # noqa
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,17 @@ from typing import List, Optional, Union
|
||||||
from lnbits.helpers import urlsafe_short_hash
|
from lnbits.helpers import urlsafe_short_hash
|
||||||
|
|
||||||
from . import db
|
from . import db
|
||||||
from .models import TPoS
|
from .models import TPoS, CreateTposData
|
||||||
|
|
||||||
|
|
||||||
async def create_tpos(*, wallet_id: str, name: str, currency: str) -> TPoS:
|
async def create_tpos(wallet_id: str, data: CreateTposData) -> TPoS:
|
||||||
tpos_id = urlsafe_short_hash()
|
tpos_id = urlsafe_short_hash()
|
||||||
await db.execute(
|
await db.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO tpos.tposs (id, wallet, name, currency)
|
INSERT INTO tpos.tposs (id, wallet, name, currency)
|
||||||
VALUES (?, ?, ?, ?)
|
VALUES (?, ?, ?, ?)
|
||||||
""",
|
""",
|
||||||
(tpos_id, wallet_id, name, currency),
|
(tpos_id, wallet_id, data.name, data.currency),
|
||||||
)
|
)
|
||||||
|
|
||||||
tpos = await get_tpos(tpos_id)
|
tpos = await get_tpos(tpos_id)
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
from sqlite3 import Row
|
from sqlite3 import Row
|
||||||
from typing import NamedTuple
|
from fastapi.param_functions import Query
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
class TPoS(NamedTuple):
|
class CreateTposData(BaseModel):
|
||||||
|
name: str
|
||||||
|
currency: str
|
||||||
|
|
||||||
|
class TPoS(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
wallet: str
|
wallet: str
|
||||||
name: str
|
name: str
|
||||||
|
|
|
||||||
|
|
@ -354,7 +354,7 @@
|
||||||
LNbits.api
|
LNbits.api
|
||||||
.request(
|
.request(
|
||||||
'GET',
|
'GET',
|
||||||
'/tpos/api/v1/tposs?all_wallets',
|
'/tpos/api/v1/tposs?all_wallets=true',
|
||||||
this.g.user.wallets[0].inkey
|
this.g.user.wallets[0].inkey
|
||||||
)
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,7 @@
|
||||||
return Math.ceil((this.amount / this.exchangeRate) * 100000000)
|
return Math.ceil((this.amount / this.exchangeRate) * 100000000)
|
||||||
},
|
},
|
||||||
fsat: function () {
|
fsat: function () {
|
||||||
|
console.log('sat', this.sat, LNbits.utils.formatSat(this.sat))
|
||||||
return LNbits.utils.formatSat(this.sat)
|
return LNbits.utils.formatSat(this.sat)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -203,12 +204,16 @@
|
||||||
showInvoice: function () {
|
showInvoice: function () {
|
||||||
var self = this
|
var self = this
|
||||||
var dialog = this.invoiceDialog
|
var dialog = this.invoiceDialog
|
||||||
|
console.log(this.sat, this.tposId)
|
||||||
axios
|
axios
|
||||||
.post('/tpos/api/v1/tposs/' + this.tposId + '/invoices/', {
|
.post(
|
||||||
|
'/tpos/api/v1/tposs/' + this.tposId + '/invoices',
|
||||||
|
JSON.stringify({
|
||||||
amount: this.sat
|
amount: this.sat
|
||||||
})
|
})
|
||||||
|
)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
console.log(response.data)
|
||||||
dialog.data = response.data
|
dialog.data = response.data
|
||||||
dialog.show = true
|
dialog.show = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,33 @@
|
||||||
from quart import g, abort, render_template
|
from starlette.exceptions import HTTPException
|
||||||
|
from starlette.responses import HTMLResponse
|
||||||
|
from lnbits.core.models import User
|
||||||
|
from lnbits.core.crud import get_wallet
|
||||||
|
from lnbits.decorators import check_user_exists
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
from lnbits.decorators import check_user_exists, validate_uuids
|
from . import tpos_ext, tpos_renderer
|
||||||
|
|
||||||
from . import tpos_ext
|
|
||||||
from .crud import get_tpos
|
from .crud import get_tpos
|
||||||
|
from fastapi import FastAPI, Request
|
||||||
|
from fastapi.params import Depends
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
@tpos_ext.get("/", response_class=HTMLResponse)
|
||||||
|
# @validate_uuids(["usr"], required=True)
|
||||||
|
# @check_user_exists()
|
||||||
|
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||||
|
return tpos_renderer().TemplateResponse("tpos/index.html", {"request": request,"user": user.dict()})
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/")
|
@tpos_ext.get("/{tpos_id}")
|
||||||
@validate_uuids(["usr"], required=True)
|
async def tpos(request: Request, tpos_id):
|
||||||
@check_user_exists()
|
|
||||||
async def index():
|
|
||||||
return await render_template("tpos/index.html", user=g.user)
|
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/<tpos_id>")
|
|
||||||
async def tpos(tpos_id):
|
|
||||||
tpos = await get_tpos(tpos_id)
|
tpos = await get_tpos(tpos_id)
|
||||||
if not tpos:
|
if not tpos:
|
||||||
abort(HTTPStatus.NOT_FOUND, "TPoS does not exist.")
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
|
detail="TPoS does not exist."
|
||||||
|
)
|
||||||
|
# abort(HTTPStatus.NOT_FOUND, "TPoS does not exist.")
|
||||||
|
|
||||||
return await render_template("tpos/tpos.html", tpos=tpos)
|
return tpos_renderer().TemplateResponse("tpos/tpos.html", {"request": request, "tpos": tpos})
|
||||||
|
|
|
||||||
|
|
@ -1,101 +1,115 @@
|
||||||
from quart import g, jsonify, request
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
|
||||||
|
from fastapi import Query
|
||||||
|
from fastapi.params import Depends
|
||||||
|
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from starlette.exceptions import HTTPException
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import HTMLResponse, JSONResponse # type: ignore
|
||||||
|
|
||||||
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 WalletTypeInfo, get_key_type
|
||||||
|
|
||||||
from . import tpos_ext
|
from . import tpos_ext
|
||||||
from .crud import create_tpos, get_tpos, get_tposs, delete_tpos
|
from .crud import create_tpos, get_tpos, get_tposs, delete_tpos
|
||||||
|
from .models import TPoS, CreateTposData
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/api/v1/tposs", methods=["GET"])
|
@tpos_ext.get("/api/v1/tposs", status_code=HTTPStatus.OK)
|
||||||
@api_check_wallet_key("invoice")
|
async def api_tposs(
|
||||||
async def api_tposs():
|
all_wallets: bool = Query(None),
|
||||||
wallet_ids = [g.wallet.id]
|
wallet: WalletTypeInfo = Depends(get_key_type)
|
||||||
if "all_wallets" in request.args:
|
):
|
||||||
wallet_ids = (await get_user(g.wallet.user)).wallet_ids
|
wallet_ids = [wallet.wallet.id]
|
||||||
|
if all_wallets:
|
||||||
|
wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids
|
||||||
|
|
||||||
return (
|
return [tpos.dict() for tpos in await get_tposs(wallet_ids)]
|
||||||
jsonify([tpos._asdict() for tpos in await get_tposs(wallet_ids)]),
|
|
||||||
HTTPStatus.OK,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/api/v1/tposs", methods=["POST"])
|
@tpos_ext.post("/api/v1/tposs", status_code=HTTPStatus.CREATED)
|
||||||
@api_check_wallet_key("invoice")
|
async def api_tpos_create(data: CreateTposData, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
@api_validate_post_request(
|
tpos = await create_tpos(wallet_id=wallet.wallet.id, data=data)
|
||||||
schema={
|
return tpos.dict()
|
||||||
"name": {"type": "string", "empty": False, "required": True},
|
|
||||||
"currency": {"type": "string", "empty": False, "required": True},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
async def api_tpos_create():
|
|
||||||
tpos = await create_tpos(wallet_id=g.wallet.id, **g.data)
|
|
||||||
return jsonify(tpos._asdict()), HTTPStatus.CREATED
|
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/api/v1/tposs/<tpos_id>", methods=["DELETE"])
|
@tpos_ext.delete("/api/v1/tposs/{tpos_id}")
|
||||||
@api_check_wallet_key("admin")
|
async def api_tpos_delete(tpos_id: str, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||||
async def api_tpos_delete(tpos_id):
|
|
||||||
tpos = await get_tpos(tpos_id)
|
tpos = await get_tpos(tpos_id)
|
||||||
|
|
||||||
if not tpos:
|
if not tpos:
|
||||||
return jsonify({"message": "TPoS does not exist."}), HTTPStatus.NOT_FOUND
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
|
detail="TPoS does not exist."
|
||||||
|
)
|
||||||
|
# return {"message": "TPoS does not exist."}, HTTPStatus.NOT_FOUND
|
||||||
|
|
||||||
if tpos.wallet != g.wallet.id:
|
if tpos.wallet != wallet.wallet.id:
|
||||||
return jsonify({"message": "Not your TPoS."}), HTTPStatus.FORBIDDEN
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.FORBIDDEN,
|
||||||
|
detail="Not your TPoS."
|
||||||
|
)
|
||||||
|
# return {"message": "Not your TPoS."}, HTTPStatus.FORBIDDEN
|
||||||
|
|
||||||
await delete_tpos(tpos_id)
|
await delete_tpos(tpos_id)
|
||||||
|
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||||
return "", HTTPStatus.NO_CONTENT
|
# return "", HTTPStatus.NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/api/v1/tposs/<tpos_id>/invoices/", methods=["POST"])
|
@tpos_ext.post("/api/v1/tposs/{tpos_id}/invoices", status_code=HTTPStatus.CREATED)
|
||||||
@api_validate_post_request(
|
async def api_tpos_create_invoice(amount: int = Query(..., ge=1), tpos_id: str = None):
|
||||||
schema={"amount": {"type": "integer", "min": 1, "required": True}}
|
print("TPOS", tpos_id, amount)
|
||||||
)
|
|
||||||
async def api_tpos_create_invoice(tpos_id):
|
|
||||||
tpos = await get_tpos(tpos_id)
|
tpos = await get_tpos(tpos_id)
|
||||||
|
|
||||||
if not tpos:
|
if not tpos:
|
||||||
return jsonify({"message": "TPoS does not exist."}), HTTPStatus.NOT_FOUND
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
|
detail="TPoS does not exist."
|
||||||
|
)
|
||||||
|
# return {"message": "TPoS does not exist."}, HTTPStatus.NOT_FOUND
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payment_hash, payment_request = await create_invoice(
|
payment_hash, payment_request = await create_invoice(
|
||||||
wallet_id=tpos.wallet,
|
wallet_id=tpos.wallet,
|
||||||
amount=g.data["amount"],
|
amount=amount,
|
||||||
memo=f"{tpos.name}",
|
memo=f"{tpos.name}",
|
||||||
extra={"tag": "tpos"},
|
extra={"tag": "tpos"},
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR
|
print("ERROR", e)
|
||||||
|
raise HTTPException(
|
||||||
return (
|
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||||
jsonify({"payment_hash": payment_hash, "payment_request": payment_request}),
|
detail=str(e)
|
||||||
HTTPStatus.CREATED,
|
|
||||||
)
|
)
|
||||||
|
# return {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
|
print("INV", payment_hash)
|
||||||
|
return {"payment_hash": payment_hash, "payment_request": payment_request}
|
||||||
|
|
||||||
|
|
||||||
@tpos_ext.route("/api/v1/tposs/<tpos_id>/invoices/<payment_hash>", methods=["GET"])
|
@tpos_ext.get("/api/v1/tposs/{tpos_id}/invoices/{payment_hash}", status_code=HTTPStatus.OK)
|
||||||
async def api_tpos_check_invoice(tpos_id, payment_hash):
|
async def api_tpos_check_invoice(tpos_id: str, payment_hash: str):
|
||||||
tpos = await get_tpos(tpos_id)
|
tpos = await get_tpos(tpos_id)
|
||||||
|
|
||||||
if not tpos:
|
if not tpos:
|
||||||
return jsonify({"message": "TPoS does not exist."}), HTTPStatus.NOT_FOUND
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND,
|
||||||
|
detail="TPoS does not exist."
|
||||||
|
)
|
||||||
|
# return {"message": "TPoS does not exist."}, HTTPStatus.NOT_FOUND
|
||||||
|
|
||||||
try:
|
try:
|
||||||
status = await check_invoice_status(tpos.wallet, payment_hash)
|
status = await check_invoice_status(tpos.wallet, payment_hash)
|
||||||
is_paid = not status.pending
|
is_paid = not status.pending
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(exc)
|
print(exc)
|
||||||
return jsonify({"paid": False}), HTTPStatus.OK
|
return {"paid": False}
|
||||||
|
|
||||||
if is_paid:
|
if is_paid:
|
||||||
wallet = await get_wallet(tpos.wallet)
|
wallet = await get_wallet(tpos.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)
|
||||||
|
|
||||||
return jsonify({"paid": True}), HTTPStatus.OK
|
return {"paid": True}
|
||||||
|
|
||||||
return jsonify({"paid": False}), HTTPStatus.OK
|
return {"paid": False}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue