black
This commit is contained in:
parent
860709f48c
commit
267dea4f75
|
@ -305,9 +305,7 @@ async def perform_lnurlauth(
|
|||
|
||||
|
||||
async def check_invoice_status(
|
||||
wallet_id: str,
|
||||
payment_hash: str,
|
||||
conn: Optional[Connection] = None,
|
||||
wallet_id: str, payment_hash: str, conn: Optional[Connection] = None
|
||||
) -> PaymentStatus:
|
||||
payment = await get_wallet_payment(wallet_id, payment_hash, conn=conn)
|
||||
if not payment:
|
||||
|
|
|
@ -54,10 +54,7 @@ async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)):
|
|||
"balance": wallet.wallet.balance_msat,
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"name": wallet.wallet.name,
|
||||
"balance": wallet.wallet.balance_msat,
|
||||
}
|
||||
return {"name": wallet.wallet.name, "balance": wallet.wallet.balance_msat}
|
||||
|
||||
|
||||
@core_app.put("/api/v1/wallet/{new_name}")
|
||||
|
@ -74,11 +71,7 @@ async def api_update_wallet(
|
|||
|
||||
@core_app.get("/api/v1/payments")
|
||||
async def api_payments(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
await get_payments(
|
||||
wallet_id=wallet.wallet.id,
|
||||
pending=True,
|
||||
complete=True,
|
||||
)
|
||||
await get_payments(wallet_id=wallet.wallet.id, pending=True, complete=True)
|
||||
pendingPayments = await get_payments(wallet_id=wallet.wallet.id, pending=True)
|
||||
for payment in pendingPayments:
|
||||
await check_invoice_status(
|
||||
|
@ -91,7 +84,7 @@ class CreateInvoiceData(BaseModel):
|
|||
out: Optional[bool] = True
|
||||
amount: int = Query(None, ge=1)
|
||||
memo: str = None
|
||||
unit: Optional[str] = 'sat'
|
||||
unit: Optional[str] = "sat"
|
||||
description_hash: Optional[str] = None
|
||||
lnurl_callback: Optional[str] = None
|
||||
lnurl_balance_check: Optional[str] = None
|
||||
|
@ -107,7 +100,7 @@ async def api_payments_create_invoice(data: CreateInvoiceData, wallet: Wallet):
|
|||
else:
|
||||
description_hash = b""
|
||||
memo = data.memo
|
||||
if data.unit == 'sat':
|
||||
if data.unit == "sat":
|
||||
amount = data.amount
|
||||
else:
|
||||
price_in_sats = await fiat_amount_as_satoshis(data.amount, data.unit)
|
||||
|
@ -334,8 +327,7 @@ async def api_payment(payment_hash):
|
|||
payment = await get_standalone_payment(payment_hash)
|
||||
if not payment:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Payment does not exist.",
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Payment does not exist."
|
||||
)
|
||||
elif not payment.pending:
|
||||
return {"paid": True, "preimage": payment.preimage}
|
||||
|
|
|
@ -14,14 +14,13 @@ bleskomat_static_files = [
|
|||
}
|
||||
]
|
||||
|
||||
bleskomat_ext: APIRouter = APIRouter(
|
||||
prefix="/bleskomat",
|
||||
tags=["Bleskomat"]
|
||||
)
|
||||
bleskomat_ext: APIRouter = APIRouter(prefix="/bleskomat", tags=["Bleskomat"])
|
||||
|
||||
|
||||
def bleskomat_renderer():
|
||||
return template_renderer(["lnbits/extensions/bleskomat/templates"])
|
||||
|
||||
|
||||
from .lnurl_api import * # noqa
|
||||
from .views import * # noqa
|
||||
from .views_api import * # noqa
|
||||
|
|
|
@ -8,10 +8,7 @@ from .helpers import generate_bleskomat_lnurl_hash
|
|||
from .models import Bleskomat, BleskomatLnurl, CreateBleskomat
|
||||
|
||||
|
||||
async def create_bleskomat(
|
||||
data: CreateBleskomat,
|
||||
wallet_id: str,
|
||||
) -> Bleskomat:
|
||||
async def create_bleskomat(data: CreateBleskomat, wallet_id: str) -> Bleskomat:
|
||||
bleskomat_id = uuid4().hex
|
||||
api_key_id = secrets.token_hex(8)
|
||||
api_key_secret = secrets.token_hex(32)
|
||||
|
|
|
@ -20,24 +20,25 @@ class CreateBleskomat(BaseModel):
|
|||
exchange_rate_provider: str = Query(...)
|
||||
fee: str = Query(...)
|
||||
|
||||
@validator('fiat_currency')
|
||||
@validator("fiat_currency")
|
||||
def allowed_fiat_currencies(cls, v):
|
||||
if(v not in fiat_currencies.keys()):
|
||||
raise ValueError('Not allowed currency')
|
||||
if v not in fiat_currencies.keys():
|
||||
raise ValueError("Not allowed currency")
|
||||
return v
|
||||
|
||||
@validator('exchange_rate_provider')
|
||||
@validator("exchange_rate_provider")
|
||||
def allowed_providers(cls, v):
|
||||
if(v not in exchange_rate_providers.keys()):
|
||||
raise ValueError('Not allowed provider')
|
||||
if v not in exchange_rate_providers.keys():
|
||||
raise ValueError("Not allowed provider")
|
||||
return v
|
||||
|
||||
@validator('fee')
|
||||
@validator("fee")
|
||||
def fee_type(cls, v):
|
||||
if(not isinstance(v, (str, float, int))):
|
||||
raise ValueError('Fee type not allowed')
|
||||
if not isinstance(v, (str, float, int)):
|
||||
raise ValueError("Fee type not allowed")
|
||||
return v
|
||||
|
||||
|
||||
class Bleskomat(BaseModel):
|
||||
id: str
|
||||
wallet: str
|
||||
|
@ -119,8 +120,7 @@ class BleskomatLnurl(BaseModel):
|
|||
if tag == "withdrawRequest":
|
||||
try:
|
||||
payment_hash = await pay_invoice(
|
||||
wallet_id=self.wallet,
|
||||
payment_request=query["pr"],
|
||||
wallet_id=self.wallet, payment_request=query["pr"]
|
||||
)
|
||||
except Exception:
|
||||
raise LnurlValidationError("Failed to pay invoice")
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
from fastapi import Request
|
||||
from fastapi.params import Depends
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
@ -22,5 +21,6 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
|
|||
"fiat_currencies": fiat_currencies,
|
||||
}
|
||||
return bleskomat_renderer().TemplateResponse(
|
||||
"bleskomat/index.html", {"request": request, "user": user.dict(), "bleskomat_vars": bleskomat_vars}
|
||||
"bleskomat/index.html",
|
||||
{"request": request, "user": user.dict(), "bleskomat_vars": bleskomat_vars},
|
||||
)
|
||||
|
|
|
@ -19,7 +19,10 @@ from .exchange_rates import fetch_fiat_exchange_rate
|
|||
|
||||
|
||||
@bleskomat_ext.get("/api/v1/bleskomats")
|
||||
async def api_bleskomats(wallet: WalletTypeInfo = Depends(require_admin_key), all_wallets: bool = Query(False)):
|
||||
async def api_bleskomats(
|
||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
all_wallets: bool = Query(False),
|
||||
):
|
||||
wallet_ids = [wallet.wallet.id]
|
||||
|
||||
if all_wallets:
|
||||
|
@ -29,21 +32,27 @@ async def api_bleskomats(wallet: WalletTypeInfo = Depends(require_admin_key), al
|
|||
|
||||
|
||||
@bleskomat_ext.get("/api/v1/bleskomat/{bleskomat_id}")
|
||||
async def api_bleskomat_retrieve(bleskomat_id, wallet: WalletTypeInfo = Depends(require_admin_key)):
|
||||
async def api_bleskomat_retrieve(
|
||||
bleskomat_id, wallet: WalletTypeInfo = Depends(require_admin_key)
|
||||
):
|
||||
bleskomat = await get_bleskomat(bleskomat_id)
|
||||
|
||||
if not bleskomat or bleskomat.wallet != wallet.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Bleskomat configuration not found."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Bleskomat configuration not found.",
|
||||
)
|
||||
|
||||
return bleskomat.dict()
|
||||
|
||||
|
||||
@bleskomat_ext.post("/api/v1/bleskomat")
|
||||
@bleskomat_ext.put("/api/v1/bleskomat/{bleskomat_id}",)
|
||||
async def api_bleskomat_create_or_update(data: CreateBleskomat, wallet: WalletTypeInfo = Depends(require_admin_key), bleskomat_id=None):
|
||||
@bleskomat_ext.put("/api/v1/bleskomat/{bleskomat_id}")
|
||||
async def api_bleskomat_create_or_update(
|
||||
data: CreateBleskomat,
|
||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
bleskomat_id=None,
|
||||
):
|
||||
try:
|
||||
fiat_currency = data.fiat_currency
|
||||
exchange_rate_provider = data.exchange_rate_provider
|
||||
|
@ -54,7 +63,7 @@ async def api_bleskomat_create_or_update(data: CreateBleskomat, wallet: WalletTy
|
|||
print(e)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=f'Failed to fetch BTC/{fiat_currency} currency pair from "{exchange_rate_provider}"'
|
||||
detail=f'Failed to fetch BTC/{fiat_currency} currency pair from "{exchange_rate_provider}"',
|
||||
)
|
||||
|
||||
if bleskomat_id:
|
||||
|
@ -62,9 +71,9 @@ async def api_bleskomat_create_or_update(data: CreateBleskomat, wallet: WalletTy
|
|||
if not bleskomat or bleskomat.wallet != wallet.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Bleskomat configuration not found."
|
||||
detail="Bleskomat configuration not found.",
|
||||
)
|
||||
|
||||
|
||||
bleskomat = await update_bleskomat(bleskomat_id, **data.dict())
|
||||
else:
|
||||
bleskomat = await create_bleskomat(wallet_id=wallet.wallet.id, data=data)
|
||||
|
@ -73,14 +82,16 @@ async def api_bleskomat_create_or_update(data: CreateBleskomat, wallet: WalletTy
|
|||
|
||||
|
||||
@bleskomat_ext.delete("/api/v1/bleskomat/{bleskomat_id}")
|
||||
async def api_bleskomat_delete(bleskomat_id, wallet: WalletTypeInfo = Depends(require_admin_key)):
|
||||
async def api_bleskomat_delete(
|
||||
bleskomat_id, wallet: WalletTypeInfo = Depends(require_admin_key)
|
||||
):
|
||||
bleskomat = await get_bleskomat(bleskomat_id)
|
||||
|
||||
if not bleskomat or bleskomat.wallet != wallet.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Bleskomat configuration not found."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Bleskomat configuration not found.",
|
||||
)
|
||||
|
||||
await delete_bleskomat(bleskomat_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
|
|
@ -31,4 +31,4 @@ from .views_api import * # noqa
|
|||
|
||||
def copilot_start():
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
|
||||
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
|
||||
|
|
|
@ -49,7 +49,7 @@ async def lnurl_callback(
|
|||
status_code=HTTPStatus.NOT_FOUND, detail="Copilot not found"
|
||||
)
|
||||
amount_received = int(amount)
|
||||
|
||||
|
||||
if amount_received < 10000:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
|
@ -80,8 +80,5 @@ async def lnurl_callback(
|
|||
).digest(),
|
||||
extra={"tag": "copilot", "copilotid": cp.id, "comment": comment},
|
||||
)
|
||||
payResponse = {
|
||||
"pr": payment_request,
|
||||
"routes": [],
|
||||
}
|
||||
payResponse = {"pr": payment_request, "routes": []}
|
||||
return json.dumps(payResponse)
|
||||
|
|
|
@ -6,13 +6,12 @@ from lnbits.helpers import template_renderer
|
|||
db = Database("ext_events")
|
||||
|
||||
|
||||
events_ext: APIRouter = APIRouter(
|
||||
prefix="/events",
|
||||
tags=["Events"]
|
||||
)
|
||||
events_ext: APIRouter = APIRouter(prefix="/events", tags=["Events"])
|
||||
|
||||
|
||||
def events_renderer():
|
||||
return template_renderer(["lnbits/extensions/events/templates"])
|
||||
|
||||
|
||||
|
||||
from .views import * # noqa
|
||||
from .views_api import * # noqa
|
||||
|
|
|
@ -74,6 +74,7 @@ async def get_tickets(wallet_ids: Union[str, List[str]]) -> List[Tickets]:
|
|||
async def delete_ticket(payment_hash: str) -> None:
|
||||
await db.execute("DELETE FROM events.ticket WHERE id = ?", (payment_hash,))
|
||||
|
||||
|
||||
async def delete_event_tickets(event_id: str) -> None:
|
||||
await db.execute("DELETE FROM events.tickets WHERE event = ?", (event_id,))
|
||||
|
||||
|
@ -81,9 +82,7 @@ async def delete_event_tickets(event_id: str) -> None:
|
|||
# EVENTS
|
||||
|
||||
|
||||
async def create_event(
|
||||
data: CreateEvent
|
||||
) -> Events:
|
||||
async def create_event(data: CreateEvent) -> Events:
|
||||
event_id = urlsafe_short_hash()
|
||||
await db.execute(
|
||||
"""
|
||||
|
|
|
@ -78,14 +78,6 @@ async def m002_changed(db):
|
|||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
row[0],
|
||||
row[1],
|
||||
row[2],
|
||||
row[3],
|
||||
row[4],
|
||||
row[5],
|
||||
True,
|
||||
),
|
||||
(row[0], row[1], row[2], row[3], row[4], row[5], True),
|
||||
)
|
||||
await db.execute("DROP TABLE events.tickets")
|
||||
|
|
|
@ -5,17 +5,19 @@ from pydantic import BaseModel
|
|||
class CreateEvent(BaseModel):
|
||||
wallet: str
|
||||
name: str
|
||||
info: str
|
||||
closing_date: str
|
||||
event_start_date: str
|
||||
info: str
|
||||
closing_date: str
|
||||
event_start_date: str
|
||||
event_end_date: str
|
||||
amount_tickets: int = Query(..., ge=0)
|
||||
price_per_ticket: int = Query(..., ge=0)
|
||||
|
||||
|
||||
class CreateTicket(BaseModel):
|
||||
name: str
|
||||
email: str
|
||||
|
||||
|
||||
class Events(BaseModel):
|
||||
id: str
|
||||
wallet: str
|
||||
|
|
|
@ -18,7 +18,9 @@ templates = Jinja2Templates(directory="templates")
|
|||
|
||||
@events_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
return events_renderer().TemplateResponse("events/index.html", {"request": request, "user": user.dict()})
|
||||
return events_renderer().TemplateResponse(
|
||||
"events/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
||||
|
||||
@events_ext.get("/{event_id}", response_class=HTMLResponse)
|
||||
|
@ -35,8 +37,8 @@ async def display(request: Request, event_id):
|
|||
{
|
||||
"request": request,
|
||||
"event_name": event.name,
|
||||
"event_error": "Sorry, tickets are sold out :("
|
||||
}
|
||||
"event_error": "Sorry, tickets are sold out :(",
|
||||
},
|
||||
)
|
||||
datetime_object = datetime.strptime(event.closing_date, "%Y-%m-%d").date()
|
||||
if date.today() > datetime_object:
|
||||
|
@ -45,8 +47,8 @@ async def display(request: Request, event_id):
|
|||
{
|
||||
"request": request,
|
||||
"event_name": event.name,
|
||||
"event_error": "Sorry, ticket closing date has passed :("
|
||||
}
|
||||
"event_error": "Sorry, ticket closing date has passed :(",
|
||||
},
|
||||
)
|
||||
|
||||
return events_renderer().TemplateResponse(
|
||||
|
@ -57,8 +59,7 @@ async def display(request: Request, event_id):
|
|||
"event_name": event.name,
|
||||
"event_info": event.info,
|
||||
"event_price": event.price_per_ticket,
|
||||
}
|
||||
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
@ -83,8 +84,7 @@ async def ticket(request: Request, ticket_id):
|
|||
"ticket_id": ticket_id,
|
||||
"ticket_name": event.name,
|
||||
"ticket_info": event.info,
|
||||
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
|
@ -103,5 +103,5 @@ async def register(request: Request, event_id):
|
|||
"event_id": event_id,
|
||||
"event_name": event.name,
|
||||
"wallet_id": event.wallet,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
@ -5,10 +5,8 @@ from lnbits.helpers import template_renderer
|
|||
|
||||
db = Database("ext_hivemind")
|
||||
|
||||
hivemind_ext: APIRouter = APIRouter(
|
||||
prefix="/hivemind",
|
||||
tags=["hivemind"]
|
||||
)
|
||||
hivemind_ext: APIRouter = APIRouter(prefix="/hivemind", tags=["hivemind"])
|
||||
|
||||
|
||||
def hivemind_renderer():
|
||||
return template_renderer(["lnbits/extensions/hivemind/templates"])
|
||||
|
|
|
@ -10,4 +10,6 @@ from . import hivemind_ext, hivemind_renderer
|
|||
|
||||
@hivemind_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
return hivemind_renderer().TemplateResponse("hivemind/index.html", {"request": request, "user": user.dict()})
|
||||
return hivemind_renderer().TemplateResponse(
|
||||
"hivemind/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
|
|
@ -17,14 +17,13 @@ livestream_static_files = [
|
|||
}
|
||||
]
|
||||
|
||||
livestream_ext: APIRouter = APIRouter(
|
||||
prefix="/livestream",
|
||||
tags=["livestream"]
|
||||
)
|
||||
livestream_ext: APIRouter = APIRouter(prefix="/livestream", tags=["livestream"])
|
||||
|
||||
|
||||
def livestream_renderer():
|
||||
return template_renderer(["lnbits/extensions/livestream/templates"])
|
||||
|
||||
|
||||
from .lnurl import * # noqa
|
||||
from .tasks import wait_for_paid_invoices
|
||||
from .views import * # noqa
|
||||
|
|
|
@ -67,8 +67,7 @@ async def update_current_track(ls_id: int, track_id: Optional[int]):
|
|||
|
||||
async def update_livestream_fee(ls_id: int, fee_pct: int):
|
||||
await db.execute(
|
||||
"UPDATE livestream.livestreams SET fee_pct = ? WHERE id = ?",
|
||||
(fee_pct, ls_id),
|
||||
"UPDATE livestream.livestreams SET fee_pct = ? WHERE id = ?", (fee_pct, ls_id)
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -19,21 +19,17 @@ async def lnurl_livestream(ls_id, request: Request):
|
|||
ls = await get_livestream(ls_id)
|
||||
if not ls:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Livestream not found."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Livestream not found."
|
||||
)
|
||||
|
||||
track = await get_track(ls.current_track)
|
||||
if not track:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="This livestream is offline."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="This livestream is offline."
|
||||
)
|
||||
|
||||
resp = LnurlPayResponse(
|
||||
callback=request.url_for(
|
||||
"livestream.lnurl_callback", track_id=track.id
|
||||
),
|
||||
callback=request.url_for("livestream.lnurl_callback", track_id=track.id),
|
||||
min_sendable=track.min_sendable,
|
||||
max_sendable=track.max_sendable,
|
||||
metadata=await track.lnurlpay_metadata(),
|
||||
|
@ -49,15 +45,10 @@ async def lnurl_livestream(ls_id, request: Request):
|
|||
async def lnurl_track(track_id, request: Request):
|
||||
track = await get_track(track_id)
|
||||
if not track:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Track not found."
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Track not found.")
|
||||
|
||||
resp = LnurlPayResponse(
|
||||
callback=request.url_for(
|
||||
"livestream.lnurl_callback", track_id=track.id
|
||||
),
|
||||
callback=request.url_for("livestream.lnurl_callback", track_id=track.id),
|
||||
min_sendable=track.min_sendable,
|
||||
max_sendable=track.max_sendable,
|
||||
metadata=await track.lnurlpay_metadata(),
|
||||
|
@ -70,29 +61,28 @@ async def lnurl_track(track_id, request: Request):
|
|||
|
||||
|
||||
@livestream_ext.get("/lnurl/cb/{track_id}", name="livestream.lnurl_callback")
|
||||
async def lnurl_callback(track_id, request: Request, amount: int = Query(...), comment: str = Query("")):
|
||||
async def lnurl_callback(
|
||||
track_id, request: Request, amount: int = Query(...), comment: str = Query("")
|
||||
):
|
||||
track = await get_track(track_id)
|
||||
if not track:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Track not found."
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Track not found.")
|
||||
|
||||
amount_received = int(amount or 0)
|
||||
|
||||
if amount_received < track.min_sendable:
|
||||
return LnurlErrorResponse(
|
||||
reason=f"Amount {round(amount_received / 1000)} is smaller than minimum {math.floor(track.min_sendable)}."
|
||||
).dict()
|
||||
reason=f"Amount {round(amount_received / 1000)} is smaller than minimum {math.floor(track.min_sendable)}."
|
||||
).dict()
|
||||
elif track.max_sendable < amount_received:
|
||||
return LnurlErrorResponse(
|
||||
reason=f"Amount {round(amount_received / 1000)} is greater than maximum {math.floor(track.max_sendable)}."
|
||||
).dict()
|
||||
reason=f"Amount {round(amount_received / 1000)} is greater than maximum {math.floor(track.max_sendable)}."
|
||||
).dict()
|
||||
|
||||
if len(comment or "") > 300:
|
||||
return LnurlErrorResponse(
|
||||
reason=f"Got a comment with {len(comment)} characters, but can only accept 300"
|
||||
).dict()
|
||||
reason=f"Got a comment with {len(comment)} characters, but can only accept 300"
|
||||
).dict()
|
||||
|
||||
ls = await get_livestream_by_track(track_id)
|
||||
|
||||
|
@ -112,9 +102,7 @@ async def lnurl_callback(track_id, request: Request, amount: int = Query(...), c
|
|||
success_action = track.success_action(payment_hash, request=request)
|
||||
|
||||
resp = LnurlPayActionResponse(
|
||||
pr=payment_request,
|
||||
success_action=success_action,
|
||||
routes=[],
|
||||
pr=payment_request, success_action=success_action, routes=[]
|
||||
)
|
||||
|
||||
return resp.dict()
|
||||
|
|
|
@ -17,6 +17,7 @@ class CreateTrack(BaseModel):
|
|||
producer_id: str = Query(None)
|
||||
producer_name: str = Query(None)
|
||||
|
||||
|
||||
class Livestream(BaseModel):
|
||||
id: int
|
||||
wallet: str
|
||||
|
@ -68,15 +69,15 @@ class Track(BaseModel):
|
|||
|
||||
return LnurlPayMetadata(json.dumps([["text/plain", description]]))
|
||||
|
||||
def success_action(self, payment_hash: str, request: Request) -> Optional[LnurlPaySuccessAction]:
|
||||
def success_action(
|
||||
self, payment_hash: str, request: Request
|
||||
) -> Optional[LnurlPaySuccessAction]:
|
||||
if not self.download_url:
|
||||
return None
|
||||
|
||||
return UrlAction(
|
||||
url=request.url_for(
|
||||
"livestream.track_redirect_download",
|
||||
track_id=self.id,
|
||||
p=payment_hash
|
||||
"livestream.track_redirect_download", track_id=self.id, p=payment_hash
|
||||
),
|
||||
description=f"Download the track {self.name}!",
|
||||
)
|
||||
|
|
|
@ -18,6 +18,7 @@ async def wait_for_paid_invoices():
|
|||
payment = await invoice_queue.get()
|
||||
await on_invoice_paid(payment)
|
||||
|
||||
|
||||
# async def register_listeners():
|
||||
# invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
|
||||
# register_invoice_listener(invoice_paid_chan_send)
|
||||
|
|
|
@ -17,7 +17,9 @@ from .crud import get_livestream_by_track, get_track
|
|||
|
||||
@livestream_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
return livestream_renderer().TemplateResponse("livestream/index.html", {"request": request, "user": user.dict()})
|
||||
return livestream_renderer().TemplateResponse(
|
||||
"livestream/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
||||
|
||||
@livestream_ext.get("/track/{track_id}", name="livestream.track_redirect_download")
|
||||
|
@ -31,12 +33,12 @@ async def track_redirect_download(track_id, p: str = Query(...)):
|
|||
if not payment:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail=f"Couldn't find the payment {payment_hash} or track {track.id}."
|
||||
detail=f"Couldn't find the payment {payment_hash} or track {track.id}.",
|
||||
)
|
||||
|
||||
if payment.pending:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.PAYMENT_REQUIRED,
|
||||
detail=f"Payment {payment_hash} wasn't received yet. Please try again in a minute."
|
||||
detail=f"Payment {payment_hash} wasn't received yet. Please try again in a minute.",
|
||||
)
|
||||
return RedirectResponse(url=track.download_url)
|
||||
|
|
|
@ -23,27 +23,29 @@ from .crud import (
|
|||
|
||||
|
||||
@livestream_ext.get("/api/v1/livestream")
|
||||
async def api_livestream_from_wallet(req: Request, g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_livestream_from_wallet(
|
||||
req: Request, g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
ls = await get_or_create_livestream_by_wallet(g.wallet.id)
|
||||
tracks = await get_tracks(ls.id)
|
||||
producers = await get_producers(ls.id)
|
||||
print("INIT", ls, tracks, producers)
|
||||
try:
|
||||
return {
|
||||
**ls.dict(),
|
||||
**{
|
||||
"lnurl": ls.lnurl(request=req),
|
||||
"tracks": [
|
||||
dict(lnurl=track.lnurl(request=req), **track.dict())
|
||||
for track in tracks
|
||||
],
|
||||
"producers": [producer.dict() for producer in producers],
|
||||
},
|
||||
}
|
||||
**ls.dict(),
|
||||
**{
|
||||
"lnurl": ls.lnurl(request=req),
|
||||
"tracks": [
|
||||
dict(lnurl=track.lnurl(request=req), **track.dict())
|
||||
for track in tracks
|
||||
],
|
||||
"producers": [producer.dict() for producer in producers],
|
||||
},
|
||||
}
|
||||
except LnurlInvalidUrl:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.UPGRADE_REQUIRED,
|
||||
detail="LNURLs need to be delivered over a publically accessible `https` domain or Tor."
|
||||
detail="LNURLs need to be delivered over a publically accessible `https` domain or Tor.",
|
||||
)
|
||||
|
||||
|
||||
|
@ -70,7 +72,9 @@ async def api_update_fee(fee_pct, g: WalletTypeInfo = Depends(get_key_type)):
|
|||
|
||||
@livestream_ext.post("/api/v1/livestream/tracks")
|
||||
@livestream_ext.put("/api/v1/livestream/tracks/{id}")
|
||||
async def api_add_track(data: CreateTrack, id=None, g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_add_track(
|
||||
data: CreateTrack, id=None, g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
ls = await get_or_create_livestream_by_wallet(g.wallet.id)
|
||||
|
||||
if data.producer_id:
|
||||
|
@ -82,21 +86,10 @@ async def api_add_track(data: CreateTrack, id=None, g: WalletTypeInfo = Depends(
|
|||
|
||||
if id:
|
||||
await update_track(
|
||||
ls.id,
|
||||
id,
|
||||
data.name,
|
||||
data.download_url,
|
||||
data.price_msat or 0,
|
||||
p_id,
|
||||
ls.id, id, data.name, data.download_url, data.price_msat or 0, p_id
|
||||
)
|
||||
else:
|
||||
await add_track(
|
||||
ls.id,
|
||||
data.name,
|
||||
data.download_url,
|
||||
data.price_msat or 0,
|
||||
p_id,
|
||||
)
|
||||
await add_track(ls.id, data.name, data.download_url, data.price_msat or 0, p_id)
|
||||
return
|
||||
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ async def lndhub_payinvoice(
|
|||
raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Payment failed")
|
||||
|
||||
invoice: bolt11.Invoice = bolt11.decode(r_invoice.invoice)
|
||||
|
||||
|
||||
return {
|
||||
"payment_error": "",
|
||||
"payment_preimage": "0" * 64,
|
||||
|
|
|
@ -8,9 +8,7 @@ from .models import lnurlposs, lnurlpospayment, createLnurlpos
|
|||
###############lnurlposS##########################
|
||||
|
||||
|
||||
async def create_lnurlpos(
|
||||
data: createLnurlpos,
|
||||
) -> lnurlposs:
|
||||
async def create_lnurlpos(data: createLnurlpos,) -> lnurlposs:
|
||||
print(data)
|
||||
lnurlpos_id = urlsafe_short_hash()
|
||||
lnurlpos_key = urlsafe_short_hash()
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import json
|
||||
import hashlib
|
||||
import math
|
||||
from lnurl import LnurlPayResponse, LnurlPayActionResponse, LnurlErrorResponse # type: ignore
|
||||
from lnurl import (
|
||||
LnurlPayResponse,
|
||||
LnurlPayActionResponse,
|
||||
LnurlErrorResponse,
|
||||
) # type: ignore
|
||||
from lnurl.types import LnurlPayMetadata
|
||||
from lnbits.core.services import create_invoice
|
||||
from hashlib import md5
|
||||
|
|
|
@ -54,6 +54,5 @@ async def displaypin(request: Request, paymentid: str = Query(None)):
|
|||
"lnurlpos/paid.html", {"request": request, "pin": lnurlpospayment.pin}
|
||||
)
|
||||
return lnurlpos_renderer().TemplateResponse(
|
||||
"lnurlpos/error.html",
|
||||
{"request": request, "pin": "filler", "not_paid": True},
|
||||
"lnurlpos/error.html", {"request": request, "pin": "filler", "not_paid": True}
|
||||
)
|
||||
|
|
|
@ -5,10 +5,8 @@ from lnbits.helpers import template_renderer
|
|||
|
||||
db = Database("ext_paywall")
|
||||
|
||||
paywall_ext: APIRouter = APIRouter(
|
||||
prefix="/paywall",
|
||||
tags=["Paywall"]
|
||||
)
|
||||
paywall_ext: APIRouter = APIRouter(prefix="/paywall", tags=["Paywall"])
|
||||
|
||||
|
||||
def paywall_renderer():
|
||||
return template_renderer(["lnbits/extensions/paywall/templates"])
|
||||
|
|
|
@ -6,17 +6,22 @@ from . import db
|
|||
from .models import CreatePaywall, Paywall
|
||||
|
||||
|
||||
async def create_paywall(
|
||||
wallet_id: str,
|
||||
data: CreatePaywall
|
||||
) -> Paywall:
|
||||
async def create_paywall(wallet_id: str, data: CreatePaywall) -> Paywall:
|
||||
paywall_id = urlsafe_short_hash()
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO paywall.paywalls (id, wallet, url, memo, description, amount, remembers)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(paywall_id, wallet_id, data.url, data.memo, data.description, data.amount, int(data.remembers)),
|
||||
(
|
||||
paywall_id,
|
||||
wallet_id,
|
||||
data.url,
|
||||
data.memo,
|
||||
data.description,
|
||||
data.amount,
|
||||
int(data.remembers),
|
||||
),
|
||||
)
|
||||
|
||||
paywall = await get_paywall(paywall_id)
|
||||
|
|
|
@ -13,12 +13,15 @@ class CreatePaywall(BaseModel):
|
|||
amount: int = Query(..., ge=0)
|
||||
remembers: bool = Query(...)
|
||||
|
||||
|
||||
class CreatePaywallInvoice(BaseModel):
|
||||
amount: int = Query(..., ge=1)
|
||||
|
||||
|
||||
class CheckPaywallInvoice(BaseModel):
|
||||
payment_hash: str = Query(...)
|
||||
|
||||
|
||||
class Paywall(BaseModel):
|
||||
id: str
|
||||
wallet: str
|
||||
|
|
|
@ -13,7 +13,9 @@ from .crud import get_paywall
|
|||
|
||||
@paywall_ext.get("/")
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
return paywall_renderer().TemplateResponse("paywall/index.html", {"request": request, "user": user.dict()})
|
||||
return paywall_renderer().TemplateResponse(
|
||||
"paywall/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
||||
|
||||
@paywall_ext.get("/{paywall_id}")
|
||||
|
@ -23,4 +25,6 @@ async def display(request: Request, paywall_id):
|
|||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Paywall does not exist."
|
||||
)
|
||||
return paywall_renderer().TemplateResponse("paywall/display.html", {"request": request, "paywall": paywall})
|
||||
return paywall_renderer().TemplateResponse(
|
||||
"paywall/display.html", {"request": request, "paywall": paywall}
|
||||
)
|
||||
|
|
|
@ -13,7 +13,9 @@ from .models import CheckPaywallInvoice, CreatePaywall, CreatePaywallInvoice
|
|||
|
||||
|
||||
@paywall_ext.get("/api/v1/paywalls")
|
||||
async def api_paywalls(wallet: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)):
|
||||
async def api_paywalls(
|
||||
wallet: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)
|
||||
):
|
||||
wallet_ids = [wallet.wallet.id]
|
||||
|
||||
if all_wallets:
|
||||
|
@ -23,47 +25,51 @@ async def api_paywalls(wallet: WalletTypeInfo = Depends(get_key_type), all_walle
|
|||
|
||||
|
||||
@paywall_ext.post("/api/v1/paywalls")
|
||||
async def api_paywall_create(data: CreatePaywall, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_paywall_create(
|
||||
data: CreatePaywall, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
paywall = await create_paywall(wallet_id=wallet.wallet.id, data=data)
|
||||
return paywall.dict()
|
||||
|
||||
|
||||
@paywall_ext.delete("/api/v1/paywalls/{paywall_id}")
|
||||
async def api_paywall_delete(paywall_id, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_paywall_delete(
|
||||
paywall_id, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
paywall = await get_paywall(paywall_id)
|
||||
|
||||
if not paywall:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Paywall does not exist."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Paywall does not exist."
|
||||
)
|
||||
|
||||
if paywall.wallet != wallet.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your paywall."
|
||||
)
|
||||
status_code=HTTPStatus.FORBIDDEN, detail="Not your paywall."
|
||||
)
|
||||
|
||||
await delete_paywall(paywall_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
|
||||
@paywall_ext.post("/api/v1/paywalls/{paywall_id}/invoice")
|
||||
async def api_paywall_create_invoice(paywall_id, data: CreatePaywallInvoice, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_paywall_create_invoice(
|
||||
paywall_id,
|
||||
data: CreatePaywallInvoice,
|
||||
wallet: WalletTypeInfo = Depends(get_key_type),
|
||||
):
|
||||
paywall = await get_paywall(paywall_id)
|
||||
print("PAYW", paywall)
|
||||
print("DATA", data)
|
||||
|
||||
|
||||
if data.amount < paywall.amount:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"Minimum amount is {paywall.amount} sat."
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"Minimum amount is {paywall.amount} sat.",
|
||||
)
|
||||
|
||||
try:
|
||||
amount = (
|
||||
data.amount if data.amount > paywall.amount else paywall.amount
|
||||
)
|
||||
amount = data.amount if data.amount > paywall.amount else paywall.amount
|
||||
payment_hash, payment_request = await create_invoice(
|
||||
wallet_id=paywall.wallet,
|
||||
amount=amount,
|
||||
|
@ -71,10 +77,7 @@ async def api_paywall_create_invoice(paywall_id, data: CreatePaywallInvoice, wal
|
|||
extra={"tag": "paywall"},
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=str(e)
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
|
||||
|
||||
return {"payment_hash": payment_hash, "payment_request": payment_request}
|
||||
|
||||
|
@ -85,9 +88,8 @@ async def api_paywal_check_invoice(data: CheckPaywallInvoice, paywall_id):
|
|||
payment_hash = data.payment_hash
|
||||
if not paywall:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Paywall does not exist."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Paywall does not exist."
|
||||
)
|
||||
|
||||
try:
|
||||
status = await check_invoice_status(paywall.wallet, payment_hash)
|
||||
|
|
|
@ -15,10 +15,7 @@ from .models import (
|
|||
)
|
||||
|
||||
|
||||
async def create_satsdice_pay(
|
||||
wallet_id: str,
|
||||
data: CreateSatsDiceLink,
|
||||
) -> satsdiceLink:
|
||||
async def create_satsdice_pay(wallet_id: str, data: CreateSatsDiceLink) -> satsdiceLink:
|
||||
satsdice_id = urlsafe_short_hash()
|
||||
await db.execute(
|
||||
"""
|
||||
|
|
|
@ -49,9 +49,7 @@ async def api_lnurlp_response(req: Request, link_id: str = Query(None)):
|
|||
name="satsdice.api_lnurlp_callback",
|
||||
)
|
||||
async def api_lnurlp_callback(
|
||||
req: Request,
|
||||
link_id: str = Query(None),
|
||||
amount: str = Query(None),
|
||||
req: Request, link_id: str = Query(None), amount: str = Query(None)
|
||||
):
|
||||
link = await get_satsdice_pay(link_id)
|
||||
print(link)
|
||||
|
@ -95,11 +93,7 @@ async def api_lnurlp_callback(
|
|||
}
|
||||
|
||||
await create_satsdice_payment(data)
|
||||
payResponse = {
|
||||
"pr": payment_request,
|
||||
"successAction": success_action,
|
||||
"routes": [],
|
||||
}
|
||||
payResponse = {"pr": payment_request, "successAction": success_action, "routes": []}
|
||||
print(json.dumps(payResponse))
|
||||
|
||||
return json.dumps(payResponse)
|
||||
|
|
|
@ -94,12 +94,7 @@ async def displaywin(
|
|||
if not rand < chance or not status["paid"]:
|
||||
return satsdice_renderer().TemplateResponse(
|
||||
"satsdice/error.html",
|
||||
{
|
||||
"request": request,
|
||||
"link": satsdicelink.id,
|
||||
"paid": False,
|
||||
"lost": True,
|
||||
},
|
||||
{"request": request, "link": satsdicelink.id, "paid": False, "lost": True},
|
||||
)
|
||||
await update_satsdice_payment(payment_hash, paid=1)
|
||||
paylink = await get_satsdice_payment(payment_hash)
|
||||
|
|
|
@ -92,7 +92,6 @@ async def api_link_create_or_update(
|
|||
detail="Come on, seriously, this isn't your satsdice!",
|
||||
)
|
||||
|
||||
|
||||
data.wallet = wallet.wallet.id
|
||||
link = await update_satsdice_pay(link_id, **data.dict())
|
||||
else:
|
||||
|
|
|
@ -10,6 +10,7 @@ class Target(BaseModel):
|
|||
percent: int
|
||||
alias: Optional[str]
|
||||
|
||||
|
||||
class TargetPutList(BaseModel):
|
||||
wallet: str = Query(...)
|
||||
alias: str = Query("")
|
||||
|
|
|
@ -38,8 +38,7 @@ async def api_targets_set(
|
|||
|
||||
if wallet.id == wal.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="Can't split to itself.",
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="Can't split to itself."
|
||||
)
|
||||
|
||||
if entry.percent < 0:
|
||||
|
@ -49,14 +48,18 @@ async def api_targets_set(
|
|||
)
|
||||
|
||||
targets.append(
|
||||
Target(wallet=wallet.id, source=wal.wallet.id, percent=entry.percent, alias=entry.alias)
|
||||
Target(
|
||||
wallet=wallet.id,
|
||||
source=wal.wallet.id,
|
||||
percent=entry.percent,
|
||||
alias=entry.alias,
|
||||
)
|
||||
)
|
||||
|
||||
percent_sum = sum([target.percent for target in targets])
|
||||
if percent_sum > 100:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="Splitting over 100%.",
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="Splitting over 100%."
|
||||
)
|
||||
|
||||
await set_targets(wal.wallet.id, targets)
|
||||
|
|
|
@ -5,13 +5,12 @@ from lnbits.helpers import template_renderer
|
|||
|
||||
db = Database("ext_streamalerts")
|
||||
|
||||
streamalerts_ext: APIRouter = APIRouter(
|
||||
prefix="/streamalerts",
|
||||
tags=["streamalerts"]
|
||||
)
|
||||
streamalerts_ext: APIRouter = APIRouter(prefix="/streamalerts", tags=["streamalerts"])
|
||||
|
||||
|
||||
def streamalerts_renderer():
|
||||
return template_renderer(["lnbits/extensions/streamalerts/templates"])
|
||||
|
||||
|
||||
from .views import * # noqa
|
||||
from .views_api import * # noqa
|
||||
|
|
|
@ -25,9 +25,7 @@ async def get_charge_details(service_id):
|
|||
|
||||
These might be different depending for services implemented in the future.
|
||||
"""
|
||||
details = {
|
||||
"time": 1440,
|
||||
}
|
||||
details = {"time": 1440}
|
||||
service = await get_service(service_id)
|
||||
wallet_id = service.wallet
|
||||
wallet = await get_wallet(wallet_id)
|
||||
|
@ -111,9 +109,7 @@ async def post_donation(donation_id: str) -> tuple:
|
|||
return response.json()
|
||||
|
||||
|
||||
async def create_service(
|
||||
data: CreateService
|
||||
) -> Service:
|
||||
async def create_service(data: CreateService) -> Service:
|
||||
"""Create a new Service"""
|
||||
|
||||
returning = "" if db.type == SQLITE else "RETURNING ID"
|
||||
|
@ -215,10 +211,7 @@ async def service_add_token(service_id, token):
|
|||
return False
|
||||
await db.execute(
|
||||
"UPDATE streamalerts.Services SET authenticated = 1, token = ? where id = ?",
|
||||
(
|
||||
token,
|
||||
service_id,
|
||||
),
|
||||
(token, service_id),
|
||||
)
|
||||
return True
|
||||
|
||||
|
|
|
@ -13,12 +13,14 @@ class CreateService(BaseModel):
|
|||
servicename: str = Query(...)
|
||||
onchain: str = Query(None)
|
||||
|
||||
|
||||
class CreateDonation(BaseModel):
|
||||
name: str = Query("Anonymous")
|
||||
sats: int = Query(..., ge=1)
|
||||
service: int = Query(...)
|
||||
message: str = Query("")
|
||||
|
||||
|
||||
class ValidateDonation(BaseModel):
|
||||
id: str = Query(...)
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ templates = Jinja2Templates(directory="templates")
|
|||
@streamalerts_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
"""Return the extension's settings page"""
|
||||
return streamalerts_renderer().TemplateResponse("streamalerts/index.html", {"request": request, "user": user.dict()})
|
||||
return streamalerts_renderer().TemplateResponse(
|
||||
"streamalerts/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
||||
|
||||
@streamalerts_ext.get("/{state}")
|
||||
|
@ -31,9 +33,5 @@ async def donation(state, request: Request):
|
|||
)
|
||||
return streamalerts_renderer().TemplateResponse(
|
||||
"streamalerts/display.html",
|
||||
{
|
||||
"request": request,
|
||||
"twitchuser": service.twitchuser,
|
||||
"service":service.id
|
||||
}
|
||||
{"request": request, "twitchuser": service.twitchuser, "service": service.id},
|
||||
)
|
||||
|
|
|
@ -35,14 +35,14 @@ from .crud import (
|
|||
|
||||
|
||||
@streamalerts_ext.post("/api/v1/services")
|
||||
async def api_create_service(data : CreateService, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_create_service(
|
||||
data: CreateService, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
"""Create a service, which holds data about how/where to post donations"""
|
||||
try:
|
||||
service = await create_service(data=data)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
|
||||
|
||||
return service.dict()
|
||||
|
||||
|
@ -68,23 +68,24 @@ async def api_get_access(service_id, request: Request):
|
|||
return RedirectResponse(redirect_url)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="Service does not exist!"
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="Service does not exist!"
|
||||
)
|
||||
|
||||
|
||||
@streamalerts_ext.get("/api/v1/authenticate/{service_id}")
|
||||
async def api_authenticate_service(service_id, request: Request, code: str = Query(...), state: str = Query(...)):
|
||||
async def api_authenticate_service(
|
||||
service_id, request: Request, code: str = Query(...), state: str = Query(...)
|
||||
):
|
||||
"""Endpoint visited via redirect during third party API authentication
|
||||
|
||||
If successful, an API access token will be added to the service, and
|
||||
the user will be redirected to index.html.
|
||||
"""
|
||||
|
||||
|
||||
service = await get_service(service_id)
|
||||
if service.state != state:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="State doesn't match!"
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="State doesn't match!"
|
||||
)
|
||||
|
||||
redirect_uri = request.url.scheme + "://" + request.headers["Host"]
|
||||
|
@ -94,8 +95,7 @@ async def api_authenticate_service(service_id, request: Request, code: str = Que
|
|||
return RedirectResponse(url)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="Service already authenticated!"
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="Service already authenticated!"
|
||||
)
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ async def api_create_donation(data: CreateDonation, request: Request):
|
|||
service = await get_service(service_id)
|
||||
charge_details = await get_charge_details(service.id)
|
||||
name = data.name
|
||||
|
||||
|
||||
description = f"{sats} sats donation from {name} to {service.twitchuser}"
|
||||
charge = await create_charge(
|
||||
amount=sats,
|
||||
|
@ -132,7 +132,7 @@ async def api_create_donation(data: CreateDonation, request: Request):
|
|||
cur_code=cur_code,
|
||||
sats=data.sats,
|
||||
amount=amount,
|
||||
service=data.service
|
||||
service=data.service,
|
||||
)
|
||||
return {"redirect_url": f"/satspay/{charge.id}"}
|
||||
|
||||
|
@ -141,15 +141,14 @@ async def api_create_donation(data: CreateDonation, request: Request):
|
|||
async def api_post_donation(request: Request, data: ValidateDonation):
|
||||
"""Post a paid donation to Stremalabs/StreamElements.
|
||||
This endpoint acts as a webhook for the SatsPayServer extension."""
|
||||
|
||||
|
||||
donation_id = data.id
|
||||
charge = await get_charge(donation_id)
|
||||
if charge and charge.paid:
|
||||
return await post_donation(donation_id)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="Not a paid charge!"
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="Not a paid charge!"
|
||||
)
|
||||
|
||||
|
||||
|
@ -178,58 +177,55 @@ async def api_get_donations(g: WalletTypeInfo = Depends(get_key_type)):
|
|||
|
||||
|
||||
@streamalerts_ext.put("/api/v1/donations/{donation_id}")
|
||||
async def api_update_donation(data: CreateDonation, donation_id=None, g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_update_donation(
|
||||
data: CreateDonation, donation_id=None, g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
"""Update a donation with the data given in the request"""
|
||||
if donation_id:
|
||||
donation = await get_donation(donation_id)
|
||||
|
||||
if not donation:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Donation does not exist."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Donation does not exist."
|
||||
)
|
||||
|
||||
|
||||
if donation.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your donation."
|
||||
status_code=HTTPStatus.FORBIDDEN, detail="Not your donation."
|
||||
)
|
||||
|
||||
donation = await update_donation(donation_id, **data.dict())
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="No donation ID specified"
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="No donation ID specified"
|
||||
)
|
||||
|
||||
return donation.dict()
|
||||
|
||||
|
||||
@streamalerts_ext.put("/api/v1/services/{service_id}")
|
||||
async def api_update_service(data: CreateService, service_id=None, g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_update_service(
|
||||
data: CreateService, service_id=None, g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
"""Update a service with the data given in the request"""
|
||||
if service_id:
|
||||
service = await get_service(service_id)
|
||||
|
||||
if not service:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Service does not exist."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Service does not exist."
|
||||
)
|
||||
|
||||
if service.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your service."
|
||||
status_code=HTTPStatus.FORBIDDEN, detail="Not your service."
|
||||
)
|
||||
|
||||
service = await update_service(service_id, **data.dict())
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail="No service ID specified"
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST, detail="No service ID specified"
|
||||
)
|
||||
return service.dict()
|
||||
|
||||
|
||||
|
@ -239,14 +235,13 @@ async def api_delete_donation(donation_id, g: WalletTypeInfo = Depends(get_key_t
|
|||
donation = await get_donation(donation_id)
|
||||
if not donation:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="No donation with this ID!"
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="No donation with this ID!"
|
||||
)
|
||||
if donation.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not authorized to delete this donation!"
|
||||
)
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not authorized to delete this donation!",
|
||||
)
|
||||
await delete_donation(donation_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
||||
|
@ -257,13 +252,12 @@ async def api_delete_service(service_id, g: WalletTypeInfo = Depends(get_key_typ
|
|||
service = await get_service(service_id)
|
||||
if not service:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="No service with this ID!"
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="No service with this ID!"
|
||||
)
|
||||
if service.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not authorized to delete this service!"
|
||||
)
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not authorized to delete this service!",
|
||||
)
|
||||
await delete_service(service_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
|
|
@ -8,10 +8,8 @@ from lnbits.tasks import catch_everything_and_restart
|
|||
|
||||
db = Database("ext_subdomains")
|
||||
|
||||
subdomains_ext: APIRouter = APIRouter(
|
||||
prefix="/subdomains",
|
||||
tags=["subdomains"]
|
||||
)
|
||||
subdomains_ext: APIRouter = APIRouter(prefix="/subdomains", tags=["subdomains"])
|
||||
|
||||
|
||||
def subdomains_renderer():
|
||||
return template_renderer(["lnbits/extensions/subdomains/templates"])
|
||||
|
@ -25,4 +23,3 @@ from .views_api import * # noqa
|
|||
def subdomains_start():
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))
|
||||
|
||||
|
|
|
@ -50,11 +50,7 @@ async def cloudflare_deletesubdomain(domain: Domains, domain_id: str):
|
|||
}
|
||||
async with httpx.AsyncClient() as client:
|
||||
try:
|
||||
r = await client.delete(
|
||||
url + "/" + domain_id,
|
||||
headers=header,
|
||||
timeout=40,
|
||||
)
|
||||
r = await client.delete(url + "/" + domain_id, headers=header, timeout=40)
|
||||
cf_response = r.text
|
||||
except AssertionError:
|
||||
cf_response = "Error occured"
|
||||
|
|
|
@ -6,11 +6,7 @@ from . import db
|
|||
from .models import CreateDomain, Domains, Subdomains
|
||||
|
||||
|
||||
async def create_subdomain(
|
||||
payment_hash,
|
||||
wallet,
|
||||
data: CreateDomain
|
||||
) -> Subdomains:
|
||||
async def create_subdomain(payment_hash, wallet, data: CreateDomain) -> Subdomains:
|
||||
await db.execute(
|
||||
"""
|
||||
INSERT INTO subdomains.subdomain (id, domain, email, subdomain, ip, wallet, sats, duration, paid, record_type)
|
||||
|
@ -105,9 +101,7 @@ async def delete_subdomain(subdomain_id: str) -> None:
|
|||
# Domains
|
||||
|
||||
|
||||
async def create_domain(
|
||||
data: CreateDomain
|
||||
) -> Domains:
|
||||
async def create_domain(data: CreateDomain) -> Domains:
|
||||
domain_id = urlsafe_short_hash()
|
||||
await db.execute(
|
||||
"""
|
||||
|
|
|
@ -12,6 +12,7 @@ class CreateDomain(BaseModel):
|
|||
cost: int = Query(..., ge=0)
|
||||
allowed_record_types: str = Query(...)
|
||||
|
||||
|
||||
class CreateSubdomain(BaseModel):
|
||||
domain: str = Query(...)
|
||||
subdomain: str = Query(...)
|
||||
|
@ -21,6 +22,7 @@ class CreateSubdomain(BaseModel):
|
|||
duration: int = Query(...)
|
||||
record_type: str = Query(...)
|
||||
|
||||
|
||||
class Domains(BaseModel):
|
||||
id: str
|
||||
wallet: str
|
||||
|
@ -34,6 +36,7 @@ class Domains(BaseModel):
|
|||
time: int
|
||||
allowed_record_types: str
|
||||
|
||||
|
||||
class Subdomains(BaseModel):
|
||||
id: str
|
||||
wallet: str
|
||||
|
|
|
@ -17,6 +17,7 @@ async def wait_for_paid_invoices():
|
|||
payment = await invoice_queue.get()
|
||||
await on_invoice_paid(payment)
|
||||
|
||||
|
||||
# async def register_listeners():
|
||||
# invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(2)
|
||||
# register_invoice_listener(invoice_paid_chan_send)
|
||||
|
|
|
@ -14,9 +14,12 @@ from .crud import get_domain
|
|||
|
||||
templates = Jinja2Templates(directory="templates")
|
||||
|
||||
|
||||
@subdomains_ext.get("/", response_class=HTMLResponse)
|
||||
async def index(request: Request, user: User = Depends(check_user_exists)):
|
||||
return subdomains_renderer().TemplateResponse("subdomains/index.html", {"request": request, "user": user.dict()})
|
||||
return subdomains_renderer().TemplateResponse(
|
||||
"subdomains/index.html", {"request": request, "user": user.dict()}
|
||||
)
|
||||
|
||||
|
||||
@subdomains_ext.get("/{domain_id}")
|
||||
|
@ -24,20 +27,20 @@ async def display(request: Request, domain_id):
|
|||
domain = await get_domain(domain_id)
|
||||
if not domain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Domain does not exist."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
|
||||
)
|
||||
allowed_records = (
|
||||
domain.allowed_record_types.replace('"', "").replace(" ", "").split(",")
|
||||
)
|
||||
|
||||
|
||||
return subdomains_renderer().TemplateResponse(
|
||||
"subdomains/display.html",{
|
||||
"subdomains/display.html",
|
||||
{
|
||||
"request": request,
|
||||
"domain_id": domain.id,
|
||||
"domain_domain": domain.domain,
|
||||
"domain_desc": domain.description,
|
||||
"domain_cost": domain.cost,
|
||||
"domain_allowed_record_types": allowed_records,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
@ -28,7 +28,9 @@ from .crud import (
|
|||
|
||||
|
||||
@subdomains_ext.get("/api/v1/domains")
|
||||
async def api_domains(g: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)):
|
||||
async def api_domains(
|
||||
g: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)
|
||||
):
|
||||
wallet_ids = [g.wallet.id]
|
||||
|
||||
if all_wallets:
|
||||
|
@ -39,19 +41,19 @@ async def api_domains(g: WalletTypeInfo = Depends(get_key_type), all_wallets: bo
|
|||
|
||||
@subdomains_ext.post("/api/v1/domains")
|
||||
@subdomains_ext.put("/api/v1/domains/{domain_id}")
|
||||
async def api_domain_create(data: CreateDomain, domain_id=None, g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_domain_create(
|
||||
data: CreateDomain, domain_id=None, g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
if domain_id:
|
||||
domain = await get_domain(domain_id)
|
||||
|
||||
if not domain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Domain does not exist."
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
|
||||
)
|
||||
if domain.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your domain."
|
||||
status_code=HTTPStatus.FORBIDDEN, detail="Not your domain."
|
||||
)
|
||||
|
||||
domain = await update_domain(domain_id, **data.dict())
|
||||
|
@ -66,14 +68,10 @@ async def api_domain_delete(domain_id, g: WalletTypeInfo = Depends(get_key_type)
|
|||
|
||||
if not domain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="Domain does not exist."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
|
||||
)
|
||||
if domain.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your domain."
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your domain.")
|
||||
|
||||
await delete_domain(domain_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
@ -83,7 +81,9 @@ async def api_domain_delete(domain_id, g: WalletTypeInfo = Depends(get_key_type)
|
|||
|
||||
|
||||
@subdomains_ext.get("/api/v1/subdomains")
|
||||
async def api_subdomains(all_wallets: bool = Query(False), g: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_subdomains(
|
||||
all_wallets: bool = Query(False), g: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
wallet_ids = [g.wallet.id]
|
||||
|
||||
if all_wallets:
|
||||
|
@ -99,22 +99,21 @@ async def api_subdomain_make_subdomain(domain_id, data: CreateSubdomain):
|
|||
# If the request is coming for the non-existant domain
|
||||
if not domain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="LNsubdomain does not exist."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="LNsubdomain does not exist."
|
||||
)
|
||||
## If record_type is not one of the allowed ones reject the request
|
||||
if data.record_type not in domain.allowed_record_types:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"{data.record_type} not a valid record."
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"{data.record_type} not a valid record.",
|
||||
)
|
||||
|
||||
## If domain already exist in our database reject it
|
||||
if await get_subdomainBySubdomain(data.subdomain) is not None:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"{data.subdomain}.{domain.domain} domain already taken."
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f"{data.subdomain}.{domain.domain} domain already taken.",
|
||||
)
|
||||
|
||||
## Dry run cloudflare... (create and if create is sucessful delete it)
|
||||
cf_response = await cloudflare_create_subdomain(
|
||||
|
@ -124,12 +123,14 @@ async def api_subdomain_make_subdomain(domain_id, data: CreateSubdomain):
|
|||
ip=data.ip,
|
||||
)
|
||||
if cf_response["success"] == True:
|
||||
await cloudflare_deletesubdomain(domain=domain, domain_id=cf_response["result"]["id"])
|
||||
await cloudflare_deletesubdomain(
|
||||
domain=domain, domain_id=cf_response["result"]["id"]
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f'Problem with cloudflare: {cf_response["errors"][0]["message"]}'
|
||||
)
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
detail=f'Problem with cloudflare: {cf_response["errors"][0]["message"]}',
|
||||
)
|
||||
|
||||
## ALL OK - create an invoice and return it to the user
|
||||
sats = data.sats
|
||||
|
@ -142,10 +143,7 @@ async def api_subdomain_make_subdomain(domain_id, data: CreateSubdomain):
|
|||
extra={"tag": "lnsubdomain"},
|
||||
)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail=str(e)
|
||||
)
|
||||
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
|
||||
|
||||
subdomain = await create_subdomain(
|
||||
payment_hash=payment_hash, wallet=domain.wallet, data=data
|
||||
|
@ -153,9 +151,8 @@ async def api_subdomain_make_subdomain(domain_id, data: CreateSubdomain):
|
|||
|
||||
if not subdomain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="LNsubdomain could not be fetched."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="LNsubdomain could not be fetched."
|
||||
)
|
||||
|
||||
return {"payment_hash": payment_hash, "payment_request": payment_request}
|
||||
|
||||
|
@ -181,15 +178,13 @@ async def api_subdomain_delete(subdomain_id, g: WalletTypeInfo = Depends(get_key
|
|||
|
||||
if not subdomain:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="LNsubdomain does not exist."
|
||||
)
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="LNsubdomain does not exist."
|
||||
)
|
||||
|
||||
if subdomain.wallet != g.wallet.id:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.FORBIDDEN,
|
||||
detail="Not your subdomain."
|
||||
)
|
||||
status_code=HTTPStatus.FORBIDDEN, detail="Not your subdomain."
|
||||
)
|
||||
|
||||
await delete_subdomain(subdomain_id)
|
||||
raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
|
||||
|
|
|
@ -9,12 +9,7 @@ from lnbits.db import SQLITE
|
|||
|
||||
|
||||
async def create_tip(
|
||||
id: int,
|
||||
wallet: str,
|
||||
message: str,
|
||||
name: str,
|
||||
sats: int,
|
||||
tipjar: str,
|
||||
id: int, wallet: str, message: str, name: str, sats: int, tipjar: str
|
||||
) -> Tip:
|
||||
"""Create a new Tip"""
|
||||
await db.execute(
|
||||
|
@ -110,8 +105,7 @@ async def update_tip(tip_id: str, **kwargs) -> Tip:
|
|||
"""Update a Tip"""
|
||||
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
|
||||
await db.execute(
|
||||
f"UPDATE tipjar.Tips SET {q} WHERE id = ?",
|
||||
(*kwargs.values(), tip_id),
|
||||
f"UPDATE tipjar.Tips SET {q} WHERE id = ?", (*kwargs.values(), tip_id)
|
||||
)
|
||||
row = await db.fetchone("SELECT * FROM tipjar.Tips WHERE id = ?", (tip_id,))
|
||||
assert row, "Newly updated tip couldn't be retrieved"
|
||||
|
@ -122,8 +116,7 @@ async def update_tipjar(tipjar_id: str, **kwargs) -> TipJar:
|
|||
"""Update a tipjar"""
|
||||
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
|
||||
await db.execute(
|
||||
f"UPDATE tipjar.TipJars SET {q} WHERE id = ?",
|
||||
(*kwargs.values(), tipjar_id),
|
||||
f"UPDATE tipjar.TipJars SET {q} WHERE id = ?", (*kwargs.values(), tipjar_id)
|
||||
)
|
||||
row = await db.fetchone("SELECT * FROM tipjar.TipJars WHERE id = ?", (tipjar_id,))
|
||||
assert row, "Newly updated tipjar couldn't be retrieved"
|
||||
|
|
|
@ -6,10 +6,7 @@ from fastapi.params import Depends
|
|||
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore
|
||||
from starlette.exceptions import HTTPException
|
||||
|
||||
from lnbits.decorators import (
|
||||
WalletTypeInfo,
|
||||
get_key_type,
|
||||
)
|
||||
from lnbits.decorators import WalletTypeInfo, get_key_type
|
||||
from lnbits.core.crud import get_user
|
||||
|
||||
from . import tipjar_ext
|
||||
|
@ -193,8 +190,7 @@ async def api_delete_tipjar(
|
|||
tipjar = await get_tipjar(tipjar_id)
|
||||
if not tipjar:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_FOUND,
|
||||
detail="No tipjar with this ID!",
|
||||
status_code=HTTPStatus.NOT_FOUND, detail="No tipjar with this ID!"
|
||||
)
|
||||
if tipjar.wallet != g.wallet.id:
|
||||
|
||||
|
|
|
@ -5,10 +5,7 @@ from lnbits.helpers import template_renderer
|
|||
|
||||
db = Database("ext_tpos")
|
||||
|
||||
tpos_ext: APIRouter = APIRouter(
|
||||
prefix="/tpos",
|
||||
tags=["TPoS"]
|
||||
)
|
||||
tpos_ext: APIRouter = APIRouter(prefix="/tpos", tags=["TPoS"])
|
||||
|
||||
|
||||
def tpos_renderer():
|
||||
|
|
|
@ -5,10 +5,7 @@ from lnbits.helpers import template_renderer
|
|||
|
||||
db = Database("ext_usermanager")
|
||||
|
||||
usermanager_ext: APIRouter = APIRouter(
|
||||
prefix="/usermanager",
|
||||
tags=["usermanager"]
|
||||
)
|
||||
usermanager_ext: APIRouter = APIRouter(prefix="/usermanager", tags=["usermanager"])
|
||||
|
||||
|
||||
def usermanager_renderer():
|
||||
|
|
|
@ -11,6 +11,7 @@ class CreateUserData(BaseModel):
|
|||
email: str = Query("")
|
||||
password: str = Query("")
|
||||
|
||||
|
||||
class CreateUserWallet(BaseModel):
|
||||
user_id: str = Query(...)
|
||||
wallet_name: str = Query(...)
|
||||
|
|
|
@ -93,10 +93,11 @@ async def api_usermanager_activate_extension(
|
|||
|
||||
@usermanager_ext.post("/api/v1/wallets")
|
||||
async def api_usermanager_wallets_create(
|
||||
data: CreateUserWallet,
|
||||
wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
data: CreateUserWallet, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
user = await create_usermanager_wallet(user_id=data.user_id, wallet_name=data.wallet_name, admin_id=data.admin_id)
|
||||
user = await create_usermanager_wallet(
|
||||
user_id=data.user_id, wallet_name=data.wallet_name, admin_id=data.admin_id
|
||||
)
|
||||
return user.dict()
|
||||
|
||||
|
||||
|
|
|
@ -93,11 +93,12 @@ async def api_lnurl_multi_response(request: Request, unique_hash, id_unique_hash
|
|||
|
||||
# CALLBACK
|
||||
|
||||
|
||||
@withdraw_ext.get(
|
||||
"/api/v1/lnurl/cb/{unique_hash}",
|
||||
status_code=HTTPStatus.OK,
|
||||
name="withdraw.api_lnurl_callback"
|
||||
)
|
||||
"/api/v1/lnurl/cb/{unique_hash}",
|
||||
status_code=HTTPStatus.OK,
|
||||
name="withdraw.api_lnurl_callback",
|
||||
)
|
||||
async def api_lnurl_callback(
|
||||
request: Request,
|
||||
unique_hash: str = Query(...),
|
||||
|
@ -153,4 +154,3 @@ async def api_lnurl_callback(
|
|||
except Exception as e:
|
||||
await update_withdraw_link(link.id, **changesback)
|
||||
return {"status": "ERROR", "reason": "Link not working"}
|
||||
|
||||
|
|
|
@ -46,7 +46,9 @@ async def api_links(
|
|||
|
||||
|
||||
@withdraw_ext.get("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
|
||||
async def api_link_retrieve(link_id, request: Request, wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_link_retrieve(
|
||||
link_id, request: Request, wallet: WalletTypeInfo = Depends(get_key_type)
|
||||
):
|
||||
link = await get_withdraw_link(link_id, 0)
|
||||
|
||||
if not link:
|
||||
|
@ -93,7 +95,9 @@ async def api_link_create_or_update(
|
|||
raise HTTPException(
|
||||
detail="Not your withdraw link.", status_code=HTTPStatus.FORBIDDEN
|
||||
)
|
||||
link = await update_withdraw_link(link_id, **data.dict(), usescsv=usescsv, used=0)
|
||||
link = await update_withdraw_link(
|
||||
link_id, **data.dict(), usescsv=usescsv, used=0
|
||||
)
|
||||
else:
|
||||
link = await create_withdraw_link(
|
||||
wallet_id=wallet.wallet.id, data=data, usescsv=usescsv
|
||||
|
|
|
@ -234,13 +234,14 @@ async def btc_price(currency: str) -> float:
|
|||
failures += 1
|
||||
|
||||
if len(rates) >= 2 or len(rates) == 1 and failures >= 2:
|
||||
for t in tasks: t.cancel()
|
||||
for t in tasks:
|
||||
t.cancel()
|
||||
break
|
||||
if failures == len(exchange_rate_providers):
|
||||
for t in tasks: t.cancel()
|
||||
for t in tasks:
|
||||
t.cancel()
|
||||
break
|
||||
|
||||
|
||||
async def fetch_price(provider: Provider):
|
||||
url = provider.api_url.format(**replacements)
|
||||
try:
|
||||
|
@ -251,19 +252,18 @@ async def btc_price(currency: str) -> float:
|
|||
rate = float(provider.getter(data, replacements))
|
||||
await send_channel.put(rate)
|
||||
except (
|
||||
TypeError, # CoinMate returns HTTPStatus 200 but no data when a currency pair is not found
|
||||
TypeError, # CoinMate returns HTTPStatus 200 but no data when a currency pair is not found
|
||||
httpx.ConnectTimeout,
|
||||
httpx.ConnectError,
|
||||
httpx.ReadTimeout,
|
||||
httpx.HTTPStatusError, # Some providers throw a 404 when a currency pair is not found
|
||||
httpx.HTTPStatusError, # Some providers throw a 404 when a currency pair is not found
|
||||
):
|
||||
await send_channel.put(None)
|
||||
|
||||
|
||||
asyncio.create_task(controller())
|
||||
for _, provider in exchange_rate_providers.items():
|
||||
tasks.append(asyncio.create_task(fetch_price(provider)))
|
||||
|
||||
|
||||
try:
|
||||
await asyncio.gather(*tasks)
|
||||
except asyncio.CancelledError:
|
||||
|
|
|
@ -139,4 +139,4 @@ class CLightningWallet(Wallet):
|
|||
wrapped = async_wrap(_paid_invoices_stream)
|
||||
paid = await wrapped(self.ln, self.last_pay_index)
|
||||
self.last_pay_index = paid["pay_index"]
|
||||
yield paid["label"]
|
||||
yield paid["label"]
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user