mirror of
https://github.com/lnbits/lnbits.git
synced 2025-09-27 20:36:16 +02:00
Merge pull request #387 from arcbtc/FastAPI
restored create invoice api endpoint
This commit is contained in:
@@ -39,14 +39,14 @@ async def update_lnurlpos(lnurlpos_id: str, **kwargs) -> Optional[lnurlposs]:
|
|||||||
row = await db.fetchone(
|
row = await db.fetchone(
|
||||||
"SELECT * FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,)
|
"SELECT * FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,)
|
||||||
)
|
)
|
||||||
return lnurlposs.from_row(row) if row else None
|
return lnurlposs(**row) if row else None
|
||||||
|
|
||||||
|
|
||||||
async def get_lnurlpos(lnurlpos_id: str) -> lnurlposs:
|
async def get_lnurlpos(lnurlpos_id: str) -> lnurlposs:
|
||||||
row = await db.fetchone(
|
row = await db.fetchone(
|
||||||
"SELECT * FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,)
|
"SELECT * FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,)
|
||||||
)
|
)
|
||||||
return lnurlposs.from_row(row) if row else None
|
return lnurlposs(**row) if row else None
|
||||||
|
|
||||||
|
|
||||||
async def get_lnurlposs(wallet_ids: Union[str, List[str]]) -> List[lnurlposs]:
|
async def get_lnurlposs(wallet_ids: Union[str, List[str]]) -> List[lnurlposs]:
|
||||||
@@ -60,7 +60,7 @@ async def get_lnurlposs(wallet_ids: Union[str, List[str]]) -> List[lnurlposs]:
|
|||||||
(*wallet_ids,),
|
(*wallet_ids,),
|
||||||
)
|
)
|
||||||
|
|
||||||
return [lnurlposs.from_row(row) for row in rows]
|
return [lnurlposs(**row) if row else None]
|
||||||
|
|
||||||
|
|
||||||
async def delete_lnurlpos(lnurlpos_id: str) -> None:
|
async def delete_lnurlpos(lnurlpos_id: str) -> None:
|
||||||
@@ -105,11 +105,11 @@ async def update_lnurlpospayment(
|
|||||||
row = await db.fetchone(
|
row = await db.fetchone(
|
||||||
"SELECT * FROM lnurlpos.lnurlpospayment WHERE id = ?", (lnurlpospayment_id,)
|
"SELECT * FROM lnurlpos.lnurlpospayment WHERE id = ?", (lnurlpospayment_id,)
|
||||||
)
|
)
|
||||||
return lnurlpospayment.from_row(row) if row else None
|
return lnurlpospayment(**row) if row else None
|
||||||
|
|
||||||
|
|
||||||
async def get_lnurlpospayment(lnurlpospayment_id: str) -> lnurlpospayment:
|
async def get_lnurlpospayment(lnurlpospayment_id: str) -> lnurlpospayment:
|
||||||
row = await db.fetchone(
|
row = await db.fetchone(
|
||||||
"SELECT * FROM lnurlpos.lnurlpospayment WHERE id = ?", (lnurlpospayment_id,)
|
"SELECT * FROM lnurlpos.lnurlpospayment WHERE id = ?", (lnurlpospayment_id,)
|
||||||
)
|
)
|
||||||
return lnurlpospayment.from_row(row) if row else None
|
return lnurlpospayment(**row) if row else None
|
||||||
|
@@ -25,7 +25,7 @@ from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
|
|||||||
|
|
||||||
@lnurlpos_ext.get(
|
@lnurlpos_ext.get(
|
||||||
"/api/v1/lnurl/{nonce}/{payload}/{pos_id}",
|
"/api/v1/lnurl/{nonce}/{payload}/{pos_id}",
|
||||||
response_class=HTMLResponse,
|
status_code=HTTPStatus.OK,
|
||||||
name="lnurlpos.lnurl_response",
|
name="lnurlpos.lnurl_response",
|
||||||
)
|
)
|
||||||
async def lnurl_response(
|
async def lnurl_response(
|
||||||
@@ -64,33 +64,33 @@ async def lnurl_response(
|
|||||||
pin=decryptedPin,
|
pin=decryptedPin,
|
||||||
payhash="payment_hash",
|
payhash="payment_hash",
|
||||||
)
|
)
|
||||||
print(price_msat)
|
|
||||||
if not lnurlpospayment:
|
if not lnurlpospayment:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=HTTPStatus.FORBIDDEN, detail="Could not create payment"
|
status_code=HTTPStatus.FORBIDDEN, detail="Could not create payment"
|
||||||
)
|
)
|
||||||
|
|
||||||
payResponse = {
|
resp = LnurlPayResponse(
|
||||||
"tag": "payRequest",
|
callback=request.url_for(
|
||||||
"callback": request.url_for(
|
"lnurlpos.lnurl_callback", paymentid=lnurlpospayment.id
|
||||||
"lnurlpos.lnurl_callback",
|
|
||||||
paymentid=lnurlpospayment.id,
|
|
||||||
),
|
),
|
||||||
"metadata": LnurlPayMetadata(json.dumps([["text/plain", str(pos.title)]])),
|
min_sendable=price_msat,
|
||||||
"minSendable": price_msat,
|
max_sendable=price_msat,
|
||||||
"maxSendable": price_msat,
|
metadata=await pos.lnurlpay_metadata(),
|
||||||
}
|
)
|
||||||
print(payResponse)
|
|
||||||
return json.dumps(payResponse)
|
return resp.dict()
|
||||||
|
|
||||||
|
|
||||||
@lnurlpos_ext.get(
|
@lnurlpos_ext.get(
|
||||||
"/api/v1/lnurl/cb/{paymentid}",
|
"/api/v1/lnurl/cb/{paymentid}",
|
||||||
response_class=HTMLResponse,
|
status_code=HTTPStatus.OK,
|
||||||
name="lnurlpos.lnurl_callback",
|
name="lnurlpos.lnurl_callback",
|
||||||
)
|
)
|
||||||
async def lnurl_callback(request: Request, paymentid: str = Query(None)):
|
async def lnurl_callback(request: Request, paymentid: str = Query(None)):
|
||||||
|
print("lnurlpospayment")
|
||||||
lnurlpospayment = await get_lnurlpospayment(paymentid)
|
lnurlpospayment = await get_lnurlpospayment(paymentid)
|
||||||
|
print(lnurlpospayment)
|
||||||
pos = await get_lnurlpos(lnurlpospayment.posid)
|
pos = await get_lnurlpos(lnurlpospayment.posid)
|
||||||
if not pos:
|
if not pos:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
@@ -101,21 +101,18 @@ async def lnurl_callback(request: Request, paymentid: str = Query(None)):
|
|||||||
amount=int(lnurlpospayment.sats / 1000),
|
amount=int(lnurlpospayment.sats / 1000),
|
||||||
memo=pos.title,
|
memo=pos.title,
|
||||||
description_hash=hashlib.sha256(
|
description_hash=hashlib.sha256(
|
||||||
(LnurlPayMetadata(json.dumps([["text/plain", str(pos.title)]]))).encode(
|
(await pos.lnurlpay_metadata()).encode("utf-8")
|
||||||
"utf-8"
|
|
||||||
)
|
|
||||||
).digest(),
|
).digest(),
|
||||||
extra={"tag": "lnurlpos"},
|
extra={"tag": "lnurlpos"},
|
||||||
)
|
)
|
||||||
lnurlpospayment = await update_lnurlpospayment(
|
lnurlpospayment = await update_lnurlpospayment(
|
||||||
lnurlpospayment_id=paymentid, payhash=payment_hash
|
lnurlpospayment_id=paymentid, payhash=payment_hash
|
||||||
)
|
)
|
||||||
success_action = pos.success_action(paymentid, request)
|
|
||||||
|
|
||||||
payResponse = {
|
resp = LnurlPayActionResponse(
|
||||||
"pr": payment_request,
|
pr=payment_request,
|
||||||
"success_action": success_action,
|
success_action=pos.success_action(paymentid, request),
|
||||||
"disposable": False,
|
routes=[],
|
||||||
"routes": [],
|
)
|
||||||
}
|
|
||||||
return json.dumps(payResponse)
|
return resp.dict()
|
||||||
|
@@ -2,6 +2,7 @@ import json
|
|||||||
from lnurl import Lnurl, LnurlWithdrawResponse, encode as lnurl_encode # type: ignore
|
from lnurl import Lnurl, LnurlWithdrawResponse, encode as lnurl_encode # type: ignore
|
||||||
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
|
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
|
||||||
from lnurl.types import LnurlPayMetadata # type: ignore
|
from lnurl.types import LnurlPayMetadata # type: ignore
|
||||||
|
from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore
|
||||||
from sqlite3 import Row
|
from sqlite3 import Row
|
||||||
from typing import NamedTuple, Optional, Dict
|
from typing import NamedTuple, Optional, Dict
|
||||||
import shortuuid # type: ignore
|
import shortuuid # type: ignore
|
||||||
@@ -26,29 +27,24 @@ class lnurlposs(BaseModel):
|
|||||||
currency: str
|
currency: str
|
||||||
timestamp: str
|
timestamp: str
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_row(cls, row: Row) -> "lnurlposs":
|
def from_row(cls, row: Row) -> "lnurlposs":
|
||||||
return cls(**dict(row))
|
return cls(**dict(row))
|
||||||
|
|
||||||
@property
|
def lnurl(self, req: Request) -> Lnurl:
|
||||||
def lnurl(self) -> Lnurl:
|
url = req.url_for("lnurlpos.lnurl_response", pos_id=self.id, _external=True)
|
||||||
url = url_for("lnurlpos.lnurl_response", pos_id=self.id, _external=True)
|
|
||||||
return lnurl_encode(url)
|
return lnurl_encode(url)
|
||||||
|
|
||||||
@property
|
async def lnurlpay_metadata(self) -> LnurlPayMetadata:
|
||||||
def lnurlpay_metadata(self) -> LnurlPayMetadata:
|
|
||||||
return LnurlPayMetadata(json.dumps([["text/plain", self.title]]))
|
return LnurlPayMetadata(json.dumps([["text/plain", self.title]]))
|
||||||
|
|
||||||
def success_action(self, paymentid: str, req: Request) -> Optional[Dict]:
|
def success_action(
|
||||||
url = url_for(
|
self, paymentid: str, req: Request
|
||||||
"lnurlpos.displaypin",
|
) -> Optional[LnurlPaySuccessAction]:
|
||||||
paymentid=paymentid,
|
|
||||||
|
return UrlAction(
|
||||||
|
url=req.url_for("lnurlpos.displaypin", paymentid=paymentid),
|
||||||
|
description="Check the attached link",
|
||||||
)
|
)
|
||||||
return {
|
|
||||||
"tag": "url",
|
|
||||||
"description": "Check the attached link",
|
|
||||||
"url": url,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class lnurlpospayment(BaseModel):
|
class lnurlpospayment(BaseModel):
|
||||||
|
@@ -26,14 +26,16 @@ from lnbits.core.models import User, Payment
|
|||||||
templates = Jinja2Templates(directory="templates")
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
|
||||||
|
|
||||||
@lnurlpos_ext.get("/")
|
@lnurlpos_ext.get("/", response_class=HTMLResponse)
|
||||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||||
return lnurlpos_renderer().TemplateResponse(
|
return lnurlpos_renderer().TemplateResponse(
|
||||||
"lnurlpos/index.html", {"request": request, "user": user.dict()}
|
"lnurlpos/index.html", {"request": request, "user": user.dict()}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@lnurlpos_ext.get("/{paymentid}")
|
@lnurlpos_ext.get(
|
||||||
|
"/{paymentid}", name="lnurlpos.displaypin", response_class=HTMLResponse
|
||||||
|
)
|
||||||
async def displaypin(request: Request, paymentid: str = Query(None)):
|
async def displaypin(request: Request, paymentid: str = Query(None)):
|
||||||
lnurlpospayment = await get_lnurlpospayment(paymentid)
|
lnurlpospayment = await get_lnurlpospayment(paymentid)
|
||||||
if not lnurlpospayment:
|
if not lnurlpospayment:
|
||||||
|
Reference in New Issue
Block a user