mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-21 02:54:20 +01:00
* add websockets for quote updates * add test (not working) * wip: emit events to everyone * wip: emit events to everyone * wip, lots of things broken but invoice callback works * wip * add wip files * tests almost passing * add task * refactor nut constants * startup fix * works with old mints * wip cli * fix mypy * remove automatic invoice test now with websockets * remove comment * better logging * send back response * add rate limiter to websocket * add rate limiter to subscriptions * refactor websocket ratelimit * websocket tests * subscription kinds * doesnt start * remove circular import * update * fix mypy * move test file in test because it fails if it runs later... dunno why * adjust websocket NUT-06 settings * local import and small fix * disable websockets in CLI if "no_check" is selected * move subscription test to where it was * check proof state with callback, add tests * tests: run mint fixture per module instead of per session * subscription command name fix * test per session again * update test race conditions * fix tests * clean up * tmp * fix db issues and remove cached secrets * fix tests * blindly try pipeline * remove comments * comments
135 lines
3.1 KiB
Python
135 lines
3.1 KiB
Python
from abc import ABC, abstractmethod
|
|
from typing import AsyncGenerator, Coroutine, Optional, Union
|
|
|
|
from pydantic import BaseModel
|
|
|
|
from ..core.base import (
|
|
Amount,
|
|
MeltQuote,
|
|
Unit,
|
|
)
|
|
from ..core.models import PostMeltQuoteRequest
|
|
|
|
|
|
class StatusResponse(BaseModel):
|
|
error_message: Optional[str]
|
|
balance: Union[int, float]
|
|
|
|
|
|
class InvoiceQuoteResponse(BaseModel):
|
|
checking_id: str
|
|
amount: int
|
|
|
|
|
|
class PaymentQuoteResponse(BaseModel):
|
|
checking_id: str
|
|
amount: Amount
|
|
fee: Amount
|
|
|
|
|
|
class InvoiceResponse(BaseModel):
|
|
ok: bool # True: invoice created, False: failed
|
|
checking_id: Optional[str] = None
|
|
payment_request: Optional[str] = None
|
|
error_message: Optional[str] = None
|
|
|
|
|
|
class PaymentResponse(BaseModel):
|
|
ok: Optional[bool] = None # True: paid, False: failed, None: pending or unknown
|
|
checking_id: Optional[str] = None
|
|
fee: Optional[Amount] = None
|
|
preimage: Optional[str] = None
|
|
error_message: Optional[str] = None
|
|
|
|
|
|
class PaymentStatus(BaseModel):
|
|
paid: Optional[bool] = None
|
|
fee: Optional[Amount] = None
|
|
preimage: Optional[str] = None
|
|
|
|
@property
|
|
def pending(self) -> bool:
|
|
return self.paid is not True
|
|
|
|
@property
|
|
def failed(self) -> bool:
|
|
return self.paid is False
|
|
|
|
def __str__(self) -> str:
|
|
if self.paid is True:
|
|
return "settled"
|
|
elif self.paid is False:
|
|
return "failed"
|
|
elif self.paid is None:
|
|
return "still pending"
|
|
else:
|
|
return "unknown (should never happen)"
|
|
|
|
|
|
class LightningBackend(ABC):
|
|
supports_mpp: bool = False
|
|
supports_incoming_payment_stream: bool = False
|
|
supported_units: set[Unit]
|
|
unit: Unit
|
|
|
|
def assert_unit_supported(self, unit: Unit):
|
|
if unit not in self.supported_units:
|
|
raise Unsupported(f"Unit {unit} is not supported")
|
|
|
|
@abstractmethod
|
|
def __init__(self, unit: Unit, **kwargs):
|
|
pass
|
|
|
|
@abstractmethod
|
|
def status(self) -> Coroutine[None, None, StatusResponse]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def create_invoice(
|
|
self,
|
|
amount: Amount,
|
|
memo: Optional[str] = None,
|
|
description_hash: Optional[bytes] = None,
|
|
) -> Coroutine[None, None, InvoiceResponse]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def pay_invoice(
|
|
self, quote: MeltQuote, fee_limit_msat: int
|
|
) -> Coroutine[None, None, PaymentResponse]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_invoice_status(
|
|
self, checking_id: str
|
|
) -> Coroutine[None, None, PaymentStatus]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def get_payment_status(
|
|
self, checking_id: str
|
|
) -> Coroutine[None, None, PaymentStatus]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_payment_quote(
|
|
self,
|
|
melt_quote: PostMeltQuoteRequest,
|
|
) -> PaymentQuoteResponse:
|
|
pass
|
|
|
|
# @abstractmethod
|
|
# async def get_invoice_quote(
|
|
# self,
|
|
# bolt11: str,
|
|
# ) -> InvoiceQuoteResponse:
|
|
# pass
|
|
|
|
@abstractmethod
|
|
def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
|
pass
|
|
|
|
|
|
class Unsupported(Exception):
|
|
pass
|