Merge pull request #21 from callebtc/validate_pay

Validate pay
This commit is contained in:
calle
2022-10-05 21:38:08 +02:00
committed by GitHub
9 changed files with 38 additions and 13 deletions

View File

@@ -153,7 +153,11 @@ class CheckRequest(BaseModel):
proofs: List[Proof] proofs: List[Proof]
class CheckInternalRequest(BaseModel):
pr: str
class MeltRequest(BaseModel): class MeltRequest(BaseModel):
proofs: List[Proof] proofs: List[Proof]
amount: int amount: int = None # deprecated
invoice: str invoice: str

View File

@@ -46,4 +46,4 @@ LNBITS_ENDPOINT = env.str("LNBITS_ENDPOINT", default=None)
LNBITS_KEY = env.str("LNBITS_KEY", default=None) LNBITS_KEY = env.str("LNBITS_KEY", default=None)
MAX_ORDER = 64 MAX_ORDER = 64
VERSION = "0.2.3" VERSION = "0.2.4"

View File

@@ -87,6 +87,8 @@ class LNbitsWallet(Wallet):
except: except:
error_message = r.json()["detail"] error_message = r.json()["detail"]
return PaymentResponse(None, None, None, None, error_message) 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(): if "detail" in r.json():
return PaymentResponse(None, None, None, None, r.json()["detail"]) return PaymentResponse(None, None, None, None, r.json()["detail"])
ok, checking_id, fee_msat, preimage, error_message = ( ok, checking_id, fee_msat, preimage, error_message = (

View File

@@ -3,11 +3,13 @@ Implementation of https://gist.github.com/phyro/935badc682057f418842c72961cf096c
""" """
import hashlib import hashlib
import math
from inspect import signature from inspect import signature
from signal import signal from signal import signal
from typing import List, Set from typing import List, Set
import cashu.core.b_dhke as b_dhke 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.base import BlindedMessage, BlindedSignature, Invoice, Proof
from cashu.core.db import Database from cashu.core.db import Database
from cashu.core.helpers import fee_reserve from cashu.core.helpers import fee_reserve
@@ -197,7 +199,7 @@ class Ledger:
async def _pay_lightning_invoice(self, invoice: str, amount: int): async def _pay_lightning_invoice(self, invoice: str, amount: int):
"""Returns an invoice from the Lightning backend.""" """Returns an invoice from the Lightning backend."""
error, balance = await WALLET.status() error, _ = await WALLET.status()
if error: if error:
raise Exception(f"Lightning wallet not responding: {error}") raise Exception(f"Lightning wallet not responding: {error}")
ok, checking_id, fee_msat, preimage, error_message = await WALLET.pay_invoice( ok, checking_id, fee_msat, preimage, error_message = await WALLET.pay_invoice(
@@ -250,10 +252,16 @@ class Ledger:
] ]
return promises 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.""" """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]) 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 # check that lightning fees are included
assert total + fee_reserve(amount * 1000) >= amount, Exception( assert total + fee_reserve(amount * 1000) >= amount, Exception(
"provided proofs not enough for Lightning payment." "provided proofs not enough for Lightning payment."

View File

@@ -62,7 +62,7 @@ async def melt(payload: MeltRequest):
""" """
Requests tokens to be destroyed and sent out via Lightning. 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) resp = GetMeltResponse(paid=ok, preimage=preimage)
return resp return resp

View File

@@ -136,7 +136,7 @@ async def pay(ctx, invoice: str):
print("Error: Balance too low.") print("Error: Balance too low.")
return return
_, send_proofs = await wallet.split_to_send(wallet.proofs, amount) _, 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() wallet.status()

View File

@@ -11,6 +11,7 @@ import cashu.core.b_dhke as b_dhke
from cashu.core.base import ( from cashu.core.base import (
BlindedMessage, BlindedMessage,
BlindedSignature, BlindedSignature,
CheckInternalRequest,
CheckRequest, CheckRequest,
MeltRequest, MeltRequest,
MintRequest, MintRequest,
@@ -210,8 +211,18 @@ class LedgerAPI:
return return_dict return return_dict
async def pay_lightning(self, proofs: List[Proof], amount: int, invoice: str): async def check_internal(self, payment_request: str):
payload = MeltRequest(proofs=proofs, amount=amount, invoice=invoice) """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( return_dict = requests.post(
self.url + "/melt", self.url + "/melt",
json=payload.dict(), json=payload.dict(),
@@ -283,9 +294,9 @@ class Wallet(LedgerAPI):
await invalidate_proof(proof, db=self.db) await invalidate_proof(proof, db=self.db)
return frst_proofs, scnd_proofs 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""" """Pays a lightning invoice"""
status = await super().pay_lightning(proofs, amount, invoice) status = await super().pay_lightning(proofs, invoice)
if status["paid"] == True: if status["paid"] == True:
await self.invalidate(proofs) await self.invalidate(proofs)
else: else:

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "cashu" name = "cashu"
version = "0.2.3" version = "0.2.4"
description = "Ecash wallet and mint." description = "Ecash wallet and mint."
authors = ["calle <callebtc@protonmail.com>"] authors = ["calle <callebtc@protonmail.com>"]
license = "MIT" license = "MIT"

View File

@@ -13,7 +13,7 @@ entry_points = {"console_scripts": ["cashu = cashu.wallet.cli:cli"]}
setuptools.setup( setuptools.setup(
name="cashu", name="cashu",
version="0.2.3", version="0.2.4",
description="Ecash wallet and mint with Bitcoin Lightning support", description="Ecash wallet and mint with Bitcoin Lightning support",
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",