Merge pull request #435 from arcbtc/FastAPI

Cleanup and black
This commit is contained in:
Arc 2021-11-26 05:59:10 +00:00 committed by GitHub
commit ed198d3e7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 317 additions and 615 deletions

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
import datetime import datetime
from http import HTTPStatus from http import HTTPStatus
from urllib.parse import urlparse
from fastapi import HTTPException from fastapi import HTTPException
from starlette.requests import Request from starlette.requests import Request
@ -15,8 +16,9 @@ from ..tasks import api_invoice_listeners
@core_app.get("/.well-known/lnurlp/{username}") @core_app.get("/.well-known/lnurlp/{username}")
async def lnaddress(username: str, request: Request): async def lnaddress(username: str, request: Request):
from lnbits.extensions.lnaddress.lnurl import lnurl_response from lnbits.extensions.lnaddress.lnurl import lnurl_response
domain = request.client.host
return await lnurl_response(username, domain) domain = urlparse(str(request.url)).netloc
return await lnurl_response(username, domain, request)
@core_app.get("/public/v1/payment/{payment_hash}") @core_app.get("/public/v1/payment/{payment_hash}")

View file

@ -1,23 +1,15 @@
from http import HTTPStatus
from typing import List from typing import List
import httpx
from collections import defaultdict
from lnbits.decorators import check_user_exists
from .crud import get_copilot
from functools import wraps from fastapi import Request, WebSocket, WebSocketDisconnect
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from starlette.responses import HTMLResponse # type: ignore
from lnbits.core.models import User
from lnbits.decorators import check_user_exists from lnbits.decorators import check_user_exists
from . import copilot_ext, copilot_renderer from . import copilot_ext, copilot_renderer
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect from .crud import get_copilot
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from fastapi.param_functions import Query
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse, JSONResponse # type: ignore
from lnbits.core.models import User
import base64
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")

View file

@ -5,8 +5,8 @@ from fastapi.params import Depends
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.requests import Request from starlette.requests import Request
from lnbits.core.crud import get_user, get_wallet from lnbits.core.crud import get_user
from lnbits.core.services import check_invoice_status, create_invoice from lnbits.core.services import create_invoice
from lnbits.core.views.api import api_payment from lnbits.core.views.api import api_payment
from lnbits.decorators import WalletTypeInfo, get_key_type from lnbits.decorators import WalletTypeInfo, get_key_type
from lnbits.extensions.events.models import CreateEvent, CreateTicket from lnbits.extensions.events.models import CreateEvent, CreateTicket
@ -33,9 +33,7 @@ from .crud import (
@events_ext.get("/api/v1/events") @events_ext.get("/api/v1/events")
async def api_events( async def api_events(
r: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
all_wallets: bool = Query(False),
wallet: WalletTypeInfo = Depends(get_key_type),
): ):
wallet_ids = [wallet.wallet.id] wallet_ids = [wallet.wallet.id]
@ -89,9 +87,7 @@ async def api_form_delete(event_id, wallet: WalletTypeInfo = Depends(get_key_typ
@events_ext.get("/api/v1/tickets") @events_ext.get("/api/v1/tickets")
async def api_tickets( async def api_tickets(
r: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
all_wallets: bool = Query(False),
wallet: WalletTypeInfo = Depends(get_key_type),
): ):
wallet_ids = [wallet.wallet.id] wallet_ids = [wallet.wallet.id]

View file

@ -1,7 +1,8 @@
import asyncio import asyncio
from fastapi import APIRouter, FastAPI
from fastapi import APIRouter
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart from lnbits.tasks import catch_everything_and_restart
@ -23,9 +24,9 @@ def jukebox_renderer():
return template_renderer(["lnbits/extensions/jukebox/templates"]) return template_renderer(["lnbits/extensions/jukebox/templates"])
from .views_api import * # noqa
from .views import * # noqa
from .tasks import wait_for_paid_invoices from .tasks import wait_for_paid_invoices
from .views import * # noqa
from .views_api import * # noqa
def jukebox_start(): def jukebox_start():

View file

@ -1,9 +1,10 @@
from typing import List, Optional from typing import List, Optional
from . import db
from .models import Jukebox, JukeboxPayment, CreateJukeLinkData, CreateJukeboxPayment
from lnbits.helpers import urlsafe_short_hash from lnbits.helpers import urlsafe_short_hash
from . import db
from .models import CreateJukeboxPayment, CreateJukeLinkData, Jukebox, JukeboxPayment
async def create_jukebox( async def create_jukebox(
data: CreateJukeLinkData, inkey: Optional[str] = "" data: CreateJukeLinkData, inkey: Optional[str] = ""
@ -40,8 +41,6 @@ async def update_jukebox(
q = ", ".join([f"{field[0]} = ?" for field in data]) q = ", ".join([f"{field[0]} = ?" for field in data])
items = [f"{field[1]}" for field in data] items = [f"{field[1]}" for field in data]
items.append(juke_id) items.append(juke_id)
print(q)
print(items)
await db.execute(f"UPDATE jukebox.jukebox SET {q} WHERE id = ?", (items)) await db.execute(f"UPDATE jukebox.jukebox SET {q} WHERE id = ?", (items))
row = await db.fetchone("SELECT * FROM jukebox.jukebox WHERE id = ?", (juke_id,)) row = await db.fetchone("SELECT * FROM jukebox.jukebox WHERE id = ?", (juke_id,))
return Jukebox(**row) if row else None return Jukebox(**row) if row else None
@ -61,7 +60,6 @@ async def get_jukeboxs(user: str) -> List[Jukebox]:
rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,)) rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,))
for row in rows: for row in rows:
if row.sp_playlists == None: if row.sp_playlists == None:
print("cunt")
await delete_jukebox(row.id) await delete_jukebox(row.id)
rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,)) rows = await db.fetchall("SELECT * FROM jukebox.jukebox WHERE user = ?", (user,))

View file

@ -1,12 +1,9 @@
import asyncio import asyncio
import json
import httpx
from lnbits.core import db as core_db
from lnbits.core.models import Payment from lnbits.core.models import Payment
from lnbits.tasks import register_invoice_listener from lnbits.tasks import register_invoice_listener
from .crud import get_jukebox, update_jukebox_payment from .crud import update_jukebox_payment
async def wait_for_paid_invoices(): async def wait_for_paid_invoices():

View file

@ -7,7 +7,7 @@ from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from lnbits.core.models import User from lnbits.core.models import User
from lnbits.decorators import WalletTypeInfo, check_user_exists, get_key_type from lnbits.decorators import check_user_exists
from . import jukebox_ext, jukebox_renderer from . import jukebox_ext, jukebox_renderer
from .crud import get_jukebox from .crud import get_jukebox

View file

@ -9,10 +9,9 @@ from fastapi.params import Depends
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse # type: ignore from starlette.responses import HTMLResponse # type: ignore
from lnbits.core.crud import get_wallet from lnbits.core.services import create_invoice
from lnbits.core.views.api import api_payment from lnbits.core.views.api import api_payment
from lnbits.core.services import check_invoice_status, create_invoice from lnbits.decorators import WalletTypeInfo, require_admin_key
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
from . import jukebox_ext from . import jukebox_ext
from .crud import ( from .crud import (
@ -75,7 +74,6 @@ async def api_check_credentials_callbac(
async def api_check_credentials_check( async def api_check_credentials_check(
juke_id: str = Query(None), wallet: WalletTypeInfo = Depends(require_admin_key) juke_id: str = Query(None), wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
print(juke_id)
jukebox = await get_jukebox(juke_id) jukebox = await get_jukebox(juke_id)
return jukebox return jukebox
@ -238,7 +236,7 @@ async def api_get_jukebox_device_check(
async def api_get_jukebox_invoice(juke_id, song_id): async def api_get_jukebox_invoice(juke_id, song_id):
try: try:
jukebox = await get_jukebox(juke_id) jukebox = await get_jukebox(juke_id)
print(jukebox)
except: except:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="No jukebox") raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="No jukebox")
try: try:
@ -269,7 +267,6 @@ async def api_get_jukebox_invoice(juke_id, song_id):
invoice=invoice[1], payment_hash=payment_hash, juke_id=juke_id, song_id=song_id invoice=invoice[1], payment_hash=payment_hash, juke_id=juke_id, song_id=song_id
) )
jukebox_payment = await create_jukebox_payment(data) jukebox_payment = await create_jukebox_payment(data)
print(data)
return data return data

View file

@ -79,8 +79,7 @@ class Track(BaseModel):
url_with_query = f"{url}?p={payment_hash}" url_with_query = f"{url}?p={payment_hash}"
return UrlAction( return UrlAction(
url=url_with_query, url=url_with_query, description=f"Download the track {self.name}!"
description=f"Download the track {self.name}!",
) )

View file

@ -19,12 +19,6 @@ async def wait_for_paid_invoices():
await on_invoice_paid(payment) 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)
# await wait_for_paid_invoices(invoice_paid_chan_recv)
async def on_invoice_paid(payment: Payment) -> None: async def on_invoice_paid(payment: Payment) -> None:
if "livestream" != payment.extra.get("tag"): if "livestream" != payment.extra.get("tag"):
# not a livestream invoice # not a livestream invoice

View file

@ -24,7 +24,6 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
@livestream_ext.get("/track/{track_id}", name="livestream.track_redirect_download") @livestream_ext.get("/track/{track_id}", name="livestream.track_redirect_download")
async def track_redirect_download(track_id, p: str = Query(...)): async def track_redirect_download(track_id, p: str = Query(...)):
print("BOO", track_id, p)
payment_hash = p payment_hash = p
track = await get_track(track_id) track = await get_track(track_id)
ls = await get_livestream_by_track(track_id) ls = await get_livestream_by_track(track_id)

View file

@ -29,7 +29,7 @@ async def api_livestream_from_wallet(
ls = await get_or_create_livestream_by_wallet(g.wallet.id) ls = await get_or_create_livestream_by_wallet(g.wallet.id)
tracks = await get_tracks(ls.id) tracks = await get_tracks(ls.id)
producers = await get_producers(ls.id) producers = await get_producers(ls.id)
print("INIT", ls, tracks, producers)
try: try:
return { return {
**ls.dict(), **ls.dict(),

View file

@ -8,10 +8,8 @@ from lnbits.tasks import catch_everything_and_restart
db = Database("ext_lnaddress") db = Database("ext_lnaddress")
lnaddress_ext: APIRouter = APIRouter( lnaddress_ext: APIRouter = APIRouter(prefix="/lnaddress", tags=["lnaddress"])
prefix="/lnaddress",
tags=["lnaddress"]
)
def lnaddress_renderer(): def lnaddress_renderer():
return template_renderer(["lnbits/extensions/lnaddress/templates"]) return template_renderer(["lnbits/extensions/lnaddress/templates"])

View file

@ -1,10 +1,11 @@
import json
import httpx
from lnbits.extensions.lnaddress.models import Domains from lnbits.extensions.lnaddress.models import Domains
import httpx, json
async def cloudflare_create_record( async def cloudflare_create_record(domain: Domains, ip: str):
domain: Domains, ip: str
):
url = ( url = (
"https://api.cloudflare.com/client/v4/zones/" "https://api.cloudflare.com/client/v4/zones/"
+ domain.cf_zone_id + domain.cf_zone_id
@ -48,11 +49,7 @@ async def cloudflare_deleterecord(domain: Domains, domain_id: str):
} }
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
try: try:
r = await client.delete( r = await client.delete(url + "/" + domain_id, headers=header, timeout=40)
url + "/" + domain_id,
headers=header,
timeout=40,
)
cf_response = r.text cf_response = r.text
except AssertionError: except AssertionError:
cf_response = "Error occured" cf_response = "Error occured"

View file

@ -7,9 +7,7 @@ from . import db
from .models import Addresses, CreateAddress, CreateDomain, Domains from .models import Addresses, CreateAddress, CreateDomain, Domains
async def create_domain( async def create_domain(data: CreateDomain) -> Domains:
data: CreateDomain
) -> Domains:
domain_id = urlsafe_short_hash() domain_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
@ -37,21 +35,21 @@ async def update_domain(domain_id: str, **kwargs) -> Domains:
await db.execute( await db.execute(
f"UPDATE lnaddress.domain SET {q} WHERE id = ?", (*kwargs.values(), domain_id) f"UPDATE lnaddress.domain SET {q} WHERE id = ?", (*kwargs.values(), domain_id)
) )
row = await db.fetchone( row = await db.fetchone("SELECT * FROM lnaddress.domain WHERE id = ?", (domain_id,))
"SELECT * FROM lnaddress.domain WHERE id = ?", (domain_id,)
)
assert row, "Newly updated domain couldn't be retrieved" assert row, "Newly updated domain couldn't be retrieved"
return Domains(**row) return Domains(**row)
async def delete_domain(domain_id: str) -> None: async def delete_domain(domain_id: str) -> None:
await db.execute("DELETE FROM lnaddress.domain WHERE id = ?", (domain_id,)) await db.execute("DELETE FROM lnaddress.domain WHERE id = ?", (domain_id,))
async def get_domain(domain_id: str) -> Optional[Domains]: async def get_domain(domain_id: str) -> Optional[Domains]:
row = await db.fetchone( row = await db.fetchone("SELECT * FROM lnaddress.domain WHERE id = ?", (domain_id,))
"SELECT * FROM lnaddress.domain WHERE id = ?", (domain_id,)
)
return Domains(**row) if row else None return Domains(**row) if row else None
async def get_domains(wallet_ids: Union[str, List[str]]) -> List[Domains]: async def get_domains(wallet_ids: Union[str, List[str]]) -> List[Domains]:
if isinstance(wallet_ids, str): if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids] wallet_ids = [wallet_ids]
@ -63,12 +61,12 @@ async def get_domains(wallet_ids: Union[str, List[str]]) -> List[Domains]:
return [Domains(**row) for row in rows] return [Domains(**row) for row in rows]
## ADRESSES ## ADRESSES
async def create_address( async def create_address(
payment_hash: str, payment_hash: str, wallet: str, data: CreateAddress
wallet: str,
data: CreateAddress
) -> Addresses: ) -> Addresses:
await db.execute( await db.execute(
""" """
@ -93,6 +91,7 @@ async def create_address(
assert new_address, "Newly created address couldn't be retrieved" assert new_address, "Newly created address couldn't be retrieved"
return new_address return new_address
async def get_address(address_id: str) -> Optional[Addresses]: async def get_address(address_id: str) -> Optional[Addresses]:
row = await db.fetchone( row = await db.fetchone(
"SELECT a.* FROM lnaddress.address AS a INNER JOIN lnaddress.domain AS d ON a.id = ? AND a.domain = d.id", "SELECT a.* FROM lnaddress.address AS a INNER JOIN lnaddress.domain AS d ON a.id = ? AND a.domain = d.id",
@ -100,35 +99,35 @@ async def get_address(address_id: str) -> Optional[Addresses]:
) )
return Addresses(**row) if row else None return Addresses(**row) if row else None
async def get_address_by_username(username: str, domain: str) -> Optional[Addresses]: async def get_address_by_username(username: str, domain: str) -> Optional[Addresses]:
row = await db.fetchone( row = await db.fetchone(
"SELECT a.* FROM lnaddress.address AS a INNER JOIN lnaddress.domain AS d ON a.username = ? AND d.domain = ?", "SELECT a.* FROM lnaddress.address AS a INNER JOIN lnaddress.domain AS d ON a.username = ? AND d.domain = ?",
# "SELECT * FROM lnaddress.address WHERE username = ? AND domain = ?", (username, domain),
(username, domain,),
) )
print("ADD", row)
return Addresses(**row) if row else None return Addresses(**row) if row else None
async def delete_address(address_id: str) -> None: async def delete_address(address_id: str) -> None:
await db.execute("DELETE FROM lnaddress.address WHERE id = ?", (address_id,)) await db.execute("DELETE FROM lnaddress.address WHERE id = ?", (address_id,))
async def get_addresses(wallet_ids: Union[str, List[str]]) -> List[Addresses]: async def get_addresses(wallet_ids: Union[str, List[str]]) -> List[Addresses]:
if isinstance(wallet_ids, str): if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids] wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids)) q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall( rows = await db.fetchall(
f"SELECT * FROM lnaddress.address WHERE wallet IN ({q})", f"SELECT * FROM lnaddress.address WHERE wallet IN ({q})", (*wallet_ids,)
(*wallet_ids,),
) )
print([Addresses(**row) for row in rows])
return [Addresses(**row) for row in rows] return [Addresses(**row) for row in rows]
async def set_address_paid(payment_hash: str) -> Addresses:
_address = await get_address(payment_hash)
address = _address._asdict()
if address["paid"] == False: async def set_address_paid(payment_hash: str) -> Addresses:
address = await get_address(payment_hash)
if address.paid == False:
await db.execute( await db.execute(
""" """
UPDATE lnaddress.address UPDATE lnaddress.address
@ -142,18 +141,18 @@ async def set_address_paid(payment_hash: str) -> Addresses:
assert new_address, "Newly paid address couldn't be retrieved" assert new_address, "Newly paid address couldn't be retrieved"
return new_address return new_address
async def set_address_renewed(address_id: str, duration: int):
_address = await get_address(address_id)
address = _address._asdict()
extend_duration = int(address["duration"]) + duration async def set_address_renewed(address_id: str, duration: int):
address = await get_address(address_id)
extend_duration = int(address.duration) + duration
await db.execute( await db.execute(
""" """
UPDATE lnaddress.address UPDATE lnaddress.address
SET duration = ? SET duration = ?
WHERE id = ? WHERE id = ?
""", """,
(extend_duration, address_id,), (extend_duration, address_id),
) )
updated_address = await get_address(address_id) updated_address = await get_address(address_id)
assert updated_address, "Renewed address couldn't be retrieved" assert updated_address, "Renewed address couldn't be retrieved"
@ -163,15 +162,15 @@ async def set_address_renewed(address_id: str, duration: int):
async def check_address_available(username: str, domain: str): async def check_address_available(username: str, domain: str):
row, = await db.fetchone( row, = await db.fetchone(
"SELECT COUNT(username) FROM lnaddress.address WHERE username = ? AND domain = ?", "SELECT COUNT(username) FROM lnaddress.address WHERE username = ? AND domain = ?",
(username, domain,), (username, domain),
) )
return row return row
async def purge_addresses(domain_id: str): async def purge_addresses(domain_id: str):
rows = await db.fetchall( rows = await db.fetchall(
"SELECT * FROM lnaddress.address WHERE domain = ?", "SELECT * FROM lnaddress.address WHERE domain = ?", (domain_id,)
(domain_id, ),
) )
now = datetime.now().timestamp() now = datetime.now().timestamp()
@ -182,7 +181,9 @@ async def purge_addresses(domain_id: str):
start = datetime.fromtimestamp(r["time"]) start = datetime.fromtimestamp(r["time"])
paid = r["paid"] paid = r["paid"]
pay_expire = now > start.timestamp() + 86400 # if payment wasn't made in 1 day pay_expire = now > start.timestamp() + 86400 # if payment wasn't made in 1 day
expired = now > (start + timedelta(days = r["duration"] + 1)).timestamp() #give user 1 day to topup is address expired = (
now > (start + timedelta(days=r["duration"] + 1)).timestamp()
) # give user 1 day to topup is address
if not paid and pay_expire: if not paid and pay_expire:
print("DELETE UNP_PAY_EXP", r["username"]) print("DELETE UNP_PAY_EXP", r["username"])

View file

@ -29,7 +29,7 @@ async def lnurl_response(username: str, domain: str, request: Request):
return LnurlErrorResponse(reason="Address has expired.").dict() return LnurlErrorResponse(reason="Address has expired.").dict()
resp = LnurlPayResponse( resp = LnurlPayResponse(
callback=request.url_for("lnaddress.lnurl_callback", address_id=address.id, _external=True), callback=request.url_for("lnaddress.lnurl_callback", address_id=address.id),
min_sendable=1000, min_sendable=1000,
max_sendable=1000000000, max_sendable=1000000000,
metadata=await address.lnurlpay_metadata(), metadata=await address.lnurlpay_metadata(),
@ -37,44 +37,38 @@ async def lnurl_response(username: str, domain: str, request: Request):
return resp.dict() return resp.dict()
@lnaddress_ext.get("/lnurl/cb/{address_id}", name="lnaddress.lnurl_callback") @lnaddress_ext.get("/lnurl/cb/{address_id}", name="lnaddress.lnurl_callback")
async def lnurl_callback(address_id, amount: int = Query(...)): async def lnurl_callback(address_id, amount: int = Query(...)):
address = await get_address(address_id) address = await get_address(address_id)
if not address: if not address:
return LnurlErrorResponse( return LnurlErrorResponse(reason=f"Address not found").dict()
reason=f"Address not found"
).dict()
amount_received = amount amount_received = amount
# min = 1000
# max = 1000000000
# if amount_received < min:
# return LnurlErrorResponse(
# reason=f"Amount {amount_received} is smaller than minimum."
# ).dict()
# elif amount_received > max:
# return jsonify(
# LnurlErrorResponse(
# reason=f"Amount {amount_received} is greater than maximum."
# ).dict()
# )
domain = await get_domain(address.domain) domain = await get_domain(address.domain)
base_url = address.wallet_endpoint[:-1] if address.wallet_endpoint.endswith('/') else address.wallet_endpoint base_url = (
address.wallet_endpoint[:-1]
if address.wallet_endpoint.endswith("/")
else address.wallet_endpoint
)
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
try: try:
call = await client.post( call = await client.post(
base_url + "/api/v1/payments", base_url + "/api/v1/payments",
headers={"X-Api-Key": address.wallet_key, "Content-Type": "application/json"}, headers={
"X-Api-Key": address.wallet_key,
"Content-Type": "application/json",
},
json={ json={
"out": False, "out": False,
"amount": int(amount_received / 1000), "amount": int(amount_received / 1000),
"description_hash": hashlib.sha256((await address.lnurlpay_metadata()).encode("utf-8")).hexdigest(), "description_hash": hashlib.sha256(
(await address.lnurlpay_metadata()).encode("utf-8")
).hexdigest(),
"extra": {"tag": f"Payment to {address.username}@{domain.domain}"}, "extra": {"tag": f"Payment to {address.username}@{domain.domain}"},
}, },
timeout=40, timeout=40,
@ -84,9 +78,6 @@ async def lnurl_callback(address_id, amount: int = Query(...)):
except AssertionError as e: except AssertionError as e:
return LnurlErrorResponse(reason="ERROR") return LnurlErrorResponse(reason="ERROR")
resp = LnurlPayActionResponse( resp = LnurlPayActionResponse(pr=r["payment_request"], routes=[])
pr=r["payment_request"],
routes=[],
)
return resp.dict() return resp.dict()

View file

@ -16,6 +16,7 @@ async def m001_initial(db):
""" """
) )
async def m002_addresses(db): async def m002_addresses(db):
await db.execute( await db.execute(
""" """
@ -36,6 +37,3 @@ async def m002_addresses(db):
); );
""" """
) )
# async def m003_create_unique_indexes(db):
# await db.execute("CREATE UNIQUE INDEX IF NOT EXISTS address_at_domain ON lnaddress.address (domain, username);")

View file

@ -14,16 +14,18 @@ class CreateDomain(BaseModel):
webhook: str = Query(None) webhook: str = Query(None)
cost: int = Query(..., ge=0) cost: int = Query(..., ge=0)
class Domains(BaseModel): class Domains(BaseModel):
id: str id: str
wallet: str wallet: str
domain: str domain: str
cf_token: str cf_token: str
cf_zone_id: str cf_zone_id: str
webhook: str webhook: Optional[str]
cost: int cost: int
time: int time: int
class CreateAddress(BaseModel): class CreateAddress(BaseModel):
domain: str = Query(...) domain: str = Query(...)
username: str = Query(...) username: str = Query(...)
@ -33,11 +35,12 @@ class CreateAddress(BaseModel):
sats: int = Query(..., ge=0) sats: int = Query(..., ge=0)
duration: int = Query(..., ge=1) duration: int = Query(..., ge=1)
class Addresses(BaseModel): class Addresses(BaseModel):
id: str id: str
wallet: str wallet: str
domain: str domain: str
email: str email: Optional[str]
username: str username: str
wallet_key: str wallet_key: str
wallet_endpoint: str wallet_endpoint: str

View file

@ -52,7 +52,9 @@ async def on_invoice_paid(payment: Payment) -> None:
elif "renew lnaddress" == payment.extra.get("tag"): elif "renew lnaddress" == payment.extra.get("tag"):
await payment.set_pending(False) await payment.set_pending(False)
await set_address_renewed(address_id=payment.extra["id"], duration=payment.extra["duration"]) await set_address_renewed(
address_id=payment.extra["id"], duration=payment.extra["duration"]
)
await call_webhook_on_paid(payment.payment_hash) await call_webhook_on_paid(payment.payment_hash)
else: else:

View file

@ -18,9 +18,12 @@ templates = Jinja2Templates(directory="templates")
@lnaddress_ext.get("/", response_class=HTMLResponse) @lnaddress_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 lnaddress_renderer().TemplateResponse("lnaddress/index.html", {"request": request, "user": user.dict()}) return lnaddress_renderer().TemplateResponse(
"lnaddress/index.html", {"request": request, "user": user.dict()}
)
@lnaddress_ext.get("/{domain_id}")
@lnaddress_ext.get("/{domain_id}", response_class=HTMLResponse)
async def display(domain_id, request: Request): async def display(domain_id, request: Request):
domain = await get_domain(domain_id) domain = await get_domain(domain_id)
if not domain: if not domain:
@ -28,16 +31,17 @@ async def display(domain_id, request: Request):
status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
) )
await purge_addresses(domain_id, response_class=HTMLResponse) await purge_addresses(domain_id)
wallet = await get_wallet(domain.wallet) wallet = await get_wallet(domain.wallet)
return lnaddress_renderer().TemplateResponse( return lnaddress_renderer().TemplateResponse(
"lnaddress/display.html",{ "lnaddress/display.html",
{
"request": request, "request": request,
"domain_id": domain.id, "domain_id": domain.id,
"domain_domain": domain.domain, "domain_domain": domain.domain,
"domain_cost": domain.cost, "domain_cost": domain.cost,
"domain_wallet_inkey": wallet.inkey "domain_wallet_inkey": wallet.inkey,
} },
) )

View file

@ -30,8 +30,7 @@ from .crud import (
# DOMAINS # DOMAINS
@lnaddress_ext.get("/api/v1/domains") @lnaddress_ext.get("/api/v1/domains")
async def api_domains( async def api_domains(
g: WalletTypeInfo = Depends(get_key_type), g: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)
all_wallets: bool = Query(False),
): ):
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
@ -43,68 +42,66 @@ async def api_domains(
@lnaddress_ext.post("/api/v1/domains") @lnaddress_ext.post("/api/v1/domains")
@lnaddress_ext.put("/api/v1/domains/{domain_id}") @lnaddress_ext.put("/api/v1/domains/{domain_id}")
async def api_domain_create(request: Request,data: CreateDomain, domain_id=None, g: WalletTypeInfo = Depends(get_key_type)): async def api_domain_create(
request: Request,
data: CreateDomain,
domain_id=None,
g: WalletTypeInfo = Depends(get_key_type),
):
if domain_id: if domain_id:
domain = await get_domain(domain_id) domain = await get_domain(domain_id)
if not domain: if not domain:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
detail="Domain does not exist.",
) )
if domain.wallet != g.wallet.id: if domain.wallet != g.wallet.id:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, status_code=HTTPStatus.FORBIDDEN, detail="Not your domain"
detail="Not your domain",
) )
domain = await update_domain(domain_id, **data.dict()) domain = await update_domain(domain_id, **data.dict())
else: else:
domain = await create_domain(data=data) domain = await create_domain(data=data)
root_url = urlparse(request.url.path).netloc root_url = urlparse(str(request.url)).netloc
#root_url = request.url_root
cf_response = await cloudflare_create_record( cf_response = await cloudflare_create_record(domain=domain, ip=root_url)
domain=domain,
ip=root_url,
)
if not cf_response or cf_response["success"] != True: if not cf_response or cf_response["success"] != True:
await delete_domain(domain.id) await delete_domain(domain.id)
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
detail="Problem with cloudflare: " + cf_response["errors"][0]["message"], detail="Problem with cloudflare: "
+ cf_response["errors"][0]["message"],
) )
return domain.dict() return domain.dict()
@lnaddress_ext.delete("/api/v1/domains/{domain_id}") @lnaddress_ext.delete("/api/v1/domains/{domain_id}")
async def api_domain_delete(domain_id, g: WalletTypeInfo = Depends(get_key_type)): async def api_domain_delete(domain_id, g: WalletTypeInfo = Depends(get_key_type)):
domain = await get_domain(domain_id) domain = await get_domain(domain_id)
if not domain: if not domain:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND, detail="Domain does not exist."
detail="Domain does not exist.",
) )
if domain.wallet != g.wallet.id: if domain.wallet != g.wallet.id:
raise HTTPException( raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your domain")
status_code=HTTPStatus.FORBIDDEN,
detail="Not your domain",
)
await delete_domain(domain_id) await delete_domain(domain_id)
raise HTTPException(status_code=HTTPStatus.NO_CONTENT) raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
# ADDRESSES # ADDRESSES
@lnaddress_ext.get("/api/v1/addresses") @lnaddress_ext.get("/api/v1/addresses")
async def api_addresses( async def api_addresses(
g: WalletTypeInfo = Depends(get_key_type), g: WalletTypeInfo = Depends(get_key_type), all_wallets: bool = Query(False)
all_wallets: bool = Query(False),
): ):
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
@ -113,14 +110,21 @@ async def api_addresses(
return [address.dict() for address in await get_addresses(wallet_ids)] return [address.dict() for address in await get_addresses(wallet_ids)]
@lnaddress_ext.get("/api/v1/address/availabity/{domain_id}/{username}")
async def api_check_available_username(domain_id, username):
used_username = await check_address_available(username, domain_id)
return used_username
@lnaddress_ext.get("/api/v1/address/{domain}/{username}/{wallet_key}") @lnaddress_ext.get("/api/v1/address/{domain}/{username}/{wallet_key}")
async def api_get_user_info(username, wallet_key, domain): async def api_get_user_info(username, wallet_key, domain):
address = await get_address_by_username(username, domain) address = await get_address_by_username(username, domain)
if not address: if not address:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND, detail="Address does not exist."
detail="Address does not exist.",
) )
if address.wallet_key != wallet_key: if address.wallet_key != wallet_key:
@ -131,48 +135,41 @@ async def api_get_user_info(username, wallet_key, domain):
return address.dict() return address.dict()
@lnaddress_ext.get("/api/v1/address/availabity/{domain_id}/{username}")
async def api_check_available_username(domain_id, username):
used_username = await check_address_available(username, domain_id)
return used_username
@lnaddress_ext.post("/api/v1/address/{domain_id}") @lnaddress_ext.post("/api/v1/address/{domain_id}")
@lnaddress_ext.put("/api/v1/address/{domain_id}/{user}/{wallet_key}") @lnaddress_ext.put("/api/v1/address/{domain_id}/{user}/{wallet_key}")
async def api_lnaddress_make_address(domain_id, data: CreateAddress, user=None, wallet_key=None): async def api_lnaddress_make_address(
domain_id, data: CreateAddress, user=None, wallet_key=None
):
domain = await get_domain(domain_id) domain = await get_domain(domain_id)
# If the request is coming for the non-existant domain # If the request is coming for the non-existant domain
if not domain: if not domain:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, status_code=HTTPStatus.FORBIDDEN, detail="The domain does not exist."
detail="The domain does not exist.",
) )
domain_cost = domain[6] domain_cost = domain.cost
sats = data.sats sats = data.sats
## FAILSAFE FOR CREATING ADDRESSES BY API ## FAILSAFE FOR CREATING ADDRESSES BY API
if(domain_cost * data.duration != data.sats): if domain_cost * data.duration != data.sats:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, status_code=HTTPStatus.FORBIDDEN,
detail="The amount is not correct. Either 'duration', or 'sats' are wrong.", detail="The amount is not correct. Either 'duration', or 'sats' are wrong.",
) )
if user: if user:
print("USER", user, domain.domain)
address = await get_address_by_username(user, domain.domain) address = await get_address_by_username(user, domain.domain)
if not address: if not address:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND, detail="The address does not exist."
detail="The address does not exist.",
) )
if address.wallet_key != wallet_key: if address.wallet_key != wallet_key:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, status_code=HTTPStatus.FORBIDDEN, detail="Not your address."
detail="Not your address.",
) )
try: try:
@ -183,14 +180,13 @@ async def api_lnaddress_make_address(domain_id, data: CreateAddress, user=None,
extra={ extra={
"tag": "renew lnaddress", "tag": "renew lnaddress",
"id": address.id, "id": address.id,
"duration": data.duration "duration": data.duration,
}, },
) )
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)
detail=str(e),
) )
else: else:
used_username = await check_address_available(data.username, data.domain) used_username = await check_address_available(data.username, data.domain)
@ -212,8 +208,7 @@ async def api_lnaddress_make_address(domain_id, data: CreateAddress, user=None,
) )
except Exception as e: except Exception as e:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR, status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)
detail=str(e),
) )
address = await create_address( address = await create_address(
@ -228,6 +223,7 @@ async def api_lnaddress_make_address(domain_id, data: CreateAddress, user=None,
return {"payment_hash": payment_hash, "payment_request": payment_request} return {"payment_hash": payment_hash, "payment_request": payment_request}
@lnaddress_ext.get("/api/v1/addresses/{payment_hash}") @lnaddress_ext.get("/api/v1/addresses/{payment_hash}")
async def api_address_send_address(payment_hash): async def api_address_send_address(payment_hash):
address = await get_address(payment_hash) address = await get_address(payment_hash)
@ -236,27 +232,25 @@ async def api_address_send_address(payment_hash):
status = await check_invoice_status(domain.wallet, payment_hash) status = await check_invoice_status(domain.wallet, payment_hash)
is_paid = not status.pending is_paid = not status.pending
except Exception as e: except Exception as e:
return {"paid": False, 'error': str(e)} return {"paid": False, "error": str(e)}
if is_paid: if is_paid:
return {"paid": True} return {"paid": True}
return {"paid": False} return {"paid": False}
@lnaddress_ext.delete("/api/v1/addresses/{address_id}") @lnaddress_ext.delete("/api/v1/addresses/{address_id}")
async def api_address_delete(address_id, g: WalletTypeInfo = Depends(get_key_type)): async def api_address_delete(address_id, g: WalletTypeInfo = Depends(get_key_type)):
address = await get_address(address_id) address = await get_address(address_id)
if not address: if not address:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, status_code=HTTPStatus.NOT_FOUND, detail="Address does not exist."
detail="Address does not exist.",
) )
if address.wallet != g.wallet.id: if address.wallet != g.wallet.id:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, status_code=HTTPStatus.FORBIDDEN, detail="Not your address."
detail="Not your address.",
) )
await delete_address(address_id) await delete_address(address_id)
raise HTTPException(status_code=HTTPStatus.NO_CONTENT) raise HTTPException(status_code=HTTPStatus.NO_CONTENT)

View file

@ -8,20 +8,16 @@ from lnbits.tasks import catch_everything_and_restart
db = Database("ext_lnticket") db = Database("ext_lnticket")
lnticket_ext: APIRouter = APIRouter( lnticket_ext: APIRouter = APIRouter(prefix="/lnticket", tags=["LNTicket"])
prefix="/lnticket",
tags=["LNTicket"]
# "lnticket", __name__, static_folder="static", template_folder="templates"
)
def lnticket_renderer(): def lnticket_renderer():
return template_renderer(["lnbits/extensions/lnticket/templates"]) return template_renderer(["lnbits/extensions/lnticket/templates"])
from .views_api import * # noqa
from .views import * # noqa
from .tasks import wait_for_paid_invoices from .tasks import wait_for_paid_invoices
from .views import * # noqa
from .views_api import * # noqa
def lnticket_start(): def lnticket_start():

View file

@ -27,5 +27,3 @@ async def on_invoice_paid(payment: Payment) -> None:
await payment.set_pending(False) await payment.set_pending(False)
await set_ticket_paid(payment.payment_hash) await set_ticket_paid(payment.payment_hash)
_ticket = await get_ticket(payment.checking_id)
print("ticket", _ticket)

View file

@ -1,25 +1,23 @@
from http import HTTPStatus
from fastapi import Request
from fastapi.param_functions import Depends from fastapi.param_functions import Depends
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from lnbits.core.models import User
from lnbits.core.crud import get_wallet from lnbits.core.crud import get_wallet
from lnbits.core.models import User
from lnbits.decorators import check_user_exists from lnbits.decorators import check_user_exists
from http import HTTPStatus
from . import lnticket_ext, lnticket_renderer from . import lnticket_ext, lnticket_renderer
from .crud import get_form from .crud import get_form
from fastapi import FastAPI, Request
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
@lnticket_ext.get("/", response_class=HTMLResponse) @lnticket_ext.get("/", response_class=HTMLResponse)
# not needed as we automatically get the user with the given ID
# If no user with this ID is found, an error is raised
# @validate_uuids(["usr"], required=True)
# @check_user_exists()
async def index(request: Request, user: User = Depends(check_user_exists)): async def index(request: Request, user: User = Depends(check_user_exists)):
return lnticket_renderer().TemplateResponse( return lnticket_renderer().TemplateResponse(
"lnticket/index.html", {"request": request, "user": user.dict()} "lnticket/index.html", {"request": request, "user": user.dict()}
@ -33,7 +31,6 @@ async def display(request: Request, form_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="LNTicket does not exist." status_code=HTTPStatus.NOT_FOUND, detail="LNTicket does not exist."
) )
# abort(HTTPStatus.NOT_FOUND, "LNTicket does not exist.")
wallet = await get_wallet(form.wallet) wallet = await get_wallet(form.wallet)

View file

@ -1,17 +1,13 @@
import re import re
from http import HTTPStatus from http import HTTPStatus
from typing import List
from fastapi import Query from fastapi import Query
from fastapi.params import Depends from fastapi.params import Depends
from pydantic import BaseModel
from starlette.exceptions import HTTPException 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
from lnbits.core.services import create_invoice
from lnbits.core.views.api import api_payment from lnbits.core.views.api import api_payment
from lnbits.core.crud import get_user, get_wallet
from lnbits.core.services import check_invoice_status, create_invoice
from lnbits.decorators import WalletTypeInfo, get_key_type from lnbits.decorators import WalletTypeInfo, get_key_type
from lnbits.extensions.lnticket.models import CreateFormData, CreateTicketData from lnbits.extensions.lnticket.models import CreateFormData, CreateTicketData
@ -34,9 +30,7 @@ from .crud import (
@lnticket_ext.get("/api/v1/forms") @lnticket_ext.get("/api/v1/forms")
async def api_forms_get( async def api_forms_get(
r: Request, all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
all_wallets: bool = Query(False),
wallet: WalletTypeInfo = Depends(get_key_type),
): ):
wallet_ids = [wallet.wallet.id] wallet_ids = [wallet.wallet.id]
@ -48,17 +42,6 @@ async def api_forms_get(
@lnticket_ext.post("/api/v1/forms", status_code=HTTPStatus.CREATED) @lnticket_ext.post("/api/v1/forms", status_code=HTTPStatus.CREATED)
@lnticket_ext.put("/api/v1/forms/{form_id}") @lnticket_ext.put("/api/v1/forms/{form_id}")
# @api_check_wallet_key("invoice")
# @api_validate_post_request(
# schema={
# "wallet": {"type": "string", "empty": False, "required": True},
# "name": {"type": "string", "empty": False, "required": True},
# "webhook": {"type": "string", "required": False},
# "description": {"type": "string", "min": 0, "required": True},
# "amount": {"type": "integer", "min": 0, "required": True},
# "flatrate": {"type": "integer", "required": True},
# }
# )
async def api_form_create( async def api_form_create(
data: CreateFormData, form_id=None, wallet: WalletTypeInfo = Depends(get_key_type) data: CreateFormData, form_id=None, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
@ -69,13 +52,11 @@ async def api_form_create(
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail=f"Form does not exist." status_code=HTTPStatus.NOT_FOUND, detail=f"Form does not exist."
) )
# return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != wallet.wallet.id: if form.wallet != wallet.wallet.id:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail=f"Not your form." status_code=HTTPStatus.FORBIDDEN, detail=f"Not your form."
) )
# return {"message": "Not your form."}, HTTPStatus.FORBIDDEN
form = await update_form(form_id, **data.dict()) form = await update_form(form_id, **data.dict())
else: else:
@ -84,7 +65,6 @@ async def api_form_create(
@lnticket_ext.delete("/api/v1/forms/{form_id}") @lnticket_ext.delete("/api/v1/forms/{form_id}")
# @api_check_wallet_key("invoice")
async def api_form_delete(form_id, wallet: WalletTypeInfo = Depends(get_key_type)): async def api_form_delete(form_id, wallet: WalletTypeInfo = Depends(get_key_type)):
form = await get_form(form_id) form = await get_form(form_id)
@ -92,15 +72,12 @@ async def api_form_delete(form_id, wallet: WalletTypeInfo = Depends(get_key_type
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail=f"Form does not exist." status_code=HTTPStatus.NOT_FOUND, detail=f"Form does not exist."
) )
# return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != wallet.wallet.id: if form.wallet != wallet.wallet.id:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail=f"Not your form.") raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail=f"Not your form.")
# return {"message": "Not your form."}, HTTPStatus.FORBIDDEN
await delete_form(form_id) await delete_form(form_id)
# return "", HTTPStatus.NO_CONTENT
raise HTTPException(status_code=HTTPStatus.NO_CONTENT) raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
@ -108,7 +85,6 @@ async def api_form_delete(form_id, wallet: WalletTypeInfo = Depends(get_key_type
@lnticket_ext.get("/api/v1/tickets") @lnticket_ext.get("/api/v1/tickets")
# @api_check_wallet_key("invoice")
async def api_tickets( async def api_tickets(
all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type) all_wallets: bool = Query(False), wallet: WalletTypeInfo = Depends(get_key_type)
): ):
@ -121,22 +97,12 @@ async def api_tickets(
@lnticket_ext.post("/api/v1/tickets/{form_id}", status_code=HTTPStatus.CREATED) @lnticket_ext.post("/api/v1/tickets/{form_id}", status_code=HTTPStatus.CREATED)
# @api_validate_post_request(
# schema={
# "form": {"type": "string", "empty": False, "required": True},
# "name": {"type": "string", "empty": False, "required": True},
# "email": {"type": "string", "empty": True, "required": True},
# "ltext": {"type": "string", "empty": False, "required": True},
# "sats": {"type": "integer", "min": 0, "required": True},
# }
# )
async def api_ticket_make_ticket(data: CreateTicketData, form_id): async def api_ticket_make_ticket(data: CreateTicketData, form_id):
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail=f"LNTicket does not exist." status_code=HTTPStatus.NOT_FOUND, detail=f"LNTicket does not exist."
) )
# return {"message": "LNTicket does not exist."}, HTTPStatus.NOT_FOUND
nwords = len(re.split(r"\s+", data.ltext)) nwords = len(re.split(r"\s+", data.ltext))
@ -149,7 +115,6 @@ async def api_ticket_make_ticket(data: CreateTicketData, form_id):
) )
except Exception as e: 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 {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR
ticket = await create_ticket( ticket = await create_ticket(
payment_hash=payment_hash, wallet=form.wallet, data=data payment_hash=payment_hash, wallet=form.wallet, data=data
@ -159,10 +124,6 @@ async def api_ticket_make_ticket(data: CreateTicketData, form_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="LNTicket could not be fetched." status_code=HTTPStatus.NOT_FOUND, detail="LNTicket could not be fetched."
) )
# return (
# {"message": "LNTicket could not be fetched."},
# HTTPStatus.NOT_FOUND,
# )
return {"payment_hash": payment_hash, "payment_request": payment_request} return {"payment_hash": payment_hash, "payment_request": payment_request}
@ -183,7 +144,6 @@ async def api_ticket_send_ticket(payment_hash):
@lnticket_ext.delete("/api/v1/tickets/{ticket_id}") @lnticket_ext.delete("/api/v1/tickets/{ticket_id}")
# @api_check_wallet_key("invoice")
async def api_ticket_delete(ticket_id, wallet: WalletTypeInfo = Depends(get_key_type)): async def api_ticket_delete(ticket_id, wallet: WalletTypeInfo = Depends(get_key_type)):
ticket = await get_ticket(ticket_id) ticket = await get_ticket(ticket_id)
@ -191,12 +151,9 @@ async def api_ticket_delete(ticket_id, wallet: WalletTypeInfo = Depends(get_key_
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail=f"LNTicket does not exist." status_code=HTTPStatus.NOT_FOUND, detail=f"LNTicket does not exist."
) )
# return {"message": "Paywall does not exist."}, HTTPStatus.NOT_FOUND
if ticket.wallet != wallet.wallet.id: if ticket.wallet != wallet.wallet.id:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your ticket.") raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your ticket.")
# return {"message": "Not your ticket."}, HTTPStatus.FORBIDDEN
await delete_ticket(ticket_id) await delete_ticket(ticket_id)
raise HTTPException(status_code=HTTPStatus.NO_CONTENT) raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
# return ""

View file

@ -17,11 +17,7 @@ lnurlp_static_files = [
} }
] ]
lnurlp_ext: APIRouter = APIRouter( lnurlp_ext: APIRouter = APIRouter(prefix="/lnurlp", tags=["lnurlp"])
prefix="/lnurlp",
tags=["lnurlp"]
# "lnurlp", __name__, static_folder="static", template_folder="templates"
)
def lnurlp_renderer(): def lnurlp_renderer():
@ -37,8 +33,3 @@ from .views_api import * # noqa
def lnurlp_start(): def lnurlp_start():
loop = asyncio.get_event_loop() 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))
# from lnbits.tasks import record_async
# lnurlp_ext.record(record_async(register_listeners))

View file

@ -110,7 +110,6 @@ async def api_link_create_or_update(
link = await update_pay_link(**data.dict(), link_id=link_id) link = await update_pay_link(**data.dict(), link_id=link_id)
else: else:
link = await create_pay_link(data, wallet_id=wallet.wallet.id) link = await create_pay_link(data, wallet_id=wallet.wallet.id)
print("LINK", link)
return {**link.dict(), "lnurl": link.lnurl} return {**link.dict(), "lnurl": link.lnurl}

View file

@ -1,10 +1,7 @@
import asyncio from fastapi import APIRouter
from fastapi import APIRouter, FastAPI
from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart
db = Database("ext_lnurlpos") db = Database("ext_lnurlpos")
@ -15,6 +12,6 @@ def lnurlpos_renderer():
return template_renderer(["lnbits/extensions/lnurlpos/templates"]) return template_renderer(["lnbits/extensions/lnurlpos/templates"])
from .views_api import * # noqa
from .views import * # noqa
from .lnurl import * # noqa from .lnurl import * # noqa
from .views import * # noqa
from .views_api import * # noqa

View file

@ -1,15 +1,14 @@
from datetime import datetime
from typing import List, Optional, Union from typing import List, Optional, Union
from lnbits.helpers import urlsafe_short_hash from lnbits.helpers import urlsafe_short_hash
from typing import List, Optional
from . import db from . import db
from .models import lnurlposs, lnurlpospayment, createLnurlpos from .models import createLnurlpos, lnurlpospayment, lnurlposs
###############lnurlposS########################## ###############lnurlposS##########################
async def create_lnurlpos(data: createLnurlpos,) -> lnurlposs: async def create_lnurlpos(data: createLnurlpos,) -> lnurlposs:
print(data)
lnurlpos_id = urlsafe_short_hash() lnurlpos_id = urlsafe_short_hash()
lnurlpos_key = urlsafe_short_hash() lnurlpos_key = urlsafe_short_hash()
await db.execute( await db.execute(
@ -60,6 +59,7 @@ async def get_lnurlposs(wallet_ids: Union[str, List[str]]) -> List[lnurlposs]:
return [lnurlposs(**row) if row else None for row in rows] return [lnurlposs(**row) if row else None for row in rows]
async def delete_lnurlpos(lnurlpos_id: str) -> None: async def delete_lnurlpos(lnurlpos_id: str) -> None:
await db.execute("DELETE FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,)) await db.execute("DELETE FROM lnurlpos.lnurlposs WHERE id = ?", (lnurlpos_id,))

View file

@ -1,30 +1,21 @@
import json
import hashlib import hashlib
import math from http import HTTPStatus
from lnurl import (
LnurlPayResponse,
LnurlPayActionResponse,
LnurlErrorResponse,
) # type: ignore
from lnurl.types import LnurlPayMetadata
from lnbits.core.services import create_invoice
from hashlib import md5
from fastapi import Request from fastapi import Request
from fastapi.param_functions import Query from fastapi.param_functions import Query
from . import lnurlpos_ext from lnurl import LnurlPayActionResponse, LnurlPayResponse # type: ignore
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse
from http import HTTPStatus from lnbits.core.services import create_invoice
from fastapi.params import Depends from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
from fastapi.param_functions import Query
from . import lnurlpos_ext
from .crud import ( from .crud import (
get_lnurlpos,
create_lnurlpospayment, create_lnurlpospayment,
get_lnurlpos,
get_lnurlpospayment, get_lnurlpospayment,
update_lnurlpospayment, update_lnurlpospayment,
) )
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
@lnurlpos_ext.get( @lnurlpos_ext.get(
@ -92,9 +83,7 @@ async def lnurl_response(
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(

View file

@ -1,16 +1,14 @@
import json import json
from lnurl import Lnurl, LnurlWithdrawResponse, encode as lnurl_encode # type: ignore
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
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
import shortuuid # type: ignore
from fastapi.param_functions import Query
from pydantic.main import BaseModel
from pydantic import BaseModel
from typing import Optional from typing import Optional
from fastapi import FastAPI, Request
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
class createLnurlpos(BaseModel): class createLnurlpos(BaseModel):

View file

@ -1,27 +1,19 @@
from http import HTTPStatus from http import HTTPStatus
import httpx
from collections import defaultdict
from lnbits.decorators import check_user_exists
from .crud import get_lnurlpos, get_lnurlpospayment from fastapi import Request
from functools import wraps from fastapi.param_functions import Query
from lnbits.core.crud import get_standalone_payment from fastapi.params import Depends
import hashlib
from lnbits.core.services import check_invoice_status
from lnbits.core.crud import update_payment_status
from lnbits.core.views.api import api_payment
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from fastapi.params import Depends
from fastapi.param_functions import Query
import random
from datetime import datetime from lnbits.core.crud import update_payment_status
from http import HTTPStatus from lnbits.core.models import User
from lnbits.core.views.api import api_payment
from lnbits.decorators import check_user_exists
from . import lnurlpos_ext, lnurlpos_renderer from . import lnurlpos_ext, lnurlpos_renderer
from lnbits.core.models import User, Payment from .crud import get_lnurlpos, get_lnurlpospayment
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")

View file

@ -32,14 +32,12 @@ async def api_list_currencies_available():
@lnurlpos_ext.post("/api/v1/lnurlpos") @lnurlpos_ext.post("/api/v1/lnurlpos")
@lnurlpos_ext.put("/api/v1/lnurlpos/{lnurlpos_id}") @lnurlpos_ext.put("/api/v1/lnurlpos/{lnurlpos_id}")
async def api_lnurlpos_create_or_update( async def api_lnurlpos_create_or_update(
request: Request,
data: createLnurlpos, data: createLnurlpos,
wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),
lnurlpos_id: str = Query(None), lnurlpos_id: str = Query(None),
): ):
if not lnurlpos_id: if not lnurlpos_id:
lnurlpos = await create_lnurlpos(data) lnurlpos = await create_lnurlpos(data)
print(lnurlpos.dict())
return lnurlpos.dict() return lnurlpos.dict()
else: else:
lnurlpos = await update_lnurlpos(data, lnurlpos_id=lnurlpos_id) lnurlpos = await update_lnurlpos(data, lnurlpos_id=lnurlpos_id)
@ -47,9 +45,7 @@ async def api_lnurlpos_create_or_update(
@lnurlpos_ext.get("/api/v1/lnurlpos") @lnurlpos_ext.get("/api/v1/lnurlpos")
async def api_lnurlposs_retrieve( async def api_lnurlposs_retrieve(wallet: WalletTypeInfo = Depends(get_key_type)):
request: Request, wallet: WalletTypeInfo = Depends(get_key_type)
):
wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids wallet_ids = (await get_user(wallet.wallet.user)).wallet_ids
try: try:
return [{**lnurlpos.dict()} for lnurlpos in await get_lnurlposs(wallet_ids)] return [{**lnurlpos.dict()} for lnurlpos in await get_lnurlposs(wallet_ids)]
@ -75,9 +71,7 @@ async def api_lnurlpos_retrieve(
@lnurlpos_ext.delete("/api/v1/lnurlpos/{lnurlpos_id}") @lnurlpos_ext.delete("/api/v1/lnurlpos/{lnurlpos_id}")
async def api_lnurlpos_delete( async def api_lnurlpos_delete(
request: Request, wallet: WalletTypeInfo = Depends(require_admin_key), lnurlpos_id: str = Query(None)
wallet: WalletTypeInfo = Depends(require_admin_key),
lnurlpos_id: str = Query(None),
): ):
lnurlpos = await get_lnurlpos(lnurlpos_id) lnurlpos = await get_lnurlpos(lnurlpos_id)

View file

@ -1,10 +1,7 @@
import asyncio from fastapi import APIRouter
from fastapi import APIRouter, FastAPI
from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart
db = Database("ext_ngrok") db = Database("ext_ngrok")

View file

@ -1,24 +1,20 @@
from http import HTTPStatus from os import getenv
from fastapi import Request
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from pyngrok import conf, ngrok
from lnbits.core.models import User
from lnbits.decorators import check_user_exists from lnbits.decorators import check_user_exists
from . import ngrok_ext, ngrok_renderer from . import ngrok_ext, ngrok_renderer
from fastapi import FastAPI, Request
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse
from lnbits.core.models import User
from os import getenv
from pyngrok import conf, ngrok
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
def log_event_callback(log): def log_event_callback(log):
string = str(log) string = str(log)
print(string)
string2 = string[string.find('url="https') : string.find('url="https') + 80] string2 = string[string.find('url="https') : string.find('url="https') + 80]
if string2: if string2:
string3 = string2 string3 = string2

View file

@ -1,6 +1,5 @@
from fastapi import APIRouter, FastAPI from fastapi import APIRouter
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
@ -15,17 +14,7 @@ offlineshop_static_files = [
} }
] ]
offlineshop_ext: APIRouter = APIRouter( offlineshop_ext: APIRouter = APIRouter(prefix="/offlineshop", tags=["Offlineshop"])
prefix="/offlineshop",
tags=["Offlineshop"],
# routes=[
# Mount(
# "/static",
# app=StaticFiles(directory="lnbits/extensions/offlineshop/static"),
# name="offlineshop_static",
# )
# ],
)
def offlineshop_renderer(): def offlineshop_renderer():

View file

@ -1,20 +1,19 @@
import hashlib import hashlib
from lnbits.extensions.offlineshop.models import Item
from fastapi.params import Query
from starlette.requests import Request from fastapi.params import Query
from lnbits.helpers import url_for from lnurl import ( # type: ignore
from lnurl import (
LnurlPayResponse,
LnurlPayActionResponse,
LnurlErrorResponse, LnurlErrorResponse,
) # type: ignore LnurlPayActionResponse,
LnurlPayResponse,
)
from starlette.requests import Request
from lnbits.core.services import create_invoice from lnbits.core.services import create_invoice
from lnbits.extensions.offlineshop.models import Item
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis from lnbits.utils.exchange_rates import fiat_amount_as_satoshis
from . import offlineshop_ext from . import offlineshop_ext
from .crud import get_shop, get_item from .crud import get_item, get_shop
@offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response") @offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response")

View file

@ -1,6 +1,3 @@
from sqlalchemy.exc import OperationalError # type: ignore
async def m001_initial(db): async def m001_initial(db):
""" """
Initial paywalls table. Initial paywalls table.

View file

@ -59,8 +59,6 @@ async def api_paywall_create_invoice(
wallet: WalletTypeInfo = Depends(get_key_type), wallet: WalletTypeInfo = Depends(get_key_type),
): ):
paywall = await get_paywall(paywall_id) paywall = await get_paywall(paywall_id)
print("PAYW", paywall)
print("DATA", data)
if data.amount < paywall.amount: if data.amount < paywall.amount:
raise HTTPException( raise HTTPException(

View file

@ -1,10 +1,7 @@
import asyncio from fastapi import APIRouter
from fastapi import APIRouter, FastAPI
from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart
db = Database("ext_satsdice") db = Database("ext_satsdice")
@ -15,11 +12,6 @@ def satsdice_renderer():
return template_renderer(["lnbits/extensions/satsdice/templates"]) return template_renderer(["lnbits/extensions/satsdice/templates"])
from .views_api import * # noqa
from .views import * # noqa
from .lnurl import * # noqa from .lnurl import * # noqa
from .views import * # noqa
from .views_api import * # noqa
# def satsdice_start():
# loop = asyncio.get_event_loop()
# loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))

View file

@ -52,7 +52,6 @@ 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) link = await get_satsdice_pay(link_id)
print(link)
if not link: if not link:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found." status_code=HTTPStatus.NOT_FOUND, detail="LNURL-pay not found."
@ -94,7 +93,6 @@ async def api_lnurlp_callback(
await create_satsdice_payment(data) 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) return json.dumps(payResponse)
@ -148,7 +146,6 @@ async def api_lnurlw_callback(
return {"status": "ERROR", "reason": "no withdraw"} return {"status": "ERROR", "reason": "no withdraw"}
if link.used: if link.used:
return {"status": "ERROR", "reason": "spent"} return {"status": "ERROR", "reason": "spent"}
print("winner")
paylink = await get_satsdice_pay(link.satsdice_pay) paylink = await get_satsdice_pay(link.satsdice_pay)
await update_satsdice_withdraw(link.id, used=1) await update_satsdice_withdraw(link.id, used=1)

View file

@ -1,10 +1,8 @@
import json import json
from sqlite3 import Row from sqlite3 import Row
from typing import Dict, NamedTuple, Optional from typing import Dict, Optional
from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
import shortuuid # type: ignore from fastapi import Request
from fastapi import FastAPI, Request
from fastapi.param_functions import Query from fastapi.param_functions import Query
from lnurl import Lnurl, LnurlWithdrawResponse from lnurl import Lnurl, LnurlWithdrawResponse
from lnurl import encode as lnurl_encode # type: ignore from lnurl import encode as lnurl_encode # type: ignore

View file

@ -1,24 +1,16 @@
import random import random
from datetime import datetime
from http import HTTPStatus from http import HTTPStatus
from fastapi import FastAPI, Request from fastapi import Request
from fastapi.param_functions import Query from fastapi.param_functions import Query
from fastapi.params import Depends from fastapi.params import Depends
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
from lnbits.core.crud import ( from lnbits.core.models import User
delete_expired_invoices,
get_balance_checks,
get_payments,
get_standalone_payment,
)
from lnbits.core.models import Payment, User
from lnbits.core.services import check_invoice_status
from lnbits.core.views.api import api_payment from lnbits.core.views.api import api_payment
from lnbits.decorators import WalletTypeInfo, check_user_exists, get_key_type from lnbits.decorators import check_user_exists
from . import satsdice_ext, satsdice_renderer from . import satsdice_ext, satsdice_renderer
from .crud import ( from .crud import (

View file

@ -7,20 +7,15 @@ from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user from lnbits.core.crud import get_user
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key from lnbits.decorators import WalletTypeInfo, get_key_type
from . import satsdice_ext from . import satsdice_ext
from .crud import ( from .crud import (
create_satsdice_pay, create_satsdice_pay,
create_satsdice_withdraw,
delete_satsdice_pay, delete_satsdice_pay,
delete_satsdice_withdraw,
get_satsdice_pay, get_satsdice_pay,
get_satsdice_pays, get_satsdice_pays,
get_satsdice_withdraw,
get_satsdice_withdraws,
update_satsdice_pay, update_satsdice_pay,
update_satsdice_withdraw,
) )
from .models import CreateSatsDiceLink, CreateSatsDiceWithdraws, satsdiceLink from .models import CreateSatsDiceLink, CreateSatsDiceWithdraws, satsdiceLink
@ -51,9 +46,7 @@ async def api_links(
@satsdice_ext.get("/api/v1/links/{link_id}") @satsdice_ext.get("/api/v1/links/{link_id}")
async def api_link_retrieve( async def api_link_retrieve(
data: CreateSatsDiceLink, link_id: str = Query(None), wallet: WalletTypeInfo = Depends(get_key_type)
link_id: str = Query(None),
wallet: WalletTypeInfo = Depends(get_key_type),
): ):
link = await get_satsdice_pay(link_id) link = await get_satsdice_pay(link_id)

View file

@ -1,5 +1,3 @@
import asyncio
from fastapi import APIRouter from fastapi import APIRouter
from lnbits.db import Database from lnbits.db import Database
@ -15,5 +13,5 @@ def satspay_renderer():
return template_renderer(["lnbits/extensions/satspay/templates"]) return template_renderer(["lnbits/extensions/satspay/templates"])
from .views_api import * # noqa
from .views import * # noqa from .views import * # noqa
from .views_api import * # noqa

View file

@ -1,16 +1,17 @@
from typing import List, Optional, Union from typing import List, Optional
import httpx
from lnbits.core.services import create_invoice
from lnbits.core.views.api import api_payment
from lnbits.helpers import urlsafe_short_hash
from ..watchonly.crud import get_fresh_address, get_mempool, get_watch_wallet
# from lnbits.db import open_ext_db # from lnbits.db import open_ext_db
from . import db from . import db
from .models import Charges, CreateCharge from .models import Charges, CreateCharge
from lnbits.helpers import urlsafe_short_hash
import httpx
from lnbits.core.services import create_invoice, check_invoice_status
from ..watchonly.crud import get_watch_wallet, get_fresh_address, get_mempool
from lnbits.core.views.api import api_payment
###############CHARGES########################## ###############CHARGES##########################

View file

@ -1,13 +1,13 @@
from fastapi.param_functions import Depends
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse
from starlette.requests import Request
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 fastapi.param_functions import Depends
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.responses import HTMLResponse
from lnbits.core.models import User
from lnbits.decorators import check_user_exists
from . import satspay_ext, satspay_renderer from . import satspay_ext, satspay_renderer
from .crud import get_charge from .crud import get_charge

View file

@ -7,7 +7,7 @@ from starlette.exceptions import HTTPException
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
from lnbits.extensions.satspay import satspay_ext from lnbits.extensions.satspay import satspay_ext
from lnbits.core.views.api import api_payment
from .crud import ( from .crud import (
check_address_balance, check_address_balance,
create_charge, create_charge,

View file

@ -1,7 +1,8 @@
import asyncio import asyncio
from fastapi import APIRouter, FastAPI
from fastapi import APIRouter
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from starlette.routing import Mount
from lnbits.db import Database from lnbits.db import Database
from lnbits.helpers import template_renderer from lnbits.helpers import template_renderer
from lnbits.tasks import catch_everything_and_restart from lnbits.tasks import catch_everything_and_restart
@ -24,13 +25,9 @@ def splitpayments_renderer():
return template_renderer(["lnbits/extensions/splitpayments/templates"]) return template_renderer(["lnbits/extensions/splitpayments/templates"])
# from lnbits.tasks import record_async
# splitpayments_ext.record(record_async(register_listeners))
from .views_api import * # noqa
from .views import * # noqa
from .tasks import wait_for_paid_invoices from .tasks import wait_for_paid_invoices
from .views import * # noqa
from .views_api import * # noqa
def splitpayments_start(): def splitpayments_start():

View file

@ -1,21 +1,15 @@
import asyncio
import json import json
from lnbits.core.models import Payment
from lnbits.core.crud import create_payment
from lnbits.core import db as core_db from lnbits.core import db as core_db
from lnbits.tasks import register_invoice_listener, internal_invoice_queue from lnbits.core.crud import create_payment
from lnbits.core.models import Payment
from lnbits.helpers import urlsafe_short_hash from lnbits.helpers import urlsafe_short_hash
from lnbits.tasks import internal_invoice_queue, register_invoice_listener
from .crud import get_targets from .crud import get_targets
import asyncio
import httpx
from lnbits.core import db as core_db
from lnbits.core.models import Payment
async def wait_for_paid_invoices(): async def wait_for_paid_invoices():
invoice_queue = asyncio.Queue() invoice_queue = asyncio.Queue()
register_invoice_listener(invoice_queue) register_invoice_listener(invoice_queue)

View file

@ -26,7 +26,6 @@ async def api_targets_set(
targets = [] targets = []
data = TargetPut.parse_obj(body["targets"]) data = TargetPut.parse_obj(body["targets"])
for entry in data.__root__: for entry in data.__root__:
print("ENTRY", entry)
wallet = await get_wallet(entry.wallet) wallet = await get_wallet(entry.wallet)
if not wallet: if not wallet:
wallet = await get_wallet_for_key(entry.wallet, "invoice") wallet = await get_wallet_for_key(entry.wallet, "invoice")

View file

@ -97,7 +97,6 @@ async def post_donation(donation_id: str) -> tuple:
} }
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
response = await client.post(url, data=data) response = await client.post(url, data=data)
print(response.json())
status = [s for s in list(HTTPStatus) if s == response.status_code][0] status = [s for s in list(HTTPStatus) if s == response.status_code][0]
elif service.servicename == "StreamElements": elif service.servicename == "StreamElements":
return {"message": "StreamElements not yet supported!"} return {"message": "StreamElements not yet supported!"}
@ -191,10 +190,8 @@ async def authenticate_service(service_id, code, redirect_uri):
"client_secret": service.client_secret, "client_secret": service.client_secret,
"redirect_uri": redirect_uri, "redirect_uri": redirect_uri,
} }
print(data)
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
response = (await client.post(url, data=data)).json() response = (await client.post(url, data=data)).json()
print(response)
token = response["access_token"] token = response["access_token"]
success = await service_add_token(service_id, token) success = await service_add_token(service_id, token)
return f"/streamalerts/?usr={user}", success return f"/streamalerts/?usr={user}", success

View file

@ -77,7 +77,6 @@ async def get_subdomainBySubdomain(subdomain: str) -> Optional[Subdomains]:
"SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.subdomain = ?", "SELECT s.*, d.domain as domain_name FROM subdomains.subdomain s INNER JOIN domain d ON (s.domain = d.id) WHERE s.subdomain = ?",
(subdomain,), (subdomain,),
) )
print(row)
return Subdomains(**row) if row else None return Subdomains(**row) if row else None

View file

@ -18,17 +18,6 @@ async def wait_for_paid_invoices():
await on_invoice_paid(payment) 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)
# await wait_for_paid_invoices(invoice_paid_chan_recv)
# async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel):
# async for payment in invoice_paid_chan:
# await on_invoice_paid(payment)
async def on_invoice_paid(payment: Payment) -> None: async def on_invoice_paid(payment: Payment) -> None:
if "lnsubdomain" != payment.extra.get("tag"): if "lnsubdomain" != payment.extra.get("tag"):
# not an lnurlp invoice # not an lnurlp invoice

View file

@ -1,11 +1,7 @@
from lnbits.extensions.subdomains.models import Subdomains
# Python3 program to validate
# domain name
# using regular expression
import re import re
import socket import socket
# Function to validate domain name. # Function to validate domain name.
def isValidDomain(str): def isValidDomain(str):
# Regex to check valid # Regex to check valid

View file

@ -1,12 +1,11 @@
from . import db
from .models import Tip, TipJar, createTip, createTipJar
from ..satspay.crud import delete_charge # type: ignore
from typing import Optional from typing import Optional
from lnbits.db import SQLITE from lnbits.db import SQLITE
from ..satspay.crud import delete_charge # type: ignore
from . import db
from .models import Tip, TipJar, createTipJar
async def create_tip( 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

View file

@ -1,6 +1,6 @@
from lnbits.core.crud import get_wallet from lnbits.core.crud import get_wallet
from .crud import get_tipjar from .crud import get_tipjar
import json
async def get_charge_details(tipjar_id): async def get_charge_details(tipjar_id):

View file

@ -1,15 +1,9 @@
import json
from lnurl import Lnurl, LnurlWithdrawResponse, encode as lnurl_encode # type: ignore
from urllib.parse import urlparse, urlunparse, parse_qs, urlencode, ParseResult
from lnurl.types import LnurlPayMetadata # type: ignore
from sqlite3 import Row from sqlite3 import Row
from typing import NamedTuple, Optional, Dict from typing import NamedTuple, Optional
import shortuuid # type: ignore
from fastapi.param_functions import Query from fastapi.param_functions import Query
from pydantic.main import BaseModel
from pydantic import BaseModel from pydantic import BaseModel
from typing import Optional, NamedTuple from pydantic.main import BaseModel
from fastapi import FastAPI, Request
class CreateCharge(BaseModel): class CreateCharge(BaseModel):

View file

@ -1,26 +1,16 @@
from .crud import get_tipjar
from http import HTTPStatus from http import HTTPStatus
import httpx
from collections import defaultdict
from lnbits.decorators import check_user_exists
from functools import wraps from fastapi import Request
import hashlib from fastapi.param_functions import Query
from lnbits.core.services import check_invoice_status from fastapi.params import Depends
from lnbits.core.crud import update_payment_status, get_standalone_payment
from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse
from fastapi.params import Depends
from fastapi.param_functions import Query
import random
from datetime import datetime from lnbits.core.models import User
from http import HTTPStatus from lnbits.decorators import check_user_exists
from . import tipjar_ext, tipjar_renderer from . import tipjar_ext, tipjar_renderer
from lnbits.core.models import User, Payment from .crud import get_tipjar
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
@ -36,7 +26,6 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
async def tip(request: Request, tipjar_id: int = Query(None)): async def tip(request: Request, tipjar_id: int = Query(None)):
"""Return the donation form for the Tipjar corresponding to id""" """Return the donation form for the Tipjar corresponding to id"""
tipjar = await get_tipjar(tipjar_id) tipjar = await get_tipjar(tipjar_id)
print(tipjar_id)
if not tipjar: if not tipjar:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="TipJar does not exist." status_code=HTTPStatus.NOT_FOUND, detail="TipJar does not exist."

View file

@ -1,30 +1,28 @@
from http import HTTPStatus from http import HTTPStatus
import json
from fastapi import Request
from fastapi.param_functions import Query from fastapi.param_functions import Query
from fastapi.params import Depends from fastapi.params import Depends
from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from lnbits.decorators import WalletTypeInfo, get_key_type
from lnbits.core.crud import get_user from lnbits.core.crud import get_user
from lnbits.decorators import WalletTypeInfo, get_key_type
from ..satspay.crud import create_charge
from . import tipjar_ext from . import tipjar_ext
from .helpers import get_charge_details
from .crud import ( from .crud import (
create_tipjar,
get_tipjar,
create_tip, create_tip,
get_tipjars, create_tipjar,
delete_tip,
delete_tipjar,
get_tip, get_tip,
get_tipjar,
get_tipjars,
get_tips, get_tips,
update_tip, update_tip,
update_tipjar, update_tipjar,
delete_tip,
delete_tipjar,
) )
from ..satspay.crud import create_charge from .helpers import get_charge_details
from .models import createTipJar, createTips, createTip, CreateCharge from .models import CreateCharge, createTipJar, createTips
@tipjar_ext.post("/api/v1/tipjars") @tipjar_ext.post("/api/v1/tipjars")
@ -54,7 +52,6 @@ async def api_create_tip(data: createTips):
webhook = tipjar.webhook webhook = tipjar.webhook
charge_details = await get_charge_details(tipjar.id) charge_details = await get_charge_details(tipjar.id)
print(charge_details["time"])
name = data.name name = data.name
# Ensure that description string can be split reliably # Ensure that description string can be split reliably
name = name.replace('"', "''") name = name.replace('"', "''")

View file

@ -29,7 +29,6 @@ async def tpos(request: Request, tpos_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist."
) )
print(request.base_url)
return tpos_renderer().TemplateResponse( return tpos_renderer().TemplateResponse(
"tpos/tpos.html", {"request": request, "tpos": tpos} "tpos/tpos.html", {"request": request, "tpos": tpos}

View file

@ -4,11 +4,11 @@ from fastapi import Query
from fastapi.params import Depends from fastapi.params import Depends
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user, get_wallet from lnbits.core.crud import get_user
from lnbits.core.services import check_invoice_status, create_invoice from lnbits.core.services import create_invoice
from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
from lnbits.core.views.api import api_payment from lnbits.core.views.api import api_payment
from lnbits.core.models import Wallet from lnbits.decorators import WalletTypeInfo, get_key_type, require_admin_key
from . import tpos_ext from . import tpos_ext
from .crud import create_tpos, delete_tpos, get_tpos, get_tposs from .crud import create_tpos, delete_tpos, get_tpos, get_tposs
from .models import CreateTposData from .models import CreateTposData
@ -43,15 +43,12 @@ async def api_tpos_delete(
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist."
) )
# return {"message": "TPoS does not exist."}, HTTPStatus.NOT_FOUND
if tpos.wallet != wallet.wallet.id: if tpos.wallet != wallet.wallet.id:
raise HTTPException(status_code=HTTPStatus.FORBIDDEN, detail="Not your TPoS.") 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) raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
# return "", HTTPStatus.NO_CONTENT
@tpos_ext.post("/api/v1/tposs/{tpos_id}/invoices", status_code=HTTPStatus.CREATED) @tpos_ext.post("/api/v1/tposs/{tpos_id}/invoices", status_code=HTTPStatus.CREATED)
@ -62,7 +59,6 @@ async def api_tpos_create_invoice(amount: int = Query(..., ge=1), tpos_id: str =
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." 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(
@ -73,7 +69,6 @@ async def api_tpos_create_invoice(amount: int = Query(..., ge=1), tpos_id: str =
) )
except Exception as e: 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 {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR
return {"payment_hash": payment_hash, "payment_request": payment_request} return {"payment_hash": payment_hash, "payment_request": payment_request}

View file

@ -39,15 +39,6 @@ async def api_usermanager_user(user_id, wallet: WalletTypeInfo = Depends(get_key
@usermanager_ext.post("/api/v1/users", status_code=HTTPStatus.CREATED) @usermanager_ext.post("/api/v1/users", status_code=HTTPStatus.CREATED)
# @api_validate_post_request(
# schema={
# "user_name": {"type": "string", "empty": False, "required": True},
# "wallet_name": {"type": "string", "empty": False, "required": True},
# "admin_id": {"type": "string", "empty": False, "required": True},
# "email": {"type": "string", "required": False},
# "password": {"type": "string", "required": False},
# }
# )
async def api_usermanager_users_create( async def api_usermanager_users_create(
data: CreateUserData, wallet: WalletTypeInfo = Depends(get_key_type) data: CreateUserData, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
@ -118,7 +109,6 @@ async def api_usermanager_wallet_transactions(
async def api_usermanager_users_wallets( async def api_usermanager_users_wallets(
user_id, wallet: WalletTypeInfo = Depends(get_key_type) user_id, wallet: WalletTypeInfo = Depends(get_key_type)
): ):
# wallet = await get_usermanager_users_wallets(user_id)
return [ return [
s_wallet.dict() for s_wallet in await get_usermanager_users_wallets(user_id) s_wallet.dict() for s_wallet in await get_usermanager_users_wallets(user_id)
] ]

View file

@ -75,7 +75,6 @@ def parse_key(masterpub: str):
async def create_watch_wallet(user: str, masterpub: str, title: str) -> Wallets: async def create_watch_wallet(user: str, masterpub: str, title: str) -> Wallets:
# check the masterpub is fine, it will raise an exception if not # check the masterpub is fine, it will raise an exception if not
print("PARSE", parse_key(masterpub))
parse_key(masterpub) parse_key(masterpub)
wallet_id = urlsafe_short_hash() wallet_id = urlsafe_short_hash()
await db.execute( await db.execute(

View file

@ -8,9 +8,6 @@ from lnbits.decorators import check_user_exists
from . import watchonly_ext, watchonly_renderer from . import watchonly_ext, watchonly_renderer
# from .crud import get_payment
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
@ -19,15 +16,3 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
return watchonly_renderer().TemplateResponse( return watchonly_renderer().TemplateResponse(
"watchonly/index.html", {"request": request, "user": user.dict()} "watchonly/index.html", {"request": request, "user": user.dict()}
) )
# @watchonly_ext.get("/{charge_id}", response_class=HTMLResponse)
# async def display(request: Request, charge_id):
# link = get_payment(charge_id)
# if not link:
# raise HTTPException(
# status_code=HTTPStatus.NOT_FOUND,
# detail="Charge link does not exist."
# )
#
# return watchonly_renderer().TemplateResponse("watchonly/display.html", {"request": request,"link": link.dict()})

View file

@ -15,11 +15,7 @@ withdraw_static_files = [
] ]
withdraw_ext: APIRouter = APIRouter( withdraw_ext: APIRouter = APIRouter(prefix="/withdraw", tags=["withdraw"])
prefix="/withdraw",
tags=["withdraw"],
# "withdraw", __name__, static_folder="static", template_folder="templates"
)
def withdraw_renderer(): def withdraw_renderer():
@ -29,7 +25,3 @@ def withdraw_renderer():
from .lnurl import * # noqa from .lnurl import * # noqa
from .views import * # noqa from .views import * # noqa
from .views_api import * # noqa from .views_api import * # noqa
# @withdraw_ext.on_event("startup")
# def _do_it():
# register_listeners()

View file

@ -22,22 +22,15 @@ from .crud import get_withdraw_link_by_hash, update_withdraw_link
name="withdraw.api_lnurl_response", name="withdraw.api_lnurl_response",
) )
async def api_lnurl_response(request: Request, unique_hash): async def api_lnurl_response(request: Request, unique_hash):
print("NOT UNIQUE")
link = await get_withdraw_link_by_hash(unique_hash) link = await get_withdraw_link_by_hash(unique_hash)
if not link: if not link:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
) )
# return ({"status": "ERROR", "reason": "LNURL-withdraw not found."},
# HTTPStatus.OK,
# )
if link.is_spent: if link.is_spent:
raise HTTPException( raise HTTPException(detail="Withdraw is spent.")
# WHAT STATUS_CODE TO USE??
detail="Withdraw is spent."
)
url = request.url_for("withdraw.api_lnurl_callback", unique_hash=link.unique_hash) url = request.url_for("withdraw.api_lnurl_callback", unique_hash=link.unique_hash)
withdrawResponse = { withdrawResponse = {
"tag": "withdrawRequest", "tag": "withdrawRequest",
@ -52,18 +45,10 @@ async def api_lnurl_response(request: Request, unique_hash):
# CALLBACK # CALLBACK
#https://5650-2001-8a0-fa12-2900-4c13-748a-fbb9-a47f.ngrok.io/withdraw/api/v1/lnurl/cb/eJHybS8hqcBWajZM63H3FP?k1=MUaYBGrUPuAs8SLpfizmCk&pr=lnbc100n1pse2tsypp5ju0yn3w9j0n8rr3squg0knddawu2ude2cgrm6zje5f34e9jzpmlsdq8w3jhxaqxqyjw5qcqpjsp5tyhu78pamqg5zfy96kup329zt40ramc8gs2ev6jxgp66zca2348qrzjqwac3nxyg3f5mfa4ke9577c4u8kvkx8pqtdsusqdfww0aymk823x6znwa5qqzyqqqyqqqqlgqqqqppgq9q9qy9qsq66zp6pctnlmk59xwtqjga5lvqrkyccmafmn43enhhc6ugew80sanxymepshpv44m9yyhfgh8r2upvxhgk00d36rpqzfy3fxemeu4jhqp96l8hx
@withdraw_ext.get("/api/v1/lnurl/cb/{unique_hash}", name="withdraw.api_lnurl_callback")
@withdraw_ext.get(
"/api/v1/lnurl/cb/{unique_hash}",
name="withdraw.api_lnurl_callback",
)
async def api_lnurl_callback( async def api_lnurl_callback(
unique_hash, unique_hash, request: Request, k1: str = Query(...), pr: str = Query(...)
request: Request,
k1: str = Query(...),
pr: str = Query(...)
): ):
link = await get_withdraw_link_by_hash(unique_hash) link = await get_withdraw_link_by_hash(unique_hash)
now = int(datetime.now().timestamp()) now = int(datetime.now().timestamp())
@ -126,7 +111,6 @@ async def api_lnurl_callback(
name="withdraw.api_lnurl_multi_response", name="withdraw.api_lnurl_multi_response",
) )
async def api_lnurl_multi_response(request: Request, unique_hash, id_unique_hash): async def api_lnurl_multi_response(request: Request, unique_hash, id_unique_hash):
print("UNIQUE")
link = await get_withdraw_link_by_hash(unique_hash) link = await get_withdraw_link_by_hash(unique_hash)
if not link: if not link:

View file

@ -18,8 +18,6 @@ templates = Jinja2Templates(directory="templates")
@withdraw_ext.get("/", response_class=HTMLResponse) @withdraw_ext.get("/", response_class=HTMLResponse)
# @validate_uuids(["usr"], required=True)
# @check_user_exists()
async def index(request: Request, user: User = Depends(check_user_exists)): async def index(request: Request, user: User = Depends(check_user_exists)):
return withdraw_renderer().TemplateResponse( return withdraw_renderer().TemplateResponse(
"withdraw/index.html", {"request": request, "user": user.dict()} "withdraw/index.html", {"request": request, "user": user.dict()}
@ -34,9 +32,6 @@ async def display(request: Request, link_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
) )
# response.status_code = HTTPStatus.NOT_FOUND
# return "Withdraw link does not exist." #probably here is where we should return the 404??
print("LINK", link)
return withdraw_renderer().TemplateResponse( return withdraw_renderer().TemplateResponse(
"withdraw/display.html", "withdraw/display.html",
{ {
@ -55,10 +50,7 @@ async def img(request: Request, link_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
) )
# response.status_code = HTTPStatus.NOT_FOUND
# return "Withdraw link does not exist."
qr = pyqrcode.create(link.lnurl(request)) qr = pyqrcode.create(link.lnurl(request))
print(qr)
stream = BytesIO() stream = BytesIO()
qr.svg(stream, scale=3) qr.svg(stream, scale=3)
stream.seek(0) stream.seek(0)
@ -102,13 +94,11 @@ async def print_qr(request: Request, link_id):
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist." status_code=HTTPStatus.NOT_FOUND, detail="Withdraw link does not exist."
) )
# response.status_code = HTTPStatus.NOT_FOUND
# return "Withdraw link does not exist."
links.append(str(linkk.lnurl(request))) links.append(str(linkk.lnurl(request)))
count = count + 1 count = count + 1
page_link = list(chunks(links, 2)) page_link = list(chunks(links, 2))
linked = list(chunks(page_link, 5)) linked = list(chunks(page_link, 5))
print("LINKED", linked)
return withdraw_renderer().TemplateResponse( return withdraw_renderer().TemplateResponse(
"withdraw/print_qr.html", {"request": request, "link": linked, "unique": True} "withdraw/print_qr.html", {"request": request, "link": linked, "unique": True}
) )

View file

@ -63,7 +63,7 @@ class LNbitsWallet(Wallet):
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
r = await client.post( r = await client.post(
url=f"{self.endpoint}/api/v1/payments", headers=self.key, json=data, url=f"{self.endpoint}/api/v1/payments", headers=self.key, json=data
) )
ok, checking_id, payment_request, error_message = ( ok, checking_id, payment_request, error_message = (
not r.is_error, not r.is_error,