2021-09-07 20:59:23 +02:00
|
|
|
import asyncio
|
refactor: improve startup procedure
During startup the API will try to connect to Bitcoin Core and the
Lightning Node. If it can't connect it will check every "n" seconds
(currently 2s) and connect when available. A new SSE event
called "system_startup_info" is introduced. This event contains
all startup status information during the startup procedure.
The old wallet_locked event is obsolete.
Sample:
--------------------------
event: system_startup_info
data: {"bitcoin": "offline", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "locked", "lightning_msg": "Wallet locked, unlock it to enable full RPC access"}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "done", "lightning_msg": ""}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "bootstraping", "lightning_msg": "RPC not yet available"}
--------------------------
refs #97
2022-06-06 19:29:21 +02:00
|
|
|
from typing import AsyncGenerator, List, Optional
|
2022-03-20 17:20:56 +01:00
|
|
|
|
|
|
|
|
from fastapi import status
|
|
|
|
|
from fastapi.exceptions import HTTPException
|
2022-12-18 20:55:48 +01:00
|
|
|
from loguru import logger
|
2021-09-07 20:59:23 +02:00
|
|
|
|
2025-02-16 20:35:21 +01:00
|
|
|
from app.api.config import config
|
2026-07-11 11:29:55 +02:00
|
|
|
from app.api.utils import Event, broadcast_msg, redis_get
|
2022-10-03 20:22:00 +02:00
|
|
|
from app.lightning.models import (
|
2022-05-18 18:20:13 +02:00
|
|
|
Channel,
|
2022-01-09 20:20:21 +01:00
|
|
|
FeeRevenue,
|
2021-11-02 19:02:08 +01:00
|
|
|
GenericTx,
|
refactor: improve startup procedure
During startup the API will try to connect to Bitcoin Core and the
Lightning Node. If it can't connect it will check every "n" seconds
(currently 2s) and connect when available. A new SSE event
called "system_startup_info" is introduced. This event contains
all startup status information during the startup procedure.
The old wallet_locked event is obsolete.
Sample:
--------------------------
event: system_startup_info
data: {"bitcoin": "offline", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "locked", "lightning_msg": "Wallet locked, unlock it to enable full RPC access"}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "done", "lightning_msg": ""}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "bootstraping", "lightning_msg": "RPC not yet available"}
--------------------------
refs #97
2022-06-06 19:29:21 +02:00
|
|
|
InitLnRepoUpdate,
|
2021-09-20 17:00:36 +02:00
|
|
|
Invoice,
|
|
|
|
|
LnInfo,
|
2021-11-22 21:54:42 +01:00
|
|
|
NewAddressInput,
|
2021-10-31 16:49:15 +01:00
|
|
|
OnChainTransaction,
|
2021-09-20 17:00:36 +02:00
|
|
|
Payment,
|
|
|
|
|
PaymentRequest,
|
2021-10-03 20:55:28 +02:00
|
|
|
SendCoinsInput,
|
|
|
|
|
SendCoinsResponse,
|
2021-09-20 17:00:36 +02:00
|
|
|
)
|
2022-10-03 20:22:00 +02:00
|
|
|
from app.system.models import APIPlatform
|
2021-07-10 17:15:02 +02:00
|
|
|
|
2025-02-16 20:35:21 +01:00
|
|
|
PLATFORM = config("BAPI_PLATFORM", cast=str)
|
2022-07-13 07:08:00 +02:00
|
|
|
|
2025-02-16 20:35:21 +01:00
|
|
|
ln_node = config("BAPI_LN_NODE", default="none").lower()
|
2022-06-08 19:25:45 +02:00
|
|
|
if ln_node == "lnd_grpc":
|
2022-10-03 20:22:00 +02:00
|
|
|
from app.lightning.impl.lnd_grpc import LnNodeLNDgRPC as LnNode
|
2023-04-09 18:38:51 +02:00
|
|
|
elif ln_node == "cln_jrpc" and PLATFORM == APIPlatform.RASPIBLITZ:
|
|
|
|
|
from app.lightning.impl.specializations.cln_jrpc_blitz import (
|
|
|
|
|
LnNodeCLNjRPCBlitz as LnNode,
|
|
|
|
|
)
|
|
|
|
|
elif ln_node == "cln_jrpc" and PLATFORM != APIPlatform.RASPIBLITZ:
|
2023-03-26 20:53:50 +02:00
|
|
|
from app.lightning.impl.cln_jrpc import LnNodeCLNjRPC as LnNode
|
2022-07-13 07:08:00 +02:00
|
|
|
elif ln_node == "cln_grpc" and PLATFORM != APIPlatform.RASPIBLITZ:
|
2022-10-03 20:22:00 +02:00
|
|
|
from app.lightning.impl.cln_grpc import LnNodeCLNgRPC as LnNode
|
2022-07-13 07:08:00 +02:00
|
|
|
elif ln_node == "cln_grpc" and PLATFORM == APIPlatform.RASPIBLITZ:
|
2022-10-03 20:22:00 +02:00
|
|
|
from app.lightning.impl.specializations.cln_grpc_blitz import (
|
2022-10-03 10:44:34 +02:00
|
|
|
LnNodeCLNgRPCBlitz as LnNode,
|
|
|
|
|
)
|
2022-06-14 14:44:55 +02:00
|
|
|
elif ln_node == "none":
|
2023-05-17 16:02:28 +02:00
|
|
|
logger.info("lightning was explicitly turned off")
|
2022-06-14 14:44:55 +02:00
|
|
|
elif ln_node == "":
|
2022-12-01 18:51:03 +01:00
|
|
|
ln_node = "none"
|
2023-05-17 16:02:28 +02:00
|
|
|
logger.info("lightning is not set yet")
|
2022-06-10 20:52:25 +02:00
|
|
|
else:
|
2022-12-18 20:55:48 +01:00
|
|
|
logger.error(f"config: unknown lightning node: {ln_node}")
|
2022-12-01 18:51:03 +01:00
|
|
|
raise RuntimeError(f"unknown lightning node type: {ln_node}")
|
2021-07-10 17:15:02 +02:00
|
|
|
|
2025-02-16 20:35:21 +01:00
|
|
|
GATHER_INFO_INTERVALL = config("BAPI_GATHER_LN_INFO_INTERVAL", default=2, cast=float)
|
2021-09-07 20:59:23 +02:00
|
|
|
|
|
|
|
|
_CACHE = {"wallet_balance": None}
|
|
|
|
|
|
2022-01-15 14:27:08 +01:00
|
|
|
ENABLE_FWD_NOTIFICATIONS = config(
|
2025-02-16 20:35:21 +01:00
|
|
|
"BAPI_SSE_NOTIFY_FORWARD_SUCCESSES", default=False, cast=bool
|
2022-01-15 14:27:08 +01:00
|
|
|
)
|
|
|
|
|
|
2025-02-16 20:35:21 +01:00
|
|
|
FWD_GATHER_INTERVAL = config("BAPI_FORWARDS_GATHER_INTERVAL", default=2.0, cast=float)
|
2022-01-15 14:27:08 +01:00
|
|
|
|
2022-05-18 00:14:35 +02:00
|
|
|
|
2022-01-15 14:27:08 +01:00
|
|
|
if FWD_GATHER_INTERVAL < 0.3:
|
2025-02-16 20:35:21 +01:00
|
|
|
raise RuntimeError("BAPI_FORWARDS_GATHER_INTERVAL cannot be less than 0.3 seconds")
|
|
|
|
|
|
|
|
|
|
if ln_node != "none":
|
|
|
|
|
ln = LnNode()
|
2022-01-15 14:27:08 +01:00
|
|
|
|
2022-12-01 18:51:03 +01:00
|
|
|
if ln_node != "none":
|
|
|
|
|
ln = LnNode()
|
2022-10-03 10:44:34 +02:00
|
|
|
|
2021-07-10 17:15:02 +02:00
|
|
|
|
refactor: improve startup procedure
During startup the API will try to connect to Bitcoin Core and the
Lightning Node. If it can't connect it will check every "n" seconds
(currently 2s) and connect when available. A new SSE event
called "system_startup_info" is introduced. This event contains
all startup status information during the startup procedure.
The old wallet_locked event is obsolete.
Sample:
--------------------------
event: system_startup_info
data: {"bitcoin": "offline", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "locked", "lightning_msg": "Wallet locked, unlock it to enable full RPC access"}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "done", "lightning_msg": ""}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "bootstraping", "lightning_msg": "RPC not yet available"}
--------------------------
refs #97
2022-06-06 19:29:21 +02:00
|
|
|
async def initialize_ln_repo() -> AsyncGenerator[InitLnRepoUpdate, None]:
|
2022-10-03 10:44:34 +02:00
|
|
|
async for u in ln.initialize():
|
refactor: improve startup procedure
During startup the API will try to connect to Bitcoin Core and the
Lightning Node. If it can't connect it will check every "n" seconds
(currently 2s) and connect when available. A new SSE event
called "system_startup_info" is introduced. This event contains
all startup status information during the startup procedure.
The old wallet_locked event is obsolete.
Sample:
--------------------------
event: system_startup_info
data: {"bitcoin": "offline", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "offline", "lightning_msg": "Unable to connect to LND daemon, waiting..."}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "locked", "lightning_msg": "Wallet locked, unlock it to enable full RPC access"}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "done", "lightning_msg": ""}
--------------------------
event: system_startup_info
data: {"bitcoin": "done", "bitcoin_msg": "", "lightning": "bootstraping", "lightning_msg": "RPC not yet available"}
--------------------------
refs #97
2022-06-06 19:29:21 +02:00
|
|
|
yield u
|
|
|
|
|
|
|
|
|
|
|
2021-07-25 16:52:34 +02:00
|
|
|
async def get_wallet_balance():
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.get_wallet_balance()
|
2021-07-21 19:38:49 +02:00
|
|
|
|
|
|
|
|
|
2021-11-02 19:02:08 +01:00
|
|
|
async def list_all_tx(
|
2022-06-04 14:46:03 +02:00
|
|
|
successful_only: bool, index_offset: int, max_tx: int, reversed: bool
|
2021-11-02 19:02:08 +01:00
|
|
|
) -> List[GenericTx]:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.list_all_tx(successful_only, index_offset, max_tx, reversed)
|
2021-11-02 19:02:08 +01:00
|
|
|
|
|
|
|
|
|
2021-10-31 19:04:39 +01:00
|
|
|
async def list_invoices(
|
|
|
|
|
pending_only: bool, index_offset: int, num_max_invoices: int, reversed: bool
|
|
|
|
|
) -> List[Invoice]:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.list_invoices(
|
2021-10-31 19:04:39 +01:00
|
|
|
pending_only,
|
|
|
|
|
index_offset,
|
|
|
|
|
num_max_invoices,
|
|
|
|
|
reversed,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-10-31 16:49:15 +01:00
|
|
|
async def list_on_chain_tx() -> List[OnChainTransaction]:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.list_on_chain_tx()
|
2021-10-31 16:49:15 +01:00
|
|
|
|
|
|
|
|
|
2021-10-31 19:33:35 +01:00
|
|
|
async def list_payments(
|
|
|
|
|
include_incomplete: bool, index_offset: int, max_payments: int, reversed: bool
|
|
|
|
|
) -> List[Payment]:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.list_payments(
|
2021-10-31 19:33:35 +01:00
|
|
|
include_incomplete, index_offset, max_payments, reversed
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2021-09-05 08:56:53 +02:00
|
|
|
async def add_invoice(
|
|
|
|
|
value_msat: int, memo: str = "", expiry: int = 3600, is_keysend: bool = False
|
|
|
|
|
) -> Invoice:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.add_invoice(memo, value_msat, expiry, is_keysend)
|
2021-07-25 18:15:26 +02:00
|
|
|
|
|
|
|
|
|
2021-09-20 17:00:36 +02:00
|
|
|
async def decode_pay_request(pay_req: str) -> PaymentRequest:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.decode_pay_request(pay_req)
|
2021-09-20 17:00:36 +02:00
|
|
|
|
|
|
|
|
|
2021-11-22 21:54:42 +01:00
|
|
|
async def new_address(input: NewAddressInput) -> str:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.new_address(input)
|
2021-11-22 21:54:42 +01:00
|
|
|
|
|
|
|
|
|
2021-10-03 20:55:28 +02:00
|
|
|
async def send_coins(input: SendCoinsInput) -> SendCoinsResponse:
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.send_coins(input)
|
2022-01-15 14:29:55 +01:00
|
|
|
_schedule_wallet_balance_update()
|
2021-10-03 20:55:28 +02:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
2021-09-05 08:56:53 +02:00
|
|
|
async def send_payment(
|
2022-01-09 18:04:10 +01:00
|
|
|
pay_req: str,
|
|
|
|
|
timeout_seconds: int,
|
|
|
|
|
fee_limit_msat: int,
|
|
|
|
|
amount_msat: Optional[int] = None,
|
2021-09-05 08:56:53 +02:00
|
|
|
) -> Payment:
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.send_payment(pay_req, timeout_seconds, fee_limit_msat, amount_msat)
|
2022-01-15 14:29:55 +01:00
|
|
|
_schedule_wallet_balance_update()
|
2021-08-03 21:20:24 +02:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
2022-05-18 18:20:13 +02:00
|
|
|
async def channel_open(
|
|
|
|
|
local_funding_amount: int, node_URI: str, target_confs: int
|
|
|
|
|
) -> str:
|
2022-05-09 19:45:18 +02:00
|
|
|
if local_funding_amount < 1:
|
|
|
|
|
raise ValueError("funding amount needs to be positive")
|
2022-05-18 18:20:13 +02:00
|
|
|
|
2022-05-09 19:45:18 +02:00
|
|
|
if target_confs < 1:
|
|
|
|
|
raise ValueError("target confs needs to be positive")
|
|
|
|
|
|
|
|
|
|
if len(node_URI) == 0:
|
|
|
|
|
raise ValueError("node_URI cant be empty")
|
|
|
|
|
|
2023-05-17 16:02:28 +02:00
|
|
|
if "@" not in node_URI:
|
2022-05-09 19:45:18 +02:00
|
|
|
raise ValueError("node_URI must contain @ with node physical address")
|
|
|
|
|
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.channel_open(local_funding_amount, node_URI, target_confs)
|
2022-05-09 19:45:18 +02:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def channel_list() -> List[Channel]:
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.channel_list()
|
2022-05-09 19:45:18 +02:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def channel_close(channel_id: int, force_close: bool) -> str:
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.channel_close(channel_id, force_close)
|
2022-05-09 19:45:18 +02:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
2021-08-02 20:30:18 +02:00
|
|
|
async def get_ln_info() -> LnInfo:
|
2022-10-03 10:44:34 +02:00
|
|
|
ln_info = await ln.get_ln_info()
|
2022-05-18 00:14:35 +02:00
|
|
|
if PLATFORM == APIPlatform.RASPIBLITZ:
|
|
|
|
|
ln_info.identity_uri = await redis_get("ln_default_address")
|
|
|
|
|
return ln_info
|
2021-08-02 20:30:18 +02:00
|
|
|
|
|
|
|
|
|
2021-11-24 11:12:10 +01:00
|
|
|
async def unlock_wallet(password: str) -> bool:
|
2022-10-03 10:44:34 +02:00
|
|
|
res = await ln.unlock_wallet(password)
|
2021-11-24 11:12:10 +01:00
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
|
2022-01-09 20:20:21 +01:00
|
|
|
async def get_fee_revenue() -> FeeRevenue:
|
2022-10-03 10:44:34 +02:00
|
|
|
return await ln.get_fee_revenue()
|
2022-01-09 20:20:21 +01:00
|
|
|
|
|
|
|
|
|
2021-07-25 18:15:26 +02:00
|
|
|
async def register_lightning_listener():
|
2021-11-24 11:12:10 +01:00
|
|
|
"""
|
|
|
|
|
Registers all lightning listeners
|
|
|
|
|
|
2022-10-03 10:44:34 +02:00
|
|
|
By calling get_ln_info() once, we ensure that wallet is unlocked.
|
2021-11-24 11:12:10 +01:00
|
|
|
Implementation will throw HTTPException with status_code 423_LOCKED if otherwise.
|
|
|
|
|
It is the task of the caller to call register_lightning_listener() again
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
try:
|
2022-12-01 18:51:03 +01:00
|
|
|
if ln_node == "none":
|
2022-12-18 20:55:48 +01:00
|
|
|
logger.info(
|
2022-06-10 19:52:18 +02:00
|
|
|
"SKIPPING register_lightning_listener -> no lightning configured"
|
|
|
|
|
)
|
2022-06-04 16:45:32 +02:00
|
|
|
return
|
|
|
|
|
|
2022-10-03 10:44:34 +02:00
|
|
|
await ln.get_ln_info()
|
2021-11-24 11:12:10 +01:00
|
|
|
|
2026-07-03 22:34:44 +02:00
|
|
|
asyncio.create_task(_handle_info_listener())
|
|
|
|
|
asyncio.create_task(_handle_invoice_listener())
|
|
|
|
|
asyncio.create_task(_handle_forward_event_listener())
|
2021-11-24 11:12:10 +01:00
|
|
|
except NotImplementedError as r:
|
|
|
|
|
raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED, detail=r.args[0])
|
2021-09-07 20:59:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _handle_info_listener():
|
|
|
|
|
last_info = None
|
2021-11-18 19:50:04 +01:00
|
|
|
last_info_lite = None
|
2021-09-07 20:59:23 +02:00
|
|
|
while True:
|
2022-10-03 10:44:34 +02:00
|
|
|
info = await ln.get_ln_info()
|
2021-09-07 20:59:23 +02:00
|
|
|
|
|
|
|
|
if last_info != info:
|
2026-07-11 11:29:55 +02:00
|
|
|
await broadcast_msg(Event.LN_INFO, info.model_dump())
|
2021-09-07 20:59:23 +02:00
|
|
|
last_info = info
|
|
|
|
|
|
|
|
|
|
await asyncio.sleep(GATHER_INFO_INTERVALL)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _handle_invoice_listener():
|
2022-06-04 14:10:44 +02:00
|
|
|
async for i in ln.listen_invoices():
|
2026-07-11 11:29:55 +02:00
|
|
|
await broadcast_msg(Event.LN_INVOICE_STATUS, i.model_dump())
|
2022-01-15 14:29:55 +01:00
|
|
|
_schedule_wallet_balance_update()
|
2021-09-07 20:59:23 +02:00
|
|
|
|
|
|
|
|
|
2022-01-15 14:27:08 +01:00
|
|
|
_fwd_update_scheduled = False
|
|
|
|
|
_fwd_successes = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _handle_forward_event_listener():
|
|
|
|
|
async def _schedule_fwd_update():
|
|
|
|
|
global _fwd_update_scheduled
|
|
|
|
|
global _fwd_successes
|
|
|
|
|
|
|
|
|
|
_fwd_update_scheduled = True
|
|
|
|
|
|
|
|
|
|
await asyncio.sleep(FWD_GATHER_INTERVAL)
|
|
|
|
|
|
|
|
|
|
if len(_fwd_successes) > 0:
|
2023-05-17 16:02:28 +02:00
|
|
|
sending_successes = _fwd_successes
|
2022-01-15 14:27:08 +01:00
|
|
|
_fwd_successes = []
|
2026-07-11 11:29:55 +02:00
|
|
|
await broadcast_msg(Event.LN_FORWARD_SUCCESSES, sending_successes)
|
2022-01-15 14:27:08 +01:00
|
|
|
|
2022-01-15 14:29:55 +01:00
|
|
|
_schedule_wallet_balance_update()
|
2022-01-15 14:27:08 +01:00
|
|
|
rev = await get_fee_revenue()
|
2026-07-11 11:29:55 +02:00
|
|
|
await broadcast_msg(Event.LN_FEE_REVENUE, rev.model_dump())
|
2022-01-15 14:27:08 +01:00
|
|
|
|
|
|
|
|
_fwd_update_scheduled = False
|
|
|
|
|
|
2022-06-04 14:10:44 +02:00
|
|
|
async for i in ln.listen_forward_events():
|
2022-01-15 14:27:08 +01:00
|
|
|
if ENABLE_FWD_NOTIFICATIONS:
|
2024-03-10 07:57:38 +01:00
|
|
|
_fwd_successes.append(i.model_dump())
|
2022-01-15 14:27:08 +01:00
|
|
|
|
|
|
|
|
if not _fwd_update_scheduled:
|
2026-07-03 22:34:44 +02:00
|
|
|
asyncio.create_task(_schedule_fwd_update())
|
2022-01-15 14:27:08 +01:00
|
|
|
|
2022-01-15 14:03:44 +01:00
|
|
|
|
|
|
|
|
_wallet_balance_update_scheduled = False
|
|
|
|
|
|
|
|
|
|
|
2022-01-15 14:29:55 +01:00
|
|
|
def _schedule_wallet_balance_update():
|
2021-09-07 20:59:23 +02:00
|
|
|
async def _perform_update():
|
2022-01-15 14:03:44 +01:00
|
|
|
global _wallet_balance_update_scheduled
|
|
|
|
|
_wallet_balance_update_scheduled = True
|
2021-09-07 20:59:23 +02:00
|
|
|
await asyncio.sleep(1.1)
|
2022-10-03 10:44:34 +02:00
|
|
|
wb = await ln.get_wallet_balance()
|
2021-09-07 20:59:23 +02:00
|
|
|
if _CACHE["wallet_balance"] != wb:
|
2026-07-11 11:29:55 +02:00
|
|
|
await broadcast_msg(Event.WALLET_BALANCE, wb.model_dump())
|
2021-09-07 20:59:23 +02:00
|
|
|
_CACHE["wallet_balance"] = wb
|
|
|
|
|
|
2022-01-15 14:03:44 +01:00
|
|
|
_wallet_balance_update_scheduled = False
|
|
|
|
|
|
|
|
|
|
global _wallet_balance_update_scheduled
|
|
|
|
|
if not _wallet_balance_update_scheduled:
|
2026-07-03 22:34:44 +02:00
|
|
|
asyncio.create_task(_perform_update())
|