Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into dlc
Browse files Browse the repository at this point in the history
  • Loading branch information
lollerfirst committed Sep 27, 2024
2 parents cd2bf24 + d8d3037 commit c58947f
Show file tree
Hide file tree
Showing 48 changed files with 1,623 additions and 719 deletions.
74 changes: 59 additions & 15 deletions cashu/core/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ def identifier(self) -> str:
def kind(self) -> JSONRPCSubscriptionKinds:
return JSONRPCSubscriptionKinds.PROOF_STATE

@property
def unspent(self) -> bool:
return self.state == ProofSpentState.unspent

@property
def spent(self) -> bool:
return self.state == ProofSpentState.spent

@property
def pending(self) -> bool:
return self.state == ProofSpentState.pending


class HTLCWitness(BaseModel):
preimage: Optional[str] = None
Expand Down Expand Up @@ -317,7 +329,6 @@ class MeltQuote(LedgerEvent):
unit: str
amount: int
fee_reserve: int
paid: bool
state: MeltQuoteState
created_time: Union[int, None] = None
paid_time: Union[int, None] = None
Expand Down Expand Up @@ -352,7 +363,6 @@ def from_row(cls, row: Row):
unit=row["unit"],
amount=row["amount"],
fee_reserve=row["fee_reserve"],
paid=row["paid"],
state=MeltQuoteState[row["state"]],
created_time=created_time,
paid_time=paid_time,
Expand All @@ -371,17 +381,34 @@ def identifier(self) -> str:
def kind(self) -> JSONRPCSubscriptionKinds:
return JSONRPCSubscriptionKinds.BOLT11_MELT_QUOTE

@property
def unpaid(self) -> bool:
return self.state == MeltQuoteState.unpaid

@property
def pending(self) -> bool:
return self.state == MeltQuoteState.pending

@property
def paid(self) -> bool:
return self.state == MeltQuoteState.paid

# method that is invoked when the `state` attribute is changed. to protect the state from being set to anything else if the current state is paid
def __setattr__(self, name, value):
# an unpaid quote can only be set to pending or paid
if name == "state" and self.state == MeltQuoteState.unpaid:
if name == "state" and self.unpaid:
if value not in [MeltQuoteState.pending, MeltQuoteState.paid]:
raise Exception(
f"Cannot change state of an unpaid melt quote to {value}."
)
# a paid quote can not be changed
if name == "state" and self.state == MeltQuoteState.paid:
if name == "state" and self.paid:
raise Exception("Cannot change state of a paid melt quote.")

if name == "paid":
raise Exception(
"MeltQuote does not support `paid` anymore! Use `state` instead."
)
super().__setattr__(name, value)


Expand All @@ -402,8 +429,6 @@ class MintQuote(LedgerEvent):
checking_id: str
unit: str
amount: int
paid: bool
issued: bool
state: MintQuoteState
created_time: Union[int, None] = None
paid_time: Union[int, None] = None
Expand All @@ -428,8 +453,6 @@ def from_row(cls, row: Row):
checking_id=row["checking_id"],
unit=row["unit"],
amount=row["amount"],
paid=row["paid"],
issued=row["issued"],
state=MintQuoteState[row["state"]],
created_time=created_time,
paid_time=paid_time,
Expand All @@ -444,24 +467,45 @@ def identifier(self) -> str:
def kind(self) -> JSONRPCSubscriptionKinds:
return JSONRPCSubscriptionKinds.BOLT11_MINT_QUOTE

@property
def unpaid(self) -> bool:
return self.state == MintQuoteState.unpaid

@property
def paid(self) -> bool:
return self.state == MintQuoteState.paid

@property
def pending(self) -> bool:
return self.state == MintQuoteState.pending

@property
def issued(self) -> bool:
return self.state == MintQuoteState.issued

def __setattr__(self, name, value):
# un unpaid quote can only be set to paid
if name == "state" and self.state == MintQuoteState.unpaid:
if name == "state" and self.unpaid:
if value != MintQuoteState.paid:
raise Exception(
f"Cannot change state of an unpaid mint quote to {value}."
)
# a paid quote can only be set to pending or issued
if name == "state" and self.state == MintQuoteState.paid:
if name == "state" and self.paid:
if value != MintQuoteState.pending and value != MintQuoteState.issued:
raise Exception(f"Cannot change state of a paid mint quote to {value}.")
# a pending quote can only be set to paid or issued
if name == "state" and self.state == MintQuoteState.pending:
if name == "state" and self.pending:
if value not in [MintQuoteState.paid, MintQuoteState.issued]:
raise Exception("Cannot change state of a pending mint quote.")
# an issued quote cannot be changed
if name == "state" and self.state == MintQuoteState.issued:
if name == "state" and self.issued:
raise Exception("Cannot change state of an issued mint quote.")

if name == "paid":
raise Exception(
"MintQuote does not support `paid` anymore! Use `state` instead."
)
super().__setattr__(name, value)


Expand Down Expand Up @@ -866,15 +910,15 @@ def amount(self) -> int:

@property
def keysets(self) -> List[str]:
return list(set([p.id for p in self.proofs]))
return list({p.id for p in self.proofs})

@property
def mint(self) -> str:
return self.mints[0]

@property
def mints(self) -> List[str]:
return list(set([t.mint for t in self.token if t.mint]))
return list({t.mint for t in self.token if t.mint})

@property
def memo(self) -> Optional[str]:
Expand Down Expand Up @@ -1070,7 +1114,7 @@ def dlc_root(self) -> Optional[str]:

@property
def keysets(self) -> List[str]:
return list(set([p.i.hex() for p in self.t]))
return list({p.i.hex() for p in self.t})

@classmethod
def from_tokenv3(cls, tokenv3: TokenV3):
Expand Down
2 changes: 1 addition & 1 deletion cashu/core/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
def amount_summary(proofs: List[Proof], unit: Unit) -> str:
amounts_we_have = [
(amount, len([p for p in proofs if p.amount == amount]))
for amount in set([p.amount for p in proofs])
for amount in {p.amount for p in proofs}
]
amounts_we_have.sort(key=lambda x: x[0])
return (
Expand Down
14 changes: 12 additions & 2 deletions cashu/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
# ------- API: INFO -------


class MintMeltMethodSetting(BaseModel):
class MintMethodSetting(BaseModel):
method: str
unit: str
min_amount: Optional[int] = None
max_amount: Optional[int] = None
description: Optional[bool] = None


class MeltMethodSetting(BaseModel):
method: str
unit: str
min_amount: Optional[int] = None
Expand Down Expand Up @@ -213,7 +221,7 @@ class PostMeltQuoteResponse(BaseModel):
fee_reserve: int # input fee reserve
paid: Optional[
bool
] # whether the request has been paid # DEPRECATED as per NUT PR #136
] = None # whether the request has been paid # DEPRECATED as per NUT PR #136
state: Optional[str] # state of the quote
expiry: Optional[int] # expiry of the quote
payment_preimage: Optional[str] = None # payment preimage
Expand All @@ -224,6 +232,8 @@ def from_melt_quote(self, melt_quote: MeltQuote) -> "PostMeltQuoteResponse":
to_dict = melt_quote.dict()
# turn state into string
to_dict["state"] = melt_quote.state.value
# add deprecated "paid" field
to_dict["paid"] = melt_quote.paid
return PostMeltQuoteResponse.parse_obj(to_dict)


Expand Down
3 changes: 2 additions & 1 deletion cashu/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ class FakeWalletSettings(MintSettings):
fakewallet_delay_outgoing_payment: Optional[float] = Field(default=3.0)
fakewallet_delay_incoming_payment: Optional[float] = Field(default=3.0)
fakewallet_stochastic_invoice: bool = Field(default=False)
fakewallet_payment_state: Optional[bool] = Field(default=None)
fakewallet_payment_state: Optional[str] = Field(default="SETTLED")
fakewallet_pay_invoice_state: Optional[str] = Field(default="SETTLED")


class MintInformation(CashuSettings):
Expand Down
64 changes: 53 additions & 11 deletions cashu/lightning/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
from enum import Enum, auto
from typing import AsyncGenerator, Coroutine, Optional, Union

from pydantic import BaseModel
Expand All @@ -12,8 +13,8 @@


class StatusResponse(BaseModel):
error_message: Optional[str]
balance: Union[int, float]
error_message: Optional[str] = None


class InvoiceQuoteResponse(BaseModel):
Expand All @@ -34,36 +35,77 @@ class InvoiceResponse(BaseModel):
error_message: Optional[str] = None


class PaymentResult(Enum):
SETTLED = auto()
FAILED = auto()
PENDING = auto()
UNKNOWN = auto()

def __str__(self):
return self.name


class PaymentResponse(BaseModel):
ok: Optional[bool] = None # True: paid, False: failed, None: pending or unknown
result: PaymentResult
checking_id: Optional[str] = None
fee: Optional[Amount] = None
preimage: Optional[str] = None
error_message: Optional[str] = None

@property
def pending(self) -> bool:
return self.result == PaymentResult.PENDING

@property
def settled(self) -> bool:
return self.result == PaymentResult.SETTLED

@property
def failed(self) -> bool:
return self.result == PaymentResult.FAILED

@property
def unknown(self) -> bool:
return self.result == PaymentResult.UNKNOWN


class PaymentStatus(BaseModel):
paid: Optional[bool] = None
result: PaymentResult
fee: Optional[Amount] = None
preimage: Optional[str] = None
error_message: Optional[str] = None

@property
def pending(self) -> bool:
return self.paid is not True
return self.result == PaymentResult.PENDING

@property
def settled(self) -> bool:
return self.result == PaymentResult.SETTLED

@property
def failed(self) -> bool:
return self.paid is False
return self.result == PaymentResult.FAILED

@property
def unknown(self) -> bool:
return self.result == PaymentResult.UNKNOWN

def __str__(self) -> str:
if self.paid is True:
return "settled"
elif self.paid is False:
if self.result == PaymentResult.SETTLED:
return (
"settled"
+ (f" (preimage: {self.preimage})" if self.preimage else "")
+ (f" (fee: {self.fee})" if self.fee else "")
)
elif self.result == PaymentResult.FAILED:
return "failed"
elif self.paid is None:
elif self.result == PaymentResult.PENDING:
return "still pending"
else:
return "unknown (should never happen)"
else: # self.result == PaymentResult.UNKNOWN:
return "unknown" + (
f" (Error: {self.error_message})" if self.error_message else ""
)


class LightningBackend(ABC):
Expand Down
Loading

0 comments on commit c58947f

Please sign in to comment.