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/core/settings.py b/cashu/core/settings.py index 4337e9b..377e88a 100644 --- a/cashu/core/settings.py +++ b/cashu/core/settings.py @@ -46,4 +46,4 @@ LNBITS_ENDPOINT = env.str("LNBITS_ENDPOINT", default=None) LNBITS_KEY = env.str("LNBITS_KEY", default=None) MAX_ORDER = 64 -VERSION = "0.2.3" +VERSION = "0.2.4" diff --git a/cashu/lightning/lnbits.py b/cashu/lightning/lnbits.py index f174f2d..ed655bf 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 > 299: + 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..97c621f 100644 --- a/cashu/mint/ledger.py +++ b/cashu/mint/ledger.py @@ -3,11 +3,13 @@ Implementation of https://gist.github.com/phyro/935badc682057f418842c72961cf096c """ import hashlib +import math from inspect import signature from signal import signal from typing import List, Set import cashu.core.b_dhke as b_dhke +import cashu.core.bolt11 as bolt11 from cashu.core.base import BlindedMessage, BlindedSignature, Invoice, Proof from cashu.core.db import Database from cashu.core.helpers import fee_reserve @@ -197,7 +199,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 +252,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/cli.py b/cashu/wallet/cli.py index 84a9a92..f53eb78 100755 --- a/cashu/wallet/cli.py +++ b/cashu/wallet/cli.py @@ -136,7 +136,7 @@ async def pay(ctx, invoice: str): print("Error: Balance too low.") return _, send_proofs = await wallet.split_to_send(wallet.proofs, amount) - await wallet.pay_lightning(send_proofs, amount, invoice) + await wallet.pay_lightning(send_proofs, invoice) wallet.status() diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index e7f97bb..cfd6a3a 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -11,6 +11,7 @@ import cashu.core.b_dhke as b_dhke from cashu.core.base import ( BlindedMessage, BlindedSignature, + CheckInternalRequest, CheckRequest, MeltRequest, MintRequest, @@ -210,8 +211,18 @@ class LedgerAPI: return return_dict - async def pay_lightning(self, proofs: List[Proof], amount: int, invoice: str): - payload = MeltRequest(proofs=proofs, amount=amount, invoice=invoice) + 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], invoice: str): + payload = MeltRequest(proofs=proofs, invoice=invoice) return_dict = requests.post( self.url + "/melt", json=payload.dict(), @@ -283,9 +294,9 @@ class Wallet(LedgerAPI): await invalidate_proof(proof, db=self.db) return frst_proofs, scnd_proofs - async def pay_lightning(self, proofs: List[Proof], amount: int, invoice: str): + async def pay_lightning(self, proofs: List[Proof], invoice: str): """Pays a lightning invoice""" - status = await super().pay_lightning(proofs, amount, invoice) + status = await super().pay_lightning(proofs, invoice) if status["paid"] == True: await self.invalidate(proofs) else: diff --git a/pyproject.toml b/pyproject.toml index d5a6abc..c16d54e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cashu" -version = "0.2.3" +version = "0.2.4" description = "Ecash wallet and mint." authors = ["calle "] license = "MIT" diff --git a/setup.py b/setup.py index 5c04243..050b1d5 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ entry_points = {"console_scripts": ["cashu = cashu.wallet.cli:cli"]} setuptools.setup( name="cashu", - version="0.2.3", + version="0.2.4", description="Ecash wallet and mint with Bitcoin Lightning support", long_description=long_description, long_description_content_type="text/markdown",