mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 10:34:20 +01:00
refactor
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import asyncio
|
||||
from functools import partial, wraps
|
||||
from typing import List
|
||||
|
||||
from cashu.core.base import Proof
|
||||
from cashu.core.settings import LIGHTNING_FEE_PERCENT, LIGHTNING_RESERVE_FEE_MIN
|
||||
|
||||
|
||||
def sum_proofs(proofs: List[Proof]):
|
||||
return sum([p.amount for p in proofs])
|
||||
|
||||
|
||||
def async_wrap(func):
|
||||
@wraps(func)
|
||||
async def run(*args, loop=None, executor=None, **kwargs):
|
||||
|
||||
@@ -19,7 +19,7 @@ from cashu.core.base import (
|
||||
)
|
||||
from cashu.core.crypto import derive_keys, derive_keyset_id, derive_pubkeys
|
||||
from cashu.core.db import Database
|
||||
from cashu.core.helpers import fee_reserve
|
||||
from cashu.core.helpers import fee_reserve, sum_proofs
|
||||
from cashu.core.script import verify_script
|
||||
from cashu.core.secp import PublicKey
|
||||
from cashu.core.settings import LIGHTNING, MAX_ORDER
|
||||
@@ -45,6 +45,7 @@ class Ledger:
|
||||
self.db: Database = Database("mint", db)
|
||||
|
||||
async def load_used_proofs(self):
|
||||
"""Load all used proofs from database."""
|
||||
self.proofs_used = set(await get_proofs_used(db=self.db))
|
||||
|
||||
async def init_keysets(self):
|
||||
@@ -93,12 +94,8 @@ class Ledger:
|
||||
"""Checks whether the proof was already spent."""
|
||||
return not proof.secret in self.proofs_used
|
||||
|
||||
def _verify_secret_or_script(self, proof: Proof):
|
||||
if proof.secret and proof.script:
|
||||
raise Exception("secret and script present at the same time.")
|
||||
return True
|
||||
|
||||
def _verify_secret_criteria(self, proof: Proof):
|
||||
"""Verifies that a secret is present"""
|
||||
if proof.secret is None or proof.secret == "":
|
||||
raise Exception("no secret in proof.")
|
||||
return True
|
||||
@@ -213,7 +210,7 @@ class Ledger:
|
||||
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])
|
||||
total_requested = sum(amounts)
|
||||
if total_requested > invoice.amount:
|
||||
raise Exception(
|
||||
f"Requested amount too high: {total_requested}. Invoice amount: {invoice.amount}"
|
||||
@@ -287,7 +284,7 @@ class Ledger:
|
||||
if not all([self._verify_proof(p) for p in proofs]):
|
||||
raise Exception("could not verify proofs.")
|
||||
|
||||
total_provided = sum([p["amount"] for p in proofs])
|
||||
total_provided = sum_proofs(proofs)
|
||||
invoice_obj = bolt11.decode(invoice)
|
||||
amount = math.ceil(invoice_obj.amount_msat / 1000)
|
||||
fees_msat = await self.check_fees(invoice)
|
||||
@@ -319,7 +316,7 @@ class Ledger:
|
||||
self, proofs: List[Proof], amount: int, outputs: List[BlindedMessage]
|
||||
):
|
||||
"""Consumes proofs and prepares new promises based on the amount split."""
|
||||
total = sum([p.amount for p in proofs])
|
||||
total = sum_proofs(proofs)
|
||||
|
||||
# verify that amount is kosher
|
||||
self._verify_split_amount(amount)
|
||||
|
||||
@@ -81,11 +81,17 @@ async def melt(payload: MeltRequest):
|
||||
|
||||
@router.post("/check")
|
||||
async def check_spendable(payload: CheckRequest):
|
||||
"""Check whether a secret has been spent already or not."""
|
||||
return await ledger.check_spendable(payload.proofs)
|
||||
|
||||
|
||||
@router.post("/checkfees")
|
||||
async def check_fees(payload: CheckFeesRequest):
|
||||
"""
|
||||
Responds with the fees necessary to pay a Lightning invoice.
|
||||
Used by wallets for figuring out the fees they need to supply.
|
||||
This is can be useful for checking whether an invoice is internal (Cashu-to-Cashu).
|
||||
"""
|
||||
fees_msat = await ledger.check_fees(payload.pr)
|
||||
return CheckFeesResponse(fee=fees_msat / 1000)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ from loguru import logger
|
||||
import cashu.core.bolt11 as bolt11
|
||||
from cashu.core.base import Proof
|
||||
from cashu.core.bolt11 import Invoice, decode
|
||||
from cashu.core.helpers import fee_reserve
|
||||
from cashu.core.helpers import fee_reserve, sum_proofs
|
||||
from cashu.core.migrations import migrate_databases
|
||||
from cashu.core.settings import CASHU_DIR, DEBUG, ENV_FILE, LIGHTNING, MINT_URL, VERSION
|
||||
from cashu.wallet import migrations
|
||||
@@ -267,7 +267,7 @@ async def pending(ctx):
|
||||
int(grouped_proofs[0].time_reserved)
|
||||
).strftime("%Y-%m-%d %H:%M:%S")
|
||||
print(
|
||||
f"#{i} Amount: {sum([p['amount'] for p in grouped_proofs])} sat Time: {reserved_date} ID: {key}\n"
|
||||
f"#{i} Amount: {sum_proofs(grouped_proofs)} sat Time: {reserved_date} ID: {key}\n"
|
||||
)
|
||||
print(f"With secret: {coin}\n\nSecretless: {coin_hidden_secret}\n")
|
||||
print(f"--------------------------\n")
|
||||
|
||||
@@ -22,6 +22,7 @@ from cashu.core.base import (
|
||||
WalletKeyset,
|
||||
)
|
||||
from cashu.core.db import Database
|
||||
from cashu.core.helpers import sum_proofs
|
||||
from cashu.core.script import (
|
||||
step0_carol_checksig_redeemscrip,
|
||||
step0_carol_privkey,
|
||||
@@ -190,7 +191,7 @@ class LedgerAPI:
|
||||
If scnd_secret is provided, the wallet will create blinded secrets with those to attach a
|
||||
predefined spending condition to the tokens they want to send."""
|
||||
|
||||
total = sum([p["amount"] for p in proofs])
|
||||
total = sum_proofs(proofs)
|
||||
frst_amt, scnd_amt = total - amount, amount
|
||||
frst_outputs = amount_split(frst_amt)
|
||||
scnd_outputs = amount_split(scnd_amt)
|
||||
@@ -312,12 +313,6 @@ class Wallet(LedgerAPI):
|
||||
for proof in proofs:
|
||||
await store_proof(proof, db=self.db)
|
||||
|
||||
@staticmethod
|
||||
def _sum_proofs(proofs: List[Proof], available_only=False):
|
||||
if available_only:
|
||||
return sum([p.amount for p in proofs if not p.reserved])
|
||||
return sum([p.amount for p in proofs])
|
||||
|
||||
@staticmethod
|
||||
def _get_proofs_per_keyset(proofs: List[Proof]):
|
||||
return {key: list(group) for key, group in groupby(proofs, lambda p: p.id)}
|
||||
@@ -345,7 +340,7 @@ class Wallet(LedgerAPI):
|
||||
# attach unlock scripts to proofs
|
||||
for p in proofs:
|
||||
p.script = P2SHScript(script=scnd_script, signature=scnd_siganture)
|
||||
return await self.split(proofs, sum(p["amount"] for p in proofs))
|
||||
return await self.split(proofs, sum_proofs(proofs))
|
||||
|
||||
async def split(
|
||||
self,
|
||||
@@ -405,7 +400,7 @@ class Wallet(LedgerAPI):
|
||||
if scnd_secret:
|
||||
logger.debug(f"Spending conditions: {scnd_secret}")
|
||||
spendable_proofs = await self._get_spendable_proofs(proofs)
|
||||
if sum([p.amount for p in spendable_proofs]) < amount:
|
||||
if sum_proofs(spendable_proofs) < amount:
|
||||
raise Exception("balance too low.")
|
||||
return await self.split(
|
||||
[p for p in spendable_proofs if not p.reserved], amount, scnd_secret
|
||||
@@ -453,11 +448,11 @@ class Wallet(LedgerAPI):
|
||||
|
||||
@property
|
||||
def balance(self):
|
||||
return sum(p["amount"] for p in self.proofs)
|
||||
return sum_proofs(self.proofs)
|
||||
|
||||
@property
|
||||
def available_balance(self):
|
||||
return sum(p["amount"] for p in self.proofs if not p.reserved)
|
||||
return sum_proofs([p for p in self.proofs if not p.reserved])
|
||||
|
||||
def status(self):
|
||||
print(
|
||||
@@ -467,8 +462,8 @@ class Wallet(LedgerAPI):
|
||||
def balance_per_keyset(self):
|
||||
return {
|
||||
key: {
|
||||
"balance": self._sum_proofs(proofs),
|
||||
"available": self._sum_proofs(proofs, available_only=True),
|
||||
"balance": sum_proofs(proofs),
|
||||
"available": sum_proofs([p for p in proofs if not p.reserved]),
|
||||
}
|
||||
for key, proofs in self._get_proofs_per_keyset(self.proofs).items()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user