feat: update account when join invoce paid

This commit is contained in:
Vlad Stan 2023-02-13 14:12:37 +02:00
parent 330fceaf34
commit bd5957b443
7 changed files with 138 additions and 11 deletions

View file

@ -1,9 +1,10 @@
import asyncio
from fastapi import APIRouter
from fastapi.staticfiles import StaticFiles
from lnbits.db import Database
from lnbits.helpers import template_renderer
from lnbits.settings import settings
from lnbits.tasks import catch_everything_and_restart
db = Database("ext_nostrrelay")
@ -22,12 +23,10 @@ def nostrrelay_renderer():
return template_renderer(["lnbits/extensions/nostrrelay/templates"])
from .models import NostrRelay
from .tasks import wait_for_paid_invoices
from .views import * # noqa
from .views_api import * # noqa
# settings.lnbits_relay_information = {
# "name": "LNbits Nostr Relay",
# "description": "Multiple relays are supported",
# **NostrRelay.info(),
# }
def nostrrelay_start():
loop = asyncio.get_event_loop()
loop.create_task(catch_everything_and_restart(wait_for_paid_invoices))

View file

@ -11,7 +11,6 @@ from .crud import (
get_config_for_all_active_relays,
get_event,
get_events,
get_prunable_events,
get_storage_for_public_key,
mark_events_deleted,
prune_old_events,

58
crud.py
View file

@ -2,11 +2,10 @@ import json
from typing import Any, List, Optional, Tuple
from . import db
from .models import NostrEvent, NostrFilter, NostrRelay, RelayPublicSpec, RelaySpec
from .models import NostrAccount, NostrEvent, NostrFilter, NostrRelay, RelayPublicSpec, RelaySpec
########################## RELAYS ####################
async def create_relay(user_id: str, r: NostrRelay) -> NostrRelay:
await db.execute(
"""
@ -318,3 +317,58 @@ def build_select_events_query(relay_id: str, filter: NostrFilter):
query += f" LIMIT {filter.limit}"
return query, values
########################## ACCOUNTS ####################
async def create_account(relay_id: str, a: NostrAccount) -> NostrAccount:
await db.execute(
"""
INSERT INTO nostrrelay.accounts (relay_id, pubkey, sats, storage, paid_to_join, allowed, blocked)
VALUES (?, ?, ?, ?, ?, ?, ?)
""",
(
relay_id,
a.pubkey,
a.sats,
a.storage,
a.paid_to_join,
a.allowed,
a.blocked,
),
)
account = await get_account(relay_id, a.pubkey)
assert account, "Created account cannot be retrieved"
return account
async def update_account(relay_id: str, a: NostrAccount) -> NostrAccount:
await db.execute(
"""
UPDATE nostrrelay.accounts
SET (sats, storage, paid_to_join, allowed, blocked) = (?, ?, ?, ?, ?)
WHERE relay_id = ? AND pubkey = ?
""",
(
a.sats,
a.storage,
a.paid_to_join,
a.allowed,
a.blocked,
relay_id,
a.pubkey
),
)
return a
async def get_account(relay_id: str, pubkey: str,) -> Optional[NostrAccount]:
row = await db.fetchone(
"SELECT * FROM nostrrelay.accounts WHERE relay_id = ? AND pubkey = ?",
(relay_id, pubkey),
)
return NostrAccount.from_row(row) if row else None

View file

@ -45,3 +45,17 @@ async def m001_initial(db):
);
"""
)
await db.execute(
f"""
CREATE TABLE nostrrelay.accounts (
relay_id TEXT NOT NULL,
pubkey TEXT NOT NULL,
sats {db.big_int} DEFAULT 0,
storage {db.big_int} DEFAULT 0,
paid_to_join BOOLEAN DEFAULT false,
allowed BOOLEAN DEFAULT false,
blocked BOOLEAN DEFAULT false
);
"""
)

View file

@ -310,3 +310,16 @@ class NostrFilter(BaseModel):
class RelayJoin(BaseModel):
relay_id: str
pubkey: str
class NostrAccount(BaseModel):
pubkey: str
sats = 0
storage = 0
paid_to_join = False
allowed = False
blocked = False
@classmethod
def from_row(cls, row: Row) -> "NostrAccount":
return cls(**dict(row))

48
tasks.py Normal file
View file

@ -0,0 +1,48 @@
import asyncio
import re
from loguru import logger
from lnbits.core.models import Payment
from lnbits.extensions.nostrrelay.models import NostrAccount
from lnbits.helpers import get_current_extension_name
from lnbits.tasks import register_invoice_listener
from .crud import create_account, get_account, update_account
async def wait_for_paid_invoices():
invoice_queue = asyncio.Queue()
register_invoice_listener(invoice_queue, get_current_extension_name())
while True:
payment = await invoice_queue.get()
await on_invoice_paid(payment)
async def on_invoice_paid(payment: Payment):
if payment.extra.get("tag") != "nostrrely":
return
relay_id = payment.extra.get("relay_id")
pubkey = payment.extra.get("pubkey")
if payment.extra.get("action") == "join":
await invoice_paid_to_join(relay_id, pubkey)
return
async def invoice_paid_to_join(relay_id: str, pubkey: str):
try:
account = await get_account(relay_id, pubkey)
if not account:
await create_account(relay_id, NostrAccount(pubkey=pubkey, paid_to_join=True))
return
if account.blocked or account.paid_to_join:
return
account.paid_to_join = True
await update_account(relay_id, account)
except Exception as ex:
logger.warning(ex)

View file

@ -176,7 +176,7 @@ async def api_pay_to_join(data: RelayJoin):
extra={
"tag": "nostrrely",
"action": "join",
"relay": relay.id,
"relay_id": relay.id,
"pubkey": pubkey,
},
)