Boots, errors, needs work
This commit is contained in:
parent
56c9234aff
commit
c10f89e1d6
5 changed files with 71 additions and 12 deletions
|
|
@ -16,7 +16,6 @@ boltcards_static_files = [
|
||||||
|
|
||||||
boltcards_ext: APIRouter = APIRouter(prefix="/boltcards", tags=["boltcards"])
|
boltcards_ext: APIRouter = APIRouter(prefix="/boltcards", tags=["boltcards"])
|
||||||
|
|
||||||
|
|
||||||
def boltcards_renderer():
|
def boltcards_renderer():
|
||||||
return template_renderer(["lnbits/extensions/boltcards/templates"])
|
return template_renderer(["lnbits/extensions/boltcards/templates"])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ 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 Card, CreateCardData, Hit
|
from .models import Card, CreateCardData, Hit, Refund
|
||||||
|
|
||||||
|
|
||||||
async def create_card(data: CreateCardData, wallet_id: str) -> Card:
|
async def create_card(data: CreateCardData, wallet_id: str) -> Card:
|
||||||
|
|
@ -143,6 +143,13 @@ async def get_hits(cards_ids: Union[str, List[str]]) -> List[Hit]:
|
||||||
|
|
||||||
return [Hit(**row) for row in rows]
|
return [Hit(**row) for row in rows]
|
||||||
|
|
||||||
|
async def get_hits_today(card_id: Union[str, List[str]]) -> List[Hit]:
|
||||||
|
rows = await db.fetchall(
|
||||||
|
f"SELECT * FROM boltcards.hits WHERE card_id = ? AND timestamp >= DATE() AND timestamp < DATE() + INTERVAL ? DAY", (card_id, 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
return [Hit(**row) for row in rows]
|
||||||
|
|
||||||
|
|
||||||
async def create_hit(card_id, ip, useragent, old_ctr, new_ctr) -> Hit:
|
async def create_hit(card_id, ip, useragent, old_ctr, new_ctr) -> Hit:
|
||||||
hit_id = urlsafe_short_hash()
|
hit_id = urlsafe_short_hash()
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,14 @@ from fastapi import Request
|
||||||
from fastapi.param_functions import Query
|
from fastapi.param_functions import Query
|
||||||
from starlette.exceptions import HTTPException
|
from starlette.exceptions import HTTPException
|
||||||
|
|
||||||
|
import secrets
|
||||||
|
from http import HTTPStatus
|
||||||
|
|
||||||
|
from fastapi.params import Depends, Query
|
||||||
|
from starlette.exceptions import HTTPException
|
||||||
|
from starlette.requests import Request
|
||||||
|
from starlette.responses import HTMLResponse
|
||||||
|
|
||||||
from lnbits.core.services import create_invoice
|
from lnbits.core.services import create_invoice
|
||||||
from lnbits.core.views.api import pay_invoice
|
from lnbits.core.views.api import pay_invoice
|
||||||
|
|
||||||
|
|
@ -24,6 +32,7 @@ from .crud import (
|
||||||
get_card_by_otp,
|
get_card_by_otp,
|
||||||
get_card_by_uid,
|
get_card_by_uid,
|
||||||
get_hit,
|
get_hit,
|
||||||
|
get_hits_today,
|
||||||
update_card,
|
update_card,
|
||||||
update_card_counter,
|
update_card_counter,
|
||||||
update_card_otp,
|
update_card_otp,
|
||||||
|
|
@ -31,6 +40,8 @@ from .crud import (
|
||||||
from .models import CreateCardData
|
from .models import CreateCardData
|
||||||
from .nxp424 import decryptSUN, getSunMAC
|
from .nxp424 import decryptSUN, getSunMAC
|
||||||
|
|
||||||
|
###############LNURLWITHDRAW#################
|
||||||
|
|
||||||
# /boltcards/api/v1/scan?p=00000000000000000000000000000000&c=0000000000000000
|
# /boltcards/api/v1/scan?p=00000000000000000000000000000000&c=0000000000000000
|
||||||
@boltcards_ext.get("/api/v1/scan/{card_uid}")
|
@boltcards_ext.get("/api/v1/scan/{card_uid}")
|
||||||
async def api_scan(p, c, request: Request, card_uid: str = None):
|
async def api_scan(p, c, request: Request, card_uid: str = None):
|
||||||
|
|
@ -70,15 +81,14 @@ async def api_scan(p, c, request: Request, card_uid: str = None):
|
||||||
|
|
||||||
agent = request.headers["user-agent"] if "user-agent" in request.headers else ""
|
agent = request.headers["user-agent"] if "user-agent" in request.headers else ""
|
||||||
todays_hits = await get_hits_today(card.id)
|
todays_hits = await get_hits_today(card.id)
|
||||||
int hits_amount = 0
|
|
||||||
|
hits_amount = 0
|
||||||
for hit in todays_hits:
|
for hit in todays_hits:
|
||||||
hits_amount = hits_amount + hit.amount
|
hits_amount = hits_amount + hit.amount
|
||||||
if (hits_amount + card.tx_limit) > card.daily_limit:
|
if (hits_amount + card.tx_limit) > card.daily_limit:
|
||||||
return {"status": "ERROR", "reason": "Max daily liit spent."}
|
return {"status": "ERROR", "reason": "Max daily liit spent."}
|
||||||
hit = await create_hit(card.id, ip, agent, card.counter, ctr_int)
|
hit = await create_hit(card.id, ip, agent, card.counter, ctr_int)
|
||||||
|
lnurlpay = lnurl_encode(request.url_for("boltcards.lnurlp_response", hit_id=hit.id))
|
||||||
# link = await get_withdraw_link(card.withdraw, 0)
|
|
||||||
return link.lnurl_response(request)
|
|
||||||
return {
|
return {
|
||||||
"tag": "withdrawRequest",
|
"tag": "withdrawRequest",
|
||||||
"callback": request.url_for(
|
"callback": request.url_for(
|
||||||
|
|
@ -87,7 +97,7 @@ async def api_scan(p, c, request: Request, card_uid: str = None):
|
||||||
"k1": hit.id,
|
"k1": hit.id,
|
||||||
"minWithdrawable": 1 * 1000,
|
"minWithdrawable": 1 * 1000,
|
||||||
"maxWithdrawable": card.tx_limit * 1000,
|
"maxWithdrawable": card.tx_limit * 1000,
|
||||||
"defaultDescription": f"Boltcard (Refunds address {lnurl_encode(req.url_for("boltcards.lnurlp_response", hit_id=hit.id))})",
|
"defaultDescription": f"Boltcard (refund address {lnurlpay})",
|
||||||
}
|
}
|
||||||
|
|
||||||
@boltcards_ext.get(
|
@boltcards_ext.get(
|
||||||
|
|
@ -149,12 +159,12 @@ async def api_auth(a, request: Request):
|
||||||
|
|
||||||
###############LNURLPAY REFUNDS#################
|
###############LNURLPAY REFUNDS#################
|
||||||
|
|
||||||
@satsdice_ext.get(
|
@boltcards_ext.get(
|
||||||
"/api/v1/lnurlp/{hit_id}",
|
"/api/v1/lnurlp/{hit_id}",
|
||||||
response_class=HTMLResponse,
|
response_class=HTMLResponse,
|
||||||
name="boltcards.lnurlp_response",
|
name="boltcards.lnurlp_response",
|
||||||
)
|
)
|
||||||
async def api_lnurlp_response(req: Request, hit_id: str = Query(None)):
|
async def lnurlp_response(req: Request, hit_id: str = Query(None)):
|
||||||
hit = await get_hit(hit_id)
|
hit = await get_hit(hit_id)
|
||||||
if not hit:
|
if not hit:
|
||||||
return {"status": "ERROR", "reason": f"LNURL-pay record not found."}
|
return {"status": "ERROR", "reason": f"LNURL-pay record not found."}
|
||||||
|
|
@ -168,12 +178,12 @@ async def api_lnurlp_response(req: Request, hit_id: str = Query(None)):
|
||||||
return json.dumps(payResponse)
|
return json.dumps(payResponse)
|
||||||
|
|
||||||
|
|
||||||
@satsdice_ext.get(
|
@boltcards_ext.get(
|
||||||
"/api/v1/lnurlp/cb/{hit_id}",
|
"/api/v1/lnurlp/cb/{hit_id}",
|
||||||
response_class=HTMLResponse,
|
response_class=HTMLResponse,
|
||||||
name="boltcards.lnurlp_callback",
|
name="boltcards.lnurlp_callback",
|
||||||
)
|
)
|
||||||
async def api_lnurlp_callback(
|
async def lnurlp_callback(
|
||||||
req: Request, hit_id: str = Query(None), amount: str = Query(None)
|
req: Request, hit_id: str = Query(None), amount: str = Query(None)
|
||||||
):
|
):
|
||||||
hit = await get_hit(hit_id)
|
hit = await get_hit(hit_id)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,15 @@
|
||||||
from fastapi.params import Query
|
from fastapi.params import Query
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
from sqlite3 import Row
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from fastapi import Request
|
||||||
|
from lnurl import Lnurl
|
||||||
|
from lnurl import encode as lnurl_encode # type: ignore
|
||||||
|
from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore
|
||||||
|
from lnurl.types import LnurlPayMetadata # type: ignore
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from pydantic.main import BaseModel
|
||||||
|
|
||||||
ZERO_KEY = "00000000000000000000000000000000"
|
ZERO_KEY = "00000000000000000000000000000000"
|
||||||
|
|
||||||
|
|
@ -56,8 +66,14 @@ class Hit(BaseModel):
|
||||||
new_ctr: int
|
new_ctr: int
|
||||||
time: int
|
time: int
|
||||||
|
|
||||||
|
def from_row(cls, row: Row) -> "Hit":
|
||||||
|
return cls(**dict(row))
|
||||||
|
|
||||||
class Refund(BaseModel):
|
class Refund(BaseModel):
|
||||||
id: str
|
id: str
|
||||||
hit_id: str
|
hit_id: str
|
||||||
refund_amount: int
|
refund_amount: int
|
||||||
time: int
|
time: int
|
||||||
|
|
||||||
|
def from_row(cls, row: Row) -> "Refund":
|
||||||
|
return cls(**dict(row))
|
||||||
|
|
@ -52,6 +52,33 @@ new Vue({
|
||||||
rowsPerPage: 10
|
rowsPerPage: 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
refundsTable: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'hit_id',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Hit ID',
|
||||||
|
field: 'hit_id'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'refund_amount',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Refund Amount',
|
||||||
|
field: 'oldrefund_amount_ctr'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'time',
|
||||||
|
align: 'left',
|
||||||
|
label: 'Time',
|
||||||
|
field: 'time'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
pagination: {
|
||||||
|
rowsPerPage: 10,
|
||||||
|
sortBy: 'date',
|
||||||
|
descending: true
|
||||||
|
}
|
||||||
|
},
|
||||||
hitsTable: {
|
hitsTable: {
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue