From b1f30390b03843e7096cf36d2f63048b45da7cb3 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Mon, 12 Oct 2020 23:18:37 -0300 Subject: [PATCH] retrieve preimage from wallet backends, save it and show on UI dialog. closes https://github.com/lnbits/lnbits/issues/77 --- lnbits/core/services.py | 15 ++++++++++----- lnbits/static/js/components.js | 4 ++++ lnbits/wallets/base.py | 1 + lnbits/wallets/clightning.py | 10 ++++++++-- lnbits/wallets/lndgrpc.py | 6 ++++-- lnbits/wallets/lndrest.py | 9 +++++---- lnbits/wallets/lnpay.py | 15 +++++++++++---- lnbits/wallets/lntxbot.py | 7 +++++-- lnbits/wallets/opennode.py | 4 ++-- lnbits/wallets/spark.py | 9 +++++---- 10 files changed, 55 insertions(+), 25 deletions(-) diff --git a/lnbits/core/services.py b/lnbits/core/services.py index d3665d55b..8bdb73aca 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -11,7 +11,7 @@ except ImportError: # pragma: nocover from lnbits import bolt11 from lnbits.helpers import urlsafe_short_hash from lnbits.settings import WALLET -from lnbits.wallets.base import PaymentStatus +from lnbits.wallets.base import PaymentStatus, PaymentResponse from .crud import get_wallet, create_payment, delete_payment, check_internal, update_payment_status, get_wallet_payment @@ -110,12 +110,17 @@ def pay_invoice( update_payment_status(checking_id=internal, pending=False) else: # actually pay the external invoice - ok, checking_id, fee_msat, error_message = WALLET.pay_invoice(payment_request) - if ok: - create_payment(checking_id=checking_id, fee=fee_msat, **payment_kwargs) + payment: PaymentResponse = WALLET.pay_invoice(payment_request) + if payment.ok: + create_payment( + checking_id=payment.checking_id, + fee=payment.fee_msat, + preimage=payment.preimage, + **payment_kwargs, + ) delete_payment(temp_id) else: - raise Exception(error_message or "Failed to pay_invoice on backend.") + raise Exception(payment.error_message or "Failed to pay_invoice on backend.") g.db.commit() return invoice.payment_hash diff --git a/lnbits/static/js/components.js b/lnbits/static/js/components.js index d8048e3ca..3d8c55474 100644 --- a/lnbits/static/js/components.js +++ b/lnbits/static/js/components.js @@ -199,6 +199,10 @@ Vue.component('lnbits-payment-details', {
Payment hash:
{{ payment.payment_hash }}
+
+
Payment proof:
+
{{ payment.preimage }}
+
` }) diff --git a/lnbits/wallets/base.py b/lnbits/wallets/base.py index d4484f37f..98f91378c 100644 --- a/lnbits/wallets/base.py +++ b/lnbits/wallets/base.py @@ -18,6 +18,7 @@ class PaymentResponse(NamedTuple): ok: bool checking_id: Optional[str] = None # payment_hash, rcp_id fee_msat: int = 0 + preimage: Optional[str] = None error_message: Optional[str] = None diff --git a/lnbits/wallets/clightning.py b/lnbits/wallets/clightning.py index e51455bf3..48d304bb6 100644 --- a/lnbits/wallets/clightning.py +++ b/lnbits/wallets/clightning.py @@ -73,8 +73,14 @@ class CLightningWallet(Wallet): return InvoiceResponse(False, label, None, error_message) def pay_invoice(self, bolt11: str) -> PaymentResponse: - r = self.ln.pay(bolt11) - return PaymentResponse(True, r["payment_hash"], r["msatoshi_sent"] - r["msatoshi"], None) + try: + r = self.ln.pay(bolt11) + except RpcError as exc: + return PaymentResponse(False, None, 0, None, str(exc)) + + fee_msat = r["msatoshi_sent"] - r["msatoshi"] + preimage = r["payment_preimage"] + return PaymentResponse(True, r["payment_hash"], fee_msat, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: r = self.ln.listinvoices(checking_id) diff --git a/lnbits/wallets/lndgrpc.py b/lnbits/wallets/lndgrpc.py index 6dc672183..d92b568f9 100644 --- a/lnbits/wallets/lndgrpc.py +++ b/lnbits/wallets/lndgrpc.py @@ -135,11 +135,13 @@ class LndWallet(Wallet): resp = self.rpc.send_payment(payment_request=bolt11) if resp.payment_error: - return PaymentResponse(False, "", 0, resp.payment_error) + return PaymentResponse(False, "", 0, None, resp.payment_error) r_hash = hashlib.sha256(resp.payment_preimage).digest() checking_id = stringify_checking_id(r_hash) - return PaymentResponse(True, checking_id, 0, None) + fee_msat = resp.payment_route.total_fees_msat + preimage = resp.payment_preimage.hex() + return PaymentResponse(True, checking_id, fee_msat, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: try: diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py index 2013a3364..6257ddec9 100644 --- a/lnbits/wallets/lndrest.py +++ b/lnbits/wallets/lndrest.py @@ -94,12 +94,13 @@ class LndRestWallet(Wallet): error_message = r.json()["error"] except: pass - return PaymentResponse(False, None, 0, error_message) + return PaymentResponse(False, None, 0, None, error_message) - payment_hash = r.json()["payment_hash"] + data = r.json() + payment_hash = data["payment_hash"] checking_id = payment_hash - - return PaymentResponse(True, checking_id, 0, None) + preimage = base64.b64decode(data["payment_preimage"]).hex() + return PaymentResponse(True, checking_id, 0, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: checking_id = checking_id.replace("_", "/") diff --git a/lnbits/wallets/lnpay.py b/lnbits/wallets/lnpay.py index 5073318a0..8b7daf5ea 100644 --- a/lnbits/wallets/lnpay.py +++ b/lnbits/wallets/lnpay.py @@ -72,12 +72,19 @@ class LNPayWallet(Wallet): headers=self.auth, json={"payment_request": bolt11}, ) - ok, checking_id, fee_msat, error_message = r.status_code == 201, None, 0, None - if ok: - checking_id = r.json()["lnTx"]["id"] + try: + data = r.json() + except: + return PaymentResponse(False, None, 0, None, f"Got invalid JSON: {r.text[:200]}") - return PaymentResponse(ok, checking_id, fee_msat, error_message) + if r.is_error: + return PaymentResponse(False, None, 0, None, data["message"]) + + checking_id = data["lnTx"]["id"] + fee_msat = 0 + preimage = data["lnTx"]["payment_preimage"] + return PaymentResponse(True, checking_id, fee_msat, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: return self.get_payment_status(checking_id) diff --git a/lnbits/wallets/lntxbot.py b/lnbits/wallets/lntxbot.py index c4ad534df..eec5e028d 100644 --- a/lnbits/wallets/lntxbot.py +++ b/lnbits/wallets/lntxbot.py @@ -67,10 +67,13 @@ class LntxbotWallet(Wallet): error_message = r.text pass - return PaymentResponse(False, None, 0, error_message) + return PaymentResponse(False, None, 0, None, error_message) data = r.json() - return PaymentResponse(True, data["decoded"]["payment_hash"], data["fee_msat"], None) + checking_id = data["payment_hash"] + fee_msat = data["fee_msat"] + preimage = data["payment_preimage"] + return PaymentResponse(True, checking_id, fee_msat, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: r = httpx.post(url=f"{self.endpoint}/invoicestatus/{checking_id}?wait=false", headers=self.auth) diff --git a/lnbits/wallets/opennode.py b/lnbits/wallets/opennode.py index 592adee14..8b772e7e4 100644 --- a/lnbits/wallets/opennode.py +++ b/lnbits/wallets/opennode.py @@ -62,12 +62,12 @@ class OpenNodeWallet(Wallet): if r.is_error: error_message = r.json()["message"] - return PaymentResponse(False, None, 0, error_message) + return PaymentResponse(False, None, 0, None, error_message) data = r.json()["data"] checking_id = data["id"] fee_msat = data["fee"] * 1000 - return PaymentResponse(True, checking_id, fee_msat, None) + return PaymentResponse(True, checking_id, fee_msat, None, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: r = httpx.get(f"{self.endpoint}/v1/charge/{checking_id}", headers=self.auth) diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index ea821ec87..bce53cd41 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -85,11 +85,12 @@ class SparkWallet(Wallet): def pay_invoice(self, bolt11: str) -> PaymentResponse: try: r = self.pay(bolt11) - ok, checking_id, fee_msat, error_message = True, r["payment_hash"], r["msatoshi_sent"] - r["msatoshi"], None - except (SparkError, UnknownError) as e: - ok, checking_id, fee_msat, error_message = False, None, None, str(e) + except (SparkError, UnknownError) as exc: + return PaymentResponse(False, None, 0, None, str(exc)) - return PaymentResponse(ok, checking_id, fee_msat, error_message) + fee_msat = r["msatoshi_sent"] - r["msatoshi"] + preimage = r["payment_preimage"] + return PaymentResponse(True, r["payment_hash"], fee_msat, preimage, None) def get_invoice_status(self, checking_id: str) -> PaymentStatus: r = self.listinvoices(label=checking_id)