From 99595ba96b3511c01ca05d6e4432472168761c15 Mon Sep 17 00:00:00 2001 From: ben Date: Sat, 27 Aug 2022 16:37:31 +0100 Subject: [PATCH] Added refunds --- lnbits/extensions/boltcards/__init__.py | 1 + lnbits/extensions/boltcards/crud.py | 44 ++++++++++++++++--- .../extensions/boltcards/static/js/index.js | 2 +- lnbits/extensions/boltcards/tasks.py | 34 ++++++++++++++ lnbits/extensions/boltcards/views_api.py | 8 +++- 5 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 lnbits/extensions/boltcards/tasks.py diff --git a/lnbits/extensions/boltcards/__init__.py b/lnbits/extensions/boltcards/__init__.py index 63b1252d..fe99ee2e 100644 --- a/lnbits/extensions/boltcards/__init__.py +++ b/lnbits/extensions/boltcards/__init__.py @@ -20,5 +20,6 @@ def boltcards_renderer(): return template_renderer(["lnbits/extensions/boltcards/templates"]) from .lnurl import * # noqa +from .tasks import * # noqa from .views import * # noqa from .views_api import * # noqa diff --git a/lnbits/extensions/boltcards/crud.py b/lnbits/extensions/boltcards/crud.py index ebcaf9d9..ab6fde09 100644 --- a/lnbits/extensions/boltcards/crud.py +++ b/lnbits/extensions/boltcards/crud.py @@ -71,12 +71,6 @@ async def get_cards(wallet_ids: Union[str, List[str]]) -> List[Card]: return [Card(**row) for row in rows] -async def get_all_cards() -> List[Card]: - rows = await db.fetchall(f"SELECT * FROM boltcards.cards") - - return [Card(**row) for row in rows] - - async def get_card(card_id: str) -> Optional[Card]: row = await db.fetchone("SELECT * FROM boltcards.cards WHERE id = ?", (card_id,)) if not row: @@ -188,3 +182,41 @@ async def create_hit(card_id, ip, useragent, old_ctr, new_ctr) -> Hit: hit = await get_hit(hit_id) assert hit, "Newly recorded hit couldn't be retrieved" return hit + +async def create_refund(hit_id, refund_amount) -> Refund: + refund_id = urlsafe_short_hash() + await db.execute( + """ + INSERT INTO boltcards.hits ( + id, + hit_id, + refund_amount, + payment_hash + ) + VALUES (?, ?, ?, ?) + """, + ( + refund_id, + hit_id, + refund_amount, + payment_hash, + ), + ) + refund = await get_refund(refund_id) + assert refund, "Newly recorded hit couldn't be retrieved" + return refund + +async def get_refund(refund_id: str) -> Optional[Refund]: + row = await db.fetchone(f"SELECT * FROM boltcards.refunds WHERE id = ?", (refund_id)) + if not row: + return None + refund = dict(**row) + return Refund.parse_obj(refund) + +async def get_refunds(hits_ids: Union[str, List[str]]) -> List[Refund]: + q = ",".join(["?"] * len(hits_ids)) + rows = await db.fetchall( + f"SELECT * FROM boltcards.refunds WHERE hit_id IN ({q})", (*hits_ids,) + ) + + return [Refund(**row) for row in rows] \ No newline at end of file diff --git a/lnbits/extensions/boltcards/static/js/index.js b/lnbits/extensions/boltcards/static/js/index.js index 7e824ea9..ceea0508 100644 --- a/lnbits/extensions/boltcards/static/js/index.js +++ b/lnbits/extensions/boltcards/static/js/index.js @@ -140,7 +140,7 @@ new Vue({ .request( 'GET', '/boltcards/api/v1/cards?all_wallets=true', - this.g.user.wallets[0].inkey + this.g.user.wallets[0].adminkey ) .then(function (response) { self.cards = response.data.map(function (obj) { diff --git a/lnbits/extensions/boltcards/tasks.py b/lnbits/extensions/boltcards/tasks.py new file mode 100644 index 00000000..30a290e9 --- /dev/null +++ b/lnbits/extensions/boltcards/tasks.py @@ -0,0 +1,34 @@ +import asyncio +import json + +import httpx + +from lnbits.core import db as core_db +from lnbits.core.models import Payment +from lnbits.tasks import register_invoice_listener + +from .crud import get_hit, create_refund + + +async def wait_for_paid_invoices(): + invoice_queue = asyncio.Queue() + register_invoice_listener(invoice_queue) + + while True: + payment = await invoice_queue.get() + await on_invoice_paid(payment) + + +async def on_invoice_paid(payment: Payment) -> None: + if payment.extra.get("tag")[0:6] != "Refund": + # not an lnurlp invoice + return + + if payment.extra.get("wh_status"): + # this webhook has already been sent + return + hit = await get_hit(payment.extra.get("tag")[7:len(payment.extra.get("tag"))]) + if hit: + refund = await create_refund(hit_id=hit.id, refund_amount=payment.extra.get("amount")) + await mark_webhook_sent(payment, 1) + diff --git a/lnbits/extensions/boltcards/views_api.py b/lnbits/extensions/boltcards/views_api.py index 4585c698..c49d20bc 100644 --- a/lnbits/extensions/boltcards/views_api.py +++ b/lnbits/extensions/boltcards/views_api.py @@ -13,7 +13,6 @@ from .crud import ( create_card, create_hit, delete_card, - get_all_cards, get_card, get_card_by_otp, get_card_by_uid, @@ -22,6 +21,7 @@ from .crud import ( update_card, update_card_counter, update_card_otp, + get_refunds, ) from .models import CreateCardData from .nxp424 import decryptSUN, getSunMAC @@ -135,5 +135,9 @@ async def api_hits( cards_ids = [] for card in cards: cards_ids.append(card.id) + hits = await get_hits(cards_ids) + hits_ids = [] + for hit in hits: + hits_ids.append(hit.id) - return [hit.dict() for hit in await get_hits(cards_ids)] \ No newline at end of file + return [refund.dict() for refund in await get_refunds(hits_ids)] \ No newline at end of file