diff --git a/lnbits/core/templates/node/_tab_channels.html b/lnbits/core/templates/node/_tab_channels.html
new file mode 100644
index 000000000..d20109a4e
--- /dev/null
+++ b/lnbits/core/templates/node/_tab_channels.html
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Channels
+
+
+
+ Open channel
+
+
+ {% raw %}
+
+
+
+
+
+
+
+
+
+
+
+ {{props.row.name}}
+
+
+ {{ props.row.short_id }}
+
+
+
+ {{ states.find(s => s.value == props.row.state)?.label
+ }}
+
+
+
+
+
+
+
+
+
+ {% endraw %}
+
+
+
+
+
+
+ {% raw %}
+
+
Peers
+
+
+ Connect Peer
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.row.alias }}
+
+
+
+ #{{ props.row.color }}
+
+
+ {{ shortenNodeId(props.row.id) }}
+
+
+
+
+
+
+ Open channel
+
+
+
+
+
+
+
+ {% endraw %}
+
+
+
+
+
+
diff --git a/lnbits/core/templates/node/_tab_dashboard.html b/lnbits/core/templates/node/_tab_dashboard.html
new file mode 100644
index 000000000..3fa8ba022
--- /dev/null
+++ b/lnbits/core/templates/node/_tab_dashboard.html
@@ -0,0 +1,70 @@
+
+
+ {% raw %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% endraw %}
+
+
diff --git a/lnbits/core/templates/node/_tab_transactions.html b/lnbits/core/templates/node/_tab_transactions.html
new file mode 100644
index 000000000..2743ff278
--- /dev/null
+++ b/lnbits/core/templates/node/_tab_transactions.html
@@ -0,0 +1,316 @@
+
+
+
+
+
+ {% raw %}
+
+
+
+
+
+
+
:
+
+ {{ transactionDetailsDialog.data.payment_hash }}
+
+
+
+
:
+
+ {{ transactionDetailsDialog.data.preimage }}
+
+
+
+
+
+
+ {% endraw %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% raw %}
+
+
+
+
+ Pending
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ props.row.destination?.alias }}
+
+
+
+
+
+
+
+
+ {% endraw %}
+
+
+
+
+
+
+
+
+
+
+ {% raw %}
+
+
+
+
+ Pending
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% endraw %}
+
+
+
+
+
+
+
diff --git a/lnbits/core/templates/node/index.html b/lnbits/core/templates/node/index.html
new file mode 100644
index 000000000..e1b0f6a44
--- /dev/null
+++ b/lnbits/core/templates/node/index.html
@@ -0,0 +1,500 @@
+{% extends "base.html" %} {% from "macros.jinja" import window_vars with context
+%} {% block page %}
+
+
+
+
+
+
+
+
+
+
+
+ tab = val.name"
+ >
+ tab = val.name"
+ >
+ tab = val.name"
+ >
+
+
+
+
+
+
+ {% include "node/_tab_dashboard.html" %} {% include
+ "node/_tab_channels.html" %} {% include "node/_tab_transactions.html"
+ %}
+
+
+
+
+
+
+{% endblock %} {% block scripts %} {{ window_vars(user) }}
+
+
+
+{% endblock %}
diff --git a/lnbits/core/templates/node/public.html b/lnbits/core/templates/node/public.html
new file mode 100644
index 000000000..957a2c19a
--- /dev/null
+++ b/lnbits/core/templates/node/public.html
@@ -0,0 +1,143 @@
+{% extends "public.html" %} {% from "macros.jinja" import window_vars with
+context %} {% block page %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %} {% block scripts %} {{ window_vars(user) }}
+
+
+
+{% endblock %}
diff --git a/lnbits/core/views/admin_api.py b/lnbits/core/views/admin_api.py
index 3f6a38944..6eecdb94c 100644
--- a/lnbits/core/views/admin_api.py
+++ b/lnbits/core/views/admin_api.py
@@ -48,7 +48,7 @@ async def api_auditor():
)
-@admin_router.get("/admin/api/v1/settings/")
+@admin_router.get("/admin/api/v1/settings/", response_model=Optional[AdminSettings])
async def api_get_settings(
user: User = Depends(check_admin),
) -> Optional[AdminSettings]:
diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py
index ecad18cf6..ce109ca6e 100644
--- a/lnbits/core/views/generic.py
+++ b/lnbits/core/views/generic.py
@@ -425,6 +425,44 @@ async def manifest(request: Request, usr: str):
}
+@generic_router.get("/node", response_class=HTMLResponse)
+async def node(request: Request, user: User = Depends(check_admin)):
+ if not settings.lnbits_node_ui:
+ raise HTTPException(status_code=HTTPStatus.SERVICE_UNAVAILABLE)
+
+ WALLET = get_wallet_class()
+ _, balance = await WALLET.status()
+
+ return template_renderer().TemplateResponse(
+ "node/index.html",
+ {
+ "request": request,
+ "user": user.dict(),
+ "settings": settings.dict(),
+ "balance": balance,
+ "wallets": user.wallets[0].dict(),
+ },
+ )
+
+
+@generic_router.get("/node/public", response_class=HTMLResponse)
+async def node_public(request: Request):
+ if not settings.lnbits_public_node_ui:
+ raise HTTPException(status_code=HTTPStatus.SERVICE_UNAVAILABLE)
+
+ WALLET = get_wallet_class()
+ _, balance = await WALLET.status()
+
+ return template_renderer().TemplateResponse(
+ "node/public.html",
+ {
+ "request": request,
+ "settings": settings.dict(),
+ "balance": balance,
+ },
+ )
+
+
@generic_router.get("/admin", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_admin)):
if not settings.lnbits_admin_ui:
diff --git a/lnbits/core/views/node_api.py b/lnbits/core/views/node_api.py
new file mode 100644
index 000000000..b9acc9e30
--- /dev/null
+++ b/lnbits/core/views/node_api.py
@@ -0,0 +1,188 @@
+from http import HTTPStatus
+from typing import List, Optional
+
+import httpx
+from fastapi import APIRouter, Body, Depends, HTTPException
+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 ...db import Filters, Page
+from ...nodes.base import (
+ ChannelPoint,
+ Node,
+ NodeChannel,
+ NodeInfoResponse,
+ NodeInvoice,
+ NodeInvoiceFilters,
+ NodePayment,
+ NodePaymentsFilters,
+ NodePeerInfo,
+ PublicNodeInfo,
+)
+from ...utils.cache import cache
+
+
+def require_node():
+ NODE = get_node_class()
+ if not NODE:
+ raise HTTPException(
+ status_code=HTTPStatus.NOT_IMPLEMENTED,
+ detail="Active backend does not implement Node API",
+ )
+ if not settings.lnbits_node_ui:
+ raise HTTPException(
+ status_code=HTTPStatus.SERVICE_UNAVAILABLE,
+ detail="Not enabled",
+ )
+ return NODE
+
+
+def check_public():
+ if not (settings.lnbits_node_ui and settings.lnbits_public_node_ui):
+ raise HTTPException(
+ status_code=HTTPStatus.SERVICE_UNAVAILABLE,
+ detail="Not enabled",
+ )
+
+
+node_router = APIRouter(prefix="/node/api/v1", dependencies=[Depends(check_admin)])
+super_node_router = APIRouter(
+ prefix="/node/api/v1", dependencies=[Depends(check_super_user)]
+)
+public_node_router = APIRouter(
+ prefix="/node/public/api/v1", dependencies=[Depends(check_public)]
+)
+
+
+@node_router.get(
+ "/ok",
+ description="Check if node api can be enabled",
+ status_code=200,
+ dependencies=[Depends(require_node)],
+)
+async def api_get_ok():
+ pass
+
+
+@public_node_router.get("/info", response_model=PublicNodeInfo)
+async def api_get_public_info(node: Node = Depends(require_node)) -> PublicNodeInfo:
+ return await cache.save_result(node.get_public_info, key="node:public_info")
+
+
+@node_router.get("/info")
+async def api_get_info(
+ node: Node = Depends(require_node),
+) -> Optional[NodeInfoResponse]:
+ return await node.get_info()
+
+
+@node_router.get("/channels")
+async def api_get_channels(
+ node: Node = Depends(require_node),
+) -> Optional[List[NodeChannel]]:
+ return await node.get_channels()
+
+
+@super_node_router.post("/channels", response_model=ChannelPoint)
+async def api_create_channel(
+ node: Node = Depends(require_node),
+ peer_id: str = Body(),
+ funding_amount: int = Body(),
+ push_amount: Optional[int] = Body(None),
+ fee_rate: Optional[int] = Body(None),
+):
+ return await node.open_channel(peer_id, funding_amount, push_amount, fee_rate)
+
+
+@super_node_router.delete("/channels")
+async def api_delete_channel(
+ short_id: Optional[str],
+ funding_txid: Optional[str],
+ output_index: Optional[int],
+ force: bool = False,
+ node: Node = Depends(require_node),
+) -> Optional[List[NodeChannel]]:
+ return await node.close_channel(
+ short_id,
+ ChannelPoint(funding_txid=funding_txid, output_index=output_index)
+ if funding_txid is not None and output_index is not None
+ else None,
+ force,
+ )
+
+
+@node_router.get("/payments", response_model=Page[NodePayment])
+async def api_get_payments(
+ node: Node = Depends(require_node),
+ filters: Filters = Depends(parse_filters(NodePaymentsFilters)),
+) -> Optional[Page[NodePayment]]:
+ if not settings.lnbits_node_ui_transactions:
+ raise HTTPException(
+ HTTP_503_SERVICE_UNAVAILABLE,
+ detail="You can enable node transactions in the Admin UI",
+ )
+ return await node.get_payments(filters)
+
+
+@node_router.get("/invoices", response_model=Page[NodeInvoice])
+async def api_get_invoices(
+ node: Node = Depends(require_node),
+ filters: Filters = Depends(parse_filters(NodeInvoiceFilters)),
+) -> Optional[Page[NodeInvoice]]:
+ if not settings.lnbits_node_ui_transactions:
+ raise HTTPException(
+ HTTP_503_SERVICE_UNAVAILABLE,
+ detail="You can enable node transactions in the Admin UI",
+ )
+ return await node.get_invoices(filters)
+
+
+@node_router.get("/peers", response_model=List[NodePeerInfo])
+async def api_get_peers(node: Node = Depends(require_node)) -> List[NodePeerInfo]:
+ return await node.get_peers()
+
+
+@super_node_router.post("/peers")
+async def api_connect_peer(
+ uri: str = Body(embed=True), node: Node = Depends(require_node)
+):
+ return await node.connect_peer(uri)
+
+
+@super_node_router.delete("/peers/{peer_id}")
+async def api_disconnect_peer(peer_id: str, node: Node = Depends(require_node)):
+ return await node.disconnect_peer(peer_id)
+
+
+class NodeRank(BaseModel):
+ capacity: Optional[int]
+ channelcount: Optional[int]
+ age: Optional[int]
+ growth: Optional[int]
+ availability: Optional[int]
+
+
+# Same for public and private api
+@node_router.get(
+ "/rank",
+ description="Retrieve node ranks from https://1ml.com",
+ response_model=Optional[NodeRank],
+)
+@public_node_router.get(
+ "/rank",
+ description="Retrieve node ranks from https://1ml.com",
+ response_model=Optional[NodeRank],
+)
+async def api_get_1ml_stats(node: Node = Depends(require_node)) -> Optional[NodeRank]:
+ node_id = await node.get_id()
+ async with httpx.AsyncClient() as client:
+ r = await client.get(url=f"https://1ml.com/node/{node_id}/json", timeout=15)
+ try:
+ r.raise_for_status()
+ return r.json()["noderank"]
+ except httpx.HTTPStatusError:
+ raise HTTPException(status_code=404, detail="Node not found on 1ml.com")
diff --git a/lnbits/helpers.py b/lnbits/helpers.py
index 8cc82d563..b803857cd 100644
--- a/lnbits/helpers.py
+++ b/lnbits/helpers.py
@@ -7,6 +7,7 @@ import shortuuid
from pydantic.schema import field_schema
from lnbits.jinja2_templating import Jinja2Templates
+from lnbits.nodes import get_node_class
from lnbits.requestvars import g
from lnbits.settings import settings
@@ -51,6 +52,10 @@ def template_renderer(additional_folders: Optional[List] = None) -> Jinja2Templa
t.env.globals["COMMIT_VERSION"] = settings.lnbits_commit
t.env.globals["LNBITS_VERSION"] = settings.version
t.env.globals["LNBITS_ADMIN_UI"] = settings.lnbits_admin_ui
+ t.env.globals["LNBITS_NODE_UI"] = (
+ settings.lnbits_node_ui and get_node_class() is not None
+ )
+ t.env.globals["LNBITS_NODE_UI_AVAILABLE"] = get_node_class() is not None
t.env.globals["EXTENSIONS"] = [
e
for e in get_valid_extensions()
diff --git a/lnbits/nodes/__init__.py b/lnbits/nodes/__init__.py
new file mode 100644
index 000000000..f341d04a0
--- /dev/null
+++ b/lnbits/nodes/__init__.py
@@ -0,0 +1,15 @@
+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
diff --git a/lnbits/nodes/base.py b/lnbits/nodes/base.py
new file mode 100644
index 000000000..5b58517e6
--- /dev/null
+++ b/lnbits/nodes/base.py
@@ -0,0 +1,223 @@
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+from enum import Enum
+from typing import TYPE_CHECKING, List, Optional
+
+from pydantic import BaseModel
+
+from lnbits.db import FilterModel, Filters, Page
+from lnbits.utils.cache import cache
+
+if TYPE_CHECKING:
+ from lnbits.wallets.base import Wallet
+
+
+class NodePeerInfo(BaseModel):
+ id: str
+ alias: Optional[str] = None
+ color: Optional[str] = None
+ last_timestamp: Optional[int] = None
+ addresses: Optional[list[str]] = None
+
+
+class ChannelState(Enum):
+ ACTIVE = "active"
+ PENDING = "pending"
+ CLOSED = "closed"
+ INACTIVE = "inactive"
+
+
+class ChannelBalance(BaseModel):
+ local_msat: int
+ remote_msat: int
+ total_msat: int
+
+
+class ChannelPoint(BaseModel):
+ funding_txid: str
+ output_index: int
+
+
+class NodeChannel(BaseModel):
+ short_id: Optional[str] = None
+ point: Optional[ChannelPoint] = None
+ peer_id: str
+ balance: ChannelBalance
+ state: ChannelState
+ name: Optional[str]
+ color: Optional[str]
+
+
+class ChannelStats(BaseModel):
+ counts: dict[ChannelState, int]
+ avg_size: int
+ biggest_size: Optional[int]
+ smallest_size: Optional[int]
+ total_capacity: int
+
+ @classmethod
+ def from_list(cls, channels: list[NodeChannel]):
+ counts: dict[ChannelState, int] = {}
+ for channel in channels:
+ counts[channel.state] = counts.get(channel.state, 0) + 1
+
+ return cls(
+ counts=counts,
+ avg_size=int(
+ sum(channel.balance.total_msat for channel in channels) / len(channels)
+ ),
+ biggest_size=max(channel.balance.total_msat for channel in channels),
+ smallest_size=min(channel.balance.total_msat for channel in channels),
+ total_capacity=sum(channel.balance.total_msat for channel in channels),
+ )
+
+
+class NodeFees(BaseModel):
+ total_msat: int
+ daily_msat: Optional[int] = None
+ weekly_msat: Optional[int] = None
+ monthly_msat: Optional[int] = None
+
+
+class PublicNodeInfo(BaseModel):
+ id: str
+ backend_name: str
+ alias: str
+ color: str
+ num_peers: int
+ blockheight: int
+ channel_stats: ChannelStats
+ addresses: list[str]
+
+
+class NodeInfoResponse(PublicNodeInfo):
+ onchain_balance_sat: int
+ onchain_confirmed_sat: int
+ fees: NodeFees
+ balance_msat: int
+
+
+class NodePayment(BaseModel):
+ pending: bool
+ amount: int
+ fee: Optional[int] = None
+ memo: Optional[str] = None
+ time: int
+ bolt11: str
+ preimage: Optional[str]
+ payment_hash: str
+ expiry: Optional[float] = None
+ destination: Optional[NodePeerInfo] = None
+
+
+class NodeInvoice(BaseModel):
+ pending: bool
+ amount: int
+ memo: Optional[str]
+ bolt11: str
+ preimage: Optional[str]
+ payment_hash: str
+ paid_at: Optional[int] = None
+ expiry: Optional[int] = None
+
+
+class NodeInvoiceFilters(FilterModel):
+ pass
+
+
+class NodePaymentsFilters(FilterModel):
+ pass
+
+
+class Node(ABC):
+ wallet: Wallet
+
+ def __init__(self, wallet: Wallet):
+ self.wallet = wallet
+ self.id: Optional[str] = None
+
+ @property
+ def name(self):
+ return self.__class__.__name__
+
+ async def get_id(self):
+ if not self.id:
+ self.id = await self._get_id()
+ return self.id
+
+ @abstractmethod
+ async def _get_id(self) -> str:
+ pass
+
+ async def get_peers(self) -> list[NodePeerInfo]:
+ peer_ids = await self.get_peer_ids()
+ return [await self.get_peer_info(peer_id) for peer_id in peer_ids]
+
+ @abstractmethod
+ async def get_peer_ids(self) -> list[str]:
+ pass
+
+ @abstractmethod
+ async def connect_peer(self, uri: str):
+ pass
+
+ @abstractmethod
+ async def disconnect_peer(self, peer_id: str):
+ pass
+
+ @abstractmethod
+ async def _get_peer_info(self, peer_id: str) -> NodePeerInfo:
+ pass
+
+ async def get_peer_info(self, peer_id: str) -> NodePeerInfo:
+ key = f"node:peers:{peer_id}"
+ info = cache.get(key)
+ if not info:
+ info = await self._get_peer_info(peer_id)
+ if info.last_timestamp:
+ cache.set(key, info)
+ return info
+
+ @abstractmethod
+ async def open_channel(
+ self,
+ peer_id: str,
+ local_amount: int,
+ push_amount: Optional[int] = None,
+ fee_rate: Optional[int] = None,
+ ) -> ChannelPoint:
+ pass
+
+ @abstractmethod
+ async def close_channel(
+ self,
+ short_id: Optional[str] = None,
+ point: Optional[ChannelPoint] = None,
+ force: bool = False,
+ ):
+ pass
+
+ @abstractmethod
+ async def get_channels(self) -> List[NodeChannel]:
+ pass
+
+ @abstractmethod
+ async def get_info(self) -> NodeInfoResponse:
+ pass
+
+ async def get_public_info(self) -> PublicNodeInfo:
+ info = await self.get_info()
+ return PublicNodeInfo(**info.__dict__)
+
+ @abstractmethod
+ async def get_payments(
+ self, filters: Filters[NodePaymentsFilters]
+ ) -> Page[NodePayment]:
+ pass
+
+ @abstractmethod
+ async def get_invoices(
+ self, filters: Filters[NodeInvoiceFilters]
+ ) -> Page[NodeInvoice]:
+ pass
diff --git a/lnbits/nodes/cln.py b/lnbits/nodes/cln.py
new file mode 100644
index 000000000..e55c9b163
--- /dev/null
+++ b/lnbits/nodes/cln.py
@@ -0,0 +1,323 @@
+from __future__ import annotations
+
+import asyncio
+from http import HTTPStatus
+from typing import TYPE_CHECKING, List, Optional
+
+from fastapi import HTTPException
+
+from lnbits.db import Filters, Page
+
+from ..utils.cache import cache
+
+try:
+ from pyln.client import RpcError # type: ignore
+
+ if TYPE_CHECKING:
+ # override the false type
+ class RpcError(RpcError): # type: ignore
+ error: dict
+
+except ImportError: # pragma: nocover
+ LightningRpc = None
+
+from lnbits.nodes.base import (
+ ChannelBalance,
+ ChannelPoint,
+ ChannelState,
+ ChannelStats,
+ Node,
+ NodeFees,
+ NodeInvoice,
+ NodeInvoiceFilters,
+ NodePaymentsFilters,
+ NodePeerInfo,
+)
+
+from .base import NodeChannel, NodeInfoResponse, NodePayment
+
+if TYPE_CHECKING:
+ from lnbits.wallets import CoreLightningWallet
+
+
+def catch_rpc_errors(f):
+ async def wrapper(*args, **kwargs):
+ try:
+ return await f(*args, **kwargs)
+ except RpcError as e:
+ if e.error["code"] == -32602:
+ raise HTTPException(status_code=400, detail=e.error["message"])
+ else:
+ raise HTTPException(status_code=500, detail=e.error["message"])
+
+ return wrapper
+
+
+class CoreLightningNode(Node):
+ wallet: CoreLightningWallet
+
+ async def ln_rpc(self, method, *args, **kwargs) -> dict:
+ loop = asyncio.get_event_loop()
+ fn = getattr(self.wallet.ln, method)
+ return await loop.run_in_executor(None, lambda: fn(*args, **kwargs))
+
+ @catch_rpc_errors
+ async def connect_peer(self, uri: str):
+ # https://docs.corelightning.org/reference/lightning-connect
+ try:
+ await self.ln_rpc("connect", uri)
+ except RpcError as e:
+ if e.error["code"] == 400:
+ raise HTTPException(HTTPStatus.BAD_REQUEST, detail=e.error["message"])
+ else:
+ raise
+
+ @catch_rpc_errors
+ async def disconnect_peer(self, peer_id: str):
+ try:
+ await self.ln_rpc("disconnect", peer_id)
+ except RpcError as e:
+ if e.error["code"] == -1:
+ raise HTTPException(
+ HTTPStatus.BAD_REQUEST,
+ detail=e.error["message"],
+ )
+ else:
+ raise
+
+ @catch_rpc_errors
+ async def open_channel(
+ self,
+ peer_id: str,
+ local_amount: int,
+ push_amount: Optional[int] = None,
+ fee_rate: Optional[int] = None,
+ ) -> ChannelPoint:
+ try:
+ result = await self.ln_rpc(
+ "fundchannel",
+ peer_id,
+ amount=local_amount,
+ push_msat=int(push_amount * 1000) if push_amount else None,
+ feerate=fee_rate,
+ )
+ return ChannelPoint(
+ funding_txid=result["txid"],
+ output_index=result["outnum"],
+ )
+ except RpcError as e:
+ message = e.error["message"]
+
+ if "amount: should be a satoshi amount" in message:
+ raise HTTPException(
+ HTTPStatus.BAD_REQUEST,
+ detail="The amount is not a valid satoshi amount.",
+ )
+
+ if "Unknown peer" in message:
+ raise HTTPException(
+ HTTPStatus.INTERNAL_SERVER_ERROR,
+ detail=(
+ "We where able to connect to the peer but CLN "
+ "can't find it when opening a channel."
+ ),
+ )
+
+ if "Owning subdaemon openingd died" in message:
+ # https://github.com/ElementsProject/lightning/issues/2798#issuecomment-511205719
+ raise HTTPException(
+ HTTPStatus.BAD_REQUEST,
+ detail=(
+ "Likely the peer didn't like our channel opening "
+ "proposal and disconnected from us."
+ ),
+ )
+
+ if (
+ "Number of pending channels exceed maximum" in message
+ or "exceeds maximum chan size of 10 BTC" in message
+ or "Could not afford" in message
+ ):
+ raise HTTPException(HTTPStatus.BAD_REQUEST, detail=message)
+ raise
+
+ @catch_rpc_errors
+ async def close_channel(
+ self,
+ short_id: Optional[str] = None,
+ point: Optional[ChannelPoint] = None,
+ force: bool = False,
+ ):
+ if not short_id:
+ raise HTTPException(status_code=400, detail="Short id required")
+ try:
+ await self.ln_rpc("close", short_id)
+ except RpcError as e:
+ message = e.error["message"]
+ if (
+ "Short channel ID not active:" in message
+ or "Short channel ID not found" in message
+ ):
+ raise HTTPException(HTTPStatus.BAD_REQUEST, detail=message)
+ else:
+ raise
+
+ @catch_rpc_errors
+ async def _get_id(self) -> str:
+ info = await self.ln_rpc("getinfo")
+ return info["id"]
+
+ @catch_rpc_errors
+ async def get_peer_ids(self) -> List[str]:
+ peers = await self.ln_rpc("listpeers")
+ return [p["id"] for p in peers["peers"] if p["connected"]]
+
+ @catch_rpc_errors
+ async def _get_peer_info(self, peer_id: str) -> NodePeerInfo:
+ result = await self.ln_rpc("listnodes", peer_id)
+ nodes = result["nodes"]
+ if len(nodes) == 0:
+ return NodePeerInfo(id=peer_id)
+ node = nodes[0]
+ if "last_timestamp" in node:
+ return NodePeerInfo(
+ id=node["nodeid"],
+ alias=node["alias"],
+ color=node["color"],
+ last_timestamp=node["last_timestamp"],
+ addresses=[
+ address["address"] + ":" + str(address["port"])
+ for address in node["addresses"]
+ ],
+ )
+ else:
+ return NodePeerInfo(id=node["nodeid"])
+
+ @catch_rpc_errors
+ async def get_channels(self) -> List[NodeChannel]:
+ funds = await self.ln_rpc("listfunds")
+ nodes = await self.ln_rpc("listnodes")
+ nodes_by_id = {n["nodeid"]: n for n in nodes["nodes"]}
+
+ return [
+ NodeChannel(
+ short_id=ch.get("short_channel_id"),
+ point=ChannelPoint(
+ funding_txid=ch["funding_txid"],
+ output_index=ch["funding_output"],
+ ),
+ peer_id=ch["peer_id"],
+ balance=ChannelBalance(
+ local_msat=ch["our_amount_msat"],
+ remote_msat=ch["amount_msat"] - ch["our_amount_msat"],
+ total_msat=ch["amount_msat"],
+ ),
+ name=nodes_by_id.get(ch["peer_id"], {}).get("alias"),
+ color=nodes_by_id.get(ch["peer_id"], {}).get("color"),
+ state=(
+ ChannelState.ACTIVE
+ if ch["state"] == "CHANNELD_NORMAL"
+ else ChannelState.PENDING
+ if ch["state"] in ("CHANNELD_AWAITING_LOCKIN", "OPENINGD")
+ else ChannelState.CLOSED
+ if ch["state"]
+ in (
+ "CHANNELD_CLOSING",
+ "CLOSINGD_COMPLETE",
+ "CLOSINGD_SIGEXCHANGE",
+ "ONCHAIN",
+ )
+ else ChannelState.INACTIVE
+ ),
+ )
+ for ch in funds["channels"]
+ ]
+
+ @catch_rpc_errors
+ async def get_info(self) -> NodeInfoResponse:
+ info = await self.ln_rpc("getinfo")
+ funds = await self.ln_rpc("listfunds")
+
+ channels = await self.get_channels()
+ active_channels = [
+ channel for channel in channels if channel.state == ChannelState.ACTIVE
+ ]
+ return NodeInfoResponse(
+ id=info["id"],
+ backend_name="CLN",
+ alias=info["alias"],
+ color=info["color"],
+ onchain_balance_sat=sum(output["value"] for output in funds["outputs"]),
+ onchain_confirmed_sat=sum(
+ output["amount_msat"] / 1000
+ for output in funds["outputs"]
+ if output["status"] == "confirmed"
+ ),
+ channel_stats=ChannelStats.from_list(channels),
+ num_peers=info["num_peers"],
+ blockheight=info["blockheight"],
+ balance_msat=sum(channel.balance.local_msat for channel in active_channels),
+ fees=NodeFees(total_msat=info["fees_collected_msat"]),
+ addresses=[address["address"] for address in info["address"]],
+ )
+
+ @catch_rpc_errors
+ async def get_payments(
+ self, filters: Filters[NodePaymentsFilters]
+ ) -> Page[NodePayment]:
+ async def get_payments():
+ result = await self.ln_rpc("listpays")
+ return [
+ NodePayment(
+ bolt11=pay["bolt11"],
+ amount=pay["amount_msat"],
+ fee=int(pay["amount_msat"]) - int(pay["amount_sent_msat"]),
+ memo=pay.get("description"),
+ time=pay["created_at"],
+ preimage=pay.get("preimage"),
+ payment_hash=pay["payment_hash"],
+ pending=pay["status"] != "complete",
+ destination=await self.get_peer_info(pay["destination"]),
+ )
+ for pay in reversed(result["pays"])
+ if pay["status"] != "failed"
+ ]
+
+ results = await cache.save_result(get_payments, key="node:payments")
+ count = len(results)
+ if filters.offset:
+ results = results[filters.offset :]
+ if filters.limit:
+ results = results[: filters.limit]
+ return Page(data=results, total=count)
+
+ @catch_rpc_errors
+ async def get_invoices(
+ self, filters: Filters[NodeInvoiceFilters]
+ ) -> Page[NodeInvoice]:
+ result = await cache.save_result(
+ lambda: self.ln_rpc("listinvoices"), key="node:invoices"
+ )
+ invoices = result["invoices"]
+ invoices.reverse()
+ count = len(invoices)
+ if filters.offset:
+ invoices = invoices[filters.offset :]
+ if filters.limit:
+ invoices = invoices[: filters.limit]
+ return Page(
+ data=[
+ NodeInvoice(
+ bolt11=invoice["bolt11"],
+ amount=invoice["amount_msat"],
+ preimage=invoice.get("payment_preimage"),
+ memo=invoice["description"],
+ paid_at=invoice.get("paid_at"),
+ expiry=invoice["expires_at"],
+ payment_hash=invoice["payment_hash"],
+ pending=invoice["status"] != "paid",
+ )
+ for invoice in invoices
+ ],
+ total=count,
+ )
diff --git a/lnbits/nodes/lndrest.py b/lnbits/nodes/lndrest.py
new file mode 100644
index 000000000..71fc91518
--- /dev/null
+++ b/lnbits/nodes/lndrest.py
@@ -0,0 +1,382 @@
+from __future__ import annotations
+
+import asyncio
+import base64
+import json
+from http import HTTPStatus
+from typing import TYPE_CHECKING, List, Optional
+
+from fastapi import HTTPException
+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,
+ NodeChannel,
+ NodeFees,
+ NodeInfoResponse,
+ NodeInvoice,
+ NodeInvoiceFilters,
+ NodePayment,
+ NodePaymentsFilters,
+ NodePeerInfo,
+ PublicNodeInfo,
+)
+from lnbits.utils.cache import cache
+
+if TYPE_CHECKING:
+ from lnbits.wallets import LndRestWallet
+
+
+def msat(raw: str) -> int:
+ return int(raw) * 1000
+
+
+def _decode_bytes(data: str) -> str:
+ return base64.b64decode(data).hex()
+
+
+def _parse_channel_point(raw: str) -> ChannelPoint:
+ funding_tx, output_index = raw.split(":")
+ return ChannelPoint(
+ funding_txid=funding_tx,
+ output_index=int(output_index),
+ )
+
+
+class LndRestNode(Node):
+ wallet: LndRestWallet
+
+ async def request(
+ self, method: str, path: str, json: Optional[dict] = None, **kwargs
+ ):
+ response = await self.wallet.client.request(
+ method, f"{self.wallet.endpoint}{path}", json=json, **kwargs
+ )
+ try:
+ response.raise_for_status()
+ except HTTPStatusError as e:
+ json = e.response.json()
+ if json:
+ error = json.get("error") or json
+ raise HTTPException(e.response.status_code, detail=error.get("message"))
+ return response.json()
+
+ def get(self, path: str, **kwargs):
+ return self.request("GET", path, **kwargs)
+
+ async def _get_id(self) -> str:
+ info = await self.get("/v1/getinfo")
+ return info["identity_pubkey"]
+
+ async def get_peer_ids(self) -> list[str]:
+ response = await self.get("/v1/peers")
+ return [p["pub_key"] for p in response["peers"]]
+
+ async def connect_peer(self, uri: str):
+ try:
+ pubkey, host = uri.split("@")
+ except ValueError:
+ raise HTTPException(400, detail="Invalid peer URI")
+ await self.request(
+ "POST",
+ "/v1/peers",
+ json={
+ "addr": {"pubkey": pubkey, "host": host},
+ "perm": True,
+ "timeout": 30,
+ },
+ )
+
+ async def disconnect_peer(self, peer_id: str):
+ try:
+ await self.request("DELETE", "/v1/peers/" + peer_id)
+ except HTTPException as e:
+ if "unable to disconnect" in e.detail:
+ raise HTTPException(
+ HTTPStatus.BAD_REQUEST, detail="Peer is not connected"
+ )
+ raise
+
+ async def _get_peer_info(self, peer_id: str) -> NodePeerInfo:
+ try:
+ response = await self.get("/v1/graph/node/" + peer_id)
+ except HTTPException:
+ return NodePeerInfo(id=peer_id)
+ node = response["node"]
+ return NodePeerInfo(
+ id=peer_id,
+ alias=node["alias"],
+ color=node["color"].strip("#"),
+ last_timestamp=node["last_update"],
+ addresses=[a["addr"] for a in node["addresses"]],
+ )
+
+ async def open_channel(
+ self,
+ peer_id: str,
+ local_amount: int,
+ push_amount: Optional[int] = None,
+ fee_rate: Optional[int] = None,
+ ) -> ChannelPoint:
+ response = await self.request(
+ "POST",
+ "/v1/channels",
+ data=json.dumps(
+ {
+ # 'node_pubkey': base64.b64encode(peer_id.encode()).decode(),
+ "node_pubkey_string": peer_id,
+ "sat_per_vbyte": fee_rate,
+ "local_funding_amount": local_amount,
+ "push_sat": push_amount,
+ }
+ ),
+ )
+ return ChannelPoint(
+ # WHY IS THIS REVERSED?!
+ funding_txid=bytes(
+ reversed(base64.b64decode(response["funding_txid_bytes"]))
+ ).hex(),
+ output_index=response["output_index"],
+ )
+
+ async def _close_channel(
+ self,
+ point: ChannelPoint,
+ force: bool = False,
+ ):
+ async with self.wallet.client.stream(
+ "DELETE",
+ f"{self.wallet.endpoint}/v1/channels/{point.funding_txid}/{point.output_index}",
+ params={"force": force},
+ timeout=None,
+ ) as stream:
+ async for chunk in stream.aiter_text():
+ if chunk:
+ chunk = json.loads(chunk)
+ logger.info(f"LND Channel close update: {chunk['result']}")
+
+ async def close_channel(
+ self,
+ short_id: Optional[str] = None,
+ point: Optional[ChannelPoint] = None,
+ force: bool = False,
+ ):
+ if not point:
+ raise HTTPException(
+ status_code=HTTPStatus.BAD_REQUEST, detail="Channel point required"
+ )
+
+ asyncio.create_task(self._close_channel(point, force))
+
+ async def get_channels(self) -> List[NodeChannel]:
+ normal, pending, closed = await asyncio.gather(
+ self.get("/v1/channels"),
+ self.get("/v1/channels/pending"),
+ self.get("/v1/channels/closed"),
+ )
+
+ channels = []
+
+ async def parse_pending(raw_channels, state):
+ for channel in raw_channels:
+ channel = channel["channel"]
+ info = await self.get_peer_info(channel["remote_node_pub"])
+ channels.append(
+ NodeChannel(
+ peer_id=info.id,
+ state=state,
+ name=info.alias,
+ color=info.color,
+ point=_parse_channel_point(channel["channel_point"]),
+ balance=ChannelBalance(
+ local_msat=msat(channel["local_balance"]),
+ remote_msat=msat(channel["remote_balance"]),
+ total_msat=msat(channel["capacity"]),
+ ),
+ )
+ )
+
+ await parse_pending(pending["pending_open_channels"], ChannelState.PENDING)
+ await parse_pending(
+ pending["pending_force_closing_channels"], ChannelState.CLOSED
+ )
+ await parse_pending(pending["waiting_close_channels"], ChannelState.CLOSED)
+
+ for channel in closed["channels"]:
+ info = await self.get_peer_info(channel["remote_pubkey"])
+ channels.append(
+ NodeChannel(
+ peer_id=info.id,
+ state=ChannelState.CLOSED,
+ name=info.alias,
+ color=info.color,
+ point=_parse_channel_point(channel["channel_point"]),
+ balance=ChannelBalance(
+ local_msat=0,
+ remote_msat=0,
+ total_msat=msat(channel["capacity"]),
+ ),
+ )
+ )
+
+ for channel in normal["channels"]:
+ info = await self.get_peer_info(channel["remote_pubkey"])
+ channels.append(
+ NodeChannel(
+ short_id=channel["chan_id"],
+ point=_parse_channel_point(channel["channel_point"]),
+ peer_id=channel["remote_pubkey"],
+ balance=ChannelBalance(
+ local_msat=msat(channel["local_balance"]),
+ remote_msat=msat(channel["remote_balance"]),
+ total_msat=msat(channel["capacity"]),
+ ),
+ state=ChannelState.ACTIVE
+ if channel["active"]
+ else ChannelState.INACTIVE,
+ # name=channel['peer_alias'],
+ name=info.alias,
+ color=info.color,
+ )
+ )
+
+ return channels
+
+ async def get_public_info(self) -> PublicNodeInfo:
+ info = await self.get("/v1/getinfo")
+ channels = await self.get_channels()
+ return PublicNodeInfo(
+ backend_name="LND",
+ id=info["identity_pubkey"],
+ color=info["color"].lstrip("#"),
+ alias=info["alias"],
+ num_peers=info["num_peers"],
+ blockheight=info["block_height"],
+ addresses=info["uris"],
+ channel_stats=ChannelStats.from_list(channels),
+ )
+
+ async def get_info(self) -> NodeInfoResponse:
+ public = await self.get_public_info()
+ onchain = await self.get("/v1/balance/blockchain")
+ fee_report = await self.get("/v1/fees")
+ balance = await self.get("/v1/balance/channels")
+ return NodeInfoResponse(
+ **public.dict(),
+ onchain_balance_sat=onchain["total_balance"],
+ onchain_confirmed_sat=onchain["confirmed_balance"],
+ balance_msat=balance["local_balance"]["msat"],
+ fees=NodeFees(
+ total_msat=0,
+ daily_msat=fee_report["day_fee_sum"],
+ weekly_msat=fee_report["week_fee_sum"],
+ monthly_msat=fee_report["month_fee_sum"],
+ ),
+ )
+
+ async def get_payments(
+ self, filters: Filters[NodePaymentsFilters]
+ ) -> Page[NodePayment]:
+ count_key = "node:payments_count"
+ payments_count = cache.get(count_key)
+ if not payments_count and filters.offset:
+ # this forces fetching the payments count
+ await self.get_payments(Filters(limit=1))
+ payments_count = cache.get(count_key)
+
+ if filters.offset and payments_count:
+ index_offset = max(payments_count + 1 - filters.offset, 0)
+ else:
+ index_offset = 0
+
+ response = await self.get(
+ "/v1/payments",
+ params={
+ "index_offset": index_offset,
+ "max_payments": filters.limit,
+ "include_incomplete": True,
+ "reversed": True,
+ "count_total_payments": not index_offset,
+ },
+ )
+
+ if not filters.offset:
+ payments_count = int(response["total_num_payments"])
+
+ cache.set(count_key, payments_count)
+
+ payments = [
+ NodePayment(
+ payment_hash=payment["payment_hash"],
+ pending=payment["status"] == "IN_FLIGHT",
+ amount=payment["value_msat"],
+ fee=payment["fee_msat"],
+ time=payment["creation_date"],
+ destination=await self.get_peer_info(
+ payment["htlcs"][0]["route"]["hops"][-1]["pub_key"]
+ )
+ if payment["htlcs"]
+ else None,
+ bolt11=payment["payment_request"],
+ preimage=payment["payment_preimage"],
+ )
+ for payment in response["payments"]
+ ]
+
+ payments.sort(key=lambda p: p.time, reverse=True)
+
+ return Page(data=payments, total=payments_count or 0)
+
+ async def get_invoices(
+ self, filters: Filters[NodeInvoiceFilters]
+ ) -> Page[NodeInvoice]:
+ last_invoice_key = "node:last_invoice_index"
+ last_invoice_index = cache.get(last_invoice_key)
+ if not last_invoice_index and filters.offset:
+ # this forces fetching the last invoice index so
+ await self.get_invoices(Filters(limit=1))
+ last_invoice_index = cache.get(last_invoice_key)
+
+ if filters.offset and last_invoice_index:
+ index_offset = max(last_invoice_index + 1 - filters.offset, 0)
+ else:
+ index_offset = 0
+
+ response = await self.get(
+ "/v1/invoices",
+ params={
+ "index_offset": index_offset,
+ "num_max_invoices": filters.limit,
+ "reversed": True,
+ },
+ )
+
+ if not filters.offset:
+ last_invoice_index = int(response["last_index_offset"])
+
+ cache.set(last_invoice_key, last_invoice_index)
+
+ invoices = [
+ NodeInvoice(
+ payment_hash=_decode_bytes(invoice["r_hash"]),
+ amount=invoice["value_msat"],
+ memo=invoice["memo"],
+ pending=invoice["state"] == "OPEN",
+ paid_at=invoice["settle_date"],
+ expiry=invoice["creation_date"] + invoice["expiry"],
+ preimage=_decode_bytes(invoice["r_preimage"]),
+ bolt11=invoice["payment_request"],
+ )
+ for invoice in reversed(response["invoices"])
+ ]
+
+ return Page(
+ data=invoices,
+ total=last_invoice_index or 0,
+ )
diff --git a/lnbits/settings.py b/lnbits/settings.py
index 0c3d2fa90..0c49ecce2 100644
--- a/lnbits/settings.py
+++ b/lnbits/settings.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import importlib
import importlib.metadata
import inspect
@@ -226,6 +228,16 @@ class WebPushSettings(LNbitsSettings):
lnbits_webpush_privkey: str = Field(default=None)
+class NodeUISettings(LNbitsSettings):
+ # on-off switch for node ui
+ lnbits_node_ui: bool = Field(default=False)
+ # whether to display the public node ui (only if lnbits_node_ui is True)
+ lnbits_public_node_ui: bool = Field(default=False)
+ # can be used to disable the transactions tab in the node ui
+ # (recommended for large cln nodes)
+ lnbits_node_ui_transactions: bool = Field(default=False)
+
+
class EditableSettings(
UsersSettings,
ExtensionsSettings,
@@ -236,6 +248,7 @@ class EditableSettings(
BoltzExtensionSettings,
LightningSettings,
WebPushSettings,
+ NodeUISettings,
):
@validator(
"lnbits_admin_users",
@@ -421,6 +434,12 @@ except Exception:
settings.version = importlib.metadata.version("lnbits")
+# printing environment variable for debugging
+if not settings.lnbits_admin_ui:
+ logger.debug("Environment Settings:")
+ for key, value in settings.dict(exclude_none=True).items():
+ logger.debug(f"{key}: {value}")
+
def get_wallet_class():
"""
diff --git a/lnbits/static/bundle.min.js b/lnbits/static/bundle.min.js
index e55653ebd..db3a175e4 100644
--- a/lnbits/static/bundle.min.js
+++ b/lnbits/static/bundle.min.js
@@ -52,4 +52,4 @@ function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.export
* (c) 2022 kazuya kawaguchi
* Released under the MIT License.
*/
-function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueI18n=e()}(this,(function(){"use strict";var t=["compactDisplay","currency","currencyDisplay","currencySign","localeMatcher","notation","numberingSystem","signDisplay","style","unit","unitDisplay","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits"],e=["dateStyle","timeStyle","calendar","localeMatcher","hour12","hourCycle","timeZone","formatMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName"];function n(t,e){"undefined"!=typeof console&&(console.warn("[vue-i18n] "+t),e&&console.warn(e.stack))}function i(t,e){"undefined"!=typeof console&&(console.error("[vue-i18n] "+t),e&&console.error(e.stack))}var r=Array.isArray;function o(t){return null!==t&&"object"==typeof t}function a(t){return"string"==typeof t}var s=Object.prototype.toString,l="[object Object]";function u(t){return s.call(t)===l}function c(t){return null==t}function d(t){return"function"==typeof t}function h(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];var n=null,i=null;return 1===t.length?o(t[0])||r(t[0])?i=t[0]:"string"==typeof t[0]&&(n=t[0]):2===t.length&&("string"==typeof t[0]&&(n=t[0]),(o(t[1])||r(t[1]))&&(i=t[1])),{locale:n,params:i}}function f(t){return JSON.parse(JSON.stringify(t))}function p(t,e){return!!~t.indexOf(e)}var m=Object.prototype.hasOwnProperty;function v(t,e){return m.call(t,e)}function g(t){for(var e=arguments,n=Object(t),i=1;i
0;)e[n]=arguments[n+1];var i=this.$i18n;return i._t.apply(i,[t,i.locale,i._getMessages(),this].concat(e))},t.prototype.$tc=function(t,e){for(var n=[],i=arguments.length-2;i-- >0;)n[i]=arguments[i+2];var r=this.$i18n;return r._tc.apply(r,[t,r.locale,r._getMessages(),this,e].concat(n))},t.prototype.$te=function(t,e){var n=this.$i18n;return n._te(t,n.locale,n._getMessages(),e)},t.prototype.$d=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this.$i18n).d.apply(e,[t].concat(n))},t.prototype.$n=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this.$i18n).n.apply(e,[t].concat(n))}}(k),k.mixin(function(t){function e(){this!==this.$root&&this.$options.__INTLIFY_META__&&this.$el&&this.$el.setAttribute("data-intlify",this.$options.__INTLIFY_META__)}return void 0===t&&(t=!1),t?{mounted:e}:{beforeCreate:function(){var t=this.$options;if(t.i18n=t.i18n||(t.__i18nBridge||t.__i18n?{}:null),t.i18n)if(t.i18n instanceof Y){if(t.__i18nBridge||t.__i18n)try{var e=t.i18n&&t.i18n.messages?t.i18n.messages:{};(t.__i18nBridge||t.__i18n).forEach((function(t){e=g(e,JSON.parse(t))})),Object.keys(e).forEach((function(n){t.i18n.mergeLocaleMessage(n,e[n])}))}catch(t){i("Cannot parse locale messages via custom blocks.",t)}this._i18n=t.i18n,this._i18nWatcher=this._i18n.watchI18nData()}else if(u(t.i18n)){var r=this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y?this.$root.$i18n:null;if(r&&(t.i18n.root=this.$root,t.i18n.formatter=r.formatter,t.i18n.fallbackLocale=r.fallbackLocale,t.i18n.formatFallbackMessages=r.formatFallbackMessages,t.i18n.silentTranslationWarn=r.silentTranslationWarn,t.i18n.silentFallbackWarn=r.silentFallbackWarn,t.i18n.pluralizationRules=r.pluralizationRules,t.i18n.preserveDirectiveContent=r.preserveDirectiveContent),t.__i18nBridge||t.__i18n)try{var o=t.i18n&&t.i18n.messages?t.i18n.messages:{};(t.__i18nBridge||t.__i18n).forEach((function(t){o=g(o,JSON.parse(t))})),t.i18n.messages=o}catch(t){n("Cannot parse locale messages via custom blocks.",t)}var a=t.i18n.sharedMessages;a&&u(a)&&(t.i18n.messages=g(t.i18n.messages,a)),this._i18n=new Y(t.i18n),this._i18nWatcher=this._i18n.watchI18nData(),(void 0===t.i18n.sync||t.i18n.sync)&&(this._localeWatcher=this.$i18n.watchLocale()),r&&r.onComponentInstanceCreated(this._i18n)}else n("Cannot be interpreted 'i18n' option.");else this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y?this._i18n=this.$root.$i18n:t.parent&&t.parent.$i18n&&t.parent.$i18n instanceof Y&&(this._i18n=t.parent.$i18n)},beforeMount:function(){var t=this.$options;t.i18n=t.i18n||(t.__i18nBridge||t.__i18n?{}:null),t.i18n?t.i18n instanceof Y||u(t.i18n)?(this._i18n.subscribeDataChanging(this),this._subscribing=!0):n("Cannot be interpreted 'i18n' option."):(this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y||t.parent&&t.parent.$i18n&&t.parent.$i18n instanceof Y)&&(this._i18n.subscribeDataChanging(this),this._subscribing=!0)},mounted:e,beforeDestroy:function(){if(this._i18n){var t=this;this.$nextTick((function(){t._subscribing&&(t._i18n.unsubscribeDataChanging(t),delete t._subscribing),t._i18nWatcher&&(t._i18nWatcher(),t._i18n.destroyVM(),delete t._i18nWatcher),t._localeWatcher&&(t._localeWatcher(),delete t._localeWatcher)}))}}}}(e.bridge)),k.directive("t",{bind:C,update:M,unbind:T}),k.component(y.name,y),k.component(S.name,S),k.config.optionMergeStrategies.i18n=function(t,e){return void 0===e?t:e}))}var L=function(){this._caches=Object.create(null)};L.prototype.interpolate=function(t,e){if(!e)return[t];var i=this._caches[t];return i||(i=function(t){var e=[],n=0,i="";for(;n0)d--,c=4,h[0]();else{if(d=0,void 0===n)return!1;if(!1===(n=j(n)))return!1;h[1]()}};null!==c;)if(u++,"\\"!==(e=t[u])||!f()){if(r=I(e),8===(o=(s=R[c])[r]||s.else||8))return;if(c=o[0],(a=h[o[1]])&&(i=void 0===(i=o[2])?e:i,!1===a()))return;if(7===c)return l}}(t),e&&(this._cache[t]=e)),e||[]},$.prototype.getPathValue=function(t,e){if(!o(t))return null;var n=this.parsePath(e);if(0===n.length)return null;for(var i=n.length,r=t,a=0;a/,z=/(?:@(?:\.[a-zA-Z]+)?:(?:[\w\-_|./]+|\([\w\-_:|./]+\)))/g,V=/^@(?:\.([a-zA-Z]+))?:/,H=/[()]/g,U={upper:function(t){return t.toLocaleUpperCase()},lower:function(t){return t.toLocaleLowerCase()},capitalize:function(t){return""+t.charAt(0).toLocaleUpperCase()+t.substr(1)}},W=new L,Y=function(t){var e=this;void 0===t&&(t={}),!k&&"undefined"!=typeof window&&window.Vue&&E(window.Vue);var n=t.locale||"en-US",i=!1!==t.fallbackLocale&&(t.fallbackLocale||"en-US"),r=t.messages||{},o=t.dateTimeFormats||t.datetimeFormats||{},a=t.numberFormats||{};this._vm=null,this._formatter=t.formatter||W,this._modifiers=t.modifiers||{},this._missing=t.missing||null,this._root=t.root||null,this._sync=void 0===t.sync||!!t.sync,this._fallbackRoot=void 0===t.fallbackRoot||!!t.fallbackRoot,this._fallbackRootWithEmptyString=void 0===t.fallbackRootWithEmptyString||!!t.fallbackRootWithEmptyString,this._formatFallbackMessages=void 0!==t.formatFallbackMessages&&!!t.formatFallbackMessages,this._silentTranslationWarn=void 0!==t.silentTranslationWarn&&t.silentTranslationWarn,this._silentFallbackWarn=void 0!==t.silentFallbackWarn&&!!t.silentFallbackWarn,this._dateTimeFormatters={},this._numberFormatters={},this._path=new $,this._dataListeners=new Set,this._componentInstanceCreatedListener=t.componentInstanceCreatedListener||null,this._preserveDirectiveContent=void 0!==t.preserveDirectiveContent&&!!t.preserveDirectiveContent,this.pluralizationRules=t.pluralizationRules||{},this._warnHtmlInMessage=t.warnHtmlInMessage||"off",this._postTranslation=t.postTranslation||null,this._escapeParameterHtml=t.escapeParameterHtml||!1,"__VUE_I18N_BRIDGE__"in t&&(this.__VUE_I18N_BRIDGE__=t.__VUE_I18N_BRIDGE__),this.getChoiceIndex=function(t,n){var i=Object.getPrototypeOf(e);if(i&&i.getChoiceIndex)return i.getChoiceIndex.call(e,t,n);var r,o;return e.locale in e.pluralizationRules?e.pluralizationRules[e.locale].apply(e,[t,n]):(r=t,o=n,r=Math.abs(r),2===o?r?r>1?1:0:1:r?Math.min(r,2):0)},this._exist=function(t,n){return!(!t||!n)&&(!c(e._path.getPathValue(t,n))||!!t[n])},"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||Object.keys(r).forEach((function(t){e._checkLocaleMessage(t,e._warnHtmlInMessage,r[t])})),this._initVM({locale:n,fallbackLocale:i,messages:r,dateTimeFormats:o,numberFormats:a})},Q={vm:{configurable:!0},messages:{configurable:!0},dateTimeFormats:{configurable:!0},numberFormats:{configurable:!0},availableLocales:{configurable:!0},locale:{configurable:!0},fallbackLocale:{configurable:!0},formatFallbackMessages:{configurable:!0},missing:{configurable:!0},formatter:{configurable:!0},silentTranslationWarn:{configurable:!0},silentFallbackWarn:{configurable:!0},preserveDirectiveContent:{configurable:!0},warnHtmlInMessage:{configurable:!0},postTranslation:{configurable:!0},sync:{configurable:!0}};return Y.prototype._checkLocaleMessage=function(t,e,o){var s=function(t,e,o,l){if(u(o))Object.keys(o).forEach((function(n){var i=o[n];u(i)?(l.push(n),l.push("."),s(t,e,i,l),l.pop(),l.pop()):(l.push(n),s(t,e,i,l),l.pop())}));else if(r(o))o.forEach((function(n,i){u(n)?(l.push("["+i+"]"),l.push("."),s(t,e,n,l),l.pop(),l.pop()):(l.push("["+i+"]"),s(t,e,n,l),l.pop())}));else if(a(o)){if(B.test(o)){var c="Detected HTML in message '"+o+"' of keypath '"+l.join("")+"' at '"+e+"'. Consider component interpolation with '' to avoid XSS. See https://bit.ly/2ZqJzkp";"warn"===t?n(c):"error"===t&&i(c)}}};s(e,t,o,[])},Y.prototype._initVM=function(t){var e=k.config.silent;k.config.silent=!0,this._vm=new k({data:t,__VUE18N__INSTANCE__:!0}),k.config.silent=e},Y.prototype.destroyVM=function(){this._vm.$destroy()},Y.prototype.subscribeDataChanging=function(t){this._dataListeners.add(t)},Y.prototype.unsubscribeDataChanging=function(t){!function(t,e){if(t.delete(e));}(this._dataListeners,t)},Y.prototype.watchI18nData=function(){var t=this;return this._vm.$watch("$data",(function(){for(var e,n,i=(e=t._dataListeners,n=[],e.forEach((function(t){return n.push(t)})),n),r=i.length;r--;)k.nextTick((function(){i[r]&&i[r].$forceUpdate()}))}),{deep:!0})},Y.prototype.watchLocale=function(t){if(t){if(!this.__VUE_I18N_BRIDGE__)return null;var e=this,n=this._vm;return this.vm.$watch("locale",(function(i){n.$set(n,"locale",i),e.__VUE_I18N_BRIDGE__&&t&&(t.locale.value=i),n.$forceUpdate()}),{immediate:!0})}if(!this._sync||!this._root)return null;var i=this._vm;return this._root.$i18n.vm.$watch("locale",(function(t){i.$set(i,"locale",t),i.$forceUpdate()}),{immediate:!0})},Y.prototype.onComponentInstanceCreated=function(t){this._componentInstanceCreatedListener&&this._componentInstanceCreatedListener(t,this)},Q.vm.get=function(){return this._vm},Q.messages.get=function(){return f(this._getMessages())},Q.dateTimeFormats.get=function(){return f(this._getDateTimeFormats())},Q.numberFormats.get=function(){return f(this._getNumberFormats())},Q.availableLocales.get=function(){return Object.keys(this.messages).sort()},Q.locale.get=function(){return this._vm.locale},Q.locale.set=function(t){this._vm.$set(this._vm,"locale",t)},Q.fallbackLocale.get=function(){return this._vm.fallbackLocale},Q.fallbackLocale.set=function(t){this._localeChainCache={},this._vm.$set(this._vm,"fallbackLocale",t)},Q.formatFallbackMessages.get=function(){return this._formatFallbackMessages},Q.formatFallbackMessages.set=function(t){this._formatFallbackMessages=t},Q.missing.get=function(){return this._missing},Q.missing.set=function(t){this._missing=t},Q.formatter.get=function(){return this._formatter},Q.formatter.set=function(t){this._formatter=t},Q.silentTranslationWarn.get=function(){return this._silentTranslationWarn},Q.silentTranslationWarn.set=function(t){this._silentTranslationWarn=t},Q.silentFallbackWarn.get=function(){return this._silentFallbackWarn},Q.silentFallbackWarn.set=function(t){this._silentFallbackWarn=t},Q.preserveDirectiveContent.get=function(){return this._preserveDirectiveContent},Q.preserveDirectiveContent.set=function(t){this._preserveDirectiveContent=t},Q.warnHtmlInMessage.get=function(){return this._warnHtmlInMessage},Q.warnHtmlInMessage.set=function(t){var e=this,n=this._warnHtmlInMessage;if(this._warnHtmlInMessage=t,n!==t&&("warn"===t||"error"===t)){var i=this._getMessages();Object.keys(i).forEach((function(t){e._checkLocaleMessage(t,e._warnHtmlInMessage,i[t])}))}},Q.postTranslation.get=function(){return this._postTranslation},Q.postTranslation.set=function(t){this._postTranslation=t},Q.sync.get=function(){return this._sync},Q.sync.set=function(t){this._sync=t},Y.prototype._getMessages=function(){return this._vm.messages},Y.prototype._getDateTimeFormats=function(){return this._vm.dateTimeFormats},Y.prototype._getNumberFormats=function(){return this._vm.numberFormats},Y.prototype._warnDefault=function(t,e,i,r,o,s){if(!c(i))return i;if(this._missing){var l=this._missing.apply(null,[t,e,r,o]);if(a(l))return l}else this._isSilentTranslationWarn(e)||n("Cannot translate the value of keypath '"+e+"'. Use the value of keypath as default.");if(this._formatFallbackMessages){var u=h.apply(void 0,o);return this._render(e,s,u.params,e)}return e},Y.prototype._isFallbackRoot=function(t){return(this._fallbackRootWithEmptyString?!t:c(t))&&!c(this._root)&&this._fallbackRoot},Y.prototype._isSilentFallbackWarn=function(t){return this._silentFallbackWarn instanceof RegExp?this._silentFallbackWarn.test(t):this._silentFallbackWarn},Y.prototype._isSilentFallback=function(t,e){return this._isSilentFallbackWarn(e)&&(this._isFallbackRoot()||t!==this.fallbackLocale)},Y.prototype._isSilentTranslationWarn=function(t){return this._silentTranslationWarn instanceof RegExp?this._silentTranslationWarn.test(t):this._silentTranslationWarn},Y.prototype._interpolate=function(t,e,i,o,s,l,h){if(!e)return null;var f,p=this._path.getPathValue(e,i);if(r(p)||u(p))return p;if(c(p)){if(!u(e))return null;if(!a(f=e[i])&&!d(f))return this._isSilentTranslationWarn(i)||this._isSilentFallback(t,i)||n("Value of key '"+i+"' is not a string or function !"),null}else{if(!a(p)&&!d(p))return this._isSilentTranslationWarn(i)||this._isSilentFallback(t,i)||n("Value of key '"+i+"' is not a string or function!"),null;f=p}return a(f)&&(f.indexOf("@:")>=0||f.indexOf("@.")>=0)&&(f=this._link(t,e,f,o,"raw",l,h)),this._render(f,s,l,i)},Y.prototype._link=function(t,e,i,o,a,s,l){var u=i,c=u.match(z);for(var d in c)if(c.hasOwnProperty(d)){var h=c[d],f=h.match(V),m=f[0],v=f[1],g=h.replace(m,"").replace(H,"");if(p(l,g))return n('Circular reference found. "'+h+'" is already visited in the chain of '+l.reverse().join(" <- ")),u;l.push(g);var _=this._interpolate(t,e,g,o,"raw"===a?"string":a,"raw"===a?void 0:s,l);if(this._isFallbackRoot(_)){if(this._isSilentTranslationWarn(g)||n("Fall back to translate the link placeholder '"+g+"' with root locale."),!this._root)throw Error("unexpected error");var y=this._root.$i18n;_=y._translate(y._getMessages(),y.locale,y.fallbackLocale,g,o,a,s)}_=this._warnDefault(t,g,_,o,r(s)?s:[s],a),this._modifiers.hasOwnProperty(v)?_=this._modifiers[v](_):U.hasOwnProperty(v)&&(_=U[v](_)),l.pop(),u=_?u.replace(h,_):u}return u},Y.prototype._createMessageContext=function(t,e,n,i){var a=this,s=r(t)?t:[],l=o(t)?t:{},u=this._getMessages(),c=this.locale;return{list:function(t){return s[t]},named:function(t){return l[t]},values:t,formatter:e,path:n,messages:u,locale:c,linked:function(t){return a._interpolate(c,u[c]||{},t,null,i,void 0,[t])}}},Y.prototype._render=function(t,e,n,i){if(d(t))return t(this._createMessageContext(n,this._formatter||W,i,e));var r=this._formatter.interpolate(t,n,i);return r||(r=W.interpolate(t,n,i)),"string"!==e||a(r)?r:r.join("")},Y.prototype._appendItemToChain=function(t,e,n){var i=!1;return p(t,e)||(i=!0,e&&(i="!"!==e[e.length-1],e=e.replace(/!/g,""),t.push(e),n&&n[e]&&(i=n[e]))),i},Y.prototype._appendLocaleToChain=function(t,e,n){var i,r=e.split("-");do{var o=r.join("-");i=this._appendItemToChain(t,o,n),r.splice(-1,1)}while(r.length&&!0===i);return i},Y.prototype._appendBlockToChain=function(t,e,n){for(var i=!0,r=0;r0;)a[s]=arguments[s+4];if(!t)return"";var l,u=h.apply(void 0,a);this._escapeParameterHtml&&(u.params=(null!=(l=u.params)&&Object.keys(l).forEach((function(t){"string"==typeof l[t]&&(l[t]=l[t].replace(//g,">").replace(/"/g,""").replace(/'/g,"'"))})),l));var c=u.locale||e,d=this._translate(i,c,this.fallbackLocale,t,r,"string",u.params);if(this._isFallbackRoot(d)){if(this._isSilentTranslationWarn(t)||this._isSilentFallbackWarn(t)||n("Fall back to translate the keypath '"+t+"' with root locale."),!this._root)throw Error("unexpected error");return(o=this._root).$t.apply(o,[t].concat(a))}return d=this._warnDefault(c,t,d,r,a,"string"),this._postTranslation&&null!=d&&(d=this._postTranslation(d,t)),d},Y.prototype.t=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this)._t.apply(e,[t,this.locale,this._getMessages(),null].concat(n))},Y.prototype._i=function(t,e,i,r,o){var a=this._translate(i,e,this.fallbackLocale,t,r,"raw",o);if(this._isFallbackRoot(a)){if(this._isSilentTranslationWarn(t)||n("Fall back to interpolate the keypath '"+t+"' with root locale."),!this._root)throw Error("unexpected error");return this._root.$i18n.i(t,e,o)}return this._warnDefault(e,t,a,r,[o],"raw")},Y.prototype.i=function(t,e,n){return t?(a(e)||(e=this.locale),this._i(t,e,this._getMessages(),null,n)):""},Y.prototype._tc=function(t,e,n,i,r){for(var o,a=[],s=arguments.length-5;s-- >0;)a[s]=arguments[s+5];if(!t)return"";void 0===r&&(r=1);var l={count:r,n:r},u=h.apply(void 0,a);return u.params=Object.assign(l,u.params),a=null===u.locale?[u.params]:[u.locale,u.params],this.fetchChoice((o=this)._t.apply(o,[t,e,n,i].concat(a)),r)},Y.prototype.fetchChoice=function(t,e){if(!t||!a(t))return null;var n=t.split("|");return n[e=this.getChoiceIndex(e,n.length)]?n[e].trim():t},Y.prototype.tc=function(t,e){for(var n,i=[],r=arguments.length-2;r-- >0;)i[r]=arguments[r+2];return(n=this)._tc.apply(n,[t,this.locale,this._getMessages(),null,e].concat(i))},Y.prototype._te=function(t,e,n){for(var i=[],r=arguments.length-3;r-- >0;)i[r]=arguments[r+3];var o=h.apply(void 0,i).locale||e;return this._exist(n[o],t)},Y.prototype.te=function(t,e){return this._te(t,this.locale,this._getMessages(),e)},Y.prototype.getLocaleMessage=function(t){return f(this._vm.messages[t]||{})},Y.prototype.setLocaleMessage=function(t,e){"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||this._checkLocaleMessage(t,this._warnHtmlInMessage,e),this._vm.$set(this._vm.messages,t,e)},Y.prototype.mergeLocaleMessage=function(t,e){"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||this._checkLocaleMessage(t,this._warnHtmlInMessage,e),this._vm.$set(this._vm.messages,t,g(void 0!==this._vm.messages[t]&&Object.keys(this._vm.messages[t]).length?Object.assign({},this._vm.messages[t]):{},e))},Y.prototype.getDateTimeFormat=function(t){return f(this._vm.dateTimeFormats[t]||{})},Y.prototype.setDateTimeFormat=function(t,e){this._vm.$set(this._vm.dateTimeFormats,t,e),this._clearDateTimeFormat(t,e)},Y.prototype.mergeDateTimeFormat=function(t,e){this._vm.$set(this._vm.dateTimeFormats,t,g(this._vm.dateTimeFormats[t]||{},e)),this._clearDateTimeFormat(t,e)},Y.prototype._clearDateTimeFormat=function(t,e){for(var n in e){var i=t+"__"+n;this._dateTimeFormatters.hasOwnProperty(i)&&delete this._dateTimeFormatters[i]}},Y.prototype._localizeDateTime=function(t,e,i,r,o,a){for(var s=e,l=r[s],u=this._getLocaleChain(e,i),d=0;d0;)n[i]=arguments[i+1];var r=this.locale,s=null,l=null;return 1===n.length?(a(n[0])?s=n[0]:o(n[0])&&(n[0].locale&&(r=n[0].locale),n[0].key&&(s=n[0].key)),l=Object.keys(n[0]).reduce((function(t,i){var r;return p(e,i)?Object.assign({},t,((r={})[i]=n[0][i],r)):t}),null)):2===n.length&&(a(n[0])&&(s=n[0]),a(n[1])&&(r=n[1])),this._d(t,r,s,l)},Y.prototype.getNumberFormat=function(t){return f(this._vm.numberFormats[t]||{})},Y.prototype.setNumberFormat=function(t,e){this._vm.$set(this._vm.numberFormats,t,e),this._clearNumberFormat(t,e)},Y.prototype.mergeNumberFormat=function(t,e){this._vm.$set(this._vm.numberFormats,t,g(this._vm.numberFormats[t]||{},e)),this._clearNumberFormat(t,e)},Y.prototype._clearNumberFormat=function(t,e){for(var n in e){var i=t+"__"+n;this._numberFormatters.hasOwnProperty(i)&&delete this._numberFormatters[i]}},Y.prototype._getNumberFormatter=function(t,e,i,r,o,a){for(var s=e,l=r[s],u=this._getLocaleChain(e,i),d=0;d0;)n[i]=arguments[i+1];var r=this.locale,s=null,l=null;return 1===n.length?a(n[0])?s=n[0]:o(n[0])&&(n[0].locale&&(r=n[0].locale),n[0].key&&(s=n[0].key),l=Object.keys(n[0]).reduce((function(e,i){var r;return p(t,i)?Object.assign({},e,((r={})[i]=n[0][i],r)):e}),null)):2===n.length&&(a(n[0])&&(s=n[0]),a(n[1])&&(r=n[1])),this._n(e,r,s,l)},Y.prototype._ntp=function(t,e,i,r){if(!Y.availabilities.numberFormat)return n("Cannot format to parts a Number value due to not supported Intl.NumberFormat."),[];if(!i)return(r?new Intl.NumberFormat(e,r):new Intl.NumberFormat(e)).formatToParts(t);var o=this._getNumberFormatter(t,e,this.fallbackLocale,this._getNumberFormats(),i,r),a=o&&o.formatToParts(t);if(this._isFallbackRoot(a)){if(this._isSilentTranslationWarn(i)||n("Fall back to format number to parts of root: key '"+i+"' ."),!this._root)throw Error("unexpected error");return this._root.$i18n._ntp(t,e,i,r)}return a||[]},Object.defineProperties(Y.prototype,Q),Object.defineProperty(Y,"availabilities",{get:function(){if(!F){var t="undefined"!=typeof Intl;F={dateTimeFormat:t&&void 0!==Intl.DateTimeFormat,numberFormat:t&&void 0!==Intl.NumberFormat}}return F}}),Y.install=E,Y.version="8.28.2",Y})),window.localisation={},window.localisation.de={server:"Server",theme:"Theme",funding:"Funding",users:"Benutzer",unit:"Einheit",restart:"Server neu starten",save:"Speichern",save_tooltip:"Änderungen speichern",topup:"Aufladen",topup_wallet:"Wallet aufladen",topup_hint:"Nutze die Wallet-ID, um eine beliebige Wallet aufzuladen",restart_tooltip:"Starte den Server neu, um die Änderungen zu übernehmen",add_funds_tooltip:"Füge Geld zu einer Wallet hinzu.",reset_defaults:"Zurücksetzen",reset_defaults_tooltip:"Alle Einstellungen auf die Standardeinstellungen zurücksetzen.",download_backup:"Datenbank-Backup herunterladen",name_your_wallet:"Vergib deiner %{name} Wallet einen Namen",paste_invoice_label:"Füge eine Rechnung, Zahlungsanforderung oder LNURL ein *",lnbits_description:"Einfach zu installieren und kompakt, LNbits kann auf jeder Funding-Quelle im Lightning Netzwerk aufsetzen. Derzeit unterstützt: LND, Core Lightning, OpenNode, LNPay und sogar LNbits selbst! Du kannst LNbits für dich selbst betreiben oder anderen die Verwaltung durch dich anbieten. Jede Wallet hat ihre eigenen API-Schlüssel und die Anzahl der Wallets ist unbegrenzt. Die Möglichkeit, Gelder auf verschiedene Accounts mit unterschiedlicher Logik aufteilen zu können macht LNbits zu einem nützlichen Werkzeug für deine Buchhaltung - aber auch als Entwicklungswerkzeug. Erweiterungen bereichern LNbits Accounts um zusätzliche Funktionalität, so dass du mit einer Reihe von neuartigen Technologien auf dem Lightning-Netzwerk experimentieren kannst. Wir haben es so einfach wie möglich gemacht, Erweiterungen zu entwickeln, und als freies und Open-Source-Projekt möchten wir Menschen ermutigen, sich selbst hieran zu versuchen und gemeinsam mit uns neue Funktionalitäten zu entwickeln.",export_to_phone:"Auf dem Telefon öffnen",export_to_phone_desc:"Dieser QR-Code beinhaltet vollständige Rechte auf deine Wallet. Du kannst den QR-Code mit Deinem Telefon scannen, um deine Wallet dort zu öffnen.",wallets:"Wallets",add_wallet:"Wallet hinzufügen",delete_wallet:"Wallet löschen",delete_wallet_desc:"Die Wallet wird gelöscht, die hierin beinhalteten Daten hierin oder innerhalb einer Erweiterung sind UNWIEDERBRINGLICH.",rename_wallet:"Wallet umbenennen",update_name:"Namen aktualisieren",press_to_claim:"Klicken, um Bitcoin einzufordern.",donate:"Spenden",view_github:"Auf GitHub anzeigen",voidwallet_active:"VoidWallet ist aktiv! Zahlungen deaktiviert",use_with_caution:"BITTE MIT VORSICHT BENUTZEN - %{name} Wallet ist noch BETA",toggle_darkmode:"Auf Dark Mode umschalten",view_swagger_docs:"LNbits Swagger API-Dokumente",api_docs:"API docs",commit_version:"Commit Version",runs_on:"Läuft auf",credit_hint:"Klicke Enter, um das Konto zu belasten",credit_label:"%{denomination} zu belasten",paste_request:"Anfrage einfügen",create_invoice:"Rechnung erstellen",camera_tooltip:"Verwende die Kamera, um eine Rechnung oder einen QR-Code zu scannen",export_csv:"Exportieren als CSV",transactions:"Transaktionen",chart_tooltip:"Diagramm anzeigen",pending:"Ausstehend",copy_invoice:"Rechnung kopieren",close:"Schließen",cancel:"Stornieren",scan:"Scannen",read:"Lesen",pay:"Zahlen",memo:"Memo",date:"Datum",processing_payment:"Zahlung wird verarbeitet ...",not_enough_funds:"Geldmittel sind erschöpft!",search_by_tag_memo_amount:"Suche nach Tag, Memo, Betrag",invoice_waiting:"Rechnung wartend auf Zahlung",payment_received:"Zahlung erhalten",payment_sent:"Zahlung gesendet",receive:"erhalten",send:"schicken",outgoing_payment_pending:"Ausgehende Zahlung wartend",drain_funds:"Sats abziehen",drain_funds_desc:"LNURL-withdraw QR-Code, der das Abziehen aller Geldmittel aus dieser Wallet erlaubt. Teile ihn mit niemandem! Kompatibel mit balanceCheck und balanceNotify, so dass dein Wallet die Sats nach dem ersten Abzug kontinuierlich von hier abziehen kann.",i_understand:"Ich verstehe",copy_wallet_url:"Wallet-URL kopieren",disclaimer_dialog:"Login-Funktionalität wird in einem zukünftigen Update veröffentlicht. Bis dahin ist die Speicherung der Wallet-URL als Lesezeichen absolut notwendig, um Zugriff auf die Wallet zu erhalten! Dieser Service ist in BETA und wir übernehmen keine Verantwortung für Verluste durch verlorene Zugriffe.",no_transactions:"Keine Transaktionen",manage_extensions:"Erweiterungen verwalten",manage_server:"Server verwalten",extensions:"Erweiterungen",no_extensions:"Du hast noch keine Erweiterungen installiert :(",created:"Erstellt",search_extensions:"Sucherweiterungen",warning:"Warnung",manage:"Verwalten",repository:"Repository",confirm_continue:"Bist du sicher, dass du fortfahren möchtest?",manage_extension_details:"Erweiterung installieren/deinstallieren",install:"Installieren",uninstall:"Deinstallieren",open:"Öffnen",enable:"Aktivieren",enable_extension_details:"Erweiterung für aktuellen Benutzer aktivieren",disable:"Deaktivieren",installed:"Installiert",activated:"Aktiviert",deactivated:"Deaktiviert",release_notes:"Versionshinweise",activate_extension_details:"Erweiterung für Benutzer verfügbar/nicht verfügbar machen",featured:"Vorgestellt",all:"Alle",only_admins_can_install:"(Nur Administratorkonten können Erweiterungen installieren)",new_version:"Neue Version",extension_depends_on:"Hängt ab von:",extension_rating_soon:"Bewertungen sind bald verfügbar",extension_installed_version:"Installierte Version",extension_uninstall_warning:"Sie sind dabei, die Erweiterung für alle Benutzer zu entfernen.",uninstall_confirm:"Ja, deinstallieren",extension_min_lnbits_version:"Diese Version erfordert mindestens die LNbits-Version",payment_hash:"Zahlungs-Hash",fee:"Gebühr",amount:"Menge",description:"Beschreibung",expiry:"Ablauf",webhook:"Webhook",payment_proof:"Beleg"},window.localisation.en={confirm:"Yes",server:"Server",theme:"Theme",funding:"Funding",users:"Users",restart:"Restart server",save:"Save",save_tooltip:"Save your changes",topup:"Topup",topup_wallet:"Topup a wallet",topup_hint:"Use the wallet ID to topup any wallet",restart_tooltip:"Restart the server for changes to take effect",add_funds_tooltip:"Add funds to a wallet.",reset_defaults:"Reset to defaults",reset_defaults_tooltip:"Delete all settings and reset to defaults.",download_backup:"Download database backup",name_your_wallet:"Name your %{name} wallet",paste_invoice_label:"Paste an invoice, payment request or lnurl code *",lnbits_description:"Easy to set up and lightweight, LNbits can run on any lightning-network funding source, currently supporting LND, Core Lightning, OpenNode, LNPay and even LNbits itself! You can run LNbits for yourself, or easily offer a custodian solution for others. Each wallet has its own API keys and there is no limit to the number of wallets you can make. Being able to partition funds makes LNbits a useful tool for money management and as a development tool. Extensions add extra functionality to LNbits so you can experiment with a range of cutting-edge technologies on the lightning network. We have made developing extensions as easy as possible, and as a free and open-source project, we encourage people to develop and submit their own.",export_to_phone:"Export to Phone with QR Code",export_to_phone_desc:"This QR code contains your wallet URL with full access. You can scan it from your phone to open your wallet from there.",wallets:"Wallets",add_wallet:"Add a new wallet",delete_wallet:"Delete wallet",delete_wallet_desc:"This whole wallet will be deleted, the funds will be UNRECOVERABLE.",rename_wallet:"Rename wallet",update_name:"Update name",fiat_tracking:"Fiat tracking",currency:"Currency",update_currency:"Update currency",press_to_claim:"Press to claim bitcoin",donate:"Donate",view_github:"View on GitHub",voidwallet_active:"VoidWallet is active! Payments disabled",use_with_caution:"USE WITH CAUTION - %{name} wallet is still in BETA",toggle_darkmode:"Toggle Dark Mode",view_swagger_docs:"View LNbits Swagger API docs",api_docs:"Api docs",commit_version:"Commit version",lnbits_version:"LNbits version",runs_on:"Runs on",credit_hint:"Press Enter to credit account",credit_label:"%{denomination} to credit",paste:"Paste",paste_from_clipboard:"Paste from clipboard",paste_request:"Paste Request",create_invoice:"Create Invoice",camera_tooltip:"Use camera to scan an invoice/QR",export_csv:"Export to CSV",transactions:"Transactions",chart_tooltip:"Show chart",pending:"Pending",copy_invoice:"Copy invoice",close:"Close",cancel:"Cancel",scan:"Scan",read:"Read",pay:"Pay",memo:"Memo",date:"Date",processing_payment:"Processing payment...",not_enough_funds:"Not enough funds!",search_by_tag_memo_amount:"Search by tag, memo, amount",invoice_waiting:"Invoice waiting to be paid",payment_received:"Payment Received",payment_sent:"Payment Sent",receive:"receive",send:"send",outgoing_payment_pending:"Outgoing payment pending",drain_funds:"Drain Funds",drain_funds_desc:"This is an LNURL-withdraw QR code for slurping everything from this wallet. Do not share with anyone. It is compatible with balanceCheck and balanceNotify so your wallet may keep pulling the funds continuously from here after the first withdraw.",i_understand:"I understand",copy_wallet_url:"Copy wallet URL",disclaimer_dialog:"Login functionality to be released in a future update, for now, make sure you bookmark this page for future access to your wallet! This service is in BETA, and we hold no responsibility for people losing access to funds.",no_transactions:"No transactions made yet",manage_server:"Manage Server",extensions:"Extensions",no_extensions:"You don't have any extensions installed :(",created:"Created",search_extensions:"Search extensions",warning:"Warning",manage:"Manage",repository:"Repository",confirm_continue:"Are you sure you want to continue?",manage_extension_details:"Install/uninstall extension",install:"Install",uninstall:"Uninstall",drop_db:"Remove Data",open:"Open",enable:"Enable",enable_extension_details:"Enable extension for current user",disable:"Disable",installed:"Installed",activated:"Activated",deactivated:"Deactivated",release_notes:"Release Notes",activate_extension_details:"Make extension available/unavailable for users",featured:"Featured",all:"All",only_admins_can_install:"(Only admin accounts can install extensions)",admin_only:"Admin Only",new_version:"New Version",extension_depends_on:"Depends on:",extension_rating_soon:"Ratings coming soon",extension_installed_version:"Installed version",extension_uninstall_warning:"You are about to remove the extension for all users.",uninstall_confirm:"Yes, Uninstall",extension_db_drop_info:"All data for the extension will be permanently deleted. There is no way to undo this operation!",extension_db_drop_warning:"You are about to remove all data for the extension. Please type the extension name to continue:",extension_min_lnbits_version:"This release requires at least LNbits version",payment_hash:"Payment Hash",fee:"Fee",amount:"Amount",unit:"Unit",description:"Description",expiry:"Expiry",webhook:"Webhook",payment_proof:"Payment Proof",update_available:"Update %{version} available!",latest_update:"You are on the latest version %{version}.",notifications:"Notifications",no_notifications:"No notifications",notifications_disabled:"LNbits status notifications are disabled.",enable_notifications:"Enable Notifications",enable_notifications_desc:"If enabled it will fetch the latest LNbits Status updates, like security incidents and updates.",enable_killswitch:"Enable Killswitch",enable_killswitch_desc:"If enabled it will change your funding source to VoidWallet automatically if LNbits sends out a killswitch signal. You will need to enable manually after an update.",killswitch_interval:"Killswitch Interval",killswitch_interval_desc:"How often the background task should check for the LNBits killswitch signal from the status source (in minutes).",enable_watchdog:"Enable Watchdog",enable_watchdog_desc:"If enabled it will change your funding source to VoidWallet automatically if your balance is lower than the LNbits balance. You will need to enable manually after an update.",watchdog_interval:"Watchdog Interval",watchdog_interval_desc:"How often the background task should check for a killswitch signal in the watchdog delta [node_balance - lnbits_balance] (in minutes).",watchdog_delta:"Watchdog Delta",watchdog_delta_desc:"Limit before killswitch changes funding source to VoidWallet [lnbits_balance - node_balance > delta]",status:"Status",notification_source:"Notification Source",notification_source_label:"Source URL (only use the official LNbits status source, and sources you can trust)",more:"more",releases:"Releases",killswitch:"Killswitch",watchdog:"Watchdog",server_logs:"Server Logs",ip_blocker:"IP Blocker",security:"Security",security_tools:"Security tools",block_access_hint:"Block access by IP",allow_access_hint:"Allow access by IP (will override blocked IPs)",enter_ip:"Enter IP and hit enter",rate_limiter:"Rate Limiter",number_of_requests:"Number of requests",time_unit:"Time unit",minute:"minute",second:"second",hour:"hour",disable_server_log:"Disable Server Log",enable_server_log:"Enable Server Log",coming_soon:"Feature coming soon"},window.localisation.es={server:"Servidor",theme:"Tema",funding:"Financiación",unit:"Unidad",users:"Usuarios",restart:"Reiniciar el servidor",save:"Guardar",save_tooltip:"Guardar cambios",topup:"Recargar",topup_wallet:"Recargar billetera",topup_hint:"Utilice el ID de billetera para recargar cualquier billetera",restart_tooltip:"Reinicie el servidor para aplicar los cambios",add_funds_tooltip:"Agregue fondos a una billetera.",reset_defaults:"Restablecer",reset_defaults_tooltip:"Borrar todas las configuraciones y restablecer a los valores predeterminados.",download_backup:"Descargar copia de seguridad de la base de datos",name_your_wallet:"Nombre de su billetera %{name}",paste_invoice_label:"Pegue la factura aquí",lnbits_description:"Fácil de instalar y liviano, LNbits puede ejecutarse en cualquier fuente de financiación de la red Lightning, actualmente compatible con LND, Core Lightning, OpenNode, LNPay y hasta LNbits mismo! Puede ejecutar LNbits para usted mismo o ofrecer una solución competente a otros. Cada billetera tiene su propia clave API y no hay límite para la cantidad de billeteras que puede crear. La capacidad de particionar fondos hace de LNbits una herramienta útil para la administración de fondos y como herramienta de desarrollo. Las extensiones agregan funcionalidad adicional a LNbits, por lo que puede experimentar con una variedad de tecnologías de vanguardia en la red Lightning. Lo hemos hecho lo más simple posible para desarrollar extensiones y, como un proyecto gratuito y de código abierto, animamos a las personas a que se desarrollen a sí mismas y envíen sus propios contribuciones.",export_to_phone:"Exportar a teléfono con código QR",export_to_phone_desc:"Este código QR contiene su URL de billetera con acceso completo. Puede escanearlo desde su teléfono para abrir su billetera allí.",wallets:"Billeteras",add_wallet:"Agregar nueva billetera",delete_wallet:"Eliminar billetera",delete_wallet_desc:"Esta billetera completa se eliminará, los fondos son IRREVERSIBLES.",rename_wallet:"Cambiar el nombre de la billetera",update_name:"Actualizar nombre",press_to_claim:"Presione para reclamar Bitcoin",donate:"Donar",view_github:"Ver en GitHub",voidwallet_active:"¡VoidWallet está activo! Pagos desactivados",use_with_caution:"USAR CON CUIDADO - %{name} Wallet aún está en BETA",toggle_darkmode:"Cambiar modo oscuro",view_swagger_docs:"Ver documentos de API de LNbits Swagger",api_docs:"Documentos de API",commit_version:"Versión de compromiso",runs_on:"Corre en",credit_hint:"Presione Enter para cargar la cuenta",credit_label:"Cargar %{denomination}",paste_request:"Pegar solicitud",create_invoice:"Crear factura",camera_tooltip:"Utilice la cámara para escanear una factura / código QR",export_csv:"Exportar a CSV",transactions:"Transacciones",chart_tooltip:"Mostrar gráfico",pending:"Pendiente",copy_invoice:"Copiar factura",close:"Cerrar",cancel:"Cancelar",scan:"Escanear",read:"Leer",pay:"Pagar",memo:"Memo",date:"Fecha",processing_payment:"Procesando pago ...",not_enough_funds:"¡No hay suficientes fondos!",search_by_tag_memo_amount:"Buscar por etiqueta, memo, cantidad",invoice_waiting:"Factura esperando pago",payment_received:"Pago recibido",payment_sent:"Pago enviado",receive:"recibir",send:"enviar",outgoing_payment_pending:"Pago saliente pendiente",drain_funds:"Drenar fondos",drain_funds_desc:"Este es un código QR LNURL-withdraw para drenar todos los fondos de esta billetera. No lo comparta con nadie. Es compatible con balanceCheck y balanceNotify, por lo que su billetera puede continuar drenando los fondos de aquí después del primer drenaje.",i_understand:"Lo entiendo",copy_wallet_url:"Copiar URL de billetera",disclaimer_dialog:"La funcionalidad de inicio de sesión se lanzará en una actualización futura, por ahora, asegúrese de guardar esta página como marcador para acceder a su billetera en el futuro. Este servicio está en BETA y no asumimos ninguna responsabilidad por personas que pierdan el acceso a sus fondos.",no_transactions:"No hay transacciones todavía",manage_server:"Administrar servidor",extensions:"Extensiones",no_extensions:"No tienes extensiones instaladas :(",created:"Creado",search_extensions:"Extensiones de búsqueda",warning:"Advertencia",manage:"Administrar",repository:"Repositorio",confirm_continue:"¿Está seguro de que desea continuar?",manage_extension_details:"Instalar/desinstalar extensión",install:"Instalar",uninstall:"Desinstalar",open:"Abrir",enable:"Habilitar",enable_extension_details:"Habilitar extensión para el usuario actual",disable:"Deshabilitar",installed:"Instalado",activated:"Activado",deactivated:"Desactivado",release_notes:"Notas de la versión",activate_extension_details:"Hacer que la extensión esté disponible/no disponible para los usuarios",featured:"Destacado",all:"Todos",only_admins_can_install:"(Solo las cuentas de administrador pueden instalar extensiones)",new_version:"Nueva Versión",extension_depends_on:"Depende de:",extension_rating_soon:"Calificaciones próximamente",extension_installed_version:"Versión instalada",extension_uninstall_warning:"Está a punto de eliminar la extensión para todos los usuarios.",uninstall_confirm:"Sí, desinstalar",extension_min_lnbits_version:"Esta versión requiere al menos una versión de LNbits",payment_hash:"Hash de pago",fee:"Cuota",amount:"Cantidad",description:"Descripción",expiry:"Expiración",webhook:"Webhook",payment_proof:"Prueba de pago"},window.localisation.fr={server:"Serveur",theme:"Thème",funding:"Financement",users:"Utilisateurs",restart:"Redémarrer le serveur",save:"Enregistrer",save_tooltip:"Enregistrer vos modifications",topup:"Renflouer",topup_wallet:"Reflouer un portefeuille",topup_hint:"Utilisez l'ID du portefeuille pour recharger n'importe quel portefeuille",restart_tooltip:"Redémarrez le serveur pour que les changements prennent effet",add_funds_tooltip:"Ajouter des fonds à un portefeuille.",reset_defaults:"Réinitialiser aux valeurs par défaut",reset_defaults_tooltip:"Supprimer tous les paramètres et les réinitialiser aux valeurs par défaut.",download_backup:"Télécharger la sauvegarde de la base de données",name_your_wallet:"Nommez votre portefeuille %{name}",paste_invoice_label:"Coller une facture, une demande de paiement ou un code lnurl *",lnbits_description:"Facile à installer et léger, LNbits peut fonctionner sur n'importe quelle source de financement du réseau Lightning, prenant actuellement en charge LND, Core Lightning, OpenNode, LNPay et même LNbits lui-même! Vous pouvez exécuter LNbits pour vous-même ou offrir facilement une solution de gardien pour les autres. Chaque portefeuille a ses propres clés API et il n'y a pas de limite au nombre de portefeuilles que vous pouvez créer. La capacité de partitionner les fonds rend LNbits un outil utile pour la gestion de l'argent et comme outil de développement. Les extensions ajoutent une fonctionnalité supplémentaire à LNbits afin que vous puissiez expérimenter une gamme de technologies de pointe sur le réseau Lightning. Nous avons rendu le développement d'extensions aussi simple que possible et, en tant que projet gratuit et open source, nous encourageons les gens à développer et à soumettre les leurs.",export_to_phone:"Exporter vers le téléphone avec un code QR",export_to_phone_desc:"Ce code QR contient l'URL de votre portefeuille avec un accès complet. Vous pouvez le scanner depuis votre téléphone pour ouvrir votre portefeuille depuis là-bas.",wallets:"Portefeuilles",add_wallet:"Ajouter un nouveau portefeuille",delete_wallet:"Supprimer le portefeuille",delete_wallet_desc:"Ce portefeuille entier sera supprimé et les fonds seront IRRECUPERABLES.",rename_wallet:"Renommer le portefeuille",update_name:"Mettre à jour le nom",press_to_claim:"Appuyez pour demander du Bitcoin",donate:"Donner",view_github:"Voir sur GitHub",voidwallet_active:"VoidWallet est actif! Paiements désactivés",use_with_caution:"UTILISER AVEC PRUDENCE - Le portefeuille %{name} est toujours en version BETA",toggle_darkmode:"Basculer le mode sombre",view_swagger_docs:"Voir les documents de l'API Swagger de LNbits",api_docs:"Documents de l'API",commit_version:"Version de commit",lnbits_version:"Version de LNbits",runs_on:"Fonctionne sur",credit_hint:"Appuyez sur Entrée pour créditer le compte",credit_label:"%{denomination} à créditer",paste_request:"Coller la requête",create_invoice:"Créer une facture",camera_tooltip:"Utiliser la caméra pour scanner une facture / un code QR",export_csv:"Exporter vers CSV",transactions:"Transactions",chart_tooltip:"Afficher le graphique",pending:"En attente",copy_invoice:"Copier la facture",close:"Fermer",cancel:"Annuler",scan:"Scanner",read:"Lire",pay:"Payer",memo:"Mémo",date:"Date",processing_payment:"Traitement du paiement...",not_enough_funds:"Fonds insuffisants !",search_by_tag_memo_amount:"Rechercher par tag, mémo, montant",invoice_waiting:"Facture en attente de paiement",payment_received:"Paiement reçu",payment_sent:"Paiement envoyé",receive:"recevoir",send:"envoyer",outgoing_payment_pending:"Paiement sortant en attente",drain_funds:"Vider les fonds",drain_funds_desc:"Il s'agit d'un code QR LNURL-withdraw pour tout aspirer de ce portefeuille. Ne le partagez avec personne. Il est compatible avec balanceCheck et balanceNotify, de sorte que votre portefeuille peut continuer à retirer les fonds continuellement à partir d'ici après le premier retrait.",i_understand:"J'ai compris",copy_wallet_url:"Copier l'URL du portefeuille",disclaimer_dialog:"La fonctionnalité de connexion sera publiée dans une future mise à jour, pour l'instant, assurez-vous de mettre cette page en favori pour accéder à votre portefeuille ultérieurement ! Ce service est en BETA, et nous ne sommes pas responsables des personnes qui perdent l'accès à leurs fonds.",no_transactions:"Aucune transaction effectuée pour le moment",manage_extensions:"Gérer les extensions",manage_server:"Gérer le serveur",extensions:"Extensions",no_extensions:"Vous n'avez installé aucune extension :(",created:"Créé",payment_hash:"Hash de paiement",fee:"Frais",amount:"Montant",unit:"Unité",description:"Description",expiry:"Expiration",webhook:"Webhook",payment_proof:"Preuve de paiement"},window.localisation.it={server:"Server",theme:"Tema",funding:"Funding",users:"Utenti",restart:"Riavvia il server",save:"Salva",save_tooltip:"Salva le modifiche",topup:"Ricarica",topup_wallet:"Ricarica un portafoglio",topup_hint:"Usa l'ID del portafoglio per ricaricare qualsiasi portafoglio",restart_tooltip:"Riavvia il server affinché le modifiche abbiano effetto",add_funds_tooltip:"Aggiungere fondi a un portafoglio",reset_defaults:"Ripristina le impostazioni predefinite",reset_defaults_tooltip:"Cancella tutte le impostazioni e ripristina i valori predefiniti",download_backup:"Scarica il backup del database",name_your_wallet:"Dai un nome al tuo portafoglio %{name}",paste_invoice_label:"Incolla una fattura, una richiesta di pagamento o un codice lnurl *",lnbits_description:"Leggero e facile da configurare, LNbits può funzionare su qualsiasi fonte di finanziamento lightning-network, attualmente supporta LND, Core Lightning, OpenNode, LNPay e persino LNbits stesso! Potete gestire LNbits per conto vostro o offrire facilmente una soluzione di custodia per altri. Ogni portafoglio ha le proprie chiavi API e non c'è limite al numero di portafogli che si possono creare. La possibilità di suddividere i fondi rende LNbits uno strumento utile per la gestione del denaro e come strumento di sviluppo. Le estensioni aggiungono ulteriori funzionalità a LNbits, consentendo di sperimentare una serie di tecnologie all'avanguardia sulla rete Lightning. Abbiamo reso lo sviluppo delle estensioni il più semplice possibile e, in quanto progetto libero e open-source, incoraggiamo le persone a sviluppare e inviare le proprie",export_to_phone:"Esportazione su telefono con codice QR",export_to_phone_desc:"Questo codice QR contiene l'URL del portafoglio con accesso da amministratore. È possibile scansionarlo dal telefono per aprire il portafoglio da lì.",wallets:"Portafogli",add_wallet:"Aggiungi un nuovo portafoglio",delete_wallet:"Elimina il portafoglio",delete_wallet_desc:"L'intero portafoglio sarà cancellato, i fondi saranno irrecuperabili",rename_wallet:"Rinomina il portafoglio",update_name:"Aggiorna il nome",press_to_claim:"Premi per richiedere bitcoin",donate:"Donazioni",view_github:"Visualizza su GitHub",voidwallet_active:"VoidWallet è attivo! Pagamenti disabilitati",use_with_caution:"USARE CON CAUTELA - %{nome} portafoglio è ancora in BETA",toggle_darkmode:"Attiva la modalità notturna",view_swagger_docs:"Visualizza i documenti dell'API Swagger di LNbits",api_docs:"Documenti API",commit_version:"Commit version",lnbits_version:"Versione di LNbits",runs_on:"Esegue su",credit_hint:"Premere Invio per accreditare i fondi",credit_label:"%{denomination} da accreditare",paste_request:"Richiesta di pagamento",create_invoice:"Crea fattura",camera_tooltip:"Usa la fotocamera per scansionare la fattura/QR",export_csv:"Esporta CSV",transactions:"Transazioni",chart_tooltip:"Mostra grafico",pending:"In attesa",copy_invoice:"Copia fattura",close:"Chiudi",cancel:"Annulla",scan:"Scansiona",read:"Leggi",pay:"Paga",memo:"Memo",data:"Dati",processing_payment:"Elaborazione pagamento...",not_enough_funds:"Non ci sono abbastanza fondi!",search_by_tag_memo_amount:"Cerca per tag, memo, importo...",invoice_waiting:"Fattura in attesa di pagamento",payment_received:"Pagamento ricevuto",payment_sent:"Pagamento inviato",receive:"ricevere",send:"inviare",outgoing_payment_pending:"Pagamento in uscita in attesa",drain_funds:"Fondi di drenaggio",drain_funds_desc:"Questo è un codice QR LNURL-withdraw
per prelevare tutti i fondi da questo portafoglio. Non condividerlo con nessuno. È compatibile con balanceCheck
e balanceNotify
, di conseguenza il vostro portafoglio può continuare a prelevare continuamente i fondi da qui dopo il primo prelievo",i_understand:"Ho capito",copy_wallet_url:"Copia URL portafoglio",disclaimer_dialog:"La funzionalità di login sarà rilasciata in un futuro aggiornamento; per ora, assicuratevi di salvare tra i preferiti questa pagina per accedere nuovamente in futuro a questo portafoglio! Questo servizio è in fase BETA e non ci assumiamo alcuna responsabilità per la perdita all'accesso dei fondi",no_transactions:"Nessuna transazione effettuata",manage_extensions:"Gestisci le estensioni",manage_server:"Gestisci server",estensioni:"Estensioni",no_extensions:"Non ci sono estensioni installate :(",created:"Creato",payment_hash:"Hash del pagamento",fee:"Tariffa",amount:"Importo",unit:"Unità",description:"Descrizione",expiry:"Scadenza",webhook:"Webhook",prova_di_pagamento:"Prova di pagamento"},window.localisation.jp={server:"サーバー",theme:"テーマ",funding:"資金調達",users:"ユーザー",restart:"サーバーを再起動する",save:"保存",unit:"単位",save_tooltip:"変更を保存する",topup:"トップアップ",topup_wallet:"ウォレットをトップアップする",topup_hint:"ウォレットIDを使用して、任意のウォレットをトップアップできます",restart_tooltip:"サーバーを再起動して変更を適用します",add_funds_tooltip:"ウォレットに資金を追加します。",reset_defaults:"リセット",reset_defaults_tooltip:"すべての設定を削除してデフォルトに戻します。",download_backup:"データベースのバックアップをダウンロードする",name_your_wallet:"あなたのウォレットの名前 %{name}",paste_invoice_label:"請求書を貼り付けてください",lnbits_description:"簡単にインストールでき、軽量で、LNbitsは現在LND、Core Lightning、OpenNode、LNPay、さらにLNbits自身で動作する任意のLightningネットワークの資金源で実行できます! LNbitsを自分で実行することも、他の人に優れたソリューションを提供することもできます。各ウォレットには独自のAPIキーがあり、作成できるウォレットの数に制限はありません。資金を分割する機能は、LNbitsを資金管理ツールとして使用したり、開発ツールとして使用したりするための便利なツールです。拡張機能は、LNbitsに追加の機能を追加します。そのため、LNbitsは最先端の技術をネットワークLightningで試すことができます。拡張機能を開発するのは簡単で、無料でオープンソースのプロジェクトであるため、人々が自分で開発し、自分の貢献を送信することを奨励しています。",export_to_phone:"電話にエクスポート",export_to_phone_desc:"ウォレットを電話にエクスポートすると、ウォレットを削除する前にウォレットを復元できます。ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。",wallets:"ウォレット",add_wallet:"ウォレットを追加",delete_wallet:"ウォレットを削除",delete_wallet_desc:"ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。",rename_wallet:"ウォレットの名前を変更",update_name:"名前を更新",press_to_claim:"クレームするには押してください",donate:"寄付",voidwallet_active:"Voidwalletアクティブ",use_with_caution:"注意して使用してください",toggle_dark_mode:"ダークモードを切り替える",view_swagger_docs:"Swaggerドキュメントを表示",api_docs:"APIドキュメント",commit_version:"コミットバージョン",runs_on:"で実行",credit_hint:"クレジットカードを使用して資金を追加するには、LNbitsを使用してください。",credit_label:"クレジットカード",paste_request:"リクエストを貼り付ける",create_invoice:"請求書を作成する",camera_tooltip:"QRコードを読み取る",export_csv:"CSVでエクスポート",transactions:"トランザクション",chart_tooltip:"チャートを表示するには、グラフの上にカーソルを合わせます",pending:"保留中",copy_invoice:"請求書をコピー",close:"閉じる",cancel:"キャンセル",scan:"スキャン",read:"読む",pay:"支払う",memo:"メモ",date:"日付",processing_payment:"支払い処理中",not_enough_funds:"資金が不足しています",search_by_tag_memo_amount:"タグ、メモ、金額で検索",invoice_waiting:"請求書を待っています",payment_received:"お支払いありがとうございます",payment_sent:"支払いが完了しました",receive:"受け取る",send:"送信",outgoing_payment_pending:"支払い保留中",drain_funds:"資金を排出する",drain_funds_desc:"ウォレットの残高をすべて他のウォレットに送金します",i_understand:"理解した",copy_wallet_url:"ウォレットURLをコピー",disclaimer_dialog:"ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。ウォレットを削除する前に、ウォレットをエクスポートしてください。",no_transactions:"トランザクションはありません",manage_server:"サーバーを管理する",extensions:"拡張機能",no_extensions:"拡張機能はありません",created:"作成済み",search_extensions:"検索拡張機能",warning:"警告",manage:"管理",repository:"リポジトリ",confirm_continue:"続行してもよろしいですか?",manage_extension_details:"拡張機能のインストール/アンインストール",install:"インストール",uninstall:"アンインストール",open:"開く",enable:"有効",enable_extension_details:"現在のユーザーの拡張機能を有効にする",disable:"無効",installed:"インストール済み",activated:"有効化",deactivated:"無効化",release_notes:"リリースノート",activate_extension_details:"拡張機能をユーザーが利用できるようにする/利用できないようにする",featured:"特集",all:"すべて",only_admins_can_install:"(管理者アカウントのみが拡張機能をインストールできます)",new_version:"新しいバージョン",extension_depends_on:"依存先:",extension_rating_soon:"評価は近日公開",extension_installed_version:"インストール済みバージョン",extension_uninstall_warning:"すべてのユーザーの拡張機能を削除しようとしています.",uninstall_confirm:"はい、アンインストールします",extension_min_lnbits_version:"このリリースには少なくとも LNbits バージョンが必要です",payment_hash:"支払いハッシュ",fee:"料金",amount:"量",description:"説明",expiry:"有効期限",webhook:"ウェブフック",payment_proof:"支払い証明"},window.localisation.cn={confirm:"确定",server:"服务器",theme:"主题",funding:"资金",users:"用户",restart:"重新启动服务器",save:"保存",save_tooltip:"保存更改",topup:"充值",topup_wallet:"给钱包充值",topup_hint:"使用钱包ID为任何钱包充值",restart_tooltip:"重新启动服务器以使更改生效",add_funds_tooltip:"为钱包添加资金",reset_defaults:"重置为默认设置",reset_defaults_tooltip:"删除所有设置并重置为默认设置",download_backup:"下载数据库备份",name_your_wallet:"给你的 %{name}钱包起个名字",paste_invoice_label:"粘贴发票,付款请求或lnurl*",lnbits_description:"LNbits 设置简单、轻量级,可以运行在任何闪电网络的版本上,目前支持 LND、Core Lightning、OpenNode、LNPay,甚至 LNbits 本身!您可以为自己运行 LNbits,或者为他人轻松提供资金托管。每个钱包都有自己的 API 密钥,你可以创建的钱包数量没有限制。能够把资金分开管理使 LNbits 成为一款有用的资金管理和开发工具。扩展程序增加了 LNbits 的额外功能,所以你可以在闪电网络上尝试各种尖端技术。我们已经尽可能简化了开发扩展程序的过程,作为一个免费和开源的项目,我们鼓励人们开发并提交自己的扩展程序。",export_to_phone:"通过二维码导出到手机",export_to_phone_desc:"这个二维码包含您钱包的URL。您可以使用手机扫描的方式打开您的钱包。",wallets:"钱包",add_wallet:"添加新钱包",delete_wallet:"删除钱包",delete_wallet_desc:"整个钱包将被删除,资金将无法恢复",rename_wallet:"重命名钱包",update_name:"更新名称",press_to_claim:"点击领取比特币",donate:"捐献",view_github:"在GitHub上查看",voidwallet_active:"VoidWallet 已激活!付款功能已禁用。",use_with_caution:"请谨慎使用 - %{name}钱包还处于测试版阶段",toggle_darkmode:"切换暗黑模式",view_swagger_docs:"查看 LNbits Swagger API 文档",api_docs:"API文档",commit_version:"提交版本",lnbits_version:"LNbits版本",runs_on:"可运行在",credit_hint:"按 Enter 键充值账户",credit_label:"%{denomination} 充值",paste_request:"粘贴请求",create_invoice:"创建发票",camera_tooltip:"用相机扫描发票/二维码",export_csv:"导出为CSV",transactions:"交易记录",chart_tooltip:"显示图表",pending:"待处理",copy_invoice:"复制发票",close:"关闭",cancel:"取消",scan:"扫描",read:"读取",pay:"付款",memo:"备注",date:"日期",processing_payment:"正在处理支付...",not_enough_funds:"资金不足!",search_by_tag_memo_amount:"按标签、备注、金额搜索",invoice_waiting:"待支付的发票",payment_received:"收到付款",payment_sent:"付款已发送",receive:"收款",send:"付款",outgoing_payment_pending:"付款正在等待处理",drain_funds:"清空资金",drain_funds_desc:"这是一个 LNURL-取款的二维码,用于从该钱包中提取全部资金。请不要与他人分享。它与 balanceCheck 和 balanceNotify 兼容,因此在第一次取款后,您的钱包还可能会持续从这里提取资金",i_understand:"我明白",copy_wallet_url:"复制钱包URL",disclaimer_dialog:"登录功能将在以后的更新中发布,请将此页面加为书签,以便将来访问您的钱包!此服务处于测试阶段,我们不对资金的丢失承担任何责任。",no_transactions:"尚未进行任何交易",manage_server:"管理服务器",extensions:"扩展程序",no_extensions:"你没有安装任何扩展程序 :(",created:"已创建",search_extensions:"搜索扩展程序",warning:"警告",manage:"管理",repository:"代码库",confirm_continue:"你确定要继续吗?",manage_extension_details:"安装/卸载扩展程序",install:"安装",uninstall:"卸载",drop_db:"删除数据",open:"打开",enable:"启用",enable_extension_details:"为当前用户启用扩展程序",disable:"禁用",installed:"已安装",activated:"已激活",deactivated:"已停用",release_notes:"发布说明",activate_extension_details:"对用户开放或禁用扩展程序",featured:"精选",all:"全部",only_admins_can_install:"(只有管理员账户可以安装扩展)",admin_only:"仅限管理员",new_version:"新版本",extension_depends_on:"依赖于:",extension_rating_soon:"即将推出评分",extension_installed_version:"已安装的版本",extension_uninstall_warning:"您即将对所有用户删除该扩展程序。",uninstall_confirm:"是的,卸载",extension_db_drop_info:"该扩展程序的所有数据将被永久删除。此操作无法撤销!",extension_db_drop_warning:"您即将删除该扩展的所有数据。请继续输入扩展程序名称以确认操作:",extension_min_lnbits_version:"此版本要求最低的 LNbits 版本为",payment_hash:"付款哈希",fee:"费",amount:"金额",unit:"单位",description:"详情",expiry:"过期时间",webhook:"Webhook",payment_proof:"付款证明"},window.localisation.nl={server:"Server",theme:"Thema",funding:"Financiering",users:"Gebruikers",restart:"Server opnieuw opstarten",save:"Opslaan",save_tooltip:"Sla uw wijzigingen op",topup:"Bijvullen",topup_wallet:"Een portemonnee bijvullen",topup_hint:"Gebruik de portemonnee-ID om elke portemonnee bij te vullen",restart_tooltip:"Start de server opnieuw op zodat wijzigingen van kracht worden",add_funds_tooltip:"Voeg geld toe aan een portemonnee.",reset_defaults:"Standaardinstellingen herstellen",reset_defaults_tooltip:"Wis alle instellingen en herstel de standaardinstellingen.",download_backup:"Databaseback-up downloaden",name_your_wallet:"Geef je %{name} portemonnee een naam",paste_invoice_label:"Plak een factuur, betalingsverzoek of lnurl-code*",lnbits_description:"Gemakkelijk in te stellen en lichtgewicht, LNbits kan op elke lightning-netwerkfinancieringsbron draaien, ondersteunt op dit moment LND, Core Lightning, OpenNode, LNPay en zelfs LNbits zelf! U kunt LNbits voor uzelf laten draaien of gemakkelijk een bewaardersoplossing voor anderen bieden. Elke portemonnee heeft zijn eigen API-sleutels en er is geen limiet aan het aantal portemonnees dat u kunt maken. Het kunnen partitioneren van fondsen maakt LNbits een nuttige tool voor geldbeheer en als ontwikkelingstool. Extensies voegen extra functionaliteit toe aan LNbits, zodat u kunt experimenteren met een reeks toonaangevende technologieën op het bliksemschichtnetwerk. We hebben het ontwikkelen van extensies zo eenvoudig mogelijk gemaakt en als een gratis en opensource-project moedigen we mensen aan om hun eigen ontwikkelingen in te dienen.",export_to_phone:"Exporteren naar telefoon met QR-code",export_to_phone_desc:"Deze QR-code bevat uw portemonnee-URL met volledige toegang. U kunt het vanaf uw telefoon scannen om uw portemonnee van daaruit te openen.",wallets:"Portemonnees",add_wallet:"Een nieuwe portemonnee toevoegen",delete_wallet:"Portemonnee verwijderen",delete_wallet_desc:"Deze hele portemonnee wordt verwijderd, de fondsen worden NIET TERUGGEVONDEN.",rename_wallet:"Portemonnee hernoemen",update_name:"Naam bijwerken",press_to_claim:"Druk om bitcoin te claimen",donate:"Doneren",view_github:"Bekijken op GitHub",voidwallet_active:"VoidWallet is actief! Betalingen uitgeschakeld",use_with_caution:"GEBRUIK MET VOORZICHTIGHEID - %{name} portemonnee is nog in BETA",toggle_darkmode:"Donkere modus aan/uit",view_swagger_docs:"Bekijk LNbits Swagger API-documentatie",api_docs:"API-documentatie",commit_version:"Commit-versie",lnbits_version:"LNbits-versie",runs_on:"Draait op",credit_hint:"Druk op Enter om de rekening te crediteren",credit_label:"%{denomination} te crediteren",paste_request:"Verzoek plakken",create_invoice:"Factuur aanmaken",camera_tooltip:"Gebruik de camera om een factuur/QR-code te scannen",export_csv:"Exporteer naar CSV",transactions:"Transacties",chart_tooltip:"Toon grafiek",pending:"In behandeling",copy_invoice:"Kopieer factuur",close:"Sluiten",cancel:"Annuleren",scan:"Scannen",read:"Lezen",pay:"Betalen",memo:"Memo",date:"Datum",processing_payment:"Verwerking betaling...",not_enough_funds:"Onvoldoende saldo!",search_by_tag_memo_amount:"Zoeken op tag, memo, bedrag",invoice_waiting:"Factuur wachtend op betaling",payment_received:"Betaling ontvangen",payment_sent:"Betaling verzonden",receive:"ontvangen",send:"versturen",voutgoing_payment_pending:"Uitgaande betaling in behandeling",drain_funds:"Geld opnemen",drain_funds_desc:"Dit is een LNURL-withdraw QR-code om alles uit deze portemonnee te halen. Deel deze code niet met anderen. Het is compatibel met balanceCheck en balanceNotify zodat jouw portemonnee continu geld kan blijven opnemen vanaf hier na de eerste opname.",i_understand:"Ik begrijp het",copy_wallet_url:"Kopieer portemonnee-URL",disclaimer_dialog:"Inlogfunctionaliteit wordt uitgebracht in een toekomstige update. Zorg er nu voor dat je deze pagina als favoriet markeert om in de toekomst toegang te krijgen tot je portemonnee! Deze service is in BETA en we zijn niet verantwoordelijk voor mensen die de toegang tot hun fondsen verliezen.",no_transactions:"Er zijn nog geen transacties gedaan",manage_extensions:"Beheer extensies",manage_server:"Beheer server",extensions:"Extensies",no_extensions:"Je hebt geen extensies geïnstalleerd :(",created:"Aangemaakt",payment_hash:"Betalings-hash",fee:"Kosten",amount:"Bedrag",unit:"Eenheid",description:"Beschrijving",expiry:"Vervaldatum",webhook:"Webhook",payment_proof:"Betalingsbewijs"},window.localisation.pi={server:"Cap`n",theme:"Theme",funding:"Funding",users:"Buccaneers",restart:"Arr, restart Cap`n",save:"Bury Treasure",save_tooltip:"Bury yer changes, matey",topup:"Top up the Chest",topup_wallet:"Add more doubloons to the chest",topup_hint:"Use the chest ID to top up any chest",restart_tooltip:"Restart the Cap`n for changes to take effect, arr!",add_funds_tooltip:"Add doubloons to a chest and make it heavier",reset_defaults:"Reset to Davy Jones Locker",reset_defaults_tooltip:"Scuttle all settings and reset to Davy Jones Locker. Aye, start anew!",download_backup:"Download database booty",name_your_wallet:"Name yer %{name} treasure chest",paste_invoice_label:"Paste a booty, payment request or lnurl code, matey!",lnbits_description:"Arr, easy to set up and lightweight, LNbits can run on any lightning-network funding source, currently supporting LND, Core Lightning, OpenNode, LNPay and even LNbits itself! Ye can run LNbits for yourself, or easily offer a custodian solution for others. Each chest has its own API keys and there be no limit to the number of chests ye can make. Being able to partition booty makes LNbits a useful tool for money management and as a development tool. Arr, extensions add extra functionality to LNbits so ye can experiment with a range of cutting-edge technologies on the lightning network. We have made developing extensions as easy as possible, and as a free and open-source project, we encourage scallywags to develop and submit their own.",export_to_phone:"Export to Phone with QR Code, me hearties",export_to_phone_desc:"This QR code contains yer chest URL with full access. Ye can scan it from yer phone to open yer chest from there, arr!",wallets:"Treasure Chests",add_wallet:"Add a new chest and fill it with doubloons!",delete_wallet:"Scuttle the Chest",delete_wallet_desc:"This whole chest will be scuttled, the booty will be UNRECOVERABLE. Aye, be warned!",rename_wallet:"Rename the Chest, me hearty",update_name:"Update name like a captain",press_to_claim:"Press to claim gold doubloons, matey!",donate:"Donate like a true pirate!",view_github:"View on GitHub and find treasures",voidwallet_active:"VoidWallet be active! Payments disabled",use_with_caution:"USE WITH CAUTION - %{name} chest be still in BETA. Aye, be careful!",toggle_darkmode:"Toggle Dark Mode, arr!",view_swagger_docs:"View LNbits Swagger API docs and learn the secrets",api_docs:"API docs for the scallywags",commit_version:"Commit version like a true pirate",lnbits_version:"LNbits version, arr!",runs_on:"Runs on, matey",credit_hint:"Press Enter to credit account and make it richer",credit_label:"%{denomination} to credit, arr!",paste_request:"Paste Request and find treasures",create_invoice:"Create Booty Request and get rich, me hearties!",camera_tooltip:"Use spyglass to scan a booty/QR, arr!",export_csv:"Export to CSV and keep track of the booty",transactions:"Pirate Transactions and loot",chart_tooltip:"Show ye chart, me hearty",pending:"Pendin like a ship at anchor",copy_invoice:"Copy booty request, arrr",close:"Batten down the hatches, we be closin",cancel:"Abandon ship! We be retreatin",scan:"Avast! Scan me beauty, arrr",read:"Read it, if ye dare",pay:"Pay up or walk the plank, ye scallywag",memo:"Message in a bottle, argh",date:"Date of the map, me matey",processing_payment:"Processing yer payment... don´t make me say it again",not_enough_funds:"Arrr, ye don´t have enough doubloons! Walk the plank!",search_by_tag_memo_amount:"Search by tag, message, or booty amount, savvy",invoice_waiting:"Invoice waiting to be plundered, arrr",payment_received:"Payment Received like a treasure, argh",payment_sent:"Payment Sent, hoist the colors! We´ve got some doubloons!",receive:"booty",send:"hoist",outgoing_payment_pending:"Outgoing payment pending in the port, ye scurvy dog",drain_funds:"Plunder all the doubloons, ye buccaneer",drain_funds_desc:"This be an LNURL-withdraw QR code for slurpin everything from this wallet. Don`t share with anyone. It be compatible with balanceCheck and balanceNotify so yer wallet may keep pullin` the funds continuously from here after the first withdraw.",i_understand:"I understand, yo ho ho and a bottle of rum!",copy_wallet_url:"Copy wallet URL like a map, savvy",disclaimer_dialog:"Login functionality to be released in a future update, for now, make sure ye bookmark this page for future access to your booty! This service be in BETA, and we hold no responsibility for people losing access to doubloons.",no_transactions:"No transactions made yet, me hearties. Belay that!",manage_extensions:"Manage Yer Extensions, ye landlubber",manage_server:"Manage Yer Server, me hearty",extensions:"Yer Extensions, ye scurvy dog",no_extensions:"Ye don't have any extensions installed, ye scallywag :(. Where be yer loot?",created:"Created like a legend, savvy",payment_hash:"Payment Hash like a treasure map, arrr",fee:"Fee like a toll to cross a strait, matey",amount:"Amount of doubloons, arrr",unit:"Unit of measurement like a fathom, ye buccaneer",description:"Description like a tale of adventure, arrr",expiry:"Expiry like the food on a ship, ye landlubber",webhook:"Webhook like a fishing line, arrr",payment_proof:"Payment Proof like a seal of authenticity, argh"},window.localisation.pl={server:"Serwer",theme:"Motyw",funding:"Finansowanie",users:"Użytkownicy",restart:"Restart serwera",save:"Zapisz",save_tooltip:"Zapisz zmiany",topup:"Doładowanie",topup_wallet:"Doładuj portfel",topup_hint:"Użyj ID portfela aby go doładować",restart_tooltip:"Zrestartuj serwer aby aktywować zmiany",add_funds_tooltip:"Dodaj środki do portfela.",reset_defaults:"Powrót do ustawień domyślnych",reset_defaults_tooltip:"Wymaż wszystkie ustawienia i ustaw domyślne.",download_backup:"Pobierz kopię zapasową bazy danych",name_your_wallet:"Nazwij swój portfel %{name}",paste_invoice_label:"Wklej fakturę, żądanie zapłaty lub kod lnurl *",lnbits_description:"Łatwy i lekki w konfiguracji, LNbits może działać w oparciu o dowolne źródło finansowania w sieci lightning, obecnie wspiera LND, Core Lightning, OpenNode, LNPay czy nawet inną instancję LNbits! Możesz uruchomić instancję LNbits dla siebie lub dla innych. Każdy portfel ma swoje klucze API i nie ma ograniczeń jeśli chodzi o ilość portfeli. LNbits umożliwia dzielenie środków w celu zarządzania nimi, jest również dobrym narzędziem deweloperskim. Rozszerzenia zwiększają funkcjonalność LNbits co umożliwia eksperymentowanie z nowym technologiami w sieci lightning. Tworzenie rozszerzeń jest proste dlatego zachęcamy innych deweloperów do tworzenia dodatkowych funkcjonalności i wysyłanie do nas PR",export_to_phone:"Eksport kodu QR na telefon",export_to_phone_desc:"Ten kod QR zawiera adres URL Twojego portfela z pełnym dostępem do niego. Możesz go zeskanować na swoim telefonie aby otworzyć na nim ten portfel.",wallets:"Portfele",add_wallet:"Dodaj portfel",delete_wallet:"Usuń portfel",delete_wallet_desc:"Ten portfel zostanie usunięty, środków na nim zgromadzonych NIE BĘDZIE MOŻNA ODZYSKAĆ.",rename_wallet:"Zmień nazwę portfela",update_name:"Zaktualizuj nazwę",press_to_claim:"Naciśnij aby odebrać Bitcoiny",donate:"Podaruj",view_github:"Otwórz GitHub",voidwallet_active:"VoidWallet jest aktywny! Płatności są niemożliwe",use_with_caution:"KORZYSTAJ Z ROZWAGĄ - portfel %{name} jest w wersji BETA",toggle_darkmode:"Tryb nocny",view_swagger_docs:"Dokumentacja Swagger API",api_docs:"Dokumentacja API",commit_version:"Commit",lnbits_version:"Wersja LNbits",runs_on:"Działa na",credit_hint:"Naciśnij Enter aby doładować konto",credit_label:"%{denomination} doładowanie",paste_request:"Wklej żądanie",create_invoice:"Utwórz fakturę",camera_tooltip:"Użyj kamery aby zeskanować fakturę lub kod QR",export_csv:"Eksport do CSV",transactions:"Transakcje",chart_tooltip:"Wykres",pending:"W toku",copy_invoice:"Skopiuj fakturę",close:"Zamknij",cancel:"Anuluj",scan:"Skanuj",read:"Odczytaj",pay:"Zapłać",memo:"Memo",date:"Data",processing_payment:"Przetwarzam płatność...",not_enough_funds:"Brak wystarczających środków!",search_by_tag_memo_amount:"Szukaj po tagu, memo czy wartości",invoice_waiting:"Faktura oczekuje na zapłatę",payment_received:"Otrzymano płatność",payment_sent:"Wysłano płatność",receive:"odbierać",send:"wysłać",outgoing_payment_pending:"Płatność wychodząca w toku",drain_funds:"Opróżnij środki",drain_funds_desc:"To jest kod QR służący do opróżnienia portfela (LNURL-withdraw). Nie udostępniaj go nikomu. Ten kod jest kompatybilny z funkcjami, które umożliwiają wielokrotne żądania aż do zupełnego opróżnienia portfela.",i_understand:"Rozumiem",copy_wallet_url:"Skopiuj URL portfela",disclaimer_dialog:"Funkcja logowania zostanie uruchomiona w przyszłości. Póki co upewnij się, że zapisałeś adres URL tej strony aby mieć dostęp do tego portfela. Nie udostępniaj adresu tej strony nikomu, kto nie ma mieć do tego portfela dostępu! Ta usługa działa w wersji BETA, nie odpowiadamy za utratę dostępu do środków przez osoby używające LNbits.",no_transactions:"Brak transakcji",manage_extensions:"Zarządzaj rozszerzeniami",manage_server:"Zarządzaj serwerem",extensions:"Rozszerzenia",no_extensions:"Nie masz zainstalowanych żadnych rozszerzeń :(",created:"Utworzono",payment_hash:"Hash Płatności",fee:"Opłata",amount:"Wartość",unit:"Jednostka",description:"Opis",expiry:"Wygasa",webhook:"Webhook",payment_proof:"Potwierdzenie płatności"},window.localisation.fr={server:"Serveur",theme:"Thème",funding:"Financement",users:"Utilisateurs",restart:"Redémarrer le serveur",save:"Enregistrer",save_tooltip:"Enregistrer vos modifications",topup:"Renflouer",topup_wallet:"Reflouer un portefeuille",topup_hint:"Utilisez l'ID du portefeuille pour recharger n'importe quel portefeuille",restart_tooltip:"Redémarrez le serveur pour que les changements prennent effet",add_funds_tooltip:"Ajouter des fonds à un portefeuille.",reset_defaults:"Réinitialiser aux valeurs par défaut",reset_defaults_tooltip:"Supprimer tous les paramètres et les réinitialiser aux valeurs par défaut.",download_backup:"Télécharger la sauvegarde de la base de données",name_your_wallet:"Nommez votre portefeuille %{name}",paste_invoice_label:"Coller une facture, une demande de paiement ou un code lnurl *",lnbits_description:"Facile à installer et léger, LNbits peut fonctionner sur n'importe quelle source de financement du réseau Lightning, prenant actuellement en charge LND, Core Lightning, OpenNode, LNPay et même LNbits lui-même! Vous pouvez exécuter LNbits pour vous-même ou offrir facilement une solution de gardien pour les autres. Chaque portefeuille a ses propres clés API et il n'y a pas de limite au nombre de portefeuilles que vous pouvez créer. La capacité de partitionner les fonds rend LNbits un outil utile pour la gestion de l'argent et comme outil de développement. Les extensions ajoutent une fonctionnalité supplémentaire à LNbits afin que vous puissiez expérimenter une gamme de technologies de pointe sur le réseau Lightning. Nous avons rendu le développement d'extensions aussi simple que possible et, en tant que projet gratuit et open source, nous encourageons les gens à développer et à soumettre les leurs.",export_to_phone:"Exporter vers le téléphone avec un code QR",export_to_phone_desc:"Ce code QR contient l'URL de votre portefeuille avec un accès complet. Vous pouvez le scanner depuis votre téléphone pour ouvrir votre portefeuille depuis là-bas.",wallets:"Portefeuilles",add_wallet:"Ajouter un nouveau portefeuille",delete_wallet:"Supprimer le portefeuille",delete_wallet_desc:"Ce portefeuille entier sera supprimé et les fonds seront IRRECUPERABLES.",rename_wallet:"Renommer le portefeuille",update_name:"Mettre à jour le nom",press_to_claim:"Appuyez pour demander du Bitcoin",donate:"Donner",view_github:"Voir sur GitHub",voidwallet_active:"VoidWallet est actif! Paiements désactivés",use_with_caution:"UTILISER AVEC PRUDENCE - Le portefeuille %{name} est toujours en version BETA",toggle_darkmode:"Basculer le mode sombre",view_swagger_docs:"Voir les documents de l'API Swagger de LNbits",api_docs:"Documents de l'API",commit_version:"Version de commit",lnbits_version:"Version de LNbits",runs_on:"Fonctionne sur",credit_hint:"Appuyez sur Entrée pour créditer le compte",credit_label:"%{denomination} à créditer",paste_request:"Coller la requête",create_invoice:"Créer une facture",camera_tooltip:"Utiliser la caméra pour scanner une facture / un code QR",export_csv:"Exporter vers CSV",transactions:"Transactions",chart_tooltip:"Afficher le graphique",pending:"En attente",copy_invoice:"Copier la facture",close:"Fermer",cancel:"Annuler",scan:"Scanner",read:"Lire",pay:"Payer",memo:"Mémo",date:"Date",processing_payment:"Traitement du paiement...",not_enough_funds:"Fonds insuffisants !",search_by_tag_memo_amount:"Rechercher par tag, mémo, montant",invoice_waiting:"Facture en attente de paiement",payment_received:"Paiement reçu",payment_sent:"Paiement envoyé",receive:"recevoir",send:"envoyer",outgoing_payment_pending:"Paiement sortant en attente",drain_funds:"Vider les fonds",drain_funds_desc:"Il s'agit d'un code QR LNURL-withdraw pour tout aspirer de ce portefeuille. Ne le partagez avec personne. Il est compatible avec balanceCheck et balanceNotify, de sorte que votre portefeuille peut continuer à retirer les fonds continuellement à partir d'ici après le premier retrait.",i_understand:"J'ai compris",copy_wallet_url:"Copier l'URL du portefeuille",disclaimer_dialog:"La fonctionnalité de connexion sera publiée dans une future mise à jour, pour l'instant, assurez-vous de mettre cette page en favori pour accéder à votre portefeuille ultérieurement ! Ce service est en BETA, et nous ne sommes pas responsables des personnes qui perdent l'accès à leurs fonds.",no_transactions:"Aucune transaction effectuée pour le moment",manage_extensions:"Gérer les extensions",manage_server:"Gérer le serveur",extensions:"Extensions",no_extensions:"Vous n'avez installé aucune extension :(",created:"Créé",payment_hash:"Hash de paiement",fee:"Frais",amount:"Montant",unit:"Unité",description:"Description",expiry:"Expiration",webhook:"Webhook",payment_proof:"Preuve de paiement"},window.localisation.nl={server:"Server",theme:"Thema",funding:"Financiering",users:"Gebruikers",restart:"Server opnieuw opstarten",save:"Opslaan",save_tooltip:"Sla uw wijzigingen op",topup:"Bijvullen",topup_wallet:"Een portemonnee bijvullen",topup_hint:"Gebruik de portemonnee-ID om elke portemonnee bij te vullen",restart_tooltip:"Start de server opnieuw op zodat wijzigingen van kracht worden",add_funds_tooltip:"Voeg geld toe aan een portemonnee.",reset_defaults:"Standaardinstellingen herstellen",reset_defaults_tooltip:"Wis alle instellingen en herstel de standaardinstellingen.",download_backup:"Databaseback-up downloaden",name_your_wallet:"Geef je %{name} portemonnee een naam",paste_invoice_label:"Plak een factuur, betalingsverzoek of lnurl-code*",lnbits_description:"Gemakkelijk in te stellen en lichtgewicht, LNbits kan op elke lightning-netwerkfinancieringsbron draaien, ondersteunt op dit moment LND, Core Lightning, OpenNode, LNPay en zelfs LNbits zelf! U kunt LNbits voor uzelf laten draaien of gemakkelijk een bewaardersoplossing voor anderen bieden. Elke portemonnee heeft zijn eigen API-sleutels en er is geen limiet aan het aantal portemonnees dat u kunt maken. Het kunnen partitioneren van fondsen maakt LNbits een nuttige tool voor geldbeheer en als ontwikkelingstool. Extensies voegen extra functionaliteit toe aan LNbits, zodat u kunt experimenteren met een reeks toonaangevende technologieën op het bliksemschichtnetwerk. We hebben het ontwikkelen van extensies zo eenvoudig mogelijk gemaakt en als een gratis en opensource-project moedigen we mensen aan om hun eigen ontwikkelingen in te dienen.",export_to_phone:"Exporteren naar telefoon met QR-code",export_to_phone_desc:"Deze QR-code bevat uw portemonnee-URL met volledige toegang. U kunt het vanaf uw telefoon scannen om uw portemonnee van daaruit te openen.",wallets:"Portemonnees",add_wallet:"Een nieuwe portemonnee toevoegen",delete_wallet:"Portemonnee verwijderen",delete_wallet_desc:"Deze hele portemonnee wordt verwijderd, de fondsen worden NIET TERUGGEVONDEN.",rename_wallet:"Portemonnee hernoemen",update_name:"Naam bijwerken",press_to_claim:"Druk om bitcoin te claimen",donate:"Doneren",view_github:"Bekijken op GitHub",voidwallet_active:"VoidWallet is actief! Betalingen uitgeschakeld",use_with_caution:"GEBRUIK MET VOORZICHTIGHEID - %{name} portemonnee is nog in BETA",toggle_darkmode:"Donkere modus aan/uit",view_swagger_docs:"Bekijk LNbits Swagger API-documentatie",api_docs:"API-documentatie",commit_version:"Commit-versie",lnbits_version:"LNbits-versie",runs_on:"Draait op",credit_hint:"Druk op Enter om de rekening te crediteren",credit_label:"%{denomination} te crediteren",paste_request:"Verzoek plakken",create_invoice:"Factuur aanmaken",camera_tooltip:"Gebruik de camera om een factuur/QR-code te scannen",export_csv:"Exporteer naar CSV",transactions:"Transacties",chart_tooltip:"Toon grafiek",pending:"In behandeling",copy_invoice:"Kopieer factuur",close:"Sluiten",cancel:"Annuleren",scan:"Scannen",read:"Lezen",pay:"Betalen",memo:"Memo",date:"Datum",processing_payment:"Verwerking betaling...",not_enough_funds:"Onvoldoende saldo!",search_by_tag_memo_amount:"Zoeken op tag, memo, bedrag",invoice_waiting:"Factuur wachtend op betaling",payment_received:"Betaling ontvangen",payment_sent:"Betaling verzonden",receive:"ontvangen",send:"versturen",voutgoing_payment_pending:"Uitgaande betaling in behandeling",drain_funds:"Geld opnemen",drain_funds_desc:"Dit is een LNURL-withdraw QR-code om alles uit deze portemonnee te halen. Deel deze code niet met anderen. Het is compatibel met balanceCheck en balanceNotify zodat jouw portemonnee continu geld kan blijven opnemen vanaf hier na de eerste opname.",i_understand:"Ik begrijp het",copy_wallet_url:"Kopieer portemonnee-URL",disclaimer_dialog:"Inlogfunctionaliteit wordt uitgebracht in een toekomstige update. Zorg er nu voor dat je deze pagina als favoriet markeert om in de toekomst toegang te krijgen tot je portemonnee! Deze service is in BETA en we zijn niet verantwoordelijk voor mensen die de toegang tot hun fondsen verliezen.",no_transactions:"Er zijn nog geen transacties gedaan",manage_extensions:"Beheer extensies",manage_server:"Beheer server",extensions:"Extensies",no_extensions:"Je hebt geen extensies geïnstalleerd :(",created:"Aangemaakt",payment_hash:"Betalings-hash",fee:"Kosten",amount:"Bedrag",unit:"Eenheid",description:"Beschrijving",expiry:"Vervaldatum",webhook:"Webhook",payment_proof:"Betalingsbewijs"},window.localisation.we={server:"Gweinydd",theme:"Thema",funding:"Arian fyndio",users:"Defnyddwyr",restart:"Ailgychwyn gweinydd",save:"Save",save_tooltip:"cadw eich newidiadau",topup:"Topup",topup_wallet:"Atodi waled",topup_hint:"Defnyddiwch ID y waled i ychwanegu at unrhyw waled",restart_tooltip:"Ailgychwyn y gweinydd er mwyn i newidiadau ddod i rym",add_funds_tooltip:"Ychwanegu arian at waled.",reset_defaults:"Ailosod i`r rhagosodiadau",reset_defaults_tooltip:"Dileu pob gosodiad ac ailosod i`r rhagosodiadau.",download_backup:"Lawrlwytho copi wrth gefn cronfa ddata",name_your_wallet:"Enwch eich waled %{name}",paste_invoice_label:"Gludwch anfoneb, cais am daliad neu god lnurl *",lnbits_description:"Yn hawdd iw sefydlu ac yn ysgafn, gall LNbits redeg ar unrhyw ffynhonnell ariannu rhwydwaith mellt, ar hyn o bryd yn cefnogi LND, Core Lightning, OpenNode, LNPay a hyd yn oed LNbits ei hun! Gallwch redeg LNbits i chi`ch hun, neu gynnig datrysiad ceidwad i eraill yn hawdd. Mae gan bob waled ei allweddi API ei hun ac nid oes cyfyngiad ar nifer y waledi y gallwch eu gwneud. Mae gallu rhannu cronfeydd yn gwneud LNbits yn arf defnyddiol ar gyfer rheoli arian ac fel offeryn datblygu. Mae estyniadau yn ychwanegu ymarferoldeb ychwanegol at LNbits fel y gallwch arbrofi gydag ystod o dechnolegau blaengar ar y rhwydwaith mellt. Rydym wedi gwneud datblygu estyniadau mor hawdd â phosibl, ac fel prosiect ffynhonnell agored am ddim, rydym yn annog pobl i ddatblygu a chyflwyno eu rhai eu hunain.",export_to_phone:"Allforio i Ffôn gyda chod QR",export_to_phone_desc:"Mae`r cod QR hwn yn cynnwys URL eich waled gyda mynediad llawn. Gallwch ei sganio o`ch ffôn i agor eich waled oddi yno.",waledi:"Waledi",add_wallet:"Ychwanegu waled newydd",delete_wallet:"Dileu waled",delete_wallet_desc:"Bydd y waled gyfan hon yn cael ei dileu, ni fydd modd adennill yr arian.",rename_wallet:"Ailenwi waled",update_name:"Diweddaru enw",press_to_claim:"Pwyswch i hawlio bitcoin",Donate:"Rhoi",view_github:"Gweld ar GitHub",voidwallet_active:" Mae VoidWallet yn weithredol! Taliadau wedi`u hanalluogi",use_with_caution:"DEFNYDDIO GYDA GOFAL - mae waled %{name} yn dal yn BETA",toggle_darkmode:"Toglo Modd Tywyll",view_swagger_docs:"Gweld dogfennau API LNbits Swagger",api_docs:"Api docs",commit_version:"fersiwn ymrwymo",lnbits_version:"Fersiwn LNbits",Runs_on:"Yn rhedeg ymlaen",credit_hint:"Pwyswch Enter i gyfrif credyd",credit_label:"%{enomination} i gredyd",paste_request:"Gludo Cais",create_invoice:"Creu Anfoneb",camera_tooltip:"Defnyddio camera i sganio anfoneb/QR",export_csv:"Allforio i CSV",trafodion:"Trafodion",chart_tooltip:"Dangos siart",pending:"yn yr arfaeth",copy_invoice:"Copi anfoneb",Close:"cau",cancel:"Canslo",scan:"Sgan",read:"Darllen",talu:"Pay",memo:"Memo",date:"Dyddiad",processing_payment:"Prosesu taliad...",not_enough_funds:"Dim digon o arian!",search_by_tag_memo_amount:"Chwilio yn ôl tag, memo, swm",invoice_waiting:"Anfoneb yn aros i gael ei thalu",payment_received:"Taliad a Dderbyniwyd",payment_sent:"Taliad a Anfonwyd",receive:"derbyn",send:"anfon",outgoing_payment_pending:"Taliad sy`n aros yn yr arfaeth",drain_funds:"Cronfeydd Draenio",drain_funds_desc:"Cod QR Tynnu`n ôl LNURL yw hwn ar gyfer slurpio popeth o`r waled hon. Peidiwch â rhannu gyda neb. Mae`n gydnaws â balanceCheck a balanceNotify felly efallai y bydd eich waled yn tynnu`r arian yn barhaus o`r fan hon ar ôl y codiad cyntaf.",i_understand:"Rwy`n deall",copy_wallet_url:"Copi URL waled",disclaimer_dialog:"Swyddogaeth mewngofnodi i`w ryddhau mewn diweddariad yn y dyfodol, am y tro, gwnewch yn siŵr eich bod yn rhoi nod tudalen ar y dudalen hon ar gyfer mynediad i`ch waled yn y dyfodol! Mae`r gwasanaeth hwn yn BETA, ac nid ydym yn gyfrifol am bobl sy`n colli mynediad at arian.",no_transactions:"Dim trafodion wedi`u gwneud eto",manage_extensions:"Rheoli Estyniadau",manage_server:"Rheoli Gweinydd",Extensions:"Estyniadau",no_extensions:"Nid oes gennych unrhyw estyniadau wedi'u gosod :(",create:"Crëwyd",payment_hash:"Hais Taliad",fee:"Fee",amount:"swm",unit:"Uned",description:"Disgrifiad",expiry:"dod i ben",webhook:"bachyn we",payment_proof:"prawf taliad"},window.localisation.pt={server:"Servidor",theme:"Tema",funding:"Financiamento",users:"Usuários",restart:"Reiniciar servidor",save:"Gravar",save_tooltip:"Gravar as alterações",topup:"Reforçar conta",topup_wallet:"Recarregar uma carteira",topup_hint:"Use o ID da carteira para recarregar qualquer carteira",restart_tooltip:"Reinicie o servidor para que as alterações tenham efeito",add_funds_tooltip:"Adicionar fundos a uma carteira.",reset_defaults:"Redefinir para padrões",reset_defaults_tooltip:"Apagar todas as configurações e redefinir para os padrões.",download_backup:"Fazer backup da base de dados",name_your_wallet:"Nomeie sua carteira %{name}",paste_invoice_label:"Cole uma fatura, pedido de pagamento ou código lnurl *",lnbits_description:"Fácil de configurar e leve, o LNbits pode ser executado em qualquer fonte de financiamento da lightning-network, atualmente suportando LND, c-lightning, OpenNode, LNPay e até mesmo o LNbits em si! Você pode executar o LNbits para si mesmo ou oferecer facilmente uma solução de custódia para outros. Cada carteira tem suas próprias chaves de API e não há limite para o número de carteiras que você pode criar. Ser capaz de particionar fundos torna o LNbits uma ferramenta útil para gerenciamento de dinheiro e como uma ferramenta de desenvolvimento. As extensões adicionam funcionalidades extras ao LNbits para que você possa experimentar uma série de tecnologias de ponta na rede lightning. Nós tornamos o desenvolvimento de extensões o mais fácil possível e, como um projeto gratuito e de código aberto, incentivamos as pessoas a desenvolver e enviar as suas próprias.",export_to_phone:"Exportar para o telefone com código QR",export_to_phone_desc:"Este código QR contém a URL da sua carteira com acesso total. Você pode escaneá-lo do seu telefone para abrir sua carteira a partir dele.",wallets:"Carteiras",add_wallet:"Adicionar nova carteira",delete_wallet:"Excluir carteira",delete_wallet_desc:"Toda a carteira será excluída, os fundos serão IRRECUPERÁVEIS.",rename_wallet:"Renomear carteira",update_name:"Atualizar nome",press_to_claim:"Pressione para solicitar bitcoin",donate:"Doar",view_github:"Ver no GitHub",voidwallet_active:"VoidWallet está ativo! Pagamentos desabilitados",use_with_caution:"USE COM CAUTELA - a carteira %{name} ainda está em BETA",toggle_darkmode:"Alternar modo escuro",view_swagger_docs:"Ver a documentação da API do LNbits Swagger",api_docs:"Documentação da API",commit_version:"Versão de commit",lnbits_version:"Versão do LNbits",runs_on:"Executa em",credit_hint:"Pressione Enter para creditar a conta",credit_label:"%{denomination} para creditar",paste_request:"Colar Pedido",create_invoice:"Criar Fatura",camera_tooltip:"Usar a câmara para escanear uma fatura / QR",export_csv:"Exportar para CSV",transactions:"Transações",chart_tooltip:"Mostrar gráfico",pending:"Pendente",copy_invoice:"Copiar fatura",close:"Fechar",cancel:"Cancelar",scan:"Escanear",read:"Ler",pay:"Pagar",memo:"Memo",date:"Data",processing_payment:"Processando pagamento...",not_enough_funds:"Fundos insuficientes!",search_by_tag_memo_amount:"Pesquisar por tag, memo, quantidade",invoice_waiting:"Fatura aguardando pagamento",payment_received:"Pagamento Recebido",payment_sent:"Pagamento Enviado",receive:"receber",send:"enviar",outgoing_payment_pending:"Pagamento de saída pendente",drain_funds:"Esvasiar carteira",drain_funds_desc:"Este é um código QR de saque LNURL para sacar tudo desta carteira. Não o partilhe com ninguém. É compatível com balanceCheck e balanceNotify para que a sua carteira possa continuar levantando os fundos continuamente daqui após o primeiro saque.",i_understand:"Eu entendo",copy_wallet_url:"Copiar URL da carteira",disclaimer_dialog:"Funcionalidade de login a ser lançada numa atualização futura, por enquanto, certifique-se que marca esta página para acesso futuro à sua carteira! Este serviço está em BETA, e não nos responsabilizamos por pessoas que perderem o acesso aos fundos.",no_transactions:"Ainda não foram feitas transações",manage_extensions:"Gerir extensões",manage_server:"Gerir servidor",extensions:"Extensões",no_extensions:"Não há nenhuma extensão instalada :(",created:"Criado",payment_hash:"Hash de pagamento",fee:"Taxa",amount:"Quantidade",unit:"Unidade",description:"Descrição",expiry:"Validade",webhook:"Webhook",payment_proof:"Comprovativo de pagamento"},window.localisation.br={server:"Servidor",theme:"Tema",funding:"Financiamento",users:"Usuários",restart:"Reiniciar servidor",save:"Salvar",save_tooltip:"Salvar suas alterações",topup:"Recarregar",topup_wallet:"Recarregar uma carteira",topup_hint:"Use o ID da carteira para recarregar qualquer carteira",restart_tooltip:"Reinicie o servidor para que as alterações tenham efeito",add_funds_tooltip:"Adicionar fundos a uma carteira.",reset_defaults:"Redefinir para padrões",reset_defaults_tooltip:"Apagar todas as configurações e redefinir para os padrões.",download_backup:"Fazer backup do banco de dados",name_your_wallet:"Nomeie sua carteira %{name}",paste_invoice_label:"Cole uma fatura, pedido de pagamento ou código lnurl *",lnbits_description:"Fácil de configurar e leve, o LNbits pode ser executado em qualquer fonte de financiamento da lightning-network, atualmente suportando LND, c-lightning, OpenNode, LNPay e até mesmo o LNbits em si! Você pode executar o LNbits para si mesmo ou oferecer facilmente uma solução de custódia para outros. Cada carteira tem suas próprias chaves de API e não há limite para o número de carteiras que você pode criar. Ser capaz de particionar fundos torna o LNbits uma ferramenta útil para gerenciamento de dinheiro e como uma ferramenta de desenvolvimento. As extensões adicionam funcionalidades extras ao LNbits para que você possa experimentar uma série de tecnologias de ponta na rede lightning. Nós tornamos o desenvolvimento de extensões o mais fácil possível e, como um projeto gratuito e de código aberto, incentivamos as pessoas a desenvolver e enviar as suas próprias.",export_to_phone:"Exportar para o telefone com código QR",export_to_phone_desc:"Este código QR contém a URL da sua carteira com acesso total. Você pode escaneá-lo do seu telefone para abrir sua carteira a partir dele.",wallets:"Carteiras",add_wallet:"Adicionar nova carteira",delete_wallet:"Excluir carteira",delete_wallet_desc:"Toda a carteira será excluída, os fundos serão IRRECUPERÁVEIS.",rename_wallet:"Renomear carteira",update_name:"Atualizar nome",press_to_claim:"Pressione para solicitar bitcoin",donate:"Doar",view_github:"Ver no GitHub",voidwallet_active:"VoidWallet está ativo! Pagamentos desabilitados",use_with_caution:"USE COM CAUTELA - a carteira %{name} ainda está em BETA",toggle_darkmode:"Alternar modo escuro",view_swagger_docs:"Ver a documentação da API do LNbits Swagger",api_docs:"Documentação da API",commit_version:"Versão de commit",lnbits_version:"Versão do LNbits",runs_on:"Executa em",credit_hint:"Pressione Enter para creditar a conta",credit_label:"%{denomination} para creditar",paste_request:"Colar Pedido",create_invoice:"Criar Fatura",camera_tooltip:"Usar a câmara para escanear uma fatura / QR",export_csv:"Exportar para CSV",transactions:"Transações",chart_tooltip:"Mostrar gráfico",pending:"Pendente",copy_invoice:"Copiar fatura",close:"Fechar",cancel:"Cancelar",scan:"Escanear",read:"Ler",pay:"Pagar",memo:"Memo",date:"Data",processing_payment:"Processando pagamento...",not_enough_funds:"Fundos insuficientes!",search_by_tag_memo_amount:"Pesquisar por tag, memo, quantidade",invoice_waiting:"Fatura aguardando pagamento",payment_received:"Pagamento Recebido",payment_sent:"Pagamento Enviado",receive:"receber",send:"enviar",outgoing_payment_pending:"Pagamento pendente de saída",drain_funds:"Drenar Fundos",drain_funds_desc:"Este é um código QR de retirada do LNURL para sugar tudo desta carteira. Não compartilhe com ninguém. É compatível com balanceCheck e balanceNotify para que sua carteira possa continuar retirando os fundos continuamente daqui após a primeira retirada.",i_understand:"Eu entendo",copy_wallet_url:"Copiar URL da carteira",disclaimer_dialog:"Funcionalidade de login a ser lançada em uma atualização futura, por enquanto, certifique-se de marcar esta página para acesso futuro à sua carteira! Este serviço está em BETA, e não nos responsabilizamos por pessoas que perderem o acesso aos fundos.",no_transactions:"Ainda não foram feitas transações",manage_extensions:"Gerenciar extensões",manage_server:"Gerenciar servidor",extensions:"Extensões",no_extensions:"Você não possui nenhuma extensão instalada :(",created:"Criado",payment_hash:"Hash de pagamento",fee:"Taxa",amount:"Quantidade",unit:"Unidade",description:"Descrição",expiry:"Validade",webhook:"Webhook",payment_proof:"Comprovante de pagamento"},Vue.use(VueI18n),window.LOCALE="en",window.i18n=new VueI18n({locale:window.LOCALE,fallbackLocale:window.LOCALE,messages:window.localisation}),window.EventHub=new Vue,window.LNbits={api:{request:function(t,e,n,i){return axios({method:t,url:e,headers:{"X-Api-Key":n},data:i})},createInvoice:async function(t,e,n,i="sat",r=null){return this.request("post","/api/v1/payments",t.inkey,{out:!1,amount:e,memo:n,unit:i,lnurl_callback:r})},payInvoice:function(t,e){return this.request("post","/api/v1/payments",t.adminkey,{out:!0,bolt11:e})},payLnurl:function(t,e,n,i,r="",o=""){return this.request("post","/api/v1/payments/lnurl",t.adminkey,{callback:e,description_hash:n,amount:i,comment:o,description:r})},authLnurl:function(t,e){return this.request("post","/api/v1/lnurlauth",t.adminkey,{callback:e})},getWallet:function(t){return this.request("get","/api/v1/wallet",t.inkey)},getPayments:function(t,e){const n=new URLSearchParams(e);return this.request("get","/api/v1/payments/paginated?"+n,t.inkey)},getPayment:function(t,e){return this.request("get","/api/v1/payments/"+e,t.inkey)}},events:{onInvoicePaid:function(t,e){let n=t=>{e(JSON.parse(t.data))};return this.listenersCount=this.listenersCount||{[t.inkey]:0},this.listenersCount[t.inkey]++,this.listeners=this.listeners||{},t.inkey in this.listeners||(this.listeners[t.inkey]=new EventSource("/api/v1/payments/sse?api-key="+t.inkey)),this.listeners[t.inkey].addEventListener("payment-received",n),()=>{this.listeners[t.inkey].removeEventListener("payment-received",n),this.listenersCount[t.inkey]--,this.listenersCount[t.inkey]<=0&&(this.listeners[t.inkey].close(),delete this.listeners[t.inkey])}}},href:{createWallet:function(t,e){window.location.href="/wallet?"+(e?"usr="+e+"&":"")+"nme="+t},updateWallet:function(t,e,n){window.location.href=`/wallet?usr=${e}&wal=${n}&nme=${t}`},deleteWallet:function(t,e){window.location.href="/deletewallet?usr="+e+"&wal="+t}},map:{extension:function(t){var e=_.object(["code","isValid","isAdminOnly","name","shortDescription","tile","contributors","hidden"],t);return e.url=["/",e.code,"/"].join(""),e},user:function(t){var e={id:t.id,admin:t.admin,email:t.email,extensions:t.extensions,wallets:t.wallets,admin:t.admin},n=this.wallet;return e.wallets=e.wallets.map((function(t){return n(t)})).sort((function(t,e){return t.name.localeCompare(e.name)})),e.walletOptions=e.wallets.map((function(t){return{label:[t.name," - ",t.id].join(""),value:t.id}})),e},wallet:function(t){return newWallet={id:t.id,name:t.name,adminkey:t.adminkey,inkey:t.inkey,currency:t.currency},newWallet.msat=t.balance_msat,newWallet.sat=Math.round(t.balance_msat/1e3),newWallet.fsat=new Intl.NumberFormat(window.LOCALE).format(newWallet.sat),newWallet.url=["/wallet?usr=",t.user,"&wal=",t.id].join(""),newWallet},payment:function(t){return obj={checking_id:t.checking_id,pending:t.pending,amount:t.amount,fee:t.fee,memo:t.memo,time:t.time,bolt11:t.bolt11,preimage:t.preimage,payment_hash:t.payment_hash,expiry:t.expiry,extra:t.extra,wallet_id:t.wallet_id,webhook:t.webhook,webhook_status:t.webhook_status,fiat_amount:t.fiat_amount,fiat_currency:t.fiat_currency},obj.date=Quasar.utils.date.formatDate(new Date(1e3*obj.time),"YYYY-MM-DD HH:mm"),obj.dateFrom=moment(obj.date).fromNow(),obj.expirydate=Quasar.utils.date.formatDate(new Date(1e3*obj.expiry),"YYYY-MM-DD HH:mm"),obj.expirydateFrom=moment(obj.expirydate).fromNow(),obj.msat=obj.amount,obj.sat=obj.msat/1e3,obj.tag=obj.extra.tag,obj.fsat=new Intl.NumberFormat(window.LOCALE).format(obj.sat),obj.isIn=obj.amount>0,obj.isOut=obj.amount<0,obj.isPaid=!obj.pending,obj._q=[obj.memo,obj.sat].join(" ").toLowerCase(),obj}},utils:{confirmDialog:function(t){return Quasar.plugins.Dialog.create({message:t,ok:{flat:!0,color:"orange"},cancel:{flat:!0,color:"grey"}})},digestMessage:async function(t){const e=(new TextEncoder).encode(t),n=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(n)).map((t=>t.toString(16).padStart(2,"0"))).join("")},formatCurrency:function(t,e){return new Intl.NumberFormat(window.LOCALE,{style:"currency",currency:e}).format(t)},formatSat:function(t){return new Intl.NumberFormat(window.LOCALE).format(t)},notifyApiError:function(t){Quasar.plugins.Notify.create({timeout:5e3,type:{400:"warning",401:"warning",500:"negative"}[t.response.status]||"warning",message:t.response.data.message||t.response.data.detail||null,caption:[t.response.status," ",t.response.statusText].join("").toUpperCase()||null,icon:null})},search:function(t,e,n,i){try{var r=e.toLowerCase().split(i||" ");return t.filter((function(t){var e=0;return _.each(r,(function(i){-1!==t[n].indexOf(i)&&e++})),e===r.length}))}catch(e){return t}},exportCSV:function(t,e,n){var i=function(t,e){var n=void 0!==e?e(t):t;return`"${n=(n=null==n?"":String(n)).split('"').join('""')}"`},r=[t.map((function(t){return i(t.label)}))].concat(e.map((function(e){return t.map((function(t){return i("function"==typeof t.field?t.field(e):e[void 0===t.field?t.name:t.field],t.format)})).join(",")}))).join("\r\n");!0!==Quasar.utils.exportFile(`${n||"table-export"}.csv`,r,"text/csv")&&Quasar.plugins.Notify.create({message:"Browser denied file download...",color:"negative",icon:null})}}},window.windowMixin={i18n:window.i18n,data:function(){return{g:{offline:!navigator.onLine,visibleDrawer:!1,extensions:[],user:null,wallet:null,payments:[],allowedThemes:null,langs:[]}}},methods:{activeLanguage:function(t){return window.i18n.locale===t},changeLanguage:function(t){window.i18n.locale=t,this.$q.localStorage.set("lnbits.lang",t)},changeColor:function(t){document.body.setAttribute("data-theme",t),this.$q.localStorage.set("lnbits.theme",t)},toggleDarkMode:function(){this.$q.dark.toggle(),this.$q.localStorage.set("lnbits.darkMode",this.$q.dark.isActive)},copyText:function(t,e,n){var i=this.$q.notify;Quasar.utils.copyToClipboard(t).then((function(){i({message:e||"Copied to clipboard!",position:n||"bottom"})}))}},created:function(){1==this.$q.localStorage.getItem("lnbits.darkMode")||0==this.$q.localStorage.getItem("lnbits.darkMode")?this.$q.dark.set(this.$q.localStorage.getItem("lnbits.darkMode")):this.$q.dark.set(!0),this.g.allowedThemes=window.allowedThemes??["bitcoin"];let t=this.$q.localStorage.getItem("lnbits.lang");if(t&&(window.LOCALE=t,window.i18n.locale=t),this.g.langs=window.langs??[],addEventListener("offline",(t=>{this.g.offline=!0})),addEventListener("online",(t=>{this.g.offline=!1})),this.$q.localStorage.getItem("lnbits.theme")||this.changeColor(this.g.allowedThemes[0]),this.$q.localStorage.getItem("lnbits.theme")&&!this.g.allowedThemes.includes(this.$q.localStorage.getItem("lnbits.theme"))&&this.changeColor(this.g.allowedThemes[0]),this.$q.localStorage.getItem("lnbits.theme")&&document.body.setAttribute("data-theme",this.$q.localStorage.getItem("lnbits.theme")),window.user&&(this.g.user=Object.freeze(window.LNbits.map.user(window.user))),window.wallet&&(this.g.wallet=Object.freeze(window.LNbits.map.wallet(window.wallet))),window.extensions){var e=this.g.user;const t=Object.freeze(window.extensions.map((function(t){return window.LNbits.map.extension(t)})).filter((function(t){return!t.hidden})).filter((function(t){return window.user.admin?t:!t.isAdminOnly})).map((function(t){return t.isEnabled=!!e&&-1!==e.extensions.indexOf(t.code),t})).sort((function(t,e){const n=t.name.toUpperCase(),i=e.name.toUpperCase();return ni?1:0})));this.g.extensions=t}}},window.decryptLnurlPayAES=function(t,e){let n=new Uint8Array(e.match(/[\da-f]{2}/gi).map((t=>parseInt(t,16))));return crypto.subtle.importKey("raw",n,{name:"AES-CBC",length:256},!1,["decrypt"]).then((e=>{let n=Uint8Array.from(window.atob(t.iv),(t=>t.charCodeAt(0))),i=Uint8Array.from(window.atob(t.ciphertext),(t=>t.charCodeAt(0)));return crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,i)})).then((t=>new TextDecoder("utf-8").decode(t)))},Vue.component("lnbits-fsat",{props:{amount:{type:Number,default:0}},template:"{{ fsat }}",computed:{fsat:function(){return LNbits.utils.formatSat(this.amount)}}}),Vue.component("lnbits-wallet-list",{data:function(){return{user:null,activeWallet:null,activeBalance:[],showForm:!1,walletName:"",LNBITS_DENOMINATION:LNBITS_DENOMINATION}},template:'\n \n \n \n \n \n \n \n \n \n {{ wallet.name }}\n {{ parseFloat(String(wallet.live_fsat).replaceAll(",", "")) / 100 }} {{ LNBITS_DENOMINATION }}\n {{ wallet.live_fsat }} {{ LNBITS_DENOMINATION }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',computed:{wallets:function(){var t=this.activeBalance;return this.user.wallets.map((function(e){return e.live_fsat=t.length&&t[0]===e.id?LNbits.utils.formatSat(t[1]):e.fsat,e}))}},methods:{createWallet:function(){LNbits.href.createWallet(this.walletName,this.user.id)},updateWalletBalance:function(t){this.activeBalance=t}},created:function(){window.user&&(this.user=LNbits.map.user(window.user)),window.wallet&&(this.activeWallet=LNbits.map.wallet(window.wallet)),EventHub.$on("update-wallet-balance",this.updateWalletBalance)}}),Vue.component("lnbits-extension-list",{data:function(){return{extensions:[],user:null}},template:'\n \n \n \n \n \n \n \n \n \n {{ extension.name }} \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',computed:{userExtensions:function(){if(!this.user)return[];var t=window.location.pathname,e=this.user.extensions;return this.extensions.filter((function(t){return-1!==e.indexOf(t.code)})).map((function(e){return e.isActive=t.startsWith(e.url),e}))}},created:function(){window.extensions&&(this.extensions=window.extensions.map((function(t){return LNbits.map.extension(t)})).sort((function(t,e){return t.name.localeCompare(e.name)}))),window.user&&(this.user=LNbits.map.user(window.user))}}),Vue.component("lnbits-admin-ui",{data:function(){return{extensions:[],user:null}},template:'\n \n Admin\n \n \n \n \n \n \n \n \n \n ',created:function(){window.user&&(this.user=LNbits.map.user(window.user))}}),Vue.component("lnbits-payment-details",{props:["payment"],mixins:[windowMixin],data:function(){return{LNBITS_DENOMINATION:LNBITS_DENOMINATION}},template:'\n \n\n
\n \n #{{ payment.tag }}\n \n
\n\n
\n :\n {{ payment.date }} ({{ payment.dateFrom }})\n
\n\n
\n :\n {{ payment.expirydate }} ({{ payment.expirydateFrom }})\n
\n\n
\n :\n {{ (payment.amount / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}\n
\n\n
\n :\n {{ (payment.fee / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}\n
\n\n
\n : {{ payment.payment_hash }}\n \n
\n\n
\n : {{ payment.memo }}\n
\n\n
\n : {{ payment.webhook }}: \n {{ webhookStatusText }}\n \n
\n\n
\n : {{ payment.preimage }}\n
\n\n
\n \n extra\n \n {{ entry.key }}:\n {{ entry.value }}\n
\n\n
\n Success action:\n \n
\n\n
\n ',computed:{hasPreimage(){return this.payment.preimage&&"0000000000000000000000000000000000000000000000000000000000000000"!==this.payment.preimage},hasSuccessAction(){return this.hasPreimage&&this.payment.extra&&this.payment.extra.success_action},webhookStatusColor(){return this.payment.webhook_status>=300||this.payment.webhook_status<0?"red-10":this.payment.webhook_status?"green-10":"cyan-7"},webhookStatusText(){return this.payment.webhook_status?this.payment.webhook_status:"not sent yet"},hasTag(){return this.payment.extra&&!!this.payment.extra.tag},extras(){if(!this.payment.extra)return[];let t=_.omit(this.payment.extra,["tag","success_action"]);return Object.keys(t).map((e=>({key:e,value:t[e]})))}}}),Vue.component("lnbits-lnurlpay-success-action",{props:["payment","success_action"],data(){return{decryptedValue:this.success_action.ciphertext}},template:'\n \n
{{ success_action.message || success_action.description }}
\n
\n {{ decryptedValue }}\n
\n
\n {{ success_action.url }}\n
\n
\n ',mounted:function(){if("aes"!==this.success_action.tag)return null;decryptLnurlPayAES(this.success_action,this.payment.preimage).then((t=>{this.decryptedValue=t}))}}),Vue.component("lnbits-notifications-btn",{mixins:[windowMixin],props:["pubkey"],data:()=>({isSupported:!1,isSubscribed:!1,isPermissionGranted:!1,isPermissionDenied:!1}),template:'\n \n Subscribe to notifications\n Unsubscribe from notifications\n \n Notifications are disabled,
please enable or reset permissions\n \n Notifications are not supported\n \n ',methods:{urlB64ToUint8Array(t){const e=(t+"=".repeat((4-t.length%4)%4)).replace(/\-/g,"+").replace(/_/g,"/"),n=atob(e),i=new Uint8Array(n.length);for(let t=0;te!==t)),this.$q.localStorage.set("lnbits.webpush.subscribedUsers",JSON.stringify(e))},isUserSubscribed(t){return(JSON.parse(this.$q.localStorage.getItem("lnbits.webpush.subscribedUsers"))||[]).includes(t)},subscribe(){var t=this;this.isSupported&&!this.isPermissionDenied&&(Notification.requestPermission().then((t=>{this.isPermissionGranted="granted"===t,this.isPermissionDenied="denied"===t})).catch((function(t){console.log(t)})),navigator.serviceWorker.ready.then((e=>{navigator.serviceWorker.getRegistration().then((e=>{e.pushManager.getSubscription().then((function(n){if(null===n||!t.isUserSubscribed(t.g.user.id)){const n={applicationServerKey:t.urlB64ToUint8Array(t.pubkey),userVisibleOnly:!0};e.pushManager.subscribe(n).then((function(e){LNbits.api.request("POST","/api/v1/webpush",t.g.user.wallets[0].adminkey,{subscription:JSON.stringify(e)}).then((function(e){t.saveUserSubscribed(e.data.user),t.isSubscribed=!0})).catch((function(t){LNbits.utils.notifyApiError(t)}))}))}})).catch((function(t){console.log(t)}))}))})))},unsubscribe(){var t=this;navigator.serviceWorker.ready.then((e=>{e.pushManager.getSubscription().then((e=>{e&&LNbits.api.request("DELETE","/api/v1/webpush?endpoint="+btoa(e.endpoint),t.g.user.wallets[0].adminkey).then((function(){t.removeUserSubscribed(t.g.user.id),t.isSubscribed=!1})).catch((function(t){LNbits.utils.notifyApiError(t)}))}))})).catch((function(t){console.log(t)}))},checkSupported:function(){let t="https:"===window.location.protocol,e="serviceWorker"in navigator,n="Notification"in window,i="PushManager"in window;return this.isSupported=t&&e&&n&&i,this.isSupported||console.log("Notifications disabled because requirements are not met:",{HTTPS:t,"Service Worker API":e,"Notification API":n,"Push API":i}),this.isSupported},updateSubscriptionStatus:async function(){var t=this;await navigator.serviceWorker.ready.then((e=>{e.pushManager.getSubscription().then((e=>{t.isSubscribed=!!e&&t.isUserSubscribed(t.g.user.id)}))})).catch((function(t){console.log(t)}))}},created:function(){this.isPermissionDenied="denied"===Notification.permission,this.checkSupported()&&this.updateSubscriptionStatus()}});const bech32CharValues="qpzry9x8gf2tvdw0s3jn54khce6mua7l";function byteArrayToInt(t){let e=0;for(let n=0;n{i=(i<<5)+t,n+=5,n>=8&&(r.push(i>>n-8&255),n-=8)})),e&&n>0&&r.push(i<<8-n&255),r}function bech32ToUTF8String(t){let e=fiveBitArrayTo8BitArray(bech32ToFiveBitArray(t)),n="";for(let t=0;t20&&(e-=20,t/=Math.pow(10,e),t+=new Array(e+1).join("0"));return t}
+function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.VueI18n=e()}(this,(function(){"use strict";var t=["compactDisplay","currency","currencyDisplay","currencySign","localeMatcher","notation","numberingSystem","signDisplay","style","unit","unitDisplay","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits"],e=["dateStyle","timeStyle","calendar","localeMatcher","hour12","hourCycle","timeZone","formatMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName"];function n(t,e){"undefined"!=typeof console&&(console.warn("[vue-i18n] "+t),e&&console.warn(e.stack))}function i(t,e){"undefined"!=typeof console&&(console.error("[vue-i18n] "+t),e&&console.error(e.stack))}var r=Array.isArray;function o(t){return null!==t&&"object"==typeof t}function a(t){return"string"==typeof t}var s=Object.prototype.toString,l="[object Object]";function u(t){return s.call(t)===l}function c(t){return null==t}function d(t){return"function"==typeof t}function h(){for(var t=[],e=arguments.length;e--;)t[e]=arguments[e];var n=null,i=null;return 1===t.length?o(t[0])||r(t[0])?i=t[0]:"string"==typeof t[0]&&(n=t[0]):2===t.length&&("string"==typeof t[0]&&(n=t[0]),(o(t[1])||r(t[1]))&&(i=t[1])),{locale:n,params:i}}function f(t){return JSON.parse(JSON.stringify(t))}function p(t,e){return!!~t.indexOf(e)}var m=Object.prototype.hasOwnProperty;function v(t,e){return m.call(t,e)}function g(t){for(var e=arguments,n=Object(t),i=1;i0;)e[n]=arguments[n+1];var i=this.$i18n;return i._t.apply(i,[t,i.locale,i._getMessages(),this].concat(e))},t.prototype.$tc=function(t,e){for(var n=[],i=arguments.length-2;i-- >0;)n[i]=arguments[i+2];var r=this.$i18n;return r._tc.apply(r,[t,r.locale,r._getMessages(),this,e].concat(n))},t.prototype.$te=function(t,e){var n=this.$i18n;return n._te(t,n.locale,n._getMessages(),e)},t.prototype.$d=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this.$i18n).d.apply(e,[t].concat(n))},t.prototype.$n=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this.$i18n).n.apply(e,[t].concat(n))}}(k),k.mixin(function(t){function e(){this!==this.$root&&this.$options.__INTLIFY_META__&&this.$el&&this.$el.setAttribute("data-intlify",this.$options.__INTLIFY_META__)}return void 0===t&&(t=!1),t?{mounted:e}:{beforeCreate:function(){var t=this.$options;if(t.i18n=t.i18n||(t.__i18nBridge||t.__i18n?{}:null),t.i18n)if(t.i18n instanceof Y){if(t.__i18nBridge||t.__i18n)try{var e=t.i18n&&t.i18n.messages?t.i18n.messages:{};(t.__i18nBridge||t.__i18n).forEach((function(t){e=g(e,JSON.parse(t))})),Object.keys(e).forEach((function(n){t.i18n.mergeLocaleMessage(n,e[n])}))}catch(t){i("Cannot parse locale messages via custom blocks.",t)}this._i18n=t.i18n,this._i18nWatcher=this._i18n.watchI18nData()}else if(u(t.i18n)){var r=this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y?this.$root.$i18n:null;if(r&&(t.i18n.root=this.$root,t.i18n.formatter=r.formatter,t.i18n.fallbackLocale=r.fallbackLocale,t.i18n.formatFallbackMessages=r.formatFallbackMessages,t.i18n.silentTranslationWarn=r.silentTranslationWarn,t.i18n.silentFallbackWarn=r.silentFallbackWarn,t.i18n.pluralizationRules=r.pluralizationRules,t.i18n.preserveDirectiveContent=r.preserveDirectiveContent),t.__i18nBridge||t.__i18n)try{var o=t.i18n&&t.i18n.messages?t.i18n.messages:{};(t.__i18nBridge||t.__i18n).forEach((function(t){o=g(o,JSON.parse(t))})),t.i18n.messages=o}catch(t){n("Cannot parse locale messages via custom blocks.",t)}var a=t.i18n.sharedMessages;a&&u(a)&&(t.i18n.messages=g(t.i18n.messages,a)),this._i18n=new Y(t.i18n),this._i18nWatcher=this._i18n.watchI18nData(),(void 0===t.i18n.sync||t.i18n.sync)&&(this._localeWatcher=this.$i18n.watchLocale()),r&&r.onComponentInstanceCreated(this._i18n)}else n("Cannot be interpreted 'i18n' option.");else this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y?this._i18n=this.$root.$i18n:t.parent&&t.parent.$i18n&&t.parent.$i18n instanceof Y&&(this._i18n=t.parent.$i18n)},beforeMount:function(){var t=this.$options;t.i18n=t.i18n||(t.__i18nBridge||t.__i18n?{}:null),t.i18n?t.i18n instanceof Y||u(t.i18n)?(this._i18n.subscribeDataChanging(this),this._subscribing=!0):n("Cannot be interpreted 'i18n' option."):(this.$root&&this.$root.$i18n&&this.$root.$i18n instanceof Y||t.parent&&t.parent.$i18n&&t.parent.$i18n instanceof Y)&&(this._i18n.subscribeDataChanging(this),this._subscribing=!0)},mounted:e,beforeDestroy:function(){if(this._i18n){var t=this;this.$nextTick((function(){t._subscribing&&(t._i18n.unsubscribeDataChanging(t),delete t._subscribing),t._i18nWatcher&&(t._i18nWatcher(),t._i18n.destroyVM(),delete t._i18nWatcher),t._localeWatcher&&(t._localeWatcher(),delete t._localeWatcher)}))}}}}(e.bridge)),k.directive("t",{bind:C,update:M,unbind:T}),k.component(y.name,y),k.component(S.name,S),k.config.optionMergeStrategies.i18n=function(t,e){return void 0===e?t:e}))}var L=function(){this._caches=Object.create(null)};L.prototype.interpolate=function(t,e){if(!e)return[t];var i=this._caches[t];return i||(i=function(t){var e=[],n=0,i="";for(;n0)d--,c=4,h[0]();else{if(d=0,void 0===n)return!1;if(!1===(n=j(n)))return!1;h[1]()}};null!==c;)if(u++,"\\"!==(e=t[u])||!f()){if(r=I(e),8===(o=(s=R[c])[r]||s.else||8))return;if(c=o[0],(a=h[o[1]])&&(i=void 0===(i=o[2])?e:i,!1===a()))return;if(7===c)return l}}(t),e&&(this._cache[t]=e)),e||[]},$.prototype.getPathValue=function(t,e){if(!o(t))return null;var n=this.parsePath(e);if(0===n.length)return null;for(var i=n.length,r=t,a=0;a/,z=/(?:@(?:\.[a-zA-Z]+)?:(?:[\w\-_|./]+|\([\w\-_:|./]+\)))/g,V=/^@(?:\.([a-zA-Z]+))?:/,H=/[()]/g,U={upper:function(t){return t.toLocaleUpperCase()},lower:function(t){return t.toLocaleLowerCase()},capitalize:function(t){return""+t.charAt(0).toLocaleUpperCase()+t.substr(1)}},W=new L,Y=function(t){var e=this;void 0===t&&(t={}),!k&&"undefined"!=typeof window&&window.Vue&&E(window.Vue);var n=t.locale||"en-US",i=!1!==t.fallbackLocale&&(t.fallbackLocale||"en-US"),r=t.messages||{},o=t.dateTimeFormats||t.datetimeFormats||{},a=t.numberFormats||{};this._vm=null,this._formatter=t.formatter||W,this._modifiers=t.modifiers||{},this._missing=t.missing||null,this._root=t.root||null,this._sync=void 0===t.sync||!!t.sync,this._fallbackRoot=void 0===t.fallbackRoot||!!t.fallbackRoot,this._fallbackRootWithEmptyString=void 0===t.fallbackRootWithEmptyString||!!t.fallbackRootWithEmptyString,this._formatFallbackMessages=void 0!==t.formatFallbackMessages&&!!t.formatFallbackMessages,this._silentTranslationWarn=void 0!==t.silentTranslationWarn&&t.silentTranslationWarn,this._silentFallbackWarn=void 0!==t.silentFallbackWarn&&!!t.silentFallbackWarn,this._dateTimeFormatters={},this._numberFormatters={},this._path=new $,this._dataListeners=new Set,this._componentInstanceCreatedListener=t.componentInstanceCreatedListener||null,this._preserveDirectiveContent=void 0!==t.preserveDirectiveContent&&!!t.preserveDirectiveContent,this.pluralizationRules=t.pluralizationRules||{},this._warnHtmlInMessage=t.warnHtmlInMessage||"off",this._postTranslation=t.postTranslation||null,this._escapeParameterHtml=t.escapeParameterHtml||!1,"__VUE_I18N_BRIDGE__"in t&&(this.__VUE_I18N_BRIDGE__=t.__VUE_I18N_BRIDGE__),this.getChoiceIndex=function(t,n){var i=Object.getPrototypeOf(e);if(i&&i.getChoiceIndex)return i.getChoiceIndex.call(e,t,n);var r,o;return e.locale in e.pluralizationRules?e.pluralizationRules[e.locale].apply(e,[t,n]):(r=t,o=n,r=Math.abs(r),2===o?r?r>1?1:0:1:r?Math.min(r,2):0)},this._exist=function(t,n){return!(!t||!n)&&(!c(e._path.getPathValue(t,n))||!!t[n])},"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||Object.keys(r).forEach((function(t){e._checkLocaleMessage(t,e._warnHtmlInMessage,r[t])})),this._initVM({locale:n,fallbackLocale:i,messages:r,dateTimeFormats:o,numberFormats:a})},Q={vm:{configurable:!0},messages:{configurable:!0},dateTimeFormats:{configurable:!0},numberFormats:{configurable:!0},availableLocales:{configurable:!0},locale:{configurable:!0},fallbackLocale:{configurable:!0},formatFallbackMessages:{configurable:!0},missing:{configurable:!0},formatter:{configurable:!0},silentTranslationWarn:{configurable:!0},silentFallbackWarn:{configurable:!0},preserveDirectiveContent:{configurable:!0},warnHtmlInMessage:{configurable:!0},postTranslation:{configurable:!0},sync:{configurable:!0}};return Y.prototype._checkLocaleMessage=function(t,e,o){var s=function(t,e,o,l){if(u(o))Object.keys(o).forEach((function(n){var i=o[n];u(i)?(l.push(n),l.push("."),s(t,e,i,l),l.pop(),l.pop()):(l.push(n),s(t,e,i,l),l.pop())}));else if(r(o))o.forEach((function(n,i){u(n)?(l.push("["+i+"]"),l.push("."),s(t,e,n,l),l.pop(),l.pop()):(l.push("["+i+"]"),s(t,e,n,l),l.pop())}));else if(a(o)){if(B.test(o)){var c="Detected HTML in message '"+o+"' of keypath '"+l.join("")+"' at '"+e+"'. Consider component interpolation with '' to avoid XSS. See https://bit.ly/2ZqJzkp";"warn"===t?n(c):"error"===t&&i(c)}}};s(e,t,o,[])},Y.prototype._initVM=function(t){var e=k.config.silent;k.config.silent=!0,this._vm=new k({data:t,__VUE18N__INSTANCE__:!0}),k.config.silent=e},Y.prototype.destroyVM=function(){this._vm.$destroy()},Y.prototype.subscribeDataChanging=function(t){this._dataListeners.add(t)},Y.prototype.unsubscribeDataChanging=function(t){!function(t,e){if(t.delete(e));}(this._dataListeners,t)},Y.prototype.watchI18nData=function(){var t=this;return this._vm.$watch("$data",(function(){for(var e,n,i=(e=t._dataListeners,n=[],e.forEach((function(t){return n.push(t)})),n),r=i.length;r--;)k.nextTick((function(){i[r]&&i[r].$forceUpdate()}))}),{deep:!0})},Y.prototype.watchLocale=function(t){if(t){if(!this.__VUE_I18N_BRIDGE__)return null;var e=this,n=this._vm;return this.vm.$watch("locale",(function(i){n.$set(n,"locale",i),e.__VUE_I18N_BRIDGE__&&t&&(t.locale.value=i),n.$forceUpdate()}),{immediate:!0})}if(!this._sync||!this._root)return null;var i=this._vm;return this._root.$i18n.vm.$watch("locale",(function(t){i.$set(i,"locale",t),i.$forceUpdate()}),{immediate:!0})},Y.prototype.onComponentInstanceCreated=function(t){this._componentInstanceCreatedListener&&this._componentInstanceCreatedListener(t,this)},Q.vm.get=function(){return this._vm},Q.messages.get=function(){return f(this._getMessages())},Q.dateTimeFormats.get=function(){return f(this._getDateTimeFormats())},Q.numberFormats.get=function(){return f(this._getNumberFormats())},Q.availableLocales.get=function(){return Object.keys(this.messages).sort()},Q.locale.get=function(){return this._vm.locale},Q.locale.set=function(t){this._vm.$set(this._vm,"locale",t)},Q.fallbackLocale.get=function(){return this._vm.fallbackLocale},Q.fallbackLocale.set=function(t){this._localeChainCache={},this._vm.$set(this._vm,"fallbackLocale",t)},Q.formatFallbackMessages.get=function(){return this._formatFallbackMessages},Q.formatFallbackMessages.set=function(t){this._formatFallbackMessages=t},Q.missing.get=function(){return this._missing},Q.missing.set=function(t){this._missing=t},Q.formatter.get=function(){return this._formatter},Q.formatter.set=function(t){this._formatter=t},Q.silentTranslationWarn.get=function(){return this._silentTranslationWarn},Q.silentTranslationWarn.set=function(t){this._silentTranslationWarn=t},Q.silentFallbackWarn.get=function(){return this._silentFallbackWarn},Q.silentFallbackWarn.set=function(t){this._silentFallbackWarn=t},Q.preserveDirectiveContent.get=function(){return this._preserveDirectiveContent},Q.preserveDirectiveContent.set=function(t){this._preserveDirectiveContent=t},Q.warnHtmlInMessage.get=function(){return this._warnHtmlInMessage},Q.warnHtmlInMessage.set=function(t){var e=this,n=this._warnHtmlInMessage;if(this._warnHtmlInMessage=t,n!==t&&("warn"===t||"error"===t)){var i=this._getMessages();Object.keys(i).forEach((function(t){e._checkLocaleMessage(t,e._warnHtmlInMessage,i[t])}))}},Q.postTranslation.get=function(){return this._postTranslation},Q.postTranslation.set=function(t){this._postTranslation=t},Q.sync.get=function(){return this._sync},Q.sync.set=function(t){this._sync=t},Y.prototype._getMessages=function(){return this._vm.messages},Y.prototype._getDateTimeFormats=function(){return this._vm.dateTimeFormats},Y.prototype._getNumberFormats=function(){return this._vm.numberFormats},Y.prototype._warnDefault=function(t,e,i,r,o,s){if(!c(i))return i;if(this._missing){var l=this._missing.apply(null,[t,e,r,o]);if(a(l))return l}else this._isSilentTranslationWarn(e)||n("Cannot translate the value of keypath '"+e+"'. Use the value of keypath as default.");if(this._formatFallbackMessages){var u=h.apply(void 0,o);return this._render(e,s,u.params,e)}return e},Y.prototype._isFallbackRoot=function(t){return(this._fallbackRootWithEmptyString?!t:c(t))&&!c(this._root)&&this._fallbackRoot},Y.prototype._isSilentFallbackWarn=function(t){return this._silentFallbackWarn instanceof RegExp?this._silentFallbackWarn.test(t):this._silentFallbackWarn},Y.prototype._isSilentFallback=function(t,e){return this._isSilentFallbackWarn(e)&&(this._isFallbackRoot()||t!==this.fallbackLocale)},Y.prototype._isSilentTranslationWarn=function(t){return this._silentTranslationWarn instanceof RegExp?this._silentTranslationWarn.test(t):this._silentTranslationWarn},Y.prototype._interpolate=function(t,e,i,o,s,l,h){if(!e)return null;var f,p=this._path.getPathValue(e,i);if(r(p)||u(p))return p;if(c(p)){if(!u(e))return null;if(!a(f=e[i])&&!d(f))return this._isSilentTranslationWarn(i)||this._isSilentFallback(t,i)||n("Value of key '"+i+"' is not a string or function !"),null}else{if(!a(p)&&!d(p))return this._isSilentTranslationWarn(i)||this._isSilentFallback(t,i)||n("Value of key '"+i+"' is not a string or function!"),null;f=p}return a(f)&&(f.indexOf("@:")>=0||f.indexOf("@.")>=0)&&(f=this._link(t,e,f,o,"raw",l,h)),this._render(f,s,l,i)},Y.prototype._link=function(t,e,i,o,a,s,l){var u=i,c=u.match(z);for(var d in c)if(c.hasOwnProperty(d)){var h=c[d],f=h.match(V),m=f[0],v=f[1],g=h.replace(m,"").replace(H,"");if(p(l,g))return n('Circular reference found. "'+h+'" is already visited in the chain of '+l.reverse().join(" <- ")),u;l.push(g);var _=this._interpolate(t,e,g,o,"raw"===a?"string":a,"raw"===a?void 0:s,l);if(this._isFallbackRoot(_)){if(this._isSilentTranslationWarn(g)||n("Fall back to translate the link placeholder '"+g+"' with root locale."),!this._root)throw Error("unexpected error");var y=this._root.$i18n;_=y._translate(y._getMessages(),y.locale,y.fallbackLocale,g,o,a,s)}_=this._warnDefault(t,g,_,o,r(s)?s:[s],a),this._modifiers.hasOwnProperty(v)?_=this._modifiers[v](_):U.hasOwnProperty(v)&&(_=U[v](_)),l.pop(),u=_?u.replace(h,_):u}return u},Y.prototype._createMessageContext=function(t,e,n,i){var a=this,s=r(t)?t:[],l=o(t)?t:{},u=this._getMessages(),c=this.locale;return{list:function(t){return s[t]},named:function(t){return l[t]},values:t,formatter:e,path:n,messages:u,locale:c,linked:function(t){return a._interpolate(c,u[c]||{},t,null,i,void 0,[t])}}},Y.prototype._render=function(t,e,n,i){if(d(t))return t(this._createMessageContext(n,this._formatter||W,i,e));var r=this._formatter.interpolate(t,n,i);return r||(r=W.interpolate(t,n,i)),"string"!==e||a(r)?r:r.join("")},Y.prototype._appendItemToChain=function(t,e,n){var i=!1;return p(t,e)||(i=!0,e&&(i="!"!==e[e.length-1],e=e.replace(/!/g,""),t.push(e),n&&n[e]&&(i=n[e]))),i},Y.prototype._appendLocaleToChain=function(t,e,n){var i,r=e.split("-");do{var o=r.join("-");i=this._appendItemToChain(t,o,n),r.splice(-1,1)}while(r.length&&!0===i);return i},Y.prototype._appendBlockToChain=function(t,e,n){for(var i=!0,r=0;r0;)a[s]=arguments[s+4];if(!t)return"";var l,u=h.apply(void 0,a);this._escapeParameterHtml&&(u.params=(null!=(l=u.params)&&Object.keys(l).forEach((function(t){"string"==typeof l[t]&&(l[t]=l[t].replace(//g,">").replace(/"/g,""").replace(/'/g,"'"))})),l));var c=u.locale||e,d=this._translate(i,c,this.fallbackLocale,t,r,"string",u.params);if(this._isFallbackRoot(d)){if(this._isSilentTranslationWarn(t)||this._isSilentFallbackWarn(t)||n("Fall back to translate the keypath '"+t+"' with root locale."),!this._root)throw Error("unexpected error");return(o=this._root).$t.apply(o,[t].concat(a))}return d=this._warnDefault(c,t,d,r,a,"string"),this._postTranslation&&null!=d&&(d=this._postTranslation(d,t)),d},Y.prototype.t=function(t){for(var e,n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];return(e=this)._t.apply(e,[t,this.locale,this._getMessages(),null].concat(n))},Y.prototype._i=function(t,e,i,r,o){var a=this._translate(i,e,this.fallbackLocale,t,r,"raw",o);if(this._isFallbackRoot(a)){if(this._isSilentTranslationWarn(t)||n("Fall back to interpolate the keypath '"+t+"' with root locale."),!this._root)throw Error("unexpected error");return this._root.$i18n.i(t,e,o)}return this._warnDefault(e,t,a,r,[o],"raw")},Y.prototype.i=function(t,e,n){return t?(a(e)||(e=this.locale),this._i(t,e,this._getMessages(),null,n)):""},Y.prototype._tc=function(t,e,n,i,r){for(var o,a=[],s=arguments.length-5;s-- >0;)a[s]=arguments[s+5];if(!t)return"";void 0===r&&(r=1);var l={count:r,n:r},u=h.apply(void 0,a);return u.params=Object.assign(l,u.params),a=null===u.locale?[u.params]:[u.locale,u.params],this.fetchChoice((o=this)._t.apply(o,[t,e,n,i].concat(a)),r)},Y.prototype.fetchChoice=function(t,e){if(!t||!a(t))return null;var n=t.split("|");return n[e=this.getChoiceIndex(e,n.length)]?n[e].trim():t},Y.prototype.tc=function(t,e){for(var n,i=[],r=arguments.length-2;r-- >0;)i[r]=arguments[r+2];return(n=this)._tc.apply(n,[t,this.locale,this._getMessages(),null,e].concat(i))},Y.prototype._te=function(t,e,n){for(var i=[],r=arguments.length-3;r-- >0;)i[r]=arguments[r+3];var o=h.apply(void 0,i).locale||e;return this._exist(n[o],t)},Y.prototype.te=function(t,e){return this._te(t,this.locale,this._getMessages(),e)},Y.prototype.getLocaleMessage=function(t){return f(this._vm.messages[t]||{})},Y.prototype.setLocaleMessage=function(t,e){"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||this._checkLocaleMessage(t,this._warnHtmlInMessage,e),this._vm.$set(this._vm.messages,t,e)},Y.prototype.mergeLocaleMessage=function(t,e){"warn"!==this._warnHtmlInMessage&&"error"!==this._warnHtmlInMessage||this._checkLocaleMessage(t,this._warnHtmlInMessage,e),this._vm.$set(this._vm.messages,t,g(void 0!==this._vm.messages[t]&&Object.keys(this._vm.messages[t]).length?Object.assign({},this._vm.messages[t]):{},e))},Y.prototype.getDateTimeFormat=function(t){return f(this._vm.dateTimeFormats[t]||{})},Y.prototype.setDateTimeFormat=function(t,e){this._vm.$set(this._vm.dateTimeFormats,t,e),this._clearDateTimeFormat(t,e)},Y.prototype.mergeDateTimeFormat=function(t,e){this._vm.$set(this._vm.dateTimeFormats,t,g(this._vm.dateTimeFormats[t]||{},e)),this._clearDateTimeFormat(t,e)},Y.prototype._clearDateTimeFormat=function(t,e){for(var n in e){var i=t+"__"+n;this._dateTimeFormatters.hasOwnProperty(i)&&delete this._dateTimeFormatters[i]}},Y.prototype._localizeDateTime=function(t,e,i,r,o,a){for(var s=e,l=r[s],u=this._getLocaleChain(e,i),d=0;d0;)n[i]=arguments[i+1];var r=this.locale,s=null,l=null;return 1===n.length?(a(n[0])?s=n[0]:o(n[0])&&(n[0].locale&&(r=n[0].locale),n[0].key&&(s=n[0].key)),l=Object.keys(n[0]).reduce((function(t,i){var r;return p(e,i)?Object.assign({},t,((r={})[i]=n[0][i],r)):t}),null)):2===n.length&&(a(n[0])&&(s=n[0]),a(n[1])&&(r=n[1])),this._d(t,r,s,l)},Y.prototype.getNumberFormat=function(t){return f(this._vm.numberFormats[t]||{})},Y.prototype.setNumberFormat=function(t,e){this._vm.$set(this._vm.numberFormats,t,e),this._clearNumberFormat(t,e)},Y.prototype.mergeNumberFormat=function(t,e){this._vm.$set(this._vm.numberFormats,t,g(this._vm.numberFormats[t]||{},e)),this._clearNumberFormat(t,e)},Y.prototype._clearNumberFormat=function(t,e){for(var n in e){var i=t+"__"+n;this._numberFormatters.hasOwnProperty(i)&&delete this._numberFormatters[i]}},Y.prototype._getNumberFormatter=function(t,e,i,r,o,a){for(var s=e,l=r[s],u=this._getLocaleChain(e,i),d=0;d0;)n[i]=arguments[i+1];var r=this.locale,s=null,l=null;return 1===n.length?a(n[0])?s=n[0]:o(n[0])&&(n[0].locale&&(r=n[0].locale),n[0].key&&(s=n[0].key),l=Object.keys(n[0]).reduce((function(e,i){var r;return p(t,i)?Object.assign({},e,((r={})[i]=n[0][i],r)):e}),null)):2===n.length&&(a(n[0])&&(s=n[0]),a(n[1])&&(r=n[1])),this._n(e,r,s,l)},Y.prototype._ntp=function(t,e,i,r){if(!Y.availabilities.numberFormat)return n("Cannot format to parts a Number value due to not supported Intl.NumberFormat."),[];if(!i)return(r?new Intl.NumberFormat(e,r):new Intl.NumberFormat(e)).formatToParts(t);var o=this._getNumberFormatter(t,e,this.fallbackLocale,this._getNumberFormats(),i,r),a=o&&o.formatToParts(t);if(this._isFallbackRoot(a)){if(this._isSilentTranslationWarn(i)||n("Fall back to format number to parts of root: key '"+i+"' ."),!this._root)throw Error("unexpected error");return this._root.$i18n._ntp(t,e,i,r)}return a||[]},Object.defineProperties(Y.prototype,Q),Object.defineProperty(Y,"availabilities",{get:function(){if(!F){var t="undefined"!=typeof Intl;F={dateTimeFormat:t&&void 0!==Intl.DateTimeFormat,numberFormat:t&&void 0!==Intl.NumberFormat}}return F}}),Y.install=E,Y.version="8.28.2",Y})),window.localisation={},window.localisation.de={server:"Server",theme:"Theme",funding:"Funding",users:"Benutzer",unit:"Einheit",restart:"Server neu starten",save:"Speichern",save_tooltip:"Änderungen speichern",topup:"Aufladen",topup_wallet:"Wallet aufladen",topup_hint:"Nutze die Wallet-ID, um eine beliebige Wallet aufzuladen",restart_tooltip:"Starte den Server neu, um die Änderungen zu übernehmen",add_funds_tooltip:"Füge Geld zu einer Wallet hinzu.",reset_defaults:"Zurücksetzen",reset_defaults_tooltip:"Alle Einstellungen auf die Standardeinstellungen zurücksetzen.",download_backup:"Datenbank-Backup herunterladen",name_your_wallet:"Vergib deiner %{name} Wallet einen Namen",paste_invoice_label:"Füge eine Rechnung, Zahlungsanforderung oder LNURL ein *",lnbits_description:"Einfach zu installieren und kompakt, LNbits kann auf jeder Funding-Quelle im Lightning Netzwerk aufsetzen. Derzeit unterstützt: LND, Core Lightning, OpenNode, LNPay und sogar LNbits selbst! Du kannst LNbits für dich selbst betreiben oder anderen die Verwaltung durch dich anbieten. Jede Wallet hat ihre eigenen API-Schlüssel und die Anzahl der Wallets ist unbegrenzt. Die Möglichkeit, Gelder auf verschiedene Accounts mit unterschiedlicher Logik aufteilen zu können macht LNbits zu einem nützlichen Werkzeug für deine Buchhaltung - aber auch als Entwicklungswerkzeug. Erweiterungen bereichern LNbits Accounts um zusätzliche Funktionalität, so dass du mit einer Reihe von neuartigen Technologien auf dem Lightning-Netzwerk experimentieren kannst. Wir haben es so einfach wie möglich gemacht, Erweiterungen zu entwickeln, und als freies und Open-Source-Projekt möchten wir Menschen ermutigen, sich selbst hieran zu versuchen und gemeinsam mit uns neue Funktionalitäten zu entwickeln.",export_to_phone:"Auf dem Telefon öffnen",export_to_phone_desc:"Dieser QR-Code beinhaltet vollständige Rechte auf deine Wallet. Du kannst den QR-Code mit Deinem Telefon scannen, um deine Wallet dort zu öffnen.",wallets:"Wallets",add_wallet:"Wallet hinzufügen",delete_wallet:"Wallet löschen",delete_wallet_desc:"Die Wallet wird gelöscht, die hierin beinhalteten Daten hierin oder innerhalb einer Erweiterung sind UNWIEDERBRINGLICH.",rename_wallet:"Wallet umbenennen",update_name:"Namen aktualisieren",press_to_claim:"Klicken, um Bitcoin einzufordern.",donate:"Spenden",view_github:"Auf GitHub anzeigen",voidwallet_active:"VoidWallet ist aktiv! Zahlungen deaktiviert",use_with_caution:"BITTE MIT VORSICHT BENUTZEN - %{name} Wallet ist noch BETA",toggle_darkmode:"Auf Dark Mode umschalten",view_swagger_docs:"LNbits Swagger API-Dokumente",api_docs:"API docs",commit_version:"Commit Version",runs_on:"Läuft auf",credit_hint:"Klicke Enter, um das Konto zu belasten",credit_label:"%{denomination} zu belasten",paste_request:"Anfrage einfügen",create_invoice:"Rechnung erstellen",camera_tooltip:"Verwende die Kamera, um eine Rechnung oder einen QR-Code zu scannen",export_csv:"Exportieren als CSV",transactions:"Transaktionen",chart_tooltip:"Diagramm anzeigen",pending:"Ausstehend",copy_invoice:"Rechnung kopieren",close:"Schließen",cancel:"Stornieren",scan:"Scannen",read:"Lesen",pay:"Zahlen",memo:"Memo",date:"Datum",processing_payment:"Zahlung wird verarbeitet ...",not_enough_funds:"Geldmittel sind erschöpft!",search_by_tag_memo_amount:"Suche nach Tag, Memo, Betrag",invoice_waiting:"Rechnung wartend auf Zahlung",payment_received:"Zahlung erhalten",payment_sent:"Zahlung gesendet",receive:"erhalten",send:"schicken",outgoing_payment_pending:"Ausgehende Zahlung wartend",drain_funds:"Sats abziehen",drain_funds_desc:"LNURL-withdraw QR-Code, der das Abziehen aller Geldmittel aus dieser Wallet erlaubt. Teile ihn mit niemandem! Kompatibel mit balanceCheck und balanceNotify, so dass dein Wallet die Sats nach dem ersten Abzug kontinuierlich von hier abziehen kann.",i_understand:"Ich verstehe",copy_wallet_url:"Wallet-URL kopieren",disclaimer_dialog:"Login-Funktionalität wird in einem zukünftigen Update veröffentlicht. Bis dahin ist die Speicherung der Wallet-URL als Lesezeichen absolut notwendig, um Zugriff auf die Wallet zu erhalten! Dieser Service ist in BETA und wir übernehmen keine Verantwortung für Verluste durch verlorene Zugriffe.",no_transactions:"Keine Transaktionen",manage_extensions:"Erweiterungen verwalten",manage_server:"Server verwalten",extensions:"Erweiterungen",no_extensions:"Du hast noch keine Erweiterungen installiert :(",created:"Erstellt",search_extensions:"Sucherweiterungen",warning:"Warnung",manage:"Verwalten",repository:"Repository",confirm_continue:"Bist du sicher, dass du fortfahren möchtest?",manage_extension_details:"Erweiterung installieren/deinstallieren",install:"Installieren",uninstall:"Deinstallieren",open:"Öffnen",enable:"Aktivieren",enable_extension_details:"Erweiterung für aktuellen Benutzer aktivieren",disable:"Deaktivieren",installed:"Installiert",activated:"Aktiviert",deactivated:"Deaktiviert",release_notes:"Versionshinweise",activate_extension_details:"Erweiterung für Benutzer verfügbar/nicht verfügbar machen",featured:"Vorgestellt",all:"Alle",only_admins_can_install:"(Nur Administratorkonten können Erweiterungen installieren)",new_version:"Neue Version",extension_depends_on:"Hängt ab von:",extension_rating_soon:"Bewertungen sind bald verfügbar",extension_installed_version:"Installierte Version",extension_uninstall_warning:"Sie sind dabei, die Erweiterung für alle Benutzer zu entfernen.",uninstall_confirm:"Ja, deinstallieren",extension_min_lnbits_version:"Diese Version erfordert mindestens die LNbits-Version",payment_hash:"Zahlungs-Hash",fee:"Gebühr",amount:"Menge",description:"Beschreibung",expiry:"Ablauf",webhook:"Webhook",payment_proof:"Beleg"},window.localisation.en={confirm:"Yes",server:"Server",theme:"Theme",funding:"Funding",users:"Users",apps:"Apps",channels:"Channels",transactions:"Transactions",dashboard:"Dashboard",manage_node:"Manage Node",total_capacity:"Total Capacity",avg_channel_size:"Avg. Channel Size",biggest_channel_size:"Biggest Channel Size",smallest_channel_size:"Smallest Channel Size",number_of_channels:"Number of Channels",active_channels:"Active Channels",connect_peer:"Connect Peer",connect:"Connect",open_channel:"Open Channel",open:"Open",close_channel:"Close Channel",close:"Close",restart:"Restart server",save:"Save",save_tooltip:"Save your changes",topup:"Topup",topup_wallet:"Topup a wallet",topup_hint:"Use the wallet ID to topup any wallet",restart_tooltip:"Restart the server for changes to take effect",add_funds_tooltip:"Add funds to a wallet.",reset_defaults:"Reset to defaults",reset_defaults_tooltip:"Delete all settings and reset to defaults.",download_backup:"Download database backup",name_your_wallet:"Name your %{name} wallet",paste_invoice_label:"Paste an invoice, payment request or lnurl code *",lnbits_description:"Easy to set up and lightweight, LNbits can run on any lightning-network funding source, currently supporting LND, Core Lightning, OpenNode, LNPay and even LNbits itself! You can run LNbits for yourself, or easily offer a custodian solution for others. Each wallet has its own API keys and there is no limit to the number of wallets you can make. Being able to partition funds makes LNbits a useful tool for money management and as a development tool. Extensions add extra functionality to LNbits so you can experiment with a range of cutting-edge technologies on the lightning network. We have made developing extensions as easy as possible, and as a free and open-source project, we encourage people to develop and submit their own.",export_to_phone:"Export to Phone with QR Code",export_to_phone_desc:"This QR code contains your wallet URL with full access. You can scan it from your phone to open your wallet from there.",wallets:"Wallets",add_wallet:"Add a new wallet",delete_wallet:"Delete wallet",delete_wallet_desc:"This whole wallet will be deleted, the funds will be UNRECOVERABLE.",rename_wallet:"Rename wallet",update_name:"Update name",fiat_tracking:"Fiat tracking",currency:"Currency",update_currency:"Update currency",press_to_claim:"Press to claim bitcoin",donate:"Donate",view_github:"View on GitHub",voidwallet_active:"VoidWallet is active! Payments disabled",use_with_caution:"USE WITH CAUTION - %{name} wallet is still in BETA",toggle_darkmode:"Toggle Dark Mode",view_swagger_docs:"View LNbits Swagger API docs",api_docs:"Api docs",commit_version:"Commit version",lnbits_version:"LNbits version",runs_on:"Runs on",credit_hint:"Press Enter to credit account",credit_label:"%{denomination} to credit",paste:"Paste",paste_from_clipboard:"Paste from clipboard",paste_request:"Paste Request",create_invoice:"Create Invoice",camera_tooltip:"Use camera to scan an invoice/QR",export_csv:"Export to CSV",transactions:"Transactions",chart_tooltip:"Show chart",pending:"Pending",copy_invoice:"Copy invoice",close:"Close",cancel:"Cancel",scan:"Scan",read:"Read",pay:"Pay",memo:"Memo",date:"Date",processing_payment:"Processing payment...",not_enough_funds:"Not enough funds!",search_by_tag_memo_amount:"Search by tag, memo, amount",invoice_waiting:"Invoice waiting to be paid",payment_received:"Payment Received",payment_sent:"Payment Sent",receive:"receive",send:"send",outgoing_payment_pending:"Outgoing payment pending",drain_funds:"Drain Funds",drain_funds_desc:"This is an LNURL-withdraw QR code for slurping everything from this wallet. Do not share with anyone. It is compatible with balanceCheck and balanceNotify so your wallet may keep pulling the funds continuously from here after the first withdraw.",i_understand:"I understand",copy_wallet_url:"Copy wallet URL",disclaimer_dialog:"Login functionality to be released in a future update, for now, make sure you bookmark this page for future access to your wallet! This service is in BETA, and we hold no responsibility for people losing access to funds.",no_transactions:"No transactions made yet",manage_server:"Manage Server",extensions:"Extensions",no_extensions:"You don't have any extensions installed :(",created:"Created",search_extensions:"Search extensions",warning:"Warning",manage:"Manage",repository:"Repository",confirm_continue:"Are you sure you want to continue?",manage_extension_details:"Install/uninstall extension",install:"Install",uninstall:"Uninstall",drop_db:"Remove Data",open:"Open",enable:"Enable",enable_extension_details:"Enable extension for current user",disable:"Disable",installed:"Installed",activated:"Activated",deactivated:"Deactivated",release_notes:"Release Notes",activate_extension_details:"Make extension available/unavailable for users",featured:"Featured",all:"All",only_admins_can_install:"(Only admin accounts can install extensions)",admin_only:"Admin Only",new_version:"New Version",extension_depends_on:"Depends on:",extension_rating_soon:"Ratings coming soon",extension_installed_version:"Installed version",extension_uninstall_warning:"You are about to remove the extension for all users.",uninstall_confirm:"Yes, Uninstall",extension_db_drop_info:"All data for the extension will be permanently deleted. There is no way to undo this operation!",extension_db_drop_warning:"You are about to remove all data for the extension. Please type the extension name to continue:",extension_min_lnbits_version:"This release requires at least LNbits version",payment_hash:"Payment Hash",fee:"Fee",amount:"Amount",unit:"Unit",description:"Description",expiry:"Expiry",webhook:"Webhook",payment_proof:"Payment Proof",update_available:"Update %{version} available!",latest_update:"You are on the latest version %{version}.",notifications:"Notifications",no_notifications:"No notifications",notifications_disabled:"LNbits status notifications are disabled.",enable_notifications:"Enable Notifications",enable_notifications_desc:"If enabled it will fetch the latest LNbits Status updates, like security incidents and updates.",enable_killswitch:"Enable Killswitch",enable_killswitch_desc:"If enabled it will change your funding source to VoidWallet automatically if LNbits sends out a killswitch signal. You will need to enable manually after an update.",killswitch_interval:"Killswitch Interval",killswitch_interval_desc:"How often the background task should check for the LNBits killswitch signal from the status source (in minutes).",enable_watchdog:"Enable Watchdog",enable_watchdog_desc:"If enabled it will change your funding source to VoidWallet automatically if your balance is lower than the LNbits balance. You will need to enable manually after an update.",watchdog_interval:"Watchdog Interval",watchdog_interval_desc:"How often the background task should check for a killswitch signal in the watchdog delta [node_balance - lnbits_balance] (in minutes).",watchdog_delta:"Watchdog Delta",watchdog_delta_desc:"Limit before killswitch changes funding source to VoidWallet [lnbits_balance - node_balance > delta]",status:"Status",notification_source:"Notification Source",notification_source_label:"Source URL (only use the official LNbits status source, and sources you can trust)",more:"more",releases:"Releases",killswitch:"Killswitch",watchdog:"Watchdog",server_logs:"Server Logs",ip_blocker:"IP Blocker",security:"Security",security_tools:"Security tools",block_access_hint:"Block access by IP",allow_access_hint:"Allow access by IP (will override blocked IPs)",enter_ip:"Enter IP and hit enter",rate_limiter:"Rate Limiter",number_of_requests:"Number of requests",time_unit:"Time unit",minute:"minute",second:"second",hour:"hour",disable_server_log:"Disable Server Log",enable_server_log:"Enable Server Log",coming_soon:"Feature coming soon"},window.localisation.es={server:"Servidor",theme:"Tema",funding:"Financiación",unit:"Unidad",users:"Usuarios",restart:"Reiniciar el servidor",save:"Guardar",save_tooltip:"Guardar cambios",topup:"Recargar",topup_wallet:"Recargar billetera",topup_hint:"Utilice el ID de billetera para recargar cualquier billetera",restart_tooltip:"Reinicie el servidor para aplicar los cambios",add_funds_tooltip:"Agregue fondos a una billetera.",reset_defaults:"Restablecer",reset_defaults_tooltip:"Borrar todas las configuraciones y restablecer a los valores predeterminados.",download_backup:"Descargar copia de seguridad de la base de datos",name_your_wallet:"Nombre de su billetera %{name}",paste_invoice_label:"Pegue la factura aquí",lnbits_description:"Fácil de instalar y liviano, LNbits puede ejecutarse en cualquier fuente de financiación de la red Lightning, actualmente compatible con LND, Core Lightning, OpenNode, LNPay y hasta LNbits mismo! Puede ejecutar LNbits para usted mismo o ofrecer una solución competente a otros. Cada billetera tiene su propia clave API y no hay límite para la cantidad de billeteras que puede crear. La capacidad de particionar fondos hace de LNbits una herramienta útil para la administración de fondos y como herramienta de desarrollo. Las extensiones agregan funcionalidad adicional a LNbits, por lo que puede experimentar con una variedad de tecnologías de vanguardia en la red Lightning. Lo hemos hecho lo más simple posible para desarrollar extensiones y, como un proyecto gratuito y de código abierto, animamos a las personas a que se desarrollen a sí mismas y envíen sus propios contribuciones.",export_to_phone:"Exportar a teléfono con código QR",export_to_phone_desc:"Este código QR contiene su URL de billetera con acceso completo. Puede escanearlo desde su teléfono para abrir su billetera allí.",wallets:"Billeteras",add_wallet:"Agregar nueva billetera",delete_wallet:"Eliminar billetera",delete_wallet_desc:"Esta billetera completa se eliminará, los fondos son IRREVERSIBLES.",rename_wallet:"Cambiar el nombre de la billetera",update_name:"Actualizar nombre",press_to_claim:"Presione para reclamar Bitcoin",donate:"Donar",view_github:"Ver en GitHub",voidwallet_active:"¡VoidWallet está activo! Pagos desactivados",use_with_caution:"USAR CON CUIDADO - %{name} Wallet aún está en BETA",toggle_darkmode:"Cambiar modo oscuro",view_swagger_docs:"Ver documentos de API de LNbits Swagger",api_docs:"Documentos de API",commit_version:"Versión de compromiso",runs_on:"Corre en",credit_hint:"Presione Enter para cargar la cuenta",credit_label:"Cargar %{denomination}",paste_request:"Pegar solicitud",create_invoice:"Crear factura",camera_tooltip:"Utilice la cámara para escanear una factura / código QR",export_csv:"Exportar a CSV",transactions:"Transacciones",chart_tooltip:"Mostrar gráfico",pending:"Pendiente",copy_invoice:"Copiar factura",close:"Cerrar",cancel:"Cancelar",scan:"Escanear",read:"Leer",pay:"Pagar",memo:"Memo",date:"Fecha",processing_payment:"Procesando pago ...",not_enough_funds:"¡No hay suficientes fondos!",search_by_tag_memo_amount:"Buscar por etiqueta, memo, cantidad",invoice_waiting:"Factura esperando pago",payment_received:"Pago recibido",payment_sent:"Pago enviado",receive:"recibir",send:"enviar",outgoing_payment_pending:"Pago saliente pendiente",drain_funds:"Drenar fondos",drain_funds_desc:"Este es un código QR LNURL-withdraw para drenar todos los fondos de esta billetera. No lo comparta con nadie. Es compatible con balanceCheck y balanceNotify, por lo que su billetera puede continuar drenando los fondos de aquí después del primer drenaje.",i_understand:"Lo entiendo",copy_wallet_url:"Copiar URL de billetera",disclaimer_dialog:"La funcionalidad de inicio de sesión se lanzará en una actualización futura, por ahora, asegúrese de guardar esta página como marcador para acceder a su billetera en el futuro. Este servicio está en BETA y no asumimos ninguna responsabilidad por personas que pierdan el acceso a sus fondos.",no_transactions:"No hay transacciones todavía",manage_server:"Administrar servidor",extensions:"Extensiones",no_extensions:"No tienes extensiones instaladas :(",created:"Creado",search_extensions:"Extensiones de búsqueda",warning:"Advertencia",manage:"Administrar",repository:"Repositorio",confirm_continue:"¿Está seguro de que desea continuar?",manage_extension_details:"Instalar/desinstalar extensión",install:"Instalar",uninstall:"Desinstalar",open:"Abrir",enable:"Habilitar",enable_extension_details:"Habilitar extensión para el usuario actual",disable:"Deshabilitar",installed:"Instalado",activated:"Activado",deactivated:"Desactivado",release_notes:"Notas de la versión",activate_extension_details:"Hacer que la extensión esté disponible/no disponible para los usuarios",featured:"Destacado",all:"Todos",only_admins_can_install:"(Solo las cuentas de administrador pueden instalar extensiones)",new_version:"Nueva Versión",extension_depends_on:"Depende de:",extension_rating_soon:"Calificaciones próximamente",extension_installed_version:"Versión instalada",extension_uninstall_warning:"Está a punto de eliminar la extensión para todos los usuarios.",uninstall_confirm:"Sí, desinstalar",extension_min_lnbits_version:"Esta versión requiere al menos una versión de LNbits",payment_hash:"Hash de pago",fee:"Cuota",amount:"Cantidad",description:"Descripción",expiry:"Expiración",webhook:"Webhook",payment_proof:"Prueba de pago"},window.localisation.fr={server:"Serveur",theme:"Thème",funding:"Financement",users:"Utilisateurs",restart:"Redémarrer le serveur",save:"Enregistrer",save_tooltip:"Enregistrer vos modifications",topup:"Renflouer",topup_wallet:"Reflouer un portefeuille",topup_hint:"Utilisez l'ID du portefeuille pour recharger n'importe quel portefeuille",restart_tooltip:"Redémarrez le serveur pour que les changements prennent effet",add_funds_tooltip:"Ajouter des fonds à un portefeuille.",reset_defaults:"Réinitialiser aux valeurs par défaut",reset_defaults_tooltip:"Supprimer tous les paramètres et les réinitialiser aux valeurs par défaut.",download_backup:"Télécharger la sauvegarde de la base de données",name_your_wallet:"Nommez votre portefeuille %{name}",paste_invoice_label:"Coller une facture, une demande de paiement ou un code lnurl *",lnbits_description:"Facile à installer et léger, LNbits peut fonctionner sur n'importe quelle source de financement du réseau Lightning, prenant actuellement en charge LND, Core Lightning, OpenNode, LNPay et même LNbits lui-même! Vous pouvez exécuter LNbits pour vous-même ou offrir facilement une solution de gardien pour les autres. Chaque portefeuille a ses propres clés API et il n'y a pas de limite au nombre de portefeuilles que vous pouvez créer. La capacité de partitionner les fonds rend LNbits un outil utile pour la gestion de l'argent et comme outil de développement. Les extensions ajoutent une fonctionnalité supplémentaire à LNbits afin que vous puissiez expérimenter une gamme de technologies de pointe sur le réseau Lightning. Nous avons rendu le développement d'extensions aussi simple que possible et, en tant que projet gratuit et open source, nous encourageons les gens à développer et à soumettre les leurs.",export_to_phone:"Exporter vers le téléphone avec un code QR",export_to_phone_desc:"Ce code QR contient l'URL de votre portefeuille avec un accès complet. Vous pouvez le scanner depuis votre téléphone pour ouvrir votre portefeuille depuis là-bas.",wallets:"Portefeuilles",add_wallet:"Ajouter un nouveau portefeuille",delete_wallet:"Supprimer le portefeuille",delete_wallet_desc:"Ce portefeuille entier sera supprimé et les fonds seront IRRECUPERABLES.",rename_wallet:"Renommer le portefeuille",update_name:"Mettre à jour le nom",press_to_claim:"Appuyez pour demander du Bitcoin",donate:"Donner",view_github:"Voir sur GitHub",voidwallet_active:"VoidWallet est actif! Paiements désactivés",use_with_caution:"UTILISER AVEC PRUDENCE - Le portefeuille %{name} est toujours en version BETA",toggle_darkmode:"Basculer le mode sombre",view_swagger_docs:"Voir les documents de l'API Swagger de LNbits",api_docs:"Documents de l'API",commit_version:"Version de commit",lnbits_version:"Version de LNbits",runs_on:"Fonctionne sur",credit_hint:"Appuyez sur Entrée pour créditer le compte",credit_label:"%{denomination} à créditer",paste_request:"Coller la requête",create_invoice:"Créer une facture",camera_tooltip:"Utiliser la caméra pour scanner une facture / un code QR",export_csv:"Exporter vers CSV",transactions:"Transactions",chart_tooltip:"Afficher le graphique",pending:"En attente",copy_invoice:"Copier la facture",close:"Fermer",cancel:"Annuler",scan:"Scanner",read:"Lire",pay:"Payer",memo:"Mémo",date:"Date",processing_payment:"Traitement du paiement...",not_enough_funds:"Fonds insuffisants !",search_by_tag_memo_amount:"Rechercher par tag, mémo, montant",invoice_waiting:"Facture en attente de paiement",payment_received:"Paiement reçu",payment_sent:"Paiement envoyé",receive:"recevoir",send:"envoyer",outgoing_payment_pending:"Paiement sortant en attente",drain_funds:"Vider les fonds",drain_funds_desc:"Il s'agit d'un code QR LNURL-withdraw pour tout aspirer de ce portefeuille. Ne le partagez avec personne. Il est compatible avec balanceCheck et balanceNotify, de sorte que votre portefeuille peut continuer à retirer les fonds continuellement à partir d'ici après le premier retrait.",i_understand:"J'ai compris",copy_wallet_url:"Copier l'URL du portefeuille",disclaimer_dialog:"La fonctionnalité de connexion sera publiée dans une future mise à jour, pour l'instant, assurez-vous de mettre cette page en favori pour accéder à votre portefeuille ultérieurement ! Ce service est en BETA, et nous ne sommes pas responsables des personnes qui perdent l'accès à leurs fonds.",no_transactions:"Aucune transaction effectuée pour le moment",manage_extensions:"Gérer les extensions",manage_server:"Gérer le serveur",extensions:"Extensions",no_extensions:"Vous n'avez installé aucune extension :(",created:"Créé",payment_hash:"Hash de paiement",fee:"Frais",amount:"Montant",unit:"Unité",description:"Description",expiry:"Expiration",webhook:"Webhook",payment_proof:"Preuve de paiement"},window.localisation.it={server:"Server",theme:"Tema",funding:"Funding",users:"Utenti",restart:"Riavvia il server",save:"Salva",save_tooltip:"Salva le modifiche",topup:"Ricarica",topup_wallet:"Ricarica un portafoglio",topup_hint:"Usa l'ID del portafoglio per ricaricare qualsiasi portafoglio",restart_tooltip:"Riavvia il server affinché le modifiche abbiano effetto",add_funds_tooltip:"Aggiungere fondi a un portafoglio",reset_defaults:"Ripristina le impostazioni predefinite",reset_defaults_tooltip:"Cancella tutte le impostazioni e ripristina i valori predefiniti",download_backup:"Scarica il backup del database",name_your_wallet:"Dai un nome al tuo portafoglio %{name}",paste_invoice_label:"Incolla una fattura, una richiesta di pagamento o un codice lnurl *",lnbits_description:"Leggero e facile da configurare, LNbits può funzionare su qualsiasi fonte di finanziamento lightning-network, attualmente supporta LND, Core Lightning, OpenNode, LNPay e persino LNbits stesso! Potete gestire LNbits per conto vostro o offrire facilmente una soluzione di custodia per altri. Ogni portafoglio ha le proprie chiavi API e non c'è limite al numero di portafogli che si possono creare. La possibilità di suddividere i fondi rende LNbits uno strumento utile per la gestione del denaro e come strumento di sviluppo. Le estensioni aggiungono ulteriori funzionalità a LNbits, consentendo di sperimentare una serie di tecnologie all'avanguardia sulla rete Lightning. Abbiamo reso lo sviluppo delle estensioni il più semplice possibile e, in quanto progetto libero e open-source, incoraggiamo le persone a sviluppare e inviare le proprie",export_to_phone:"Esportazione su telefono con codice QR",export_to_phone_desc:"Questo codice QR contiene l'URL del portafoglio con accesso da amministratore. È possibile scansionarlo dal telefono per aprire il portafoglio da lì.",wallets:"Portafogli",add_wallet:"Aggiungi un nuovo portafoglio",delete_wallet:"Elimina il portafoglio",delete_wallet_desc:"L'intero portafoglio sarà cancellato, i fondi saranno irrecuperabili",rename_wallet:"Rinomina il portafoglio",update_name:"Aggiorna il nome",press_to_claim:"Premi per richiedere bitcoin",donate:"Donazioni",view_github:"Visualizza su GitHub",voidwallet_active:"VoidWallet è attivo! Pagamenti disabilitati",use_with_caution:"USARE CON CAUTELA - %{nome} portafoglio è ancora in BETA",toggle_darkmode:"Attiva la modalità notturna",view_swagger_docs:"Visualizza i documenti dell'API Swagger di LNbits",api_docs:"Documenti API",commit_version:"Commit version",lnbits_version:"Versione di LNbits",runs_on:"Esegue su",credit_hint:"Premere Invio per accreditare i fondi",credit_label:"%{denomination} da accreditare",paste_request:"Richiesta di pagamento",create_invoice:"Crea fattura",camera_tooltip:"Usa la fotocamera per scansionare la fattura/QR",export_csv:"Esporta CSV",transactions:"Transazioni",chart_tooltip:"Mostra grafico",pending:"In attesa",copy_invoice:"Copia fattura",close:"Chiudi",cancel:"Annulla",scan:"Scansiona",read:"Leggi",pay:"Paga",memo:"Memo",data:"Dati",processing_payment:"Elaborazione pagamento...",not_enough_funds:"Non ci sono abbastanza fondi!",search_by_tag_memo_amount:"Cerca per tag, memo, importo...",invoice_waiting:"Fattura in attesa di pagamento",payment_received:"Pagamento ricevuto",payment_sent:"Pagamento inviato",receive:"ricevere",send:"inviare",outgoing_payment_pending:"Pagamento in uscita in attesa",drain_funds:"Fondi di drenaggio",drain_funds_desc:"Questo è un codice QR LNURL-withdraw
per prelevare tutti i fondi da questo portafoglio. Non condividerlo con nessuno. È compatibile con balanceCheck
e balanceNotify
, di conseguenza il vostro portafoglio può continuare a prelevare continuamente i fondi da qui dopo il primo prelievo",i_understand:"Ho capito",copy_wallet_url:"Copia URL portafoglio",disclaimer_dialog:"La funzionalità di login sarà rilasciata in un futuro aggiornamento; per ora, assicuratevi di salvare tra i preferiti questa pagina per accedere nuovamente in futuro a questo portafoglio! Questo servizio è in fase BETA e non ci assumiamo alcuna responsabilità per la perdita all'accesso dei fondi",no_transactions:"Nessuna transazione effettuata",manage_extensions:"Gestisci le estensioni",manage_server:"Gestisci server",estensioni:"Estensioni",no_extensions:"Non ci sono estensioni installate :(",created:"Creato",payment_hash:"Hash del pagamento",fee:"Tariffa",amount:"Importo",unit:"Unità",description:"Descrizione",expiry:"Scadenza",webhook:"Webhook",prova_di_pagamento:"Prova di pagamento"},window.localisation.jp={server:"サーバー",theme:"テーマ",funding:"資金調達",users:"ユーザー",restart:"サーバーを再起動する",save:"保存",unit:"単位",save_tooltip:"変更を保存する",topup:"トップアップ",topup_wallet:"ウォレットをトップアップする",topup_hint:"ウォレットIDを使用して、任意のウォレットをトップアップできます",restart_tooltip:"サーバーを再起動して変更を適用します",add_funds_tooltip:"ウォレットに資金を追加します。",reset_defaults:"リセット",reset_defaults_tooltip:"すべての設定を削除してデフォルトに戻します。",download_backup:"データベースのバックアップをダウンロードする",name_your_wallet:"あなたのウォレットの名前 %{name}",paste_invoice_label:"請求書を貼り付けてください",lnbits_description:"簡単にインストールでき、軽量で、LNbitsは現在LND、Core Lightning、OpenNode、LNPay、さらにLNbits自身で動作する任意のLightningネットワークの資金源で実行できます! LNbitsを自分で実行することも、他の人に優れたソリューションを提供することもできます。各ウォレットには独自のAPIキーがあり、作成できるウォレットの数に制限はありません。資金を分割する機能は、LNbitsを資金管理ツールとして使用したり、開発ツールとして使用したりするための便利なツールです。拡張機能は、LNbitsに追加の機能を追加します。そのため、LNbitsは最先端の技術をネットワークLightningで試すことができます。拡張機能を開発するのは簡単で、無料でオープンソースのプロジェクトであるため、人々が自分で開発し、自分の貢献を送信することを奨励しています。",export_to_phone:"電話にエクスポート",export_to_phone_desc:"ウォレットを電話にエクスポートすると、ウォレットを削除する前にウォレットを復元できます。ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。",wallets:"ウォレット",add_wallet:"ウォレットを追加",delete_wallet:"ウォレットを削除",delete_wallet_desc:"ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。",rename_wallet:"ウォレットの名前を変更",update_name:"名前を更新",press_to_claim:"クレームするには押してください",donate:"寄付",voidwallet_active:"Voidwalletアクティブ",use_with_caution:"注意して使用してください",toggle_dark_mode:"ダークモードを切り替える",view_swagger_docs:"Swaggerドキュメントを表示",api_docs:"APIドキュメント",commit_version:"コミットバージョン",runs_on:"で実行",credit_hint:"クレジットカードを使用して資金を追加するには、LNbitsを使用してください。",credit_label:"クレジットカード",paste_request:"リクエストを貼り付ける",create_invoice:"請求書を作成する",camera_tooltip:"QRコードを読み取る",export_csv:"CSVでエクスポート",transactions:"トランザクション",chart_tooltip:"チャートを表示するには、グラフの上にカーソルを合わせます",pending:"保留中",copy_invoice:"請求書をコピー",close:"閉じる",cancel:"キャンセル",scan:"スキャン",read:"読む",pay:"支払う",memo:"メモ",date:"日付",processing_payment:"支払い処理中",not_enough_funds:"資金が不足しています",search_by_tag_memo_amount:"タグ、メモ、金額で検索",invoice_waiting:"請求書を待っています",payment_received:"お支払いありがとうございます",payment_sent:"支払いが完了しました",receive:"受け取る",send:"送信",outgoing_payment_pending:"支払い保留中",drain_funds:"資金を排出する",drain_funds_desc:"ウォレットの残高をすべて他のウォレットに送金します",i_understand:"理解した",copy_wallet_url:"ウォレットURLをコピー",disclaimer_dialog:"ウォレットを削除すると、ウォレットの秘密鍵が削除され、ウォレットを復元することはできません。ウォレットを削除する前に、ウォレットをエクスポートしてください。",no_transactions:"トランザクションはありません",manage_server:"サーバーを管理する",extensions:"拡張機能",no_extensions:"拡張機能はありません",created:"作成済み",search_extensions:"検索拡張機能",warning:"警告",manage:"管理",repository:"リポジトリ",confirm_continue:"続行してもよろしいですか?",manage_extension_details:"拡張機能のインストール/アンインストール",install:"インストール",uninstall:"アンインストール",open:"開く",enable:"有効",enable_extension_details:"現在のユーザーの拡張機能を有効にする",disable:"無効",installed:"インストール済み",activated:"有効化",deactivated:"無効化",release_notes:"リリースノート",activate_extension_details:"拡張機能をユーザーが利用できるようにする/利用できないようにする",featured:"特集",all:"すべて",only_admins_can_install:"(管理者アカウントのみが拡張機能をインストールできます)",new_version:"新しいバージョン",extension_depends_on:"依存先:",extension_rating_soon:"評価は近日公開",extension_installed_version:"インストール済みバージョン",extension_uninstall_warning:"すべてのユーザーの拡張機能を削除しようとしています.",uninstall_confirm:"はい、アンインストールします",extension_min_lnbits_version:"このリリースには少なくとも LNbits バージョンが必要です",payment_hash:"支払いハッシュ",fee:"料金",amount:"量",description:"説明",expiry:"有効期限",webhook:"ウェブフック",payment_proof:"支払い証明"},window.localisation.cn={confirm:"确定",server:"服务器",theme:"主题",funding:"资金",users:"用户",restart:"重新启动服务器",save:"保存",save_tooltip:"保存更改",topup:"充值",topup_wallet:"给钱包充值",topup_hint:"使用钱包ID为任何钱包充值",restart_tooltip:"重新启动服务器以使更改生效",add_funds_tooltip:"为钱包添加资金",reset_defaults:"重置为默认设置",reset_defaults_tooltip:"删除所有设置并重置为默认设置",download_backup:"下载数据库备份",name_your_wallet:"给你的 %{name}钱包起个名字",paste_invoice_label:"粘贴发票,付款请求或lnurl*",lnbits_description:"LNbits 设置简单、轻量级,可以运行在任何闪电网络的版本上,目前支持 LND、Core Lightning、OpenNode、LNPay,甚至 LNbits 本身!您可以为自己运行 LNbits,或者为他人轻松提供资金托管。每个钱包都有自己的 API 密钥,你可以创建的钱包数量没有限制。能够把资金分开管理使 LNbits 成为一款有用的资金管理和开发工具。扩展程序增加了 LNbits 的额外功能,所以你可以在闪电网络上尝试各种尖端技术。我们已经尽可能简化了开发扩展程序的过程,作为一个免费和开源的项目,我们鼓励人们开发并提交自己的扩展程序。",export_to_phone:"通过二维码导出到手机",export_to_phone_desc:"这个二维码包含您钱包的URL。您可以使用手机扫描的方式打开您的钱包。",wallets:"钱包",add_wallet:"添加新钱包",delete_wallet:"删除钱包",delete_wallet_desc:"整个钱包将被删除,资金将无法恢复",rename_wallet:"重命名钱包",update_name:"更新名称",press_to_claim:"点击领取比特币",donate:"捐献",view_github:"在GitHub上查看",voidwallet_active:"VoidWallet 已激活!付款功能已禁用。",use_with_caution:"请谨慎使用 - %{name}钱包还处于测试版阶段",toggle_darkmode:"切换暗黑模式",view_swagger_docs:"查看 LNbits Swagger API 文档",api_docs:"API文档",commit_version:"提交版本",lnbits_version:"LNbits版本",runs_on:"可运行在",credit_hint:"按 Enter 键充值账户",credit_label:"%{denomination} 充值",paste_request:"粘贴请求",create_invoice:"创建发票",camera_tooltip:"用相机扫描发票/二维码",export_csv:"导出为CSV",transactions:"交易记录",chart_tooltip:"显示图表",pending:"待处理",copy_invoice:"复制发票",close:"关闭",cancel:"取消",scan:"扫描",read:"读取",pay:"付款",memo:"备注",date:"日期",processing_payment:"正在处理支付...",not_enough_funds:"资金不足!",search_by_tag_memo_amount:"按标签、备注、金额搜索",invoice_waiting:"待支付的发票",payment_received:"收到付款",payment_sent:"付款已发送",receive:"收款",send:"付款",outgoing_payment_pending:"付款正在等待处理",drain_funds:"清空资金",drain_funds_desc:"这是一个 LNURL-取款的二维码,用于从该钱包中提取全部资金。请不要与他人分享。它与 balanceCheck 和 balanceNotify 兼容,因此在第一次取款后,您的钱包还可能会持续从这里提取资金",i_understand:"我明白",copy_wallet_url:"复制钱包URL",disclaimer_dialog:"登录功能将在以后的更新中发布,请将此页面加为书签,以便将来访问您的钱包!此服务处于测试阶段,我们不对资金的丢失承担任何责任。",no_transactions:"尚未进行任何交易",manage_server:"管理服务器",extensions:"扩展程序",no_extensions:"你没有安装任何扩展程序 :(",created:"已创建",search_extensions:"搜索扩展程序",warning:"警告",manage:"管理",repository:"代码库",confirm_continue:"你确定要继续吗?",manage_extension_details:"安装/卸载扩展程序",install:"安装",uninstall:"卸载",drop_db:"删除数据",open:"打开",enable:"启用",enable_extension_details:"为当前用户启用扩展程序",disable:"禁用",installed:"已安装",activated:"已激活",deactivated:"已停用",release_notes:"发布说明",activate_extension_details:"对用户开放或禁用扩展程序",featured:"精选",all:"全部",only_admins_can_install:"(只有管理员账户可以安装扩展)",admin_only:"仅限管理员",new_version:"新版本",extension_depends_on:"依赖于:",extension_rating_soon:"即将推出评分",extension_installed_version:"已安装的版本",extension_uninstall_warning:"您即将对所有用户删除该扩展程序。",uninstall_confirm:"是的,卸载",extension_db_drop_info:"该扩展程序的所有数据将被永久删除。此操作无法撤销!",extension_db_drop_warning:"您即将删除该扩展的所有数据。请继续输入扩展程序名称以确认操作:",extension_min_lnbits_version:"此版本要求最低的 LNbits 版本为",payment_hash:"付款哈希",fee:"费",amount:"金额",unit:"单位",description:"详情",expiry:"过期时间",webhook:"Webhook",payment_proof:"付款证明"},window.localisation.nl={server:"Server",theme:"Thema",funding:"Financiering",users:"Gebruikers",restart:"Server opnieuw opstarten",save:"Opslaan",save_tooltip:"Sla uw wijzigingen op",topup:"Bijvullen",topup_wallet:"Een portemonnee bijvullen",topup_hint:"Gebruik de portemonnee-ID om elke portemonnee bij te vullen",restart_tooltip:"Start de server opnieuw op zodat wijzigingen van kracht worden",add_funds_tooltip:"Voeg geld toe aan een portemonnee.",reset_defaults:"Standaardinstellingen herstellen",reset_defaults_tooltip:"Wis alle instellingen en herstel de standaardinstellingen.",download_backup:"Databaseback-up downloaden",name_your_wallet:"Geef je %{name} portemonnee een naam",paste_invoice_label:"Plak een factuur, betalingsverzoek of lnurl-code*",lnbits_description:"Gemakkelijk in te stellen en lichtgewicht, LNbits kan op elke lightning-netwerkfinancieringsbron draaien, ondersteunt op dit moment LND, Core Lightning, OpenNode, LNPay en zelfs LNbits zelf! U kunt LNbits voor uzelf laten draaien of gemakkelijk een bewaardersoplossing voor anderen bieden. Elke portemonnee heeft zijn eigen API-sleutels en er is geen limiet aan het aantal portemonnees dat u kunt maken. Het kunnen partitioneren van fondsen maakt LNbits een nuttige tool voor geldbeheer en als ontwikkelingstool. Extensies voegen extra functionaliteit toe aan LNbits, zodat u kunt experimenteren met een reeks toonaangevende technologieën op het bliksemschichtnetwerk. We hebben het ontwikkelen van extensies zo eenvoudig mogelijk gemaakt en als een gratis en opensource-project moedigen we mensen aan om hun eigen ontwikkelingen in te dienen.",export_to_phone:"Exporteren naar telefoon met QR-code",export_to_phone_desc:"Deze QR-code bevat uw portemonnee-URL met volledige toegang. U kunt het vanaf uw telefoon scannen om uw portemonnee van daaruit te openen.",wallets:"Portemonnees",add_wallet:"Een nieuwe portemonnee toevoegen",delete_wallet:"Portemonnee verwijderen",delete_wallet_desc:"Deze hele portemonnee wordt verwijderd, de fondsen worden NIET TERUGGEVONDEN.",rename_wallet:"Portemonnee hernoemen",update_name:"Naam bijwerken",press_to_claim:"Druk om bitcoin te claimen",donate:"Doneren",view_github:"Bekijken op GitHub",voidwallet_active:"VoidWallet is actief! Betalingen uitgeschakeld",use_with_caution:"GEBRUIK MET VOORZICHTIGHEID - %{name} portemonnee is nog in BETA",toggle_darkmode:"Donkere modus aan/uit",view_swagger_docs:"Bekijk LNbits Swagger API-documentatie",api_docs:"API-documentatie",commit_version:"Commit-versie",lnbits_version:"LNbits-versie",runs_on:"Draait op",credit_hint:"Druk op Enter om de rekening te crediteren",credit_label:"%{denomination} te crediteren",paste_request:"Verzoek plakken",create_invoice:"Factuur aanmaken",camera_tooltip:"Gebruik de camera om een factuur/QR-code te scannen",export_csv:"Exporteer naar CSV",transactions:"Transacties",chart_tooltip:"Toon grafiek",pending:"In behandeling",copy_invoice:"Kopieer factuur",close:"Sluiten",cancel:"Annuleren",scan:"Scannen",read:"Lezen",pay:"Betalen",memo:"Memo",date:"Datum",processing_payment:"Verwerking betaling...",not_enough_funds:"Onvoldoende saldo!",search_by_tag_memo_amount:"Zoeken op tag, memo, bedrag",invoice_waiting:"Factuur wachtend op betaling",payment_received:"Betaling ontvangen",payment_sent:"Betaling verzonden",receive:"ontvangen",send:"versturen",voutgoing_payment_pending:"Uitgaande betaling in behandeling",drain_funds:"Geld opnemen",drain_funds_desc:"Dit is een LNURL-withdraw QR-code om alles uit deze portemonnee te halen. Deel deze code niet met anderen. Het is compatibel met balanceCheck en balanceNotify zodat jouw portemonnee continu geld kan blijven opnemen vanaf hier na de eerste opname.",i_understand:"Ik begrijp het",copy_wallet_url:"Kopieer portemonnee-URL",disclaimer_dialog:"Inlogfunctionaliteit wordt uitgebracht in een toekomstige update. Zorg er nu voor dat je deze pagina als favoriet markeert om in de toekomst toegang te krijgen tot je portemonnee! Deze service is in BETA en we zijn niet verantwoordelijk voor mensen die de toegang tot hun fondsen verliezen.",no_transactions:"Er zijn nog geen transacties gedaan",manage_extensions:"Beheer extensies",manage_server:"Beheer server",extensions:"Extensies",no_extensions:"Je hebt geen extensies geïnstalleerd :(",created:"Aangemaakt",payment_hash:"Betalings-hash",fee:"Kosten",amount:"Bedrag",unit:"Eenheid",description:"Beschrijving",expiry:"Vervaldatum",webhook:"Webhook",payment_proof:"Betalingsbewijs"},window.localisation.pi={server:"Cap`n",theme:"Theme",funding:"Funding",users:"Buccaneers",restart:"Arr, restart Cap`n",save:"Bury Treasure",save_tooltip:"Bury yer changes, matey",topup:"Top up the Chest",topup_wallet:"Add more doubloons to the chest",topup_hint:"Use the chest ID to top up any chest",restart_tooltip:"Restart the Cap`n for changes to take effect, arr!",add_funds_tooltip:"Add doubloons to a chest and make it heavier",reset_defaults:"Reset to Davy Jones Locker",reset_defaults_tooltip:"Scuttle all settings and reset to Davy Jones Locker. Aye, start anew!",download_backup:"Download database booty",name_your_wallet:"Name yer %{name} treasure chest",paste_invoice_label:"Paste a booty, payment request or lnurl code, matey!",lnbits_description:"Arr, easy to set up and lightweight, LNbits can run on any lightning-network funding source, currently supporting LND, Core Lightning, OpenNode, LNPay and even LNbits itself! Ye can run LNbits for yourself, or easily offer a custodian solution for others. Each chest has its own API keys and there be no limit to the number of chests ye can make. Being able to partition booty makes LNbits a useful tool for money management and as a development tool. Arr, extensions add extra functionality to LNbits so ye can experiment with a range of cutting-edge technologies on the lightning network. We have made developing extensions as easy as possible, and as a free and open-source project, we encourage scallywags to develop and submit their own.",export_to_phone:"Export to Phone with QR Code, me hearties",export_to_phone_desc:"This QR code contains yer chest URL with full access. Ye can scan it from yer phone to open yer chest from there, arr!",wallets:"Treasure Chests",add_wallet:"Add a new chest and fill it with doubloons!",delete_wallet:"Scuttle the Chest",delete_wallet_desc:"This whole chest will be scuttled, the booty will be UNRECOVERABLE. Aye, be warned!",rename_wallet:"Rename the Chest, me hearty",update_name:"Update name like a captain",press_to_claim:"Press to claim gold doubloons, matey!",donate:"Donate like a true pirate!",view_github:"View on GitHub and find treasures",voidwallet_active:"VoidWallet be active! Payments disabled",use_with_caution:"USE WITH CAUTION - %{name} chest be still in BETA. Aye, be careful!",toggle_darkmode:"Toggle Dark Mode, arr!",view_swagger_docs:"View LNbits Swagger API docs and learn the secrets",api_docs:"API docs for the scallywags",commit_version:"Commit version like a true pirate",lnbits_version:"LNbits version, arr!",runs_on:"Runs on, matey",credit_hint:"Press Enter to credit account and make it richer",credit_label:"%{denomination} to credit, arr!",paste_request:"Paste Request and find treasures",create_invoice:"Create Booty Request and get rich, me hearties!",camera_tooltip:"Use spyglass to scan a booty/QR, arr!",export_csv:"Export to CSV and keep track of the booty",transactions:"Pirate Transactions and loot",chart_tooltip:"Show ye chart, me hearty",pending:"Pendin like a ship at anchor",copy_invoice:"Copy booty request, arrr",close:"Batten down the hatches, we be closin",cancel:"Abandon ship! We be retreatin",scan:"Avast! Scan me beauty, arrr",read:"Read it, if ye dare",pay:"Pay up or walk the plank, ye scallywag",memo:"Message in a bottle, argh",date:"Date of the map, me matey",processing_payment:"Processing yer payment... don´t make me say it again",not_enough_funds:"Arrr, ye don´t have enough doubloons! Walk the plank!",search_by_tag_memo_amount:"Search by tag, message, or booty amount, savvy",invoice_waiting:"Invoice waiting to be plundered, arrr",payment_received:"Payment Received like a treasure, argh",payment_sent:"Payment Sent, hoist the colors! We´ve got some doubloons!",receive:"booty",send:"hoist",outgoing_payment_pending:"Outgoing payment pending in the port, ye scurvy dog",drain_funds:"Plunder all the doubloons, ye buccaneer",drain_funds_desc:"This be an LNURL-withdraw QR code for slurpin everything from this wallet. Don`t share with anyone. It be compatible with balanceCheck and balanceNotify so yer wallet may keep pullin` the funds continuously from here after the first withdraw.",i_understand:"I understand, yo ho ho and a bottle of rum!",copy_wallet_url:"Copy wallet URL like a map, savvy",disclaimer_dialog:"Login functionality to be released in a future update, for now, make sure ye bookmark this page for future access to your booty! This service be in BETA, and we hold no responsibility for people losing access to doubloons.",no_transactions:"No transactions made yet, me hearties. Belay that!",manage_extensions:"Manage Yer Extensions, ye landlubber",manage_server:"Manage Yer Server, me hearty",extensions:"Yer Extensions, ye scurvy dog",no_extensions:"Ye don't have any extensions installed, ye scallywag :(. Where be yer loot?",created:"Created like a legend, savvy",payment_hash:"Payment Hash like a treasure map, arrr",fee:"Fee like a toll to cross a strait, matey",amount:"Amount of doubloons, arrr",unit:"Unit of measurement like a fathom, ye buccaneer",description:"Description like a tale of adventure, arrr",expiry:"Expiry like the food on a ship, ye landlubber",webhook:"Webhook like a fishing line, arrr",payment_proof:"Payment Proof like a seal of authenticity, argh"},window.localisation.pl={server:"Serwer",theme:"Motyw",funding:"Finansowanie",users:"Użytkownicy",restart:"Restart serwera",save:"Zapisz",save_tooltip:"Zapisz zmiany",topup:"Doładowanie",topup_wallet:"Doładuj portfel",topup_hint:"Użyj ID portfela aby go doładować",restart_tooltip:"Zrestartuj serwer aby aktywować zmiany",add_funds_tooltip:"Dodaj środki do portfela.",reset_defaults:"Powrót do ustawień domyślnych",reset_defaults_tooltip:"Wymaż wszystkie ustawienia i ustaw domyślne.",download_backup:"Pobierz kopię zapasową bazy danych",name_your_wallet:"Nazwij swój portfel %{name}",paste_invoice_label:"Wklej fakturę, żądanie zapłaty lub kod lnurl *",lnbits_description:"Łatwy i lekki w konfiguracji, LNbits może działać w oparciu o dowolne źródło finansowania w sieci lightning, obecnie wspiera LND, Core Lightning, OpenNode, LNPay czy nawet inną instancję LNbits! Możesz uruchomić instancję LNbits dla siebie lub dla innych. Każdy portfel ma swoje klucze API i nie ma ograniczeń jeśli chodzi o ilość portfeli. LNbits umożliwia dzielenie środków w celu zarządzania nimi, jest również dobrym narzędziem deweloperskim. Rozszerzenia zwiększają funkcjonalność LNbits co umożliwia eksperymentowanie z nowym technologiami w sieci lightning. Tworzenie rozszerzeń jest proste dlatego zachęcamy innych deweloperów do tworzenia dodatkowych funkcjonalności i wysyłanie do nas PR",export_to_phone:"Eksport kodu QR na telefon",export_to_phone_desc:"Ten kod QR zawiera adres URL Twojego portfela z pełnym dostępem do niego. Możesz go zeskanować na swoim telefonie aby otworzyć na nim ten portfel.",wallets:"Portfele",add_wallet:"Dodaj portfel",delete_wallet:"Usuń portfel",delete_wallet_desc:"Ten portfel zostanie usunięty, środków na nim zgromadzonych NIE BĘDZIE MOŻNA ODZYSKAĆ.",rename_wallet:"Zmień nazwę portfela",update_name:"Zaktualizuj nazwę",press_to_claim:"Naciśnij aby odebrać Bitcoiny",donate:"Podaruj",view_github:"Otwórz GitHub",voidwallet_active:"VoidWallet jest aktywny! Płatności są niemożliwe",use_with_caution:"KORZYSTAJ Z ROZWAGĄ - portfel %{name} jest w wersji BETA",toggle_darkmode:"Tryb nocny",view_swagger_docs:"Dokumentacja Swagger API",api_docs:"Dokumentacja API",commit_version:"Commit",lnbits_version:"Wersja LNbits",runs_on:"Działa na",credit_hint:"Naciśnij Enter aby doładować konto",credit_label:"%{denomination} doładowanie",paste_request:"Wklej żądanie",create_invoice:"Utwórz fakturę",camera_tooltip:"Użyj kamery aby zeskanować fakturę lub kod QR",export_csv:"Eksport do CSV",transactions:"Transakcje",chart_tooltip:"Wykres",pending:"W toku",copy_invoice:"Skopiuj fakturę",close:"Zamknij",cancel:"Anuluj",scan:"Skanuj",read:"Odczytaj",pay:"Zapłać",memo:"Memo",date:"Data",processing_payment:"Przetwarzam płatność...",not_enough_funds:"Brak wystarczających środków!",search_by_tag_memo_amount:"Szukaj po tagu, memo czy wartości",invoice_waiting:"Faktura oczekuje na zapłatę",payment_received:"Otrzymano płatność",payment_sent:"Wysłano płatność",receive:"odbierać",send:"wysłać",outgoing_payment_pending:"Płatność wychodząca w toku",drain_funds:"Opróżnij środki",drain_funds_desc:"To jest kod QR służący do opróżnienia portfela (LNURL-withdraw). Nie udostępniaj go nikomu. Ten kod jest kompatybilny z funkcjami, które umożliwiają wielokrotne żądania aż do zupełnego opróżnienia portfela.",i_understand:"Rozumiem",copy_wallet_url:"Skopiuj URL portfela",disclaimer_dialog:"Funkcja logowania zostanie uruchomiona w przyszłości. Póki co upewnij się, że zapisałeś adres URL tej strony aby mieć dostęp do tego portfela. Nie udostępniaj adresu tej strony nikomu, kto nie ma mieć do tego portfela dostępu! Ta usługa działa w wersji BETA, nie odpowiadamy za utratę dostępu do środków przez osoby używające LNbits.",no_transactions:"Brak transakcji",manage_extensions:"Zarządzaj rozszerzeniami",manage_server:"Zarządzaj serwerem",extensions:"Rozszerzenia",no_extensions:"Nie masz zainstalowanych żadnych rozszerzeń :(",created:"Utworzono",payment_hash:"Hash Płatności",fee:"Opłata",amount:"Wartość",unit:"Jednostka",description:"Opis",expiry:"Wygasa",webhook:"Webhook",payment_proof:"Potwierdzenie płatności"},window.localisation.fr={server:"Serveur",theme:"Thème",funding:"Financement",users:"Utilisateurs",restart:"Redémarrer le serveur",save:"Enregistrer",save_tooltip:"Enregistrer vos modifications",topup:"Renflouer",topup_wallet:"Reflouer un portefeuille",topup_hint:"Utilisez l'ID du portefeuille pour recharger n'importe quel portefeuille",restart_tooltip:"Redémarrez le serveur pour que les changements prennent effet",add_funds_tooltip:"Ajouter des fonds à un portefeuille.",reset_defaults:"Réinitialiser aux valeurs par défaut",reset_defaults_tooltip:"Supprimer tous les paramètres et les réinitialiser aux valeurs par défaut.",download_backup:"Télécharger la sauvegarde de la base de données",name_your_wallet:"Nommez votre portefeuille %{name}",paste_invoice_label:"Coller une facture, une demande de paiement ou un code lnurl *",lnbits_description:"Facile à installer et léger, LNbits peut fonctionner sur n'importe quelle source de financement du réseau Lightning, prenant actuellement en charge LND, Core Lightning, OpenNode, LNPay et même LNbits lui-même! Vous pouvez exécuter LNbits pour vous-même ou offrir facilement une solution de gardien pour les autres. Chaque portefeuille a ses propres clés API et il n'y a pas de limite au nombre de portefeuilles que vous pouvez créer. La capacité de partitionner les fonds rend LNbits un outil utile pour la gestion de l'argent et comme outil de développement. Les extensions ajoutent une fonctionnalité supplémentaire à LNbits afin que vous puissiez expérimenter une gamme de technologies de pointe sur le réseau Lightning. Nous avons rendu le développement d'extensions aussi simple que possible et, en tant que projet gratuit et open source, nous encourageons les gens à développer et à soumettre les leurs.",export_to_phone:"Exporter vers le téléphone avec un code QR",export_to_phone_desc:"Ce code QR contient l'URL de votre portefeuille avec un accès complet. Vous pouvez le scanner depuis votre téléphone pour ouvrir votre portefeuille depuis là-bas.",wallets:"Portefeuilles",add_wallet:"Ajouter un nouveau portefeuille",delete_wallet:"Supprimer le portefeuille",delete_wallet_desc:"Ce portefeuille entier sera supprimé et les fonds seront IRRECUPERABLES.",rename_wallet:"Renommer le portefeuille",update_name:"Mettre à jour le nom",press_to_claim:"Appuyez pour demander du Bitcoin",donate:"Donner",view_github:"Voir sur GitHub",voidwallet_active:"VoidWallet est actif! Paiements désactivés",use_with_caution:"UTILISER AVEC PRUDENCE - Le portefeuille %{name} est toujours en version BETA",toggle_darkmode:"Basculer le mode sombre",view_swagger_docs:"Voir les documents de l'API Swagger de LNbits",api_docs:"Documents de l'API",commit_version:"Version de commit",lnbits_version:"Version de LNbits",runs_on:"Fonctionne sur",credit_hint:"Appuyez sur Entrée pour créditer le compte",credit_label:"%{denomination} à créditer",paste_request:"Coller la requête",create_invoice:"Créer une facture",camera_tooltip:"Utiliser la caméra pour scanner une facture / un code QR",export_csv:"Exporter vers CSV",transactions:"Transactions",chart_tooltip:"Afficher le graphique",pending:"En attente",copy_invoice:"Copier la facture",close:"Fermer",cancel:"Annuler",scan:"Scanner",read:"Lire",pay:"Payer",memo:"Mémo",date:"Date",processing_payment:"Traitement du paiement...",not_enough_funds:"Fonds insuffisants !",search_by_tag_memo_amount:"Rechercher par tag, mémo, montant",invoice_waiting:"Facture en attente de paiement",payment_received:"Paiement reçu",payment_sent:"Paiement envoyé",receive:"recevoir",send:"envoyer",outgoing_payment_pending:"Paiement sortant en attente",drain_funds:"Vider les fonds",drain_funds_desc:"Il s'agit d'un code QR LNURL-withdraw pour tout aspirer de ce portefeuille. Ne le partagez avec personne. Il est compatible avec balanceCheck et balanceNotify, de sorte que votre portefeuille peut continuer à retirer les fonds continuellement à partir d'ici après le premier retrait.",i_understand:"J'ai compris",copy_wallet_url:"Copier l'URL du portefeuille",disclaimer_dialog:"La fonctionnalité de connexion sera publiée dans une future mise à jour, pour l'instant, assurez-vous de mettre cette page en favori pour accéder à votre portefeuille ultérieurement ! Ce service est en BETA, et nous ne sommes pas responsables des personnes qui perdent l'accès à leurs fonds.",no_transactions:"Aucune transaction effectuée pour le moment",manage_extensions:"Gérer les extensions",manage_server:"Gérer le serveur",extensions:"Extensions",no_extensions:"Vous n'avez installé aucune extension :(",created:"Créé",payment_hash:"Hash de paiement",fee:"Frais",amount:"Montant",unit:"Unité",description:"Description",expiry:"Expiration",webhook:"Webhook",payment_proof:"Preuve de paiement"},window.localisation.nl={server:"Server",theme:"Thema",funding:"Financiering",users:"Gebruikers",restart:"Server opnieuw opstarten",save:"Opslaan",save_tooltip:"Sla uw wijzigingen op",topup:"Bijvullen",topup_wallet:"Een portemonnee bijvullen",topup_hint:"Gebruik de portemonnee-ID om elke portemonnee bij te vullen",restart_tooltip:"Start de server opnieuw op zodat wijzigingen van kracht worden",add_funds_tooltip:"Voeg geld toe aan een portemonnee.",reset_defaults:"Standaardinstellingen herstellen",reset_defaults_tooltip:"Wis alle instellingen en herstel de standaardinstellingen.",download_backup:"Databaseback-up downloaden",name_your_wallet:"Geef je %{name} portemonnee een naam",paste_invoice_label:"Plak een factuur, betalingsverzoek of lnurl-code*",lnbits_description:"Gemakkelijk in te stellen en lichtgewicht, LNbits kan op elke lightning-netwerkfinancieringsbron draaien, ondersteunt op dit moment LND, Core Lightning, OpenNode, LNPay en zelfs LNbits zelf! U kunt LNbits voor uzelf laten draaien of gemakkelijk een bewaardersoplossing voor anderen bieden. Elke portemonnee heeft zijn eigen API-sleutels en er is geen limiet aan het aantal portemonnees dat u kunt maken. Het kunnen partitioneren van fondsen maakt LNbits een nuttige tool voor geldbeheer en als ontwikkelingstool. Extensies voegen extra functionaliteit toe aan LNbits, zodat u kunt experimenteren met een reeks toonaangevende technologieën op het bliksemschichtnetwerk. We hebben het ontwikkelen van extensies zo eenvoudig mogelijk gemaakt en als een gratis en opensource-project moedigen we mensen aan om hun eigen ontwikkelingen in te dienen.",export_to_phone:"Exporteren naar telefoon met QR-code",export_to_phone_desc:"Deze QR-code bevat uw portemonnee-URL met volledige toegang. U kunt het vanaf uw telefoon scannen om uw portemonnee van daaruit te openen.",wallets:"Portemonnees",add_wallet:"Een nieuwe portemonnee toevoegen",delete_wallet:"Portemonnee verwijderen",delete_wallet_desc:"Deze hele portemonnee wordt verwijderd, de fondsen worden NIET TERUGGEVONDEN.",rename_wallet:"Portemonnee hernoemen",update_name:"Naam bijwerken",press_to_claim:"Druk om bitcoin te claimen",donate:"Doneren",view_github:"Bekijken op GitHub",voidwallet_active:"VoidWallet is actief! Betalingen uitgeschakeld",use_with_caution:"GEBRUIK MET VOORZICHTIGHEID - %{name} portemonnee is nog in BETA",toggle_darkmode:"Donkere modus aan/uit",view_swagger_docs:"Bekijk LNbits Swagger API-documentatie",api_docs:"API-documentatie",commit_version:"Commit-versie",lnbits_version:"LNbits-versie",runs_on:"Draait op",credit_hint:"Druk op Enter om de rekening te crediteren",credit_label:"%{denomination} te crediteren",paste_request:"Verzoek plakken",create_invoice:"Factuur aanmaken",camera_tooltip:"Gebruik de camera om een factuur/QR-code te scannen",export_csv:"Exporteer naar CSV",transactions:"Transacties",chart_tooltip:"Toon grafiek",pending:"In behandeling",copy_invoice:"Kopieer factuur",close:"Sluiten",cancel:"Annuleren",scan:"Scannen",read:"Lezen",pay:"Betalen",memo:"Memo",date:"Datum",processing_payment:"Verwerking betaling...",not_enough_funds:"Onvoldoende saldo!",search_by_tag_memo_amount:"Zoeken op tag, memo, bedrag",invoice_waiting:"Factuur wachtend op betaling",payment_received:"Betaling ontvangen",payment_sent:"Betaling verzonden",receive:"ontvangen",send:"versturen",voutgoing_payment_pending:"Uitgaande betaling in behandeling",drain_funds:"Geld opnemen",drain_funds_desc:"Dit is een LNURL-withdraw QR-code om alles uit deze portemonnee te halen. Deel deze code niet met anderen. Het is compatibel met balanceCheck en balanceNotify zodat jouw portemonnee continu geld kan blijven opnemen vanaf hier na de eerste opname.",i_understand:"Ik begrijp het",copy_wallet_url:"Kopieer portemonnee-URL",disclaimer_dialog:"Inlogfunctionaliteit wordt uitgebracht in een toekomstige update. Zorg er nu voor dat je deze pagina als favoriet markeert om in de toekomst toegang te krijgen tot je portemonnee! Deze service is in BETA en we zijn niet verantwoordelijk voor mensen die de toegang tot hun fondsen verliezen.",no_transactions:"Er zijn nog geen transacties gedaan",manage_extensions:"Beheer extensies",manage_server:"Beheer server",extensions:"Extensies",no_extensions:"Je hebt geen extensies geïnstalleerd :(",created:"Aangemaakt",payment_hash:"Betalings-hash",fee:"Kosten",amount:"Bedrag",unit:"Eenheid",description:"Beschrijving",expiry:"Vervaldatum",webhook:"Webhook",payment_proof:"Betalingsbewijs"},window.localisation.we={server:"Gweinydd",theme:"Thema",funding:"Arian fyndio",users:"Defnyddwyr",restart:"Ailgychwyn gweinydd",save:"Save",save_tooltip:"cadw eich newidiadau",topup:"Topup",topup_wallet:"Atodi waled",topup_hint:"Defnyddiwch ID y waled i ychwanegu at unrhyw waled",restart_tooltip:"Ailgychwyn y gweinydd er mwyn i newidiadau ddod i rym",add_funds_tooltip:"Ychwanegu arian at waled.",reset_defaults:"Ailosod i`r rhagosodiadau",reset_defaults_tooltip:"Dileu pob gosodiad ac ailosod i`r rhagosodiadau.",download_backup:"Lawrlwytho copi wrth gefn cronfa ddata",name_your_wallet:"Enwch eich waled %{name}",paste_invoice_label:"Gludwch anfoneb, cais am daliad neu god lnurl *",lnbits_description:"Yn hawdd iw sefydlu ac yn ysgafn, gall LNbits redeg ar unrhyw ffynhonnell ariannu rhwydwaith mellt, ar hyn o bryd yn cefnogi LND, Core Lightning, OpenNode, LNPay a hyd yn oed LNbits ei hun! Gallwch redeg LNbits i chi`ch hun, neu gynnig datrysiad ceidwad i eraill yn hawdd. Mae gan bob waled ei allweddi API ei hun ac nid oes cyfyngiad ar nifer y waledi y gallwch eu gwneud. Mae gallu rhannu cronfeydd yn gwneud LNbits yn arf defnyddiol ar gyfer rheoli arian ac fel offeryn datblygu. Mae estyniadau yn ychwanegu ymarferoldeb ychwanegol at LNbits fel y gallwch arbrofi gydag ystod o dechnolegau blaengar ar y rhwydwaith mellt. Rydym wedi gwneud datblygu estyniadau mor hawdd â phosibl, ac fel prosiect ffynhonnell agored am ddim, rydym yn annog pobl i ddatblygu a chyflwyno eu rhai eu hunain.",export_to_phone:"Allforio i Ffôn gyda chod QR",export_to_phone_desc:"Mae`r cod QR hwn yn cynnwys URL eich waled gyda mynediad llawn. Gallwch ei sganio o`ch ffôn i agor eich waled oddi yno.",waledi:"Waledi",add_wallet:"Ychwanegu waled newydd",delete_wallet:"Dileu waled",delete_wallet_desc:"Bydd y waled gyfan hon yn cael ei dileu, ni fydd modd adennill yr arian.",rename_wallet:"Ailenwi waled",update_name:"Diweddaru enw",press_to_claim:"Pwyswch i hawlio bitcoin",Donate:"Rhoi",view_github:"Gweld ar GitHub",voidwallet_active:" Mae VoidWallet yn weithredol! Taliadau wedi`u hanalluogi",use_with_caution:"DEFNYDDIO GYDA GOFAL - mae waled %{name} yn dal yn BETA",toggle_darkmode:"Toglo Modd Tywyll",view_swagger_docs:"Gweld dogfennau API LNbits Swagger",api_docs:"Api docs",commit_version:"fersiwn ymrwymo",lnbits_version:"Fersiwn LNbits",Runs_on:"Yn rhedeg ymlaen",credit_hint:"Pwyswch Enter i gyfrif credyd",credit_label:"%{enomination} i gredyd",paste_request:"Gludo Cais",create_invoice:"Creu Anfoneb",camera_tooltip:"Defnyddio camera i sganio anfoneb/QR",export_csv:"Allforio i CSV",trafodion:"Trafodion",chart_tooltip:"Dangos siart",pending:"yn yr arfaeth",copy_invoice:"Copi anfoneb",Close:"cau",cancel:"Canslo",scan:"Sgan",read:"Darllen",talu:"Pay",memo:"Memo",date:"Dyddiad",processing_payment:"Prosesu taliad...",not_enough_funds:"Dim digon o arian!",search_by_tag_memo_amount:"Chwilio yn ôl tag, memo, swm",invoice_waiting:"Anfoneb yn aros i gael ei thalu",payment_received:"Taliad a Dderbyniwyd",payment_sent:"Taliad a Anfonwyd",receive:"derbyn",send:"anfon",outgoing_payment_pending:"Taliad sy`n aros yn yr arfaeth",drain_funds:"Cronfeydd Draenio",drain_funds_desc:"Cod QR Tynnu`n ôl LNURL yw hwn ar gyfer slurpio popeth o`r waled hon. Peidiwch â rhannu gyda neb. Mae`n gydnaws â balanceCheck a balanceNotify felly efallai y bydd eich waled yn tynnu`r arian yn barhaus o`r fan hon ar ôl y codiad cyntaf.",i_understand:"Rwy`n deall",copy_wallet_url:"Copi URL waled",disclaimer_dialog:"Swyddogaeth mewngofnodi i`w ryddhau mewn diweddariad yn y dyfodol, am y tro, gwnewch yn siŵr eich bod yn rhoi nod tudalen ar y dudalen hon ar gyfer mynediad i`ch waled yn y dyfodol! Mae`r gwasanaeth hwn yn BETA, ac nid ydym yn gyfrifol am bobl sy`n colli mynediad at arian.",no_transactions:"Dim trafodion wedi`u gwneud eto",manage_extensions:"Rheoli Estyniadau",manage_server:"Rheoli Gweinydd",Extensions:"Estyniadau",no_extensions:"Nid oes gennych unrhyw estyniadau wedi'u gosod :(",create:"Crëwyd",payment_hash:"Hais Taliad",fee:"Fee",amount:"swm",unit:"Uned",description:"Disgrifiad",expiry:"dod i ben",webhook:"bachyn we",payment_proof:"prawf taliad"},window.localisation.pt={server:"Servidor",theme:"Tema",funding:"Financiamento",users:"Usuários",restart:"Reiniciar servidor",save:"Gravar",save_tooltip:"Gravar as alterações",topup:"Reforçar conta",topup_wallet:"Recarregar uma carteira",topup_hint:"Use o ID da carteira para recarregar qualquer carteira",restart_tooltip:"Reinicie o servidor para que as alterações tenham efeito",add_funds_tooltip:"Adicionar fundos a uma carteira.",reset_defaults:"Redefinir para padrões",reset_defaults_tooltip:"Apagar todas as configurações e redefinir para os padrões.",download_backup:"Fazer backup da base de dados",name_your_wallet:"Nomeie sua carteira %{name}",paste_invoice_label:"Cole uma fatura, pedido de pagamento ou código lnurl *",lnbits_description:"Fácil de configurar e leve, o LNbits pode ser executado em qualquer fonte de financiamento da lightning-network, atualmente suportando LND, c-lightning, OpenNode, LNPay e até mesmo o LNbits em si! Você pode executar o LNbits para si mesmo ou oferecer facilmente uma solução de custódia para outros. Cada carteira tem suas próprias chaves de API e não há limite para o número de carteiras que você pode criar. Ser capaz de particionar fundos torna o LNbits uma ferramenta útil para gerenciamento de dinheiro e como uma ferramenta de desenvolvimento. As extensões adicionam funcionalidades extras ao LNbits para que você possa experimentar uma série de tecnologias de ponta na rede lightning. Nós tornamos o desenvolvimento de extensões o mais fácil possível e, como um projeto gratuito e de código aberto, incentivamos as pessoas a desenvolver e enviar as suas próprias.",export_to_phone:"Exportar para o telefone com código QR",export_to_phone_desc:"Este código QR contém a URL da sua carteira com acesso total. Você pode escaneá-lo do seu telefone para abrir sua carteira a partir dele.",wallets:"Carteiras",add_wallet:"Adicionar nova carteira",delete_wallet:"Excluir carteira",delete_wallet_desc:"Toda a carteira será excluída, os fundos serão IRRECUPERÁVEIS.",rename_wallet:"Renomear carteira",update_name:"Atualizar nome",press_to_claim:"Pressione para solicitar bitcoin",donate:"Doar",view_github:"Ver no GitHub",voidwallet_active:"VoidWallet está ativo! Pagamentos desabilitados",use_with_caution:"USE COM CAUTELA - a carteira %{name} ainda está em BETA",toggle_darkmode:"Alternar modo escuro",view_swagger_docs:"Ver a documentação da API do LNbits Swagger",api_docs:"Documentação da API",commit_version:"Versão de commit",lnbits_version:"Versão do LNbits",runs_on:"Executa em",credit_hint:"Pressione Enter para creditar a conta",credit_label:"%{denomination} para creditar",paste_request:"Colar Pedido",create_invoice:"Criar Fatura",camera_tooltip:"Usar a câmara para escanear uma fatura / QR",export_csv:"Exportar para CSV",transactions:"Transações",chart_tooltip:"Mostrar gráfico",pending:"Pendente",copy_invoice:"Copiar fatura",close:"Fechar",cancel:"Cancelar",scan:"Escanear",read:"Ler",pay:"Pagar",memo:"Memo",date:"Data",processing_payment:"Processando pagamento...",not_enough_funds:"Fundos insuficientes!",search_by_tag_memo_amount:"Pesquisar por tag, memo, quantidade",invoice_waiting:"Fatura aguardando pagamento",payment_received:"Pagamento Recebido",payment_sent:"Pagamento Enviado",receive:"receber",send:"enviar",outgoing_payment_pending:"Pagamento de saída pendente",drain_funds:"Esvasiar carteira",drain_funds_desc:"Este é um código QR de saque LNURL para sacar tudo desta carteira. Não o partilhe com ninguém. É compatível com balanceCheck e balanceNotify para que a sua carteira possa continuar levantando os fundos continuamente daqui após o primeiro saque.",i_understand:"Eu entendo",copy_wallet_url:"Copiar URL da carteira",disclaimer_dialog:"Funcionalidade de login a ser lançada numa atualização futura, por enquanto, certifique-se que marca esta página para acesso futuro à sua carteira! Este serviço está em BETA, e não nos responsabilizamos por pessoas que perderem o acesso aos fundos.",no_transactions:"Ainda não foram feitas transações",manage_extensions:"Gerir extensões",manage_server:"Gerir servidor",extensions:"Extensões",no_extensions:"Não há nenhuma extensão instalada :(",created:"Criado",payment_hash:"Hash de pagamento",fee:"Taxa",amount:"Quantidade",unit:"Unidade",description:"Descrição",expiry:"Validade",webhook:"Webhook",payment_proof:"Comprovativo de pagamento"},window.localisation.br={server:"Servidor",theme:"Tema",funding:"Financiamento",users:"Usuários",restart:"Reiniciar servidor",save:"Salvar",save_tooltip:"Salvar suas alterações",topup:"Recarregar",topup_wallet:"Recarregar uma carteira",topup_hint:"Use o ID da carteira para recarregar qualquer carteira",restart_tooltip:"Reinicie o servidor para que as alterações tenham efeito",add_funds_tooltip:"Adicionar fundos a uma carteira.",reset_defaults:"Redefinir para padrões",reset_defaults_tooltip:"Apagar todas as configurações e redefinir para os padrões.",download_backup:"Fazer backup do banco de dados",name_your_wallet:"Nomeie sua carteira %{name}",paste_invoice_label:"Cole uma fatura, pedido de pagamento ou código lnurl *",lnbits_description:"Fácil de configurar e leve, o LNbits pode ser executado em qualquer fonte de financiamento da lightning-network, atualmente suportando LND, c-lightning, OpenNode, LNPay e até mesmo o LNbits em si! Você pode executar o LNbits para si mesmo ou oferecer facilmente uma solução de custódia para outros. Cada carteira tem suas próprias chaves de API e não há limite para o número de carteiras que você pode criar. Ser capaz de particionar fundos torna o LNbits uma ferramenta útil para gerenciamento de dinheiro e como uma ferramenta de desenvolvimento. As extensões adicionam funcionalidades extras ao LNbits para que você possa experimentar uma série de tecnologias de ponta na rede lightning. Nós tornamos o desenvolvimento de extensões o mais fácil possível e, como um projeto gratuito e de código aberto, incentivamos as pessoas a desenvolver e enviar as suas próprias.",export_to_phone:"Exportar para o telefone com código QR",export_to_phone_desc:"Este código QR contém a URL da sua carteira com acesso total. Você pode escaneá-lo do seu telefone para abrir sua carteira a partir dele.",wallets:"Carteiras",add_wallet:"Adicionar nova carteira",delete_wallet:"Excluir carteira",delete_wallet_desc:"Toda a carteira será excluída, os fundos serão IRRECUPERÁVEIS.",rename_wallet:"Renomear carteira",update_name:"Atualizar nome",press_to_claim:"Pressione para solicitar bitcoin",donate:"Doar",view_github:"Ver no GitHub",voidwallet_active:"VoidWallet está ativo! Pagamentos desabilitados",use_with_caution:"USE COM CAUTELA - a carteira %{name} ainda está em BETA",toggle_darkmode:"Alternar modo escuro",view_swagger_docs:"Ver a documentação da API do LNbits Swagger",api_docs:"Documentação da API",commit_version:"Versão de commit",lnbits_version:"Versão do LNbits",runs_on:"Executa em",credit_hint:"Pressione Enter para creditar a conta",credit_label:"%{denomination} para creditar",paste_request:"Colar Pedido",create_invoice:"Criar Fatura",camera_tooltip:"Usar a câmara para escanear uma fatura / QR",export_csv:"Exportar para CSV",transactions:"Transações",chart_tooltip:"Mostrar gráfico",pending:"Pendente",copy_invoice:"Copiar fatura",close:"Fechar",cancel:"Cancelar",scan:"Escanear",read:"Ler",pay:"Pagar",memo:"Memo",date:"Data",processing_payment:"Processando pagamento...",not_enough_funds:"Fundos insuficientes!",search_by_tag_memo_amount:"Pesquisar por tag, memo, quantidade",invoice_waiting:"Fatura aguardando pagamento",payment_received:"Pagamento Recebido",payment_sent:"Pagamento Enviado",receive:"receber",send:"enviar",outgoing_payment_pending:"Pagamento pendente de saída",drain_funds:"Drenar Fundos",drain_funds_desc:"Este é um código QR de retirada do LNURL para sugar tudo desta carteira. Não compartilhe com ninguém. É compatível com balanceCheck e balanceNotify para que sua carteira possa continuar retirando os fundos continuamente daqui após a primeira retirada.",i_understand:"Eu entendo",copy_wallet_url:"Copiar URL da carteira",disclaimer_dialog:"Funcionalidade de login a ser lançada em uma atualização futura, por enquanto, certifique-se de marcar esta página para acesso futuro à sua carteira! Este serviço está em BETA, e não nos responsabilizamos por pessoas que perderem o acesso aos fundos.",no_transactions:"Ainda não foram feitas transações",manage_extensions:"Gerenciar extensões",manage_server:"Gerenciar servidor",extensions:"Extensões",no_extensions:"Você não possui nenhuma extensão instalada :(",created:"Criado",payment_hash:"Hash de pagamento",fee:"Taxa",amount:"Quantidade",unit:"Unidade",description:"Descrição",expiry:"Validade",webhook:"Webhook",payment_proof:"Comprovante de pagamento"},Vue.use(VueI18n),window.LOCALE="en",window.i18n=new VueI18n({locale:window.LOCALE,fallbackLocale:window.LOCALE,messages:window.localisation}),window.EventHub=new Vue,window.LNbits={api:{request:function(t,e,n,i){return axios({method:t,url:e,headers:{"X-Api-Key":n},data:i})},createInvoice:async function(t,e,n,i="sat",r=null){return this.request("post","/api/v1/payments",t.inkey,{out:!1,amount:e,memo:n,unit:i,lnurl_callback:r})},payInvoice:function(t,e){return this.request("post","/api/v1/payments",t.adminkey,{out:!0,bolt11:e})},payLnurl:function(t,e,n,i,r="",o=""){return this.request("post","/api/v1/payments/lnurl",t.adminkey,{callback:e,description_hash:n,amount:i,comment:o,description:r})},authLnurl:function(t,e){return this.request("post","/api/v1/lnurlauth",t.adminkey,{callback:e})},getWallet:function(t){return this.request("get","/api/v1/wallet",t.inkey)},getPayments:function(t,e){const n=new URLSearchParams(e);return this.request("get","/api/v1/payments/paginated?"+n,t.inkey)},getPayment:function(t,e){return this.request("get","/api/v1/payments/"+e,t.inkey)}},events:{onInvoicePaid:function(t,e){let n=t=>{e(JSON.parse(t.data))};return this.listenersCount=this.listenersCount||{[t.inkey]:0},this.listenersCount[t.inkey]++,this.listeners=this.listeners||{},t.inkey in this.listeners||(this.listeners[t.inkey]=new EventSource("/api/v1/payments/sse?api-key="+t.inkey)),this.listeners[t.inkey].addEventListener("payment-received",n),()=>{this.listeners[t.inkey].removeEventListener("payment-received",n),this.listenersCount[t.inkey]--,this.listenersCount[t.inkey]<=0&&(this.listeners[t.inkey].close(),delete this.listeners[t.inkey])}}},href:{createWallet:function(t,e){window.location.href="/wallet?"+(e?"usr="+e+"&":"")+"nme="+t},updateWallet:function(t,e,n){window.location.href=`/wallet?usr=${e}&wal=${n}&nme=${t}`},deleteWallet:function(t,e){window.location.href="/deletewallet?usr="+e+"&wal="+t}},map:{extension:function(t){var e=_.object(["code","isValid","isAdminOnly","name","shortDescription","tile","contributors","hidden"],t);return e.url=["/",e.code,"/"].join(""),e},user:function(t){var e={id:t.id,admin:t.admin,email:t.email,extensions:t.extensions,wallets:t.wallets,admin:t.admin},n=this.wallet;return e.wallets=e.wallets.map((function(t){return n(t)})).sort((function(t,e){return t.name.localeCompare(e.name)})),e.walletOptions=e.wallets.map((function(t){return{label:[t.name," - ",t.id].join(""),value:t.id}})),e},wallet:function(t){return newWallet={id:t.id,name:t.name,adminkey:t.adminkey,inkey:t.inkey,currency:t.currency},newWallet.msat=t.balance_msat,newWallet.sat=Math.round(t.balance_msat/1e3),newWallet.fsat=new Intl.NumberFormat(window.LOCALE).format(newWallet.sat),newWallet.url=["/wallet?usr=",t.user,"&wal=",t.id].join(""),newWallet},payment:function(t){return obj={checking_id:t.checking_id,pending:t.pending,amount:t.amount,fee:t.fee,memo:t.memo,time:t.time,bolt11:t.bolt11,preimage:t.preimage,payment_hash:t.payment_hash,expiry:t.expiry,extra:t.extra,wallet_id:t.wallet_id,webhook:t.webhook,webhook_status:t.webhook_status,fiat_amount:t.fiat_amount,fiat_currency:t.fiat_currency},obj.date=Quasar.utils.date.formatDate(new Date(1e3*obj.time),"YYYY-MM-DD HH:mm"),obj.dateFrom=moment(obj.date).fromNow(),obj.expirydate=Quasar.utils.date.formatDate(new Date(1e3*obj.expiry),"YYYY-MM-DD HH:mm"),obj.expirydateFrom=moment(obj.expirydate).fromNow(),obj.msat=obj.amount,obj.sat=obj.msat/1e3,obj.tag=obj.extra?.tag,obj.fsat=new Intl.NumberFormat(window.LOCALE).format(obj.sat),obj.isIn=obj.amount>0,obj.isOut=obj.amount<0,obj.isPaid=!obj.pending,obj._q=[obj.memo,obj.sat].join(" ").toLowerCase(),obj}},utils:{confirmDialog:function(t){return Quasar.plugins.Dialog.create({message:t,ok:{flat:!0,color:"orange"},cancel:{flat:!0,color:"grey"}})},digestMessage:async function(t){const e=(new TextEncoder).encode(t),n=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(n)).map((t=>t.toString(16).padStart(2,"0"))).join("")},formatCurrency:function(t,e){return new Intl.NumberFormat(window.LOCALE,{style:"currency",currency:e}).format(t)},formatSat:function(t){return new Intl.NumberFormat(window.LOCALE).format(t)},formatMsat:function(t){return this.formatSat(t/1e3)},notifyApiError:function(t){Quasar.plugins.Notify.create({timeout:5e3,type:{400:"warning",401:"warning",500:"negative"}[t.response.status]||"warning",message:t.response.data.message||t.response.data.detail||null,caption:[t.response.status," ",t.response.statusText].join("").toUpperCase()||null,icon:null})},search:function(t,e,n,i){try{var r=e.toLowerCase().split(i||" ");return t.filter((function(t){var e=0;return _.each(r,(function(i){-1!==t[n].indexOf(i)&&e++})),e===r.length}))}catch(e){return t}},exportCSV:function(t,e,n){var i=function(t,e){var n=void 0!==e?e(t):t;return`"${n=(n=null==n?"":String(n)).split('"').join('""')}"`},r=[t.map((function(t){return i(t.label)}))].concat(e.map((function(e){return t.map((function(t){return i("function"==typeof t.field?t.field(e):e[void 0===t.field?t.name:t.field],t.format)})).join(",")}))).join("\r\n");!0!==Quasar.utils.exportFile(`${n||"table-export"}.csv`,r,"text/csv")&&Quasar.plugins.Notify.create({message:"Browser denied file download...",color:"negative",icon:null})}}},window.windowMixin={i18n:window.i18n,data:function(){return{toggleSubs:!0,g:{offline:!navigator.onLine,visibleDrawer:!1,extensions:[],user:null,wallet:null,payments:[],allowedThemes:null,langs:[]}}},methods:{activeLanguage:function(t){return window.i18n.locale===t},changeLanguage:function(t){window.i18n.locale=t,this.$q.localStorage.set("lnbits.lang",t)},changeColor:function(t){document.body.setAttribute("data-theme",t),this.$q.localStorage.set("lnbits.theme",t)},toggleDarkMode:function(){this.$q.dark.toggle(),this.$q.localStorage.set("lnbits.darkMode",this.$q.dark.isActive)},copyText:function(t,e,n){var i=this.$q.notify;Quasar.utils.copyToClipboard(t).then((function(){i({message:e||"Copied to clipboard!",position:n||"bottom"})}))}},created:function(){1==this.$q.localStorage.getItem("lnbits.darkMode")||0==this.$q.localStorage.getItem("lnbits.darkMode")?this.$q.dark.set(this.$q.localStorage.getItem("lnbits.darkMode")):this.$q.dark.set(!0),this.g.allowedThemes=window.allowedThemes??["bitcoin"];let t=this.$q.localStorage.getItem("lnbits.lang");if(t&&(window.LOCALE=t,window.i18n.locale=t),this.g.langs=window.langs??[],addEventListener("offline",(t=>{this.g.offline=!0})),addEventListener("online",(t=>{this.g.offline=!1})),this.$q.localStorage.getItem("lnbits.theme")||this.changeColor(this.g.allowedThemes[0]),this.$q.localStorage.getItem("lnbits.theme")&&!this.g.allowedThemes.includes(this.$q.localStorage.getItem("lnbits.theme"))&&this.changeColor(this.g.allowedThemes[0]),this.$q.localStorage.getItem("lnbits.theme")&&document.body.setAttribute("data-theme",this.$q.localStorage.getItem("lnbits.theme")),window.user&&(this.g.user=Object.freeze(window.LNbits.map.user(window.user))),window.wallet&&(this.g.wallet=Object.freeze(window.LNbits.map.wallet(window.wallet))),window.extensions){var e=this.g.user;const t=Object.freeze(window.extensions.map((function(t){return window.LNbits.map.extension(t)})).filter((function(t){return!t.hidden})).filter((function(t){return window.user?.admin?t:!t.isAdminOnly})).map((function(t){return t.isEnabled=!!e&&-1!==e.extensions.indexOf(t.code),t})).sort((function(t,e){const n=t.name.toUpperCase(),i=e.name.toUpperCase();return ni?1:0})));this.g.extensions=t}}},window.decryptLnurlPayAES=function(t,e){let n=new Uint8Array(e.match(/[\da-f]{2}/gi).map((t=>parseInt(t,16))));return crypto.subtle.importKey("raw",n,{name:"AES-CBC",length:256},!1,["decrypt"]).then((e=>{let n=Uint8Array.from(window.atob(t.iv),(t=>t.charCodeAt(0))),i=Uint8Array.from(window.atob(t.ciphertext),(t=>t.charCodeAt(0)));return crypto.subtle.decrypt({name:"AES-CBC",iv:n},e,i)})).then((t=>new TextDecoder("utf-8").decode(t)))},Vue.component("lnbits-fsat",{props:{amount:{type:Number,default:0}},template:"{{ fsat }}",computed:{fsat:function(){return LNbits.utils.formatSat(this.amount)}}}),Vue.component("lnbits-wallet-list",{data:function(){return{user:null,activeWallet:null,activeBalance:[],showForm:!1,walletName:"",LNBITS_DENOMINATION:LNBITS_DENOMINATION}},template:'\n \n \n \n \n \n \n \n \n \n {{ wallet.name }}\n {{ parseFloat(String(wallet.live_fsat).replaceAll(",", "")) / 100 }} {{ LNBITS_DENOMINATION }}\n {{ wallet.live_fsat }} {{ LNBITS_DENOMINATION }}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',computed:{wallets:function(){var t=this.activeBalance;return this.user.wallets.map((function(e){return e.live_fsat=t.length&&t[0]===e.id?LNbits.utils.formatSat(t[1]):e.fsat,e}))}},methods:{createWallet:function(){LNbits.href.createWallet(this.walletName,this.user.id)},updateWalletBalance:function(t){this.activeBalance=t}},created:function(){window.user&&(this.user=LNbits.map.user(window.user)),window.wallet&&(this.activeWallet=LNbits.map.wallet(window.wallet)),EventHub.$on("update-wallet-balance",this.updateWalletBalance)}}),Vue.component("lnbits-extension-list",{data:function(){return{extensions:[],user:null}},template:'\n \n \n \n \n \n \n \n \n \n {{ extension.name }} \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',computed:{userExtensions:function(){if(!this.user)return[];var t=window.location.pathname,e=this.user.extensions;return this.extensions.filter((function(t){return-1!==e.indexOf(t.code)})).map((function(e){return e.isActive=t.startsWith(e.url),e}))}},created:function(){window.extensions&&(this.extensions=window.extensions.map((function(t){return LNbits.map.extension(t)})).sort((function(t,e){return t.name.localeCompare(e.name)}))),window.user&&(this.user=LNbits.map.user(window.user))}}),Vue.component("lnbits-admin-ui",{props:["showNode"],data:function(){return{extensions:[],user:null}},template:'\n \n Admin\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n ',created:function(){window.user&&(this.user=LNbits.map.user(window.user))}}),Vue.component("lnbits-payment-details",{props:["payment"],mixins:[windowMixin],data:function(){return{LNBITS_DENOMINATION:LNBITS_DENOMINATION}},template:'\n \n\n
\n \n #{{ payment.tag }}\n \n
\n\n
\n :\n {{ payment.date }} ({{ payment.dateFrom }})\n
\n\n
\n :\n {{ payment.expirydate }} ({{ payment.expirydateFrom }})\n
\n\n
\n :\n {{ (payment.amount / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}\n
\n\n
\n :\n {{ (payment.fee / 1000).toFixed(3) }} {{LNBITS_DENOMINATION}}\n
\n\n
\n : {{ payment.payment_hash }}\n \n
\n\n
\n : {{ payment.memo }}\n
\n\n
\n : {{ payment.webhook }}: \n {{ webhookStatusText }}\n \n
\n\n
\n : {{ payment.preimage }}\n
\n\n
\n \n extra\n \n {{ entry.key }}:\n {{ entry.value }}\n
\n\n
\n Success action:\n \n
\n\n
\n ',computed:{hasPreimage(){return this.payment.preimage&&"0000000000000000000000000000000000000000000000000000000000000000"!==this.payment.preimage},hasSuccessAction(){return this.hasPreimage&&this.payment.extra&&this.payment.extra.success_action},webhookStatusColor(){return this.payment.webhook_status>=300||this.payment.webhook_status<0?"red-10":this.payment.webhook_status?"green-10":"cyan-7"},webhookStatusText(){return this.payment.webhook_status?this.payment.webhook_status:"not sent yet"},hasTag(){return this.payment.extra&&!!this.payment.extra.tag},extras(){if(!this.payment.extra)return[];let t=_.omit(this.payment.extra,["tag","success_action"]);return Object.keys(t).map((e=>({key:e,value:t[e]})))}}}),Vue.component("lnbits-lnurlpay-success-action",{props:["payment","success_action"],data(){return{decryptedValue:this.success_action.ciphertext}},template:'\n \n
{{ success_action.message || success_action.description }}
\n
\n {{ decryptedValue }}\n
\n
\n {{ success_action.url }}\n
\n
\n ',mounted:function(){if("aes"!==this.success_action.tag)return null;decryptLnurlPayAES(this.success_action,this.payment.preimage).then((t=>{this.decryptedValue=t}))}}),Vue.component("lnbits-notifications-btn",{mixins:[windowMixin],props:["pubkey"],data:()=>({isSupported:!1,isSubscribed:!1,isPermissionGranted:!1,isPermissionDenied:!1}),template:'\n \n Subscribe to notifications\n Unsubscribe from notifications\n \n Notifications are disabled,
please enable or reset permissions\n \n Notifications are not supported\n \n ',methods:{urlB64ToUint8Array(t){const e=(t+"=".repeat((4-t.length%4)%4)).replace(/\-/g,"+").replace(/_/g,"/"),n=atob(e),i=new Uint8Array(n.length);for(let t=0;te!==t)),this.$q.localStorage.set("lnbits.webpush.subscribedUsers",JSON.stringify(e))},isUserSubscribed(t){return(JSON.parse(this.$q.localStorage.getItem("lnbits.webpush.subscribedUsers"))||[]).includes(t)},subscribe(){var t=this;this.isSupported&&!this.isPermissionDenied&&(Notification.requestPermission().then((t=>{this.isPermissionGranted="granted"===t,this.isPermissionDenied="denied"===t})).catch((function(t){console.log(t)})),navigator.serviceWorker.ready.then((e=>{navigator.serviceWorker.getRegistration().then((e=>{e.pushManager.getSubscription().then((function(n){if(null===n||!t.isUserSubscribed(t.g.user.id)){const n={applicationServerKey:t.urlB64ToUint8Array(t.pubkey),userVisibleOnly:!0};e.pushManager.subscribe(n).then((function(e){LNbits.api.request("POST","/api/v1/webpush",t.g.user.wallets[0].adminkey,{subscription:JSON.stringify(e)}).then((function(e){t.saveUserSubscribed(e.data.user),t.isSubscribed=!0})).catch((function(t){LNbits.utils.notifyApiError(t)}))}))}})).catch((function(t){console.log(t)}))}))})))},unsubscribe(){var t=this;navigator.serviceWorker.ready.then((e=>{e.pushManager.getSubscription().then((e=>{e&&LNbits.api.request("DELETE","/api/v1/webpush?endpoint="+btoa(e.endpoint),t.g.user.wallets[0].adminkey).then((function(){t.removeUserSubscribed(t.g.user.id),t.isSubscribed=!1})).catch((function(t){LNbits.utils.notifyApiError(t)}))}))})).catch((function(t){console.log(t)}))},checkSupported:function(){let t="https:"===window.location.protocol,e="serviceWorker"in navigator,n="Notification"in window,i="PushManager"in window;return this.isSupported=t&&e&&n&&i,this.isSupported||console.log("Notifications disabled because requirements are not met:",{HTTPS:t,"Service Worker API":e,"Notification API":n,"Push API":i}),this.isSupported},updateSubscriptionStatus:async function(){var t=this;await navigator.serviceWorker.ready.then((e=>{e.pushManager.getSubscription().then((e=>{t.isSubscribed=!!e&&t.isUserSubscribed(t.g.user.id)}))})).catch((function(t){console.log(t)}))}},created:function(){this.isPermissionDenied="denied"===Notification.permission,this.checkSupported()&&this.updateSubscriptionStatus()}});const bech32CharValues="qpzry9x8gf2tvdw0s3jn54khce6mua7l";function byteArrayToInt(t){let e=0;for(let n=0;n{i=(i<<5)+t,n+=5,n>=8&&(r.push(i>>n-8&255),n-=8)})),e&&n>0&&r.push(i<<8-n&255),r}function bech32ToUTF8String(t){let e=fiveBitArrayTo8BitArray(bech32ToFiveBitArray(t)),n="";for(let t=0;t20&&(e-=20,t/=Math.pow(10,e),t+=new Array(e+1).join("0"));return t}
diff --git a/lnbits/static/i18n/en.js b/lnbits/static/i18n/en.js
index 2db16300e..49893b1ef 100644
--- a/lnbits/static/i18n/en.js
+++ b/lnbits/static/i18n/en.js
@@ -3,7 +3,25 @@ window.localisation.en = {
server: 'Server',
theme: 'Theme',
funding: 'Funding',
+
users: 'Users',
+ apps: 'Apps',
+ channels: 'Channels',
+ transactions: 'Transactions',
+ dashboard: 'Dashboard',
+ manage_node: 'Manage Node',
+ total_capacity: 'Total Capacity',
+ avg_channel_size: 'Avg. Channel Size',
+ biggest_channel_size: 'Biggest Channel Size',
+ smallest_channel_size: 'Smallest Channel Size',
+ number_of_channels: 'Number of Channels',
+ active_channels: 'Active Channels',
+ connect_peer: 'Connect Peer',
+ connect: 'Connect',
+ open_channel: 'Open Channel',
+ open: 'Open',
+ close_channel: 'Close Channel',
+ close: 'Close',
restart: 'Restart server',
save: 'Save',
save_tooltip: 'Save your changes',
diff --git a/lnbits/static/js/base.js b/lnbits/static/js/base.js
index 12f9d0f1c..e475bd682 100644
--- a/lnbits/static/js/base.js
+++ b/lnbits/static/js/base.js
@@ -221,7 +221,7 @@ window.LNbits = {
obj.expirydateFrom = moment(obj.expirydate).fromNow()
obj.msat = obj.amount
obj.sat = obj.msat / 1000
- obj.tag = obj.extra.tag
+ obj.tag = obj.extra?.tag
obj.fsat = new Intl.NumberFormat(window.LOCALE).format(obj.sat)
obj.isIn = obj.amount > 0
obj.isOut = obj.amount < 0
@@ -262,6 +262,9 @@ window.LNbits = {
formatSat: function (value) {
return new Intl.NumberFormat(window.LOCALE).format(value)
},
+ formatMsat: function (value) {
+ return this.formatSat(value / 1000)
+ },
notifyApiError: function (error) {
var types = {
400: 'warning',
@@ -348,6 +351,7 @@ window.windowMixin = {
i18n: window.i18n,
data: function () {
return {
+ toggleSubs: true,
g: {
offline: !navigator.onLine,
visibleDrawer: false,
@@ -451,7 +455,7 @@ window.windowMixin = {
return !obj.hidden
})
.filter(function (obj) {
- if (window.user.admin) return obj
+ if (window.user?.admin) return obj
return !obj.isAdminOnly
})
.map(function (obj) {
diff --git a/lnbits/static/js/components.js b/lnbits/static/js/components.js
index fc098ef71..476b5396e 100644
--- a/lnbits/static/js/components.js
+++ b/lnbits/static/js/components.js
@@ -178,6 +178,7 @@ Vue.component('lnbits-extension-list', {
})
Vue.component('lnbits-admin-ui', {
+ props: ['showNode'],
data: function () {
return {
extensions: [],
@@ -195,6 +196,14 @@ Vue.component('lnbits-admin-ui', {
+
+
+
+
+
+
+
+
`,
diff --git a/lnbits/templates/base.html b/lnbits/templates/base.html
index d6cf155b2..b713dede6 100644
--- a/lnbits/templates/base.html
+++ b/lnbits/templates/base.html
@@ -228,6 +228,7 @@
diff --git a/lnbits/wallets/__init__.py b/lnbits/wallets/__init__.py
index 838d7e270..6b3759f76 100644
--- a/lnbits/wallets/__init__.py
+++ b/lnbits/wallets/__init__.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import importlib
from typing import Optional
+from lnbits.nodes import set_node_class
from lnbits.settings import settings
from lnbits.wallets.base import Wallet
@@ -27,6 +28,8 @@ def set_wallet_class(class_name: Optional[str] = None):
wallet_class = getattr(wallets_module, backend_wallet_class)
global WALLET
WALLET = wallet_class()
+ if WALLET.__node_cls__:
+ set_node_class(WALLET.__node_cls__(WALLET))
def get_wallet_class() -> Wallet:
@@ -34,7 +37,7 @@ def get_wallet_class() -> Wallet:
wallets_module = importlib.import_module("lnbits.wallets")
-FAKE_WALLET: Wallet = FakeWallet()
+FAKE_WALLET = FakeWallet()
# initialize as fake wallet
WALLET: Wallet = FAKE_WALLET
diff --git a/lnbits/wallets/base.py b/lnbits/wallets/base.py
index 7c8e032df..46786265c 100644
--- a/lnbits/wallets/base.py
+++ b/lnbits/wallets/base.py
@@ -1,5 +1,10 @@
+from __future__ import annotations
+
from abc import ABC, abstractmethod
-from typing import AsyncGenerator, Coroutine, NamedTuple, Optional
+from typing import TYPE_CHECKING, AsyncGenerator, Coroutine, NamedTuple, Optional, Type
+
+if TYPE_CHECKING:
+ from lnbits.nodes.base import Node
class StatusResponse(NamedTuple):
@@ -51,6 +56,8 @@ class Wallet(ABC):
async def cleanup(self):
pass
+ __node_cls__: Optional[Type[Node]] = None
+
@abstractmethod
def status(self) -> Coroutine[None, None, StatusResponse]:
pass
@@ -61,6 +68,7 @@ class Wallet(ABC):
amount: int,
memo: Optional[str] = None,
description_hash: Optional[bytes] = None,
+ unhashed_description: Optional[bytes] = None,
**kwargs,
) -> Coroutine[None, None, InvoiceResponse]:
pass
diff --git a/lnbits/wallets/corelightning.py b/lnbits/wallets/corelightning.py
index 63c11821b..7080d2309 100644
--- a/lnbits/wallets/corelightning.py
+++ b/lnbits/wallets/corelightning.py
@@ -7,6 +7,7 @@ from bolt11.exceptions import Bolt11Exception
from loguru import logger
from pyln.client import LightningRpc, RpcError
+from lnbits.nodes.cln import CoreLightningNode
from lnbits.settings import settings
from .base import (
@@ -25,6 +26,8 @@ async def run_sync(func) -> Any:
class CoreLightningWallet(Wallet):
+ __node_cls__ = CoreLightningNode
+
def __init__(self):
self.rpc = settings.corelightning_rpc or settings.clightning_rpc
self.ln = LightningRpc(self.rpc)
@@ -117,6 +120,9 @@ class CoreLightningWallet(Wallet):
"bolt11": bolt11,
"maxfeepercent": f"{fee_limit_percent:.11}",
"exemptfee": 0,
+ # so fee_limit_percent is applied even on payments with fee < 5000
+ # millisatoshi (which is default value of exemptfee)
+ "description": invoice.description,
}
try:
r = await run_sync(lambda: self.ln.call("pay", payload))
diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py
index 119fa10ee..10be48ede 100644
--- a/lnbits/wallets/lndrest.py
+++ b/lnbits/wallets/lndrest.py
@@ -7,6 +7,7 @@ from typing import AsyncGenerator, Dict, Optional
import httpx
from loguru import logger
+from lnbits.nodes.lndrest import LndRestNode
from lnbits.settings import settings
from .base import (
@@ -22,6 +23,8 @@ from .macaroon import AESCipher, load_macaroon
class LndRestWallet(Wallet):
"""https://api.lightning.community/rest/index.html#lnd-rest-api-reference"""
+ __node_cls__ = LndRestNode
+
def __init__(self):
endpoint = settings.lnd_rest_endpoint
cert = settings.lnd_rest_cert
diff --git a/tests/conftest.py b/tests/conftest.py
index 6b9e1dbbd..f370b1bd4 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -102,6 +102,14 @@ async def to_user():
yield user
+@pytest.fixture()
+def from_super_user(from_user):
+ prev = settings.super_user
+ settings.super_user = from_user.id
+ yield from_user
+ settings.super_user = prev
+
+
@pytest_asyncio.fixture(scope="session")
async def superuser():
user = await get_user(settings.super_user)
diff --git a/tests/core/views/test_node_api.py b/tests/core/views/test_node_api.py
new file mode 100644
index 000000000..c7fb5db78
--- /dev/null
+++ b/tests/core/views/test_node_api.py
@@ -0,0 +1,171 @@
+import asyncio
+import random
+from http import HTTPStatus
+
+import pytest
+from pydantic import parse_obj_as
+
+from lnbits import bolt11
+from lnbits.nodes.base import ChannelPoint, ChannelState, NodeChannel
+from tests.conftest import pytest_asyncio, settings
+
+from ...helpers import (
+ WALLET,
+ get_random_invoice_data,
+ get_unconnected_node_uri,
+ mine_blocks,
+)
+
+pytestmark = pytest.mark.skipif(
+ WALLET.__node_cls__ is None, reason="Cant test if node implementation isnt avilable"
+)
+
+
+@pytest_asyncio.fixture()
+async def node_client(client, from_super_user):
+ settings.lnbits_node_ui = True
+ settings.lnbits_public_node_ui = False
+ settings.lnbits_node_ui_transactions = True
+ params = client.params
+ client.params = {"usr": from_super_user.id}
+ yield client
+ client.params = params
+ settings.lnbits_node_ui = False
+
+
+@pytest_asyncio.fixture()
+async def public_node_client(node_client):
+ settings.lnbits_public_node_ui = True
+ yield node_client
+ settings.lnbits_public_node_ui = False
+
+
+@pytest.mark.asyncio
+async def test_node_info_not_found(client):
+ response = await client.get("/node/api/v1/info")
+ assert response.status_code == HTTPStatus.SERVICE_UNAVAILABLE
+
+
+@pytest.mark.asyncio
+async def test_public_node_info_not_found(node_client):
+ response = await node_client.get("/node/public/api/v1/info")
+ assert response.status_code == HTTPStatus.SERVICE_UNAVAILABLE
+
+
+@pytest.mark.asyncio
+async def test_public_node_info(public_node_client):
+ response = await public_node_client.get("/node/public/api/v1/info")
+ assert response.status_code == 200
+
+
+@pytest.mark.asyncio
+async def test_node_info(node_client, from_super_user):
+ response = await node_client.get("/node/api/v1/info")
+ assert response.status_code == 200
+
+
+@pytest.mark.asyncio
+async def test_node_invoices(inkey_headers_from, node_client):
+ data = await get_random_invoice_data()
+ response = await node_client.post(
+ "/api/v1/payments", json=data, headers=inkey_headers_from
+ )
+ invoice = response.json()
+
+ response = await node_client.get("/node/api/v1/invoices", params={"limit": 1})
+ assert response.status_code == 200
+ invoices = response.json()["data"]
+ assert len(invoices) == 1
+ assert invoices[0]["payment_hash"] == invoice["payment_hash"]
+
+
+@pytest.mark.asyncio
+async def test_node_payments(node_client, real_invoice, adminkey_headers_from):
+ response = await node_client.post(
+ "/api/v1/payments", json=real_invoice, headers=adminkey_headers_from
+ )
+ assert response.status_code < 300
+
+ response = await node_client.get("/node/api/v1/payments", params={"limit": 1})
+ assert response.status_code == 200
+ payments = response.json()["data"]
+ assert len(payments) == 1
+ assert (
+ payments[0]["payment_hash"]
+ == bolt11.decode(real_invoice["bolt11"]).payment_hash
+ )
+
+
+@pytest.mark.asyncio
+async def test_channel_management(node_client):
+ async def get_channels():
+ response = await node_client.get("/node/api/v1/channels")
+ assert response.status_code == 200
+ return parse_obj_as(list[NodeChannel], response.json())
+
+ data = await get_channels()
+ close = random.choice(
+ [channel for channel in data if channel.state == ChannelState.ACTIVE]
+ )
+ assert close, "No active channel found"
+
+ response = await node_client.delete(
+ "/node/api/v1/channels",
+ params={"short_id": close.short_id, **close.point.dict()},
+ )
+ assert response.status_code == 200
+
+ data = await get_channels()
+ assert any(
+ channel.point == close.point and channel.state == ChannelState.CLOSED
+ for channel in data
+ )
+
+ response = await node_client.post(
+ "/node/api/v1/channels",
+ json={
+ "peer_id": close.peer_id,
+ "funding_amount": 100000,
+ },
+ )
+ assert response.status_code == 200
+ created = ChannelPoint(**response.json())
+ data = await get_channels()
+ assert any(
+ channel.point == created and channel.state == ChannelState.PENDING
+ for channel in data
+ )
+
+ # mine some blocks so that the newly created channel eventually
+ # gets confirmed to avoid a situation where no channels are
+ # left for testing
+ mine_blocks(5)
+
+
+@pytest.mark.asyncio
+async def test_peer_management(node_client):
+ connect_uri = get_unconnected_node_uri()
+ id = connect_uri.split("@")[0]
+ response = await node_client.post("/node/api/v1/peers", json={"uri": connect_uri})
+ assert response.status_code == 200
+
+ response = await node_client.get("/node/api/v1/peers")
+ assert response.status_code == 200
+ assert any(peer["id"] == id for peer in response.json())
+
+ response = await node_client.delete(f"/node/api/v1/peers/{id}")
+ assert response.status_code == 200
+ await asyncio.sleep(0.1)
+
+ response = await node_client.get("/node/api/v1/peers")
+ assert response.status_code == 200
+ assert not any(peer["id"] == id for peer in response.json())
+
+ response = await node_client.delete(f"/node/api/v1/peers/{id}")
+ assert response.status_code == 400
+
+
+@pytest.mark.asyncio
+async def test_connect_invalid_uri(node_client):
+ response = await node_client.post("/node/api/v1/peers", json={"uri": "invalid"})
+ assert response.status_code == 400
diff --git a/tests/helpers.py b/tests/helpers.py
index e06af92c5..cf47e16cd 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -53,6 +53,17 @@ docker_bitcoin_cli = [
]
+docker_lightning_unconnected_cli = [
+ "docker",
+ "exec",
+ "lnbits-legend-lnd-2-1",
+ "lncli",
+ "--network",
+ "regtest",
+ "--rpcserver=lnd-2",
+]
+
+
def run_cmd(cmd: list) -> str:
timeout = 20
process = Popen(cmd, stdout=PIPE, stderr=PIPE)
@@ -124,6 +135,14 @@ def mine_blocks(blocks: int = 1) -> str:
return run_cmd(cmd)
+def get_unconnected_node_uri() -> str:
+ cmd = docker_lightning_unconnected_cli.copy()
+ cmd.append("getinfo")
+ info = run_cmd_json(cmd)
+ pubkey = info["identity_pubkey"]
+ return f"{pubkey}@lnd-2:9735"
+
+
def create_onchain_address(address_type: str = "bech32") -> str:
cmd = docker_bitcoin_cli.copy()
cmd.extend(["getnewaddress", address_type])