From d8b5a6d402b70172908ca7bca356eb4c76aaf522 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 5 Oct 2022 21:20:24 +0200 Subject: [PATCH] validate pay --- cashu/core/base.py | 6 +++++- cashu/lightning/lnbits.py | 2 ++ cashu/mint/ledger.py | 15 +++++++++++---- cashu/mint/router.py | 2 +- cashu/wallet/wallet.py | 11 +++++++++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/cashu/core/base.py b/cashu/core/base.py index 63d7f5c..e30168b 100644 --- a/cashu/core/base.py +++ b/cashu/core/base.py @@ -153,7 +153,11 @@ class CheckRequest(BaseModel): proofs: List[Proof] +class CheckInternalRequest(BaseModel): + pr: str + + class MeltRequest(BaseModel): proofs: List[Proof] - amount: int + amount: int = None # deprecated invoice: str diff --git a/cashu/lightning/lnbits.py b/cashu/lightning/lnbits.py index f174f2d..0df13b2 100644 --- a/cashu/lightning/lnbits.py +++ b/cashu/lightning/lnbits.py @@ -87,6 +87,8 @@ class LNbitsWallet(Wallet): except: error_message = r.json()["detail"] return PaymentResponse(None, None, None, None, error_message) + if r.status_code != 200: + return PaymentResponse(None, None, None, None, f"HTTP status: {r.reason}") if "detail" in r.json(): return PaymentResponse(None, None, None, None, r.json()["detail"]) ok, checking_id, fee_msat, preimage, error_message = ( diff --git a/cashu/mint/ledger.py b/cashu/mint/ledger.py index 12c610d..e6b780b 100644 --- a/cashu/mint/ledger.py +++ b/cashu/mint/ledger.py @@ -6,7 +6,7 @@ import hashlib from inspect import signature from signal import signal from typing import List, Set - +import math import cashu.core.b_dhke as b_dhke from cashu.core.base import BlindedMessage, BlindedSignature, Invoice, Proof from cashu.core.db import Database @@ -24,6 +24,7 @@ from cashu.mint.crud import ( store_promise, update_lightning_invoice, ) +import cashu.core.bolt11 as bolt11 class Ledger: @@ -197,7 +198,7 @@ class Ledger: async def _pay_lightning_invoice(self, invoice: str, amount: int): """Returns an invoice from the Lightning backend.""" - error, balance = await WALLET.status() + error, _ = await WALLET.status() if error: raise Exception(f"Lightning wallet not responding: {error}") ok, checking_id, fee_msat, preimage, error_message = await WALLET.pay_invoice( @@ -250,10 +251,16 @@ class Ledger: ] return promises - async def melt(self, proofs: List[Proof], amount: int, invoice: str): + async def melt(self, proofs: List[Proof], invoice: str): """Invalidates proofs and pays a Lightning invoice.""" - # if not LIGHTNING: + # Verify proofs + if not all([self._verify_proof(p) for p in proofs]): + raise Exception("could not verify proofs.") + total = sum([p["amount"] for p in proofs]) + invoice_obj = bolt11.decode(invoice) + amount = math.ceil(invoice_obj.amount_msat / 1000) + # check that lightning fees are included assert total + fee_reserve(amount * 1000) >= amount, Exception( "provided proofs not enough for Lightning payment." diff --git a/cashu/mint/router.py b/cashu/mint/router.py index bb91695..7a0378c 100644 --- a/cashu/mint/router.py +++ b/cashu/mint/router.py @@ -62,7 +62,7 @@ async def melt(payload: MeltRequest): """ Requests tokens to be destroyed and sent out via Lightning. """ - ok, preimage = await ledger.melt(payload.proofs, payload.amount, payload.invoice) + ok, preimage = await ledger.melt(payload.proofs, payload.invoice) resp = GetMeltResponse(paid=ok, preimage=preimage) return resp diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index e7f97bb..9dcd764 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -17,6 +17,7 @@ from cashu.core.base import ( P2SHScript, Proof, SplitRequest, + CheckInternalRequest, ) from cashu.core.db import Database from cashu.core.script import ( @@ -210,6 +211,16 @@ class LedgerAPI: return return_dict + async def check_internal(self, payment_request: str): + """Checks whether the Lightning payment is internal.""" + payload = CheckInternalRequest(pr=payment_request) + return_dict = requests.post( + self.url + "/checkinternal", + json=payload.dict(), + ).json() + + return return_dict + async def pay_lightning(self, proofs: List[Proof], amount: int, invoice: str): payload = MeltRequest(proofs=proofs, amount=amount, invoice=invoice) return_dict = requests.post(