2022-11-25 10:48:57 +02:00
|
|
|
import json
|
2021-11-25 18:52:16 +00:00
|
|
|
from typing import List, Optional
|
2021-10-14 10:02:02 +01:00
|
|
|
|
2022-11-25 10:48:57 +02:00
|
|
|
from loguru import logger
|
2021-10-14 10:02:02 +01:00
|
|
|
|
2021-11-25 18:52:16 +00:00
|
|
|
from lnbits.core.services import create_invoice
|
|
|
|
from lnbits.core.views.api import api_payment
|
2021-10-14 10:02:02 +01:00
|
|
|
from lnbits.helpers import urlsafe_short_hash
|
|
|
|
|
2022-11-26 15:27:52 +00:00
|
|
|
from ..watchonly.crud import get_config, get_fresh_address
|
2022-11-28 15:52:39 +02:00
|
|
|
from . import db
|
2022-11-25 11:25:40 +02:00
|
|
|
from .helpers import fetch_onchain_balance
|
2022-11-24 14:54:19 +00:00
|
|
|
from .models import Charges, CreateCharge, SatsPayThemes
|
|
|
|
|
2021-10-14 10:02:02 +01:00
|
|
|
###############CHARGES##########################
|
|
|
|
|
|
|
|
|
2021-10-17 18:33:29 +01:00
|
|
|
async def create_charge(user: str, data: CreateCharge) -> Charges:
|
2022-11-28 17:51:29 +02:00
|
|
|
data = CreateCharge(**data.dict())
|
2021-10-14 10:02:02 +01:00
|
|
|
charge_id = urlsafe_short_hash()
|
2021-10-14 11:45:56 +01:00
|
|
|
if data.onchainwallet:
|
2022-11-25 10:48:57 +02:00
|
|
|
config = await get_config(user)
|
|
|
|
data.extra = json.dumps(
|
|
|
|
{"mempool_endpoint": config.mempool_endpoint, "network": config.network}
|
|
|
|
)
|
2021-10-14 11:45:56 +01:00
|
|
|
onchain = await get_fresh_address(data.onchainwallet)
|
2022-12-23 22:15:32 +02:00
|
|
|
if not onchain:
|
|
|
|
raise Exception(f"Wallet '{data.onchainwallet}' can no longer be accessed.")
|
2021-10-14 10:02:02 +01:00
|
|
|
onchainaddress = onchain.address
|
|
|
|
else:
|
|
|
|
onchainaddress = None
|
2021-10-14 11:45:56 +01:00
|
|
|
if data.lnbitswallet:
|
2021-10-14 10:02:02 +01:00
|
|
|
payment_hash, payment_request = await create_invoice(
|
2021-12-29 12:57:43 +00:00
|
|
|
wallet_id=data.lnbitswallet,
|
|
|
|
amount=data.amount,
|
|
|
|
memo=charge_id,
|
|
|
|
extra={"tag": "charge"},
|
2021-10-14 10:02:02 +01:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
payment_hash = None
|
|
|
|
payment_request = None
|
|
|
|
await db.execute(
|
|
|
|
"""
|
|
|
|
INSERT INTO satspay.charges (
|
|
|
|
id,
|
|
|
|
"user",
|
|
|
|
description,
|
|
|
|
onchainwallet,
|
|
|
|
onchainaddress,
|
|
|
|
lnbitswallet,
|
|
|
|
payment_request,
|
|
|
|
payment_hash,
|
|
|
|
webhook,
|
|
|
|
completelink,
|
|
|
|
completelinktext,
|
|
|
|
time,
|
|
|
|
amount,
|
2022-11-25 10:48:57 +02:00
|
|
|
balance,
|
2022-11-24 14:54:19 +00:00
|
|
|
extra,
|
2022-11-28 16:11:05 +02:00
|
|
|
custom_css
|
2021-10-14 10:02:02 +01:00
|
|
|
)
|
2022-11-25 19:43:45 +00:00
|
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
2021-10-14 10:02:02 +01:00
|
|
|
""",
|
|
|
|
(
|
|
|
|
charge_id,
|
|
|
|
user,
|
2021-10-14 11:45:56 +01:00
|
|
|
data.description,
|
|
|
|
data.onchainwallet,
|
2021-10-14 10:02:02 +01:00
|
|
|
onchainaddress,
|
2021-10-14 11:45:56 +01:00
|
|
|
data.lnbitswallet,
|
2021-10-14 10:02:02 +01:00
|
|
|
payment_request,
|
|
|
|
payment_hash,
|
2021-10-14 11:45:56 +01:00
|
|
|
data.webhook,
|
|
|
|
data.completelink,
|
|
|
|
data.completelinktext,
|
|
|
|
data.time,
|
|
|
|
data.amount,
|
2021-10-14 10:02:02 +01:00
|
|
|
0,
|
2022-11-25 10:48:57 +02:00
|
|
|
data.extra,
|
2022-11-28 16:40:39 +02:00
|
|
|
data.custom_css,
|
2021-10-14 10:02:02 +01:00
|
|
|
),
|
|
|
|
)
|
|
|
|
return await get_charge(charge_id)
|
|
|
|
|
|
|
|
|
|
|
|
async def update_charge(charge_id: str, **kwargs) -> Optional[Charges]:
|
|
|
|
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
|
|
|
|
await db.execute(
|
|
|
|
f"UPDATE satspay.charges SET {q} WHERE id = ?", (*kwargs.values(), charge_id)
|
|
|
|
)
|
|
|
|
row = await db.fetchone("SELECT * FROM satspay.charges WHERE id = ?", (charge_id,))
|
|
|
|
return Charges.from_row(row) if row else None
|
|
|
|
|
|
|
|
|
|
|
|
async def get_charge(charge_id: str) -> Charges:
|
|
|
|
row = await db.fetchone("SELECT * FROM satspay.charges WHERE id = ?", (charge_id,))
|
|
|
|
return Charges.from_row(row) if row else None
|
|
|
|
|
|
|
|
|
|
|
|
async def get_charges(user: str) -> List[Charges]:
|
|
|
|
rows = await db.fetchall(
|
2022-07-08 15:47:28 +03:00
|
|
|
"""SELECT * FROM satspay.charges WHERE "user" = ? ORDER BY "timestamp" DESC """,
|
|
|
|
(user,),
|
2021-10-14 10:02:02 +01:00
|
|
|
)
|
|
|
|
return [Charges.from_row(row) for row in rows]
|
|
|
|
|
2022-10-24 16:38:56 +01:00
|
|
|
|
2021-10-14 10:02:02 +01:00
|
|
|
async def delete_charge(charge_id: str) -> None:
|
|
|
|
await db.execute("DELETE FROM satspay.charges WHERE id = ?", (charge_id,))
|
|
|
|
|
|
|
|
|
2022-11-24 16:55:35 +02:00
|
|
|
async def check_address_balance(charge_id: str) -> Optional[Charges]:
|
2021-10-14 10:02:02 +01:00
|
|
|
charge = await get_charge(charge_id)
|
2022-11-25 10:48:57 +02:00
|
|
|
|
2021-10-14 10:02:02 +01:00
|
|
|
if not charge.paid:
|
|
|
|
if charge.onchainaddress:
|
|
|
|
try:
|
2022-11-25 11:25:40 +02:00
|
|
|
respAmount = await fetch_onchain_balance(charge)
|
|
|
|
if respAmount > charge.balance:
|
|
|
|
await update_charge(charge_id=charge_id, balance=respAmount)
|
2022-11-25 10:48:57 +02:00
|
|
|
except Exception as e:
|
|
|
|
logger.warning(e)
|
2021-10-14 10:02:02 +01:00
|
|
|
if charge.lnbitswallet:
|
2021-10-22 00:41:30 +01:00
|
|
|
invoice_status = await api_payment(charge.payment_hash)
|
2022-01-30 19:43:30 +00:00
|
|
|
|
2021-10-22 00:41:30 +01:00
|
|
|
if invoice_status["paid"]:
|
2021-10-14 10:02:02 +01:00
|
|
|
return await update_charge(charge_id=charge_id, balance=charge.amount)
|
2022-11-24 16:55:35 +02:00
|
|
|
return await get_charge(charge_id)
|
2022-10-24 15:33:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
################## SETTINGS ###################
|
2022-11-24 14:54:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def save_theme(data: SatsPayThemes, css_id: str = None):
|
2022-10-24 15:33:49 +01:00
|
|
|
# insert or update
|
2022-11-24 14:54:19 +00:00
|
|
|
if css_id:
|
2022-10-24 15:33:49 +01:00
|
|
|
await db.execute(
|
|
|
|
"""
|
2022-11-24 14:54:19 +00:00
|
|
|
UPDATE satspay.themes SET custom_css = ?, title = ? WHERE css_id = ?
|
2022-10-24 15:33:49 +01:00
|
|
|
""",
|
2022-11-24 14:54:19 +00:00
|
|
|
(data.custom_css, data.title, css_id),
|
2022-10-24 15:33:49 +01:00
|
|
|
)
|
|
|
|
else:
|
2022-11-24 14:54:19 +00:00
|
|
|
css_id = urlsafe_short_hash()
|
2022-10-24 15:33:49 +01:00
|
|
|
await db.execute(
|
|
|
|
"""
|
2022-11-24 14:54:19 +00:00
|
|
|
INSERT INTO satspay.themes (
|
|
|
|
css_id,
|
|
|
|
title,
|
2022-11-28 10:53:16 +02:00
|
|
|
"user",
|
2022-10-24 15:33:49 +01:00
|
|
|
custom_css
|
|
|
|
)
|
2022-11-24 14:54:19 +00:00
|
|
|
VALUES (?, ?, ?, ?)
|
2022-10-24 15:33:49 +01:00
|
|
|
""",
|
|
|
|
(
|
2022-11-24 14:54:19 +00:00
|
|
|
css_id,
|
|
|
|
data.title,
|
|
|
|
data.user,
|
2022-10-24 15:33:49 +01:00
|
|
|
data.custom_css,
|
|
|
|
),
|
|
|
|
)
|
2022-11-24 14:54:19 +00:00
|
|
|
return await get_theme(css_id)
|
|
|
|
|
2022-10-25 14:30:37 +01:00
|
|
|
|
2022-11-24 14:54:19 +00:00
|
|
|
async def get_theme(css_id: str) -> SatsPayThemes:
|
|
|
|
row = await db.fetchone("SELECT * FROM satspay.themes WHERE css_id = ?", (css_id,))
|
|
|
|
return SatsPayThemes.from_row(row) if row else None
|
2022-10-25 14:30:37 +01:00
|
|
|
|
2022-11-24 14:54:19 +00:00
|
|
|
|
|
|
|
async def get_themes(user_id: str) -> List[SatsPayThemes]:
|
|
|
|
rows = await db.fetchall(
|
2022-11-28 10:53:16 +02:00
|
|
|
"""SELECT * FROM satspay.themes WHERE "user" = ? ORDER BY "title" DESC """,
|
2022-10-25 14:30:37 +01:00
|
|
|
(user_id,),
|
|
|
|
)
|
2022-11-24 14:54:19 +00:00
|
|
|
return [SatsPayThemes.from_row(row) for row in rows]
|
|
|
|
|
|
|
|
|
|
|
|
async def delete_theme(theme_id: str) -> None:
|
|
|
|
await db.execute("DELETE FROM satspay.themes WHERE css_id = ?", (theme_id,))
|