diff --git a/.env.example b/.env.example index 78504b0..2b58494 100644 --- a/.env.example +++ b/.env.example @@ -4,6 +4,7 @@ CASHU_DIR=~/.cashu # WALLET +# MINT_URL=https://localhost:3338 MINT_HOST=127.0.0.1 MINT_PORT=3338 diff --git a/cashu/core/settings.py b/cashu/core/settings.py index 5a95fbf..6f98127 100644 --- a/cashu/core/settings.py +++ b/cashu/core/settings.py @@ -34,13 +34,15 @@ MINT_PRIVATE_KEY = env.str("MINT_PRIVATE_KEY", default=None) MINT_SERVER_HOST = env.str("MINT_SERVER_HOST", default="127.0.0.1") MINT_SERVER_PORT = env.int("MINT_SERVER_PORT", default=3338) +MINT_URL = env.str("MINT_URL", default=None) MINT_HOST = env.str("MINT_HOST", default="8333.space") MINT_PORT = env.int("MINT_PORT", default=3338) -if MINT_HOST in ["localhost", "127.0.0.1"]: - MINT_URL = f"http://{MINT_HOST}:{MINT_PORT}" -else: - MINT_URL = f"https://{MINT_HOST}:{MINT_PORT}" +if not MINT_URL: + if MINT_HOST in ["localhost", "127.0.0.1"]: + MINT_URL = f"http://{MINT_HOST}:{MINT_PORT}" + else: + MINT_URL = f"https://{MINT_HOST}:{MINT_PORT}" LNBITS_ENDPOINT = env.str("LNBITS_ENDPOINT", default=None) LNBITS_KEY = env.str("LNBITS_KEY", default=None) diff --git a/cashu/mint/ledger.py b/cashu/mint/ledger.py index 501eaa4..26f6ee1 100644 --- a/cashu/mint/ledger.py +++ b/cashu/mint/ledger.py @@ -187,11 +187,14 @@ class Ledger: ) return payment_request, checking_id - async def _check_lightning_invoice(self, payment_hash: str): + async def _check_lightning_invoice(self, amounts, payment_hash: str): """Checks with the Lightning backend whether an invoice with this payment_hash was paid.""" invoice: Invoice = await get_lightning_invoice(payment_hash, db=self.db) if invoice.issued: raise Exception("tokens already issued for this invoice.") + total_requested = sum([amount for amount in amounts]) + if total_requested > invoice.amount: + raise Exception(f"Requested amount too high: {total_requested}. Invoice amount: {invoice.amount}") status = await WALLET.get_invoice_status(payment_hash) if status.paid: await update_lightning_invoice(payment_hash, issued=True, db=self.db) @@ -237,9 +240,9 @@ class Ledger: # check if lightning invoice was paid if LIGHTNING: try: - paid = await self._check_lightning_invoice(payment_hash) - except: - raise Exception("could not check invoice.") + paid = await self._check_lightning_invoice(amounts, payment_hash) + except Exception as e: + raise Exception("could not check invoice: " + str(e)) if not paid: raise Exception("Lightning invoice not paid yet.") diff --git a/cashu/wallet/cli.py b/cashu/wallet/cli.py index 39086ac..b11d9b1 100755 --- a/cashu/wallet/cli.py +++ b/cashu/wallet/cli.py @@ -104,12 +104,13 @@ async def mint(ctx, amount: int, hash: str): time.sleep(3) try: await wallet.mint(amount, r["hash"]) + paid = True + print("Invoice paid.") except Exception as e: + print(str(e)) if str(e) == "Error: Lightning invoice not paid yet.": print(".", end="", flush=True) continue - paid = True - print(" Invoice paid.") elif amount and hash: await wallet.mint(amount, hash) wallet.status() diff --git a/cashu/wallet/wallet.py b/cashu/wallet/wallet.py index 719ffee..b32421a 100644 --- a/cashu/wallet/wallet.py +++ b/cashu/wallet/wallet.py @@ -45,10 +45,12 @@ class LedgerAPI: @staticmethod def _get_keys(url): - resp = requests.get(url + "/keys").json() + resp = requests.get(url + "/keys") + resp.raise_for_status() + data = resp.json() return { int(amt): PublicKey(bytes.fromhex(val), raw=True) - for amt, val in resp.items() + for amt, val in data.items() } @staticmethod @@ -88,6 +90,7 @@ class LedgerAPI: def request_mint(self, amount): """Requests a mint from the server and returns Lightning invoice.""" r = requests.get(self.url + "/mint", params={"amount": amount}) + r.raise_for_status() return r.json() @staticmethod @@ -130,13 +133,11 @@ class LedgerAPI: json=payloads.dict(), params={"payment_hash": payment_hash}, ) + resp.raise_for_status() try: promises_list = resp.json() except: - if resp.status_code >= 300: - raise Exception(f"Error: {f'mint returned {resp.status_code}'}") - else: - raise Exception("Unkown mint error.") + raise Exception("Unkown mint error.") if "error" in promises_list: raise Exception("Error: {}".format(promises_list["error"])) @@ -180,14 +181,11 @@ class LedgerAPI: self.url + "/split", json=split_payload.dict(), ) - + resp.raise_for_status() try: promises_dict = resp.json() except: - if resp.status_code >= 300: - raise Exception(f"Error: {f'mint returned {resp.status_code}'}") - else: - raise Exception("Unkown mint error.") + raise Exception("Unkown mint error.") if "error" in promises_dict: raise Exception("Mint Error: {}".format(promises_dict["error"])) promises_fst = [BlindedSignature.from_dict(p) for p in promises_dict["fst"]] @@ -204,28 +202,36 @@ class LedgerAPI: async def check_spendable(self, proofs: List[Proof]): payload = CheckRequest(proofs=proofs) - return_dict = requests.post( + resp = requests.post( self.url + "/check", json=payload.dict(), - ).json() - + ) + resp.raise_for_status() + return_dict = resp.json() + return return_dict async def check_fees(self, payment_request: str): """Checks whether the Lightning payment is internal.""" payload = CheckFeesRequest(pr=payment_request) - return_dict = requests.post( + resp = requests.post( self.url + "/checkfees", json=payload.dict(), - ).json() + ) + resp.raise_for_status() + + return_dict = resp.json() return return_dict async def pay_lightning(self, proofs: List[Proof], invoice: str): payload = MeltRequest(proofs=proofs, invoice=invoice) - return_dict = requests.post( + resp = requests.post( self.url + "/melt", json=payload.dict(), - ).json() + ) + resp.raise_for_status() + + return_dict = resp.json() return return_dict