lnbits-legend/lnbits/extensions/satsdice/lnurl.py

169 lines
4.6 KiB
Python
Raw Normal View History

2021-10-13 17:08:48 +01:00
import hashlib
2021-10-19 23:05:29 +01:00
import json
2021-10-25 11:54:58 +01:00
import math
2021-10-13 17:08:48 +01:00
from http import HTTPStatus
2021-10-25 11:54:58 +01:00
from fastapi import Request
2021-10-15 14:28:41 +01:00
from fastapi.param_functions import Query
2021-10-25 11:54:58 +01:00
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse # type: ignore
from lnbits.core.services import create_invoice, pay_invoice
2021-10-13 17:08:48 +01:00
from . import satsdice_ext
from .crud import (
2021-10-25 11:54:58 +01:00
create_satsdice_payment,
get_satsdice_pay,
2021-10-13 17:08:48 +01:00
get_satsdice_withdraw_by_hash,
update_satsdice_withdraw,
2021-10-19 23:05:29 +01:00
)
from .models import CreateSatsDicePayment
2021-10-13 17:08:48 +01:00
##############LNURLP STUFF
@satsdice_ext.get(
"/api/v1/lnurlp/{link_id}",
response_class=HTMLResponse,
name="satsdice.lnurlp_response",
)
2021-10-15 14:28:41 +01:00
async def api_lnurlp_response(req: Request, link_id: str = Query(None)):
2021-10-13 17:08:48 +01:00
link = await get_satsdice_pay(link_id)
if not link:
2021-10-15 14:28:41 +01:00
raise HTTPException(
2021-10-17 18:33:29 +01:00
status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found."
2021-10-13 17:08:48 +01:00
)
2021-10-19 23:05:29 +01:00
payResponse = {
"tag": "payRequest",
"callback": req.url_for("satsdice.api_lnurlp_callback", link_id=link.id),
"metadata": link.lnurlpay_metadata,
"minSendable": math.ceil(link.min_bet * 1) * 1000,
"maxSendable": round(link.max_bet * 1) * 1000,
}
return json.dumps(payResponse)
@satsdice_ext.get(
"/api/v1/lnurlp/cb/{link_id}",
response_class=HTMLResponse,
name="satsdice.api_lnurlp_callback",
)
async def api_lnurlp_callback(
req: Request,
link_id: str = Query(None),
amount: str = Query(None),
):
2021-10-13 17:08:48 +01:00
link = await get_satsdice_pay(link_id)
print(link)
2021-10-13 17:08:48 +01:00
if not link:
2021-10-15 14:28:41 +01:00
raise HTTPException(
2021-10-17 18:33:29 +01:00
status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found."
2021-10-13 17:08:48 +01:00
)
min, max = link.min_bet, link.max_bet
min = link.min_bet * 1000
max = link.max_bet * 1000
2021-10-15 14:28:41 +01:00
amount_received = int(amount or 0)
2021-10-13 17:08:48 +01:00
if amount_received < min:
2021-10-19 23:05:29 +01:00
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail=f"Amount {amount_received} is smaller than minimum {min}.",
)
2021-10-13 17:08:48 +01:00
elif amount_received > max:
2021-10-19 23:05:29 +01:00
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail=f"Amount {amount_received} is greater than maximum {max}.",
)
2021-10-13 17:08:48 +01:00
payment_hash, payment_request = await create_invoice(
wallet_id=link.wallet,
amount=int(amount_received / 1000),
memo="Satsdice bet",
description_hash=hashlib.sha256(
link.lnurlpay_metadata.encode("utf-8")
).digest(),
extra={"tag": "satsdice", "link": link.id, "comment": "comment"},
)
2021-10-19 23:05:29 +01:00
success_action = link.success_action(payment_hash=payment_hash, req=req)
data: CreateSatsDicePayment = {
"satsdice_pay": link.id,
"value": amount_received / 1000,
"payment_hash": payment_hash,
}
await create_satsdice_payment(data)
payResponse = {
"pr": payment_request,
"successAction": success_action,
"routes": [],
}
print(json.dumps(payResponse))
2021-10-13 17:08:48 +01:00
2021-10-19 23:05:29 +01:00
return json.dumps(payResponse)
2021-10-13 17:08:48 +01:00
##############LNURLW STUFF
@satsdice_ext.get(
"/api/v1/lnurlw/{unique_hash}",
response_class=HTMLResponse,
name="satsdice.lnurlw_response",
)
async def api_lnurlw_response(req: Request, unique_hash: str = Query(None)):
2021-10-13 17:08:48 +01:00
link = await get_satsdice_withdraw_by_hash(unique_hash)
if not link:
2021-10-15 14:28:41 +01:00
raise HTTPException(
2021-10-17 18:33:29 +01:00
status_code=HTTPStatus.NOT_FOUND, detail="LNURL-satsdice not found."
2021-10-13 17:08:48 +01:00
)
if link.used:
2021-10-17 18:33:29 +01:00
raise HTTPException(status_code=HTTPStatus.OK, detail="satsdice is spent.")
url = req.url_for("satsdice.api_lnurlw_callback", unique_hash=link.unique_hash)
withdrawResponse = {
"tag": "withdrawRequest",
"callback": url,
"k1": link.k1,
"minWithdrawable": link.value * 1000,
"maxWithdrawable": link.value * 1000,
"defaultDescription": "Satsdice winnings!",
}
return json.dumps(withdrawResponse)
2021-10-13 17:08:48 +01:00
# CALLBACK
2021-10-19 23:05:29 +01:00
@satsdice_ext.get(
"/api/v1/lnurlw/cb/{unique_hash}",
2021-11-04 11:11:56 +00:00
status_code=HTTPStatus.OK,
name="satsdice.api_lnurlw_callback",
2021-10-19 23:05:29 +01:00
)
2021-10-15 14:28:41 +01:00
async def api_lnurlw_callback(
req: Request,
unique_hash: str = Query(None),
k1: str = Query(None),
pr: str = Query(None),
2021-10-15 14:28:41 +01:00
):
2021-10-13 17:08:48 +01:00
2021-10-22 03:05:48 +01:00
link = await get_satsdice_withdraw_by_hash(unique_hash)
2021-10-13 17:08:48 +01:00
if not link:
2021-10-22 03:05:48 +01:00
return {"status": "ERROR", "reason": "no withdraw"}
2021-10-13 17:08:48 +01:00
if link.used:
2021-10-22 03:05:48 +01:00
return {"status": "ERROR", "reason": "spent"}
2021-10-13 17:08:48 +01:00
2021-10-22 03:05:48 +01:00
paylink = await get_satsdice_pay(link.satsdice_pay)
2021-10-13 17:08:48 +01:00
2021-10-22 03:05:48 +01:00
await update_satsdice_withdraw(link.id, used=1)
await pay_invoice(
wallet_id=paylink.wallet,
payment_request=pr,
max_sat=link.value,
extra={"tag": "withdraw"},
)
2021-10-13 17:08:48 +01:00
2021-10-15 14:28:41 +01:00
return {"status": "OK"}