WIP: New melt flow (#622)

* `PaymentResult`

* ledger: rely on PaymentResult instead of paid flag. Double check for payments marked pending.

* `None` is `PENDING`

* make format

* reflected changes API tests where `PaymentStatus` is used + reflected changes in lnbits

* reflect changes in blink backend and tests

* fix lnbits get_payment_status

* remove paid flag

* fix mypy

* remove more paid flags

* fix strike mypy

* green

* shorten all state checks

* fix

* fix some tests

* gimme 

* fix............

* fix lnbits

* fix error

* lightning refactor

* add more regtest tests

* add tests for pending state and failure

* shorten checks

* use match case for startup check - and remember modified checking_id from pay_invoice

* fix strike pending return

* new tests?

* refactor startup routine into get_melt_quote

* test with purge

* refactor blink

* cleanup responses

* blink: return checking_id on failure

* fix lndgrpc try except

* add more testing for melt branches

* speed things up a bit

* remove comments

* remove comments

* block pending melt quotes

* remove comments

---------

Co-authored-by: lollerfirst <lollerfirst@gmail.com>
This commit is contained in:
callebtc
2024-09-24 14:55:35 +02:00
committed by GitHub
parent 25f0763f94
commit d8d3037cc5
39 changed files with 1575 additions and 682 deletions

View File

@@ -80,6 +80,18 @@ class ProofState(LedgerEvent):
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
@@ -290,7 +302,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
@@ -325,7 +336,6 @@ class MeltQuote(LedgerEvent):
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,
@@ -344,17 +354,34 @@ class MeltQuote(LedgerEvent):
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)
@@ -375,8 +402,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
@@ -401,8 +426,6 @@ class MintQuote(LedgerEvent):
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,
@@ -417,24 +440,45 @@ class MintQuote(LedgerEvent):
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)