feat: introduce self.features to wallets, refactor feature nodemanager (#3260)
This commit is contained in:
parent
256a8098c6
commit
6e9f451419
9 changed files with 36 additions and 29 deletions
|
|
@ -7,8 +7,9 @@ from pydantic import BaseModel
|
|||
from starlette.status import HTTP_503_SERVICE_UNAVAILABLE
|
||||
|
||||
from lnbits.decorators import check_admin, check_super_user, parse_filters
|
||||
from lnbits.nodes import get_node_class
|
||||
from lnbits.settings import settings
|
||||
from lnbits.wallets import get_funding_source
|
||||
from lnbits.wallets.base import Feature
|
||||
|
||||
from ...db import Filters, Page
|
||||
from ...nodes.base import (
|
||||
|
|
@ -26,9 +27,13 @@ from ...nodes.base import (
|
|||
from ...utils.cache import cache
|
||||
|
||||
|
||||
def require_node():
|
||||
node_class = get_node_class()
|
||||
if not node_class:
|
||||
def require_node() -> Node:
|
||||
funding_source = get_funding_source()
|
||||
if (
|
||||
not funding_source.features
|
||||
or Feature.nodemanager not in funding_source.features
|
||||
or not funding_source.__node_cls__
|
||||
):
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.NOT_IMPLEMENTED,
|
||||
detail="Active backend does not implement Node API",
|
||||
|
|
@ -38,7 +43,7 @@ def require_node():
|
|||
status_code=HTTPStatus.SERVICE_UNAVAILABLE,
|
||||
detail="Not enabled",
|
||||
)
|
||||
return node_class
|
||||
return funding_source.__node_cls__(funding_source)
|
||||
|
||||
|
||||
def check_public():
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ from packaging import version
|
|||
from pydantic.schema import field_schema
|
||||
|
||||
from lnbits.jinja2_templating import Jinja2Templates
|
||||
from lnbits.nodes import get_node_class
|
||||
from lnbits.settings import settings
|
||||
from lnbits.utils.crypto import AESCipher
|
||||
|
||||
|
|
@ -83,8 +82,8 @@ def template_renderer(additional_folders: Optional[list] = None) -> Jinja2Templa
|
|||
"LNBITS_CUSTOM_BADGE_COLOR": settings.lnbits_custom_badge_color,
|
||||
"LNBITS_EXTENSIONS_DEACTIVATE_ALL": settings.lnbits_extensions_deactivate_all,
|
||||
"LNBITS_NEW_ACCOUNTS_ALLOWED": settings.new_accounts_allowed,
|
||||
"LNBITS_NODE_UI": settings.lnbits_node_ui and get_node_class() is not None,
|
||||
"LNBITS_NODE_UI_AVAILABLE": get_node_class() is not None,
|
||||
"LNBITS_NODE_UI": settings.lnbits_node_ui and settings.has_nodemanager,
|
||||
"LNBITS_NODE_UI_AVAILABLE": settings.has_nodemanager,
|
||||
"LNBITS_QR_LOGO": settings.lnbits_qr_logo,
|
||||
"LNBITS_SERVICE_FEE": settings.lnbits_service_fee,
|
||||
"LNBITS_SERVICE_FEE_MAX": settings.lnbits_service_fee_max,
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
from .base import Node
|
||||
|
||||
|
||||
def get_node_class() -> Optional[Node]:
|
||||
return NODE
|
||||
|
||||
|
||||
def set_node_class(node: Node):
|
||||
global NODE
|
||||
NODE = node
|
||||
|
||||
|
||||
NODE: Optional[Node] = None
|
||||
|
|
@ -11,12 +11,12 @@ from httpx import HTTPStatusError
|
|||
from loguru import logger
|
||||
|
||||
from lnbits.db import Filters, Page
|
||||
from lnbits.nodes import Node
|
||||
from lnbits.nodes.base import (
|
||||
ChannelBalance,
|
||||
ChannelPoint,
|
||||
ChannelState,
|
||||
ChannelStats,
|
||||
Node,
|
||||
NodeChannel,
|
||||
NodeFees,
|
||||
NodeInfoResponse,
|
||||
|
|
|
|||
|
|
@ -987,6 +987,8 @@ class TransientSettings(InstalledExtensionsSettings, ExchangeHistorySettings):
|
|||
|
||||
server_startup_time: int = Field(default=time())
|
||||
|
||||
has_nodemanager: bool = Field(default=False)
|
||||
|
||||
@property
|
||||
def lnbits_server_up_time(self) -> str:
|
||||
up_time = int(time() - self.server_startup_time)
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ from __future__ import annotations
|
|||
|
||||
import importlib
|
||||
|
||||
from lnbits.nodes import set_node_class
|
||||
from lnbits.settings import settings
|
||||
from lnbits.wallets.base import Wallet
|
||||
from lnbits.wallets.base import Feature, Wallet
|
||||
|
||||
from .alby import AlbyWallet
|
||||
from .blink import BlinkWallet
|
||||
|
|
@ -35,13 +34,12 @@ from .void import VoidWallet
|
|||
from .zbd import ZBDWallet
|
||||
|
||||
|
||||
def set_funding_source(class_name: str | None = None):
|
||||
def set_funding_source(class_name: str | None = None) -> None:
|
||||
backend_wallet_class = class_name or settings.lnbits_backend_wallet_class
|
||||
funding_source_constructor = getattr(wallets_module, backend_wallet_class)
|
||||
global funding_source
|
||||
funding_source = funding_source_constructor()
|
||||
if funding_source.__node_cls__:
|
||||
set_node_class(funding_source.__node_cls__(funding_source))
|
||||
settings.has_nodemanager = funding_source.has_feature(Feature.nodemanager)
|
||||
|
||||
|
||||
def get_funding_source() -> Wallet:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
import asyncio
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import AsyncGenerator, Coroutine
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, NamedTuple
|
||||
|
||||
from loguru import logger
|
||||
|
|
@ -13,6 +14,12 @@ if TYPE_CHECKING:
|
|||
from lnbits.nodes.base import Node
|
||||
|
||||
|
||||
class Feature(Enum):
|
||||
nodemanager = "nodemanager"
|
||||
# hold = "hold"
|
||||
# bolt12 = "bolt12"
|
||||
|
||||
|
||||
class StatusResponse(NamedTuple):
|
||||
error_message: str | None
|
||||
balance_msat: int
|
||||
|
|
@ -100,6 +107,10 @@ class PaymentPendingStatus(PaymentStatus):
|
|||
class Wallet(ABC):
|
||||
|
||||
__node_cls__: type[Node] | None = None
|
||||
features: list[Feature] | None = None
|
||||
|
||||
def has_feature(self, feature: Feature) -> bool:
|
||||
return self.features is not None and feature in self.features
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.pending_invoices: list[str] = []
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from lnbits.settings import settings
|
|||
from lnbits.utils.crypto import random_secret_and_hash
|
||||
|
||||
from .base import (
|
||||
Feature,
|
||||
InvoiceResponse,
|
||||
PaymentFailedStatus,
|
||||
PaymentPendingStatus,
|
||||
|
|
@ -31,12 +32,16 @@ async def run_sync(func) -> Any:
|
|||
|
||||
|
||||
class CoreLightningWallet(Wallet):
|
||||
"""Core Lightning RPC implementation."""
|
||||
|
||||
__node_cls__ = CoreLightningNode
|
||||
features = [Feature.nodemanager]
|
||||
|
||||
async def cleanup(self):
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
|
||||
rpc = settings.corelightning_rpc or settings.clightning_rpc
|
||||
if not rpc:
|
||||
raise ValueError(
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ from lnbits.settings import settings
|
|||
from lnbits.utils.crypto import random_secret_and_hash
|
||||
|
||||
from .base import (
|
||||
Feature,
|
||||
InvoiceResponse,
|
||||
PaymentFailedStatus,
|
||||
PaymentPendingStatus,
|
||||
|
|
@ -30,6 +31,7 @@ class LndRestWallet(Wallet):
|
|||
"""https://api.lightning.community/rest/index.html#lnd-rest-api-reference"""
|
||||
|
||||
__node_cls__ = LndRestNode
|
||||
features = [Feature.nodemanager]
|
||||
|
||||
def __init__(self):
|
||||
if not settings.lnd_rest_endpoint:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue