2023-09-25 15:04:44 +02:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2020-01-10 21:26:42 +01:00
|
|
|
from abc import ABC, abstractmethod
|
2023-09-25 15:04:44 +02:00
|
|
|
from typing import TYPE_CHECKING, AsyncGenerator, Coroutine, NamedTuple, Optional, Type
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from lnbits.nodes.base import Node
|
2020-01-10 21:26:42 +01:00
|
|
|
|
|
|
|
|
2020-10-12 22:25:55 -03:00
|
|
|
class StatusResponse(NamedTuple):
|
|
|
|
error_message: Optional[str]
|
|
|
|
balance_msat: int
|
|
|
|
|
|
|
|
|
2020-01-10 21:26:42 +01:00
|
|
|
class InvoiceResponse(NamedTuple):
|
2020-03-31 19:05:25 +02:00
|
|
|
ok: bool
|
|
|
|
checking_id: Optional[str] = None # payment_hash, rpc_id
|
2020-01-10 21:26:42 +01:00
|
|
|
payment_request: Optional[str] = None
|
2020-03-31 19:05:25 +02:00
|
|
|
error_message: Optional[str] = None
|
2020-01-10 21:26:42 +01:00
|
|
|
|
|
|
|
|
2020-01-16 13:58:27 +01:00
|
|
|
class PaymentResponse(NamedTuple):
|
2021-03-24 01:51:15 -03:00
|
|
|
# when ok is None it means we don't know if this succeeded
|
|
|
|
ok: Optional[bool] = None
|
2020-03-31 19:05:25 +02:00
|
|
|
checking_id: Optional[str] = None # payment_hash, rcp_id
|
2022-08-30 13:28:58 +02:00
|
|
|
fee_msat: Optional[int] = None
|
2020-10-12 23:18:37 -03:00
|
|
|
preimage: Optional[str] = None
|
2020-03-07 22:27:00 +01:00
|
|
|
error_message: Optional[str] = None
|
2020-01-16 13:58:27 +01:00
|
|
|
|
|
|
|
|
2020-03-07 22:27:00 +01:00
|
|
|
class PaymentStatus(NamedTuple):
|
|
|
|
paid: Optional[bool] = None
|
2022-08-30 13:28:58 +02:00
|
|
|
fee_msat: Optional[int] = None
|
|
|
|
preimage: Optional[str] = None
|
2020-03-07 22:27:00 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def pending(self) -> bool:
|
2024-03-24 12:58:15 +00:00
|
|
|
return self.paid is not True
|
2020-01-10 21:26:42 +01:00
|
|
|
|
2021-03-28 00:11:41 -03:00
|
|
|
@property
|
|
|
|
def failed(self) -> bool:
|
2023-01-21 15:02:35 +00:00
|
|
|
return self.paid is False
|
2021-03-28 00:11:41 -03:00
|
|
|
|
|
|
|
def __str__(self) -> str:
|
2023-01-21 15:02:35 +00:00
|
|
|
if self.paid is True:
|
2021-03-28 00:11:41 -03:00
|
|
|
return "settled"
|
2023-01-21 15:02:35 +00:00
|
|
|
elif self.paid is False:
|
2021-03-28 00:11:41 -03:00
|
|
|
return "failed"
|
2023-01-21 15:08:59 +00:00
|
|
|
elif self.paid is None:
|
2021-03-28 00:11:41 -03:00
|
|
|
return "still pending"
|
|
|
|
else:
|
|
|
|
return "unknown (should never happen)"
|
|
|
|
|
2020-01-10 21:26:42 +01:00
|
|
|
|
2024-03-13 17:17:33 +02:00
|
|
|
class PaymentSuccessStatus(PaymentStatus):
|
|
|
|
paid = True
|
|
|
|
|
|
|
|
|
|
|
|
class PaymentFailedStatus(PaymentStatus):
|
|
|
|
paid = False
|
|
|
|
|
|
|
|
|
|
|
|
class PaymentPendingStatus(PaymentStatus):
|
|
|
|
paid = None
|
|
|
|
|
|
|
|
|
2020-01-10 21:26:42 +01:00
|
|
|
class Wallet(ABC):
|
2023-06-19 12:12:00 +02:00
|
|
|
async def cleanup(self):
|
|
|
|
pass
|
|
|
|
|
2023-09-25 15:04:44 +02:00
|
|
|
__node_cls__: Optional[Type[Node]] = None
|
|
|
|
|
2020-10-12 22:25:55 -03:00
|
|
|
@abstractmethod
|
2021-03-24 01:01:09 -03:00
|
|
|
def status(self) -> Coroutine[None, None, StatusResponse]:
|
2020-10-12 22:25:55 -03:00
|
|
|
pass
|
|
|
|
|
2020-01-10 21:26:42 +01:00
|
|
|
@abstractmethod
|
2020-08-30 23:48:46 -03:00
|
|
|
def create_invoice(
|
2021-03-24 00:40:32 -03:00
|
|
|
self,
|
|
|
|
amount: int,
|
|
|
|
memo: Optional[str] = None,
|
|
|
|
description_hash: Optional[bytes] = None,
|
2023-09-25 15:04:44 +02:00
|
|
|
unhashed_description: Optional[bytes] = None,
|
2023-06-27 16:11:00 +02:00
|
|
|
**kwargs,
|
2021-03-24 01:01:09 -03:00
|
|
|
) -> Coroutine[None, None, InvoiceResponse]:
|
2020-01-10 21:26:42 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
2022-03-16 07:20:15 +01:00
|
|
|
def pay_invoice(
|
|
|
|
self, bolt11: str, fee_limit_msat: int
|
|
|
|
) -> Coroutine[None, None, PaymentResponse]:
|
2020-01-10 21:26:42 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
2021-03-24 01:01:09 -03:00
|
|
|
def get_invoice_status(
|
|
|
|
self, checking_id: str
|
|
|
|
) -> Coroutine[None, None, PaymentStatus]:
|
2020-01-10 21:26:42 +01:00
|
|
|
pass
|
|
|
|
|
|
|
|
@abstractmethod
|
2021-03-24 01:01:09 -03:00
|
|
|
def get_payment_status(
|
|
|
|
self, checking_id: str
|
|
|
|
) -> Coroutine[None, None, PaymentStatus]:
|
2020-01-10 21:26:42 +01:00
|
|
|
pass
|
2020-06-07 19:46:16 -03:00
|
|
|
|
2020-10-02 17:13:33 -03:00
|
|
|
@abstractmethod
|
|
|
|
def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
|
|
|
|
pass
|
|
|
|
|
2023-12-24 15:03:58 +01:00
|
|
|
def normalize_endpoint(self, endpoint: str, add_proto=True) -> str:
|
|
|
|
endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
|
|
|
|
if add_proto:
|
|
|
|
endpoint = (
|
|
|
|
f"https://{endpoint}" if not endpoint.startswith("http") else endpoint
|
|
|
|
)
|
|
|
|
return endpoint
|
|
|
|
|
2020-06-07 19:46:16 -03:00
|
|
|
|
|
|
|
class Unsupported(Exception):
|
|
|
|
pass
|