From b56d08a70e0c4a5866d3299e054fe95723058ef1 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Thu, 22 Dec 2022 11:12:19 +0200 Subject: [PATCH 1/3] fix: handle `extra` updates for internal payments --- lnbits/core/crud.py | 22 ++++++++++++++-------- lnbits/extensions/withdraw/lnurl.py | 5 +++-- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 7d9f2a5b..bed28111 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -452,18 +452,27 @@ async def update_payment_details( async def update_payment_extra( - payment_hash: str, + hash: str, extra: dict, + outgoing: bool = False, + incoming: bool = False, conn: Optional[Connection] = None, ) -> None: """ Only update the `extra` field for the payment. Old values in the `extra` JSON object will be kept unless the new `extra` overwrites them. """ + amount_clause = "" + + if outgoing != incoming: + if outgoing: + amount_clause = "AND amount < 0" + else: + amount_clause = "AND amount > 0" row = await (conn or db).fetchone( - "SELECT hash, extra from apipayments WHERE hash = ?", - (payment_hash,), + f"SELECT hash, extra from apipayments WHERE hash = ? {amount_clause}", + (hash,), ) if not row: return @@ -471,11 +480,8 @@ async def update_payment_extra( db_extra.update(extra) await (conn or db).execute( - """ - UPDATE apipayments SET extra = ? - WHERE hash = ? - """, - (json.dumps(db_extra), payment_hash), + f"UPDATE apipayments SET extra = ? WHERE hash = ? {amount_clause} ", + (json.dumps(db_extra), hash), ) diff --git a/lnbits/extensions/withdraw/lnurl.py b/lnbits/extensions/withdraw/lnurl.py index 7260df1e..48ccaf4a 100644 --- a/lnbits/extensions/withdraw/lnurl.py +++ b/lnbits/extensions/withdraw/lnurl.py @@ -163,12 +163,13 @@ async def api_lnurl_callback( r: httpx.Response = await client.post(link.webhook_url, **kwargs) await update_payment_extra( - payment_hash, - { + hash=payment_hash, + extra={ "wh_success": r.is_success, "wh_message": r.reason_phrase, "wh_response": r.text, }, + outgoing=True, ) except Exception as exc: # webhook fails shouldn't cause the lnurlw to fail since invoice is already paid From a434731729db18632e134fa9ccceb709f3aed3fd Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Thu, 22 Dec 2022 11:28:12 +0200 Subject: [PATCH 2/3] fix: update the rest of `update_payment_extra` calls --- lnbits/core/crud.py | 6 +++--- lnbits/extensions/lnurlp/tasks.py | 4 +++- lnbits/extensions/withdraw/lnurl.py | 7 ++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index bed28111..b38a3d14 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -452,7 +452,7 @@ async def update_payment_details( async def update_payment_extra( - hash: str, + payment_hash: str, extra: dict, outgoing: bool = False, incoming: bool = False, @@ -472,7 +472,7 @@ async def update_payment_extra( row = await (conn or db).fetchone( f"SELECT hash, extra from apipayments WHERE hash = ? {amount_clause}", - (hash,), + (payment_hash,), ) if not row: return @@ -481,7 +481,7 @@ async def update_payment_extra( await (conn or db).execute( f"UPDATE apipayments SET extra = ? WHERE hash = ? {amount_clause} ", - (json.dumps(db_extra), hash), + (json.dumps(db_extra), payment_hash), ) diff --git a/lnbits/extensions/lnurlp/tasks.py b/lnbits/extensions/lnurlp/tasks.py index 72805603..e243e1a4 100644 --- a/lnbits/extensions/lnurlp/tasks.py +++ b/lnbits/extensions/lnurlp/tasks.py @@ -67,4 +67,6 @@ async def mark_webhook_sent( payment.extra["wh_message"] = reason_phrase payment.extra["wh_response"] = text - await update_payment_extra(payment.payment_hash, payment.extra) + await update_payment_extra( + payment_hash=payment.payment_hash, extra=payment.extra, incoming=True + ) diff --git a/lnbits/extensions/withdraw/lnurl.py b/lnbits/extensions/withdraw/lnurl.py index 48ccaf4a..86640443 100644 --- a/lnbits/extensions/withdraw/lnurl.py +++ b/lnbits/extensions/withdraw/lnurl.py @@ -163,7 +163,7 @@ async def api_lnurl_callback( r: httpx.Response = await client.post(link.webhook_url, **kwargs) await update_payment_extra( - hash=payment_hash, + payment_hash=payment_hash, extra={ "wh_success": r.is_success, "wh_message": r.reason_phrase, @@ -177,8 +177,9 @@ async def api_lnurl_callback( "Caught exception when dispatching webhook url: " + str(exc) ) await update_payment_extra( - payment_hash, - {"wh_success": False, "wh_message": str(exc)}, + payment_hash=payment_hash, + extra={"wh_success": False, "wh_message": str(exc)}, + outgoing=True, ) return {"status": "OK"} From 98e0ea5ae271fd11497202ca4137bc44151b481c Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Thu, 22 Dec 2022 12:23:46 +0200 Subject: [PATCH 3/3] refactor: only use one (direction) flag for identifying payment --- lnbits/core/crud.py | 8 +------- lnbits/extensions/lnurlp/tasks.py | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index b38a3d14..a80fadf2 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -455,20 +455,14 @@ async def update_payment_extra( payment_hash: str, extra: dict, outgoing: bool = False, - incoming: bool = False, conn: Optional[Connection] = None, ) -> None: """ Only update the `extra` field for the payment. Old values in the `extra` JSON object will be kept unless the new `extra` overwrites them. """ - amount_clause = "" - if outgoing != incoming: - if outgoing: - amount_clause = "AND amount < 0" - else: - amount_clause = "AND amount > 0" + amount_clause = "AND amount < 0" if outgoing else "AND amount > 0" row = await (conn or db).fetchone( f"SELECT hash, extra from apipayments WHERE hash = ? {amount_clause}", diff --git a/lnbits/extensions/lnurlp/tasks.py b/lnbits/extensions/lnurlp/tasks.py index e243e1a4..b8da5e43 100644 --- a/lnbits/extensions/lnurlp/tasks.py +++ b/lnbits/extensions/lnurlp/tasks.py @@ -52,21 +52,29 @@ async def on_invoice_paid(payment: Payment) -> None: r: httpx.Response = await client.post(pay_link.webhook_url, **kwargs) await mark_webhook_sent( - payment, r.status_code, r.is_success, r.reason_phrase, r.text + payment.payment_hash, + r.status_code, + r.is_success, + r.reason_phrase, + r.text, ) except Exception as ex: logger.error(ex) - await mark_webhook_sent(payment, -1, False, "Unexpected Error", str(ex)) + await mark_webhook_sent( + payment.payment_hash, -1, False, "Unexpected Error", str(ex) + ) async def mark_webhook_sent( - payment: Payment, status: int, is_success: bool, reason_phrase="", text="" + payment_hash: str, status: int, is_success: bool, reason_phrase="", text="" ) -> None: - payment.extra["wh_status"] = status # keep for backwards compability - payment.extra["wh_success"] = is_success - payment.extra["wh_message"] = reason_phrase - payment.extra["wh_response"] = text await update_payment_extra( - payment_hash=payment.payment_hash, extra=payment.extra, incoming=True + payment_hash, + { + "wh_status": status, # keep for backwards compability + "wh_success": is_success, + "wh_message": reason_phrase, + "wh_response": text, + }, )