lnlink-server 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.js +312 -312
- package/dist/build-info.json +1 -1
- package/dist/index.js +282 -173
- package/dist/index.js.map +2 -2
- package/dist/package.json +1 -1
- package/dist/public/css/initOwner.css +7 -0
- package/dist/public/js/init.js +366 -357
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -122,6 +122,15 @@ var require_linkLogger = __commonJS({
|
|
|
122
122
|
}
|
|
123
123
|
// Cache for logger instances to avoid creating multiple instances with the same logType
|
|
124
124
|
static instances = /* @__PURE__ */ new Map();
|
|
125
|
+
// Silent mode flag - when true, all logging is suppressed (used during graceful shutdown)
|
|
126
|
+
static silentMode = false;
|
|
127
|
+
/**
|
|
128
|
+
* Set silent mode to suppress all logging (used during graceful shutdown)
|
|
129
|
+
* @param {boolean} value - Whether to enable silent mode
|
|
130
|
+
*/
|
|
131
|
+
static setSilentMode(value) {
|
|
132
|
+
_Logger.silentMode = value;
|
|
133
|
+
}
|
|
125
134
|
constructor(logType) {
|
|
126
135
|
if (_Logger.instances.has(logType)) {
|
|
127
136
|
return _Logger.instances.get(logType);
|
|
@@ -131,21 +140,27 @@ var require_linkLogger = __commonJS({
|
|
|
131
140
|
_Logger.instances.set(logType, this);
|
|
132
141
|
}
|
|
133
142
|
debug(message, ...args) {
|
|
143
|
+
if (_Logger.silentMode) return;
|
|
134
144
|
this.logger.debug({ msg: message }, ...args);
|
|
135
145
|
}
|
|
136
146
|
info(message, ...args) {
|
|
147
|
+
if (_Logger.silentMode) return;
|
|
137
148
|
this.logger.info({ msg: message }, ...args);
|
|
138
149
|
}
|
|
139
150
|
warn(message, ...args) {
|
|
151
|
+
if (_Logger.silentMode) return;
|
|
140
152
|
this.logger.warn({ msg: message }, ...args);
|
|
141
153
|
}
|
|
142
154
|
error(message, ...args) {
|
|
155
|
+
if (_Logger.silentMode) return;
|
|
143
156
|
this.logger.error({ msg: message }, ...args);
|
|
144
157
|
}
|
|
145
158
|
fatal(message, ...args) {
|
|
159
|
+
if (_Logger.silentMode) return;
|
|
146
160
|
this.logger.fatal({ msg: message }, ...args);
|
|
147
161
|
}
|
|
148
162
|
logWithData(level, message, data) {
|
|
163
|
+
if (_Logger.silentMode) return;
|
|
149
164
|
this.logger[level]({ ...data, msg: message });
|
|
150
165
|
}
|
|
151
166
|
};
|
|
@@ -2720,7 +2735,6 @@ var require_getConfig = __commonJS({
|
|
|
2720
2735
|
"LINK_DEBUG",
|
|
2721
2736
|
"LINK_ENABLE_TOR",
|
|
2722
2737
|
"LINK_NODE_ENV",
|
|
2723
|
-
"LINK_AUTO_ASSIGN_PORTS",
|
|
2724
2738
|
"LINK_HTTPS_PROXY",
|
|
2725
2739
|
"LINK_DATABASE_URL",
|
|
2726
2740
|
"LINK_REPORT_BASE_URL",
|
|
@@ -2759,7 +2773,7 @@ var require_getConfig = __commonJS({
|
|
|
2759
2773
|
});
|
|
2760
2774
|
}
|
|
2761
2775
|
__name(isPortAvailable, "isPortAvailable");
|
|
2762
|
-
async function findAvailablePort(basePort) {
|
|
2776
|
+
async function findAvailablePort(basePort, assignedPorts = /* @__PURE__ */ new Set()) {
|
|
2763
2777
|
const portRanges = {
|
|
2764
2778
|
10009: [10009, 20009, 30009, 40009, 50009],
|
|
2765
2779
|
// LINK_LND_RPC_PORT: 10009 -> 20009 -> 30009...
|
|
@@ -2778,13 +2792,13 @@ var require_getConfig = __commonJS({
|
|
|
2778
2792
|
};
|
|
2779
2793
|
if (portRanges[basePort]) {
|
|
2780
2794
|
for (const port2 of portRanges[basePort]) {
|
|
2781
|
-
if (await isPortAvailable(port2)) {
|
|
2795
|
+
if (!assignedPorts.has(port2) && await isPortAvailable(port2)) {
|
|
2782
2796
|
return port2;
|
|
2783
2797
|
}
|
|
2784
2798
|
}
|
|
2785
2799
|
let port = portRanges[basePort][portRanges[basePort].length - 1] + 1;
|
|
2786
2800
|
while (port < 65535) {
|
|
2787
|
-
if (await isPortAvailable(port)) {
|
|
2801
|
+
if (!assignedPorts.has(port) && await isPortAvailable(port)) {
|
|
2788
2802
|
return port;
|
|
2789
2803
|
}
|
|
2790
2804
|
port++;
|
|
@@ -2792,7 +2806,7 @@ var require_getConfig = __commonJS({
|
|
|
2792
2806
|
} else {
|
|
2793
2807
|
let port = basePort;
|
|
2794
2808
|
while (port < 65535) {
|
|
2795
|
-
if (await isPortAvailable(port)) {
|
|
2809
|
+
if (!assignedPorts.has(port) && await isPortAvailable(port)) {
|
|
2796
2810
|
return port;
|
|
2797
2811
|
}
|
|
2798
2812
|
port++;
|
|
@@ -2812,16 +2826,18 @@ var require_getConfig = __commonJS({
|
|
|
2812
2826
|
"LINK_HTTP_PORT"
|
|
2813
2827
|
];
|
|
2814
2828
|
const updatedConfig = { ...config };
|
|
2829
|
+
const assignedPorts = /* @__PURE__ */ new Set();
|
|
2815
2830
|
for (const key of portKeys) {
|
|
2816
2831
|
if (updatedConfig[key]) {
|
|
2817
2832
|
const basePort = Number.parseInt(updatedConfig[key]);
|
|
2818
2833
|
if (!Number.isNaN(basePort)) {
|
|
2819
2834
|
try {
|
|
2820
|
-
const availablePort = await findAvailablePort(basePort);
|
|
2835
|
+
const availablePort = await findAvailablePort(basePort, assignedPorts);
|
|
2821
2836
|
if (availablePort !== basePort) {
|
|
2822
2837
|
console.log(`[port-assign] Port ${basePort} for ${key} is occupied, using ${availablePort} instead`);
|
|
2823
2838
|
updatedConfig[key] = availablePort;
|
|
2824
2839
|
}
|
|
2840
|
+
assignedPorts.add(availablePort);
|
|
2825
2841
|
} catch (error) {
|
|
2826
2842
|
console.warn(`[port-assign] Failed to find available port for ${key}: ${error?.message}`);
|
|
2827
2843
|
}
|
|
@@ -2885,9 +2901,7 @@ var require_getConfig = __commonJS({
|
|
|
2885
2901
|
combinedConfig.LINK_TOR_SOCKS_PORT = combinedConfig.LINK_TOR_SOCKS_PORT || 9050;
|
|
2886
2902
|
combinedConfig.LINK_TOR_CONTROL_PORT = combinedConfig.LINK_TOR_CONTROL_PORT || 9051;
|
|
2887
2903
|
try {
|
|
2888
|
-
|
|
2889
|
-
combinedConfig = await assignAvailablePorts(combinedConfig);
|
|
2890
|
-
}
|
|
2904
|
+
combinedConfig = await assignAvailablePorts(combinedConfig);
|
|
2891
2905
|
} catch (portError) {
|
|
2892
2906
|
console.warn(
|
|
2893
2907
|
"Port assignment failed, using default ports:",
|
|
@@ -5577,7 +5591,6 @@ var require_processManager = __commonJS({
|
|
|
5577
5591
|
"business/service/nodeManage/processManager.js"(exports2, module2) {
|
|
5578
5592
|
var { spawn } = require("node:child_process");
|
|
5579
5593
|
var findProcess = require("find-process").default;
|
|
5580
|
-
var { getLightningService } = require_common();
|
|
5581
5594
|
var { getConfig: getConfig2 } = require_getConfig();
|
|
5582
5595
|
var Logger = require_linkLogger();
|
|
5583
5596
|
var { sleep } = require_timeUtils();
|
|
@@ -5587,6 +5600,11 @@ var require_processManager = __commonJS({
|
|
|
5587
5600
|
return config.LINK_EXTERNAL_NODES === "true" || config.LINK_EXTERNAL_NODES === true;
|
|
5588
5601
|
}
|
|
5589
5602
|
__name(isExternalNodesMode, "isExternalNodesMode");
|
|
5603
|
+
function shouldDetach() {
|
|
5604
|
+
const config = getConfig2();
|
|
5605
|
+
return config.LINK_NODE_ENV !== "app";
|
|
5606
|
+
}
|
|
5607
|
+
__name(shouldDetach, "shouldDetach");
|
|
5590
5608
|
function terminateProcess(pid, force = false) {
|
|
5591
5609
|
const logger2 = new Logger("processManager");
|
|
5592
5610
|
try {
|
|
@@ -5601,9 +5619,19 @@ var require_processManager = __commonJS({
|
|
|
5601
5619
|
}
|
|
5602
5620
|
__name(terminateProcess, "terminateProcess");
|
|
5603
5621
|
var serviceState = {
|
|
5604
|
-
services: null
|
|
5622
|
+
services: null,
|
|
5605
5623
|
// Will be initialized when needed
|
|
5624
|
+
isShuttingDown: false
|
|
5625
|
+
// Flag to suppress async logs during shutdown
|
|
5606
5626
|
};
|
|
5627
|
+
function setShuttingDown(value) {
|
|
5628
|
+
serviceState.isShuttingDown = value;
|
|
5629
|
+
}
|
|
5630
|
+
__name(setShuttingDown, "setShuttingDown");
|
|
5631
|
+
function isShuttingDown() {
|
|
5632
|
+
return serviceState.isShuttingDown;
|
|
5633
|
+
}
|
|
5634
|
+
__name(isShuttingDown, "isShuttingDown");
|
|
5607
5635
|
function initializeServices() {
|
|
5608
5636
|
if (!serviceState.services) {
|
|
5609
5637
|
serviceState.services = getServiceConfig();
|
|
@@ -5654,7 +5682,8 @@ var require_processManager = __commonJS({
|
|
|
5654
5682
|
}
|
|
5655
5683
|
}, "settleReject");
|
|
5656
5684
|
const proc = spawn(service.command, args, {
|
|
5657
|
-
stdio: "pipe"
|
|
5685
|
+
stdio: "pipe",
|
|
5686
|
+
detached: shouldDetach()
|
|
5658
5687
|
});
|
|
5659
5688
|
setServiceProcess("litd", proc);
|
|
5660
5689
|
timeoutId = setTimeout(() => {
|
|
@@ -5664,7 +5693,9 @@ var require_processManager = __commonJS({
|
|
|
5664
5693
|
}
|
|
5665
5694
|
}, LITD_STARTUP_TIMEOUT);
|
|
5666
5695
|
proc.once("exit", (code, signal) => {
|
|
5667
|
-
|
|
5696
|
+
if (!isShuttingDown()) {
|
|
5697
|
+
logger2.info(`litd process exited with code ${code ?? "null"}, signal ${signal ?? "null"}`);
|
|
5698
|
+
}
|
|
5668
5699
|
const currentService = getService("litd");
|
|
5669
5700
|
if (currentService?.process === proc) {
|
|
5670
5701
|
setServiceProcess("litd", null);
|
|
@@ -5727,7 +5758,8 @@ var require_processManager = __commonJS({
|
|
|
5727
5758
|
}, "settleReject");
|
|
5728
5759
|
logger2.info(`Tor config: ${JSON.stringify(args, null, 2)}`);
|
|
5729
5760
|
const proc = spawn(service.command, args, {
|
|
5730
|
-
stdio: "pipe"
|
|
5761
|
+
stdio: "pipe",
|
|
5762
|
+
detached: shouldDetach()
|
|
5731
5763
|
});
|
|
5732
5764
|
setServiceProcess("tor", proc);
|
|
5733
5765
|
timeoutId = setTimeout(() => {
|
|
@@ -5737,7 +5769,9 @@ var require_processManager = __commonJS({
|
|
|
5737
5769
|
}
|
|
5738
5770
|
}, TOR_STARTUP_TIMEOUT);
|
|
5739
5771
|
proc.once("exit", (code, signal) => {
|
|
5740
|
-
|
|
5772
|
+
if (!isShuttingDown()) {
|
|
5773
|
+
logger2.info(`tor process exited with code ${code ?? "null"}, signal ${signal ?? "null"}`);
|
|
5774
|
+
}
|
|
5741
5775
|
const currentService = getService("tor");
|
|
5742
5776
|
if (currentService?.process === proc) {
|
|
5743
5777
|
setServiceProcess("tor", null);
|
|
@@ -5805,7 +5839,8 @@ var require_processManager = __commonJS({
|
|
|
5805
5839
|
}
|
|
5806
5840
|
}, "settleReject");
|
|
5807
5841
|
const proc = spawn(service.command, args, {
|
|
5808
|
-
stdio: "pipe"
|
|
5842
|
+
stdio: "pipe",
|
|
5843
|
+
detached: shouldDetach()
|
|
5809
5844
|
});
|
|
5810
5845
|
setServiceProcess("rgb", proc);
|
|
5811
5846
|
timeoutId = setTimeout(() => {
|
|
@@ -5815,7 +5850,9 @@ var require_processManager = __commonJS({
|
|
|
5815
5850
|
}
|
|
5816
5851
|
}, RGB_STARTUP_TIMEOUT);
|
|
5817
5852
|
proc.once("exit", (code, signal) => {
|
|
5818
|
-
|
|
5853
|
+
if (!isShuttingDown()) {
|
|
5854
|
+
logger2.info(`rgb process exited with code ${code ?? "null"}, signal ${signal ?? "null"}`);
|
|
5855
|
+
}
|
|
5819
5856
|
const currentService = getService("rgb");
|
|
5820
5857
|
if (currentService?.process === proc) {
|
|
5821
5858
|
setServiceProcess("rgb", null);
|
|
@@ -5923,35 +5960,12 @@ var require_processManager = __commonJS({
|
|
|
5923
5960
|
const trackedProcess = initialService.process;
|
|
5924
5961
|
const processAlive = trackedProcess && !trackedProcess.killed && trackedProcess.exitCode === null;
|
|
5925
5962
|
if (processAlive) {
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
const lightningService = getLightningService();
|
|
5929
|
-
await lightningService.stopDaemon();
|
|
5930
|
-
logger2.info("LND daemon stopped gracefully via RPC");
|
|
5931
|
-
let waitCount = 0;
|
|
5932
|
-
const maxWait = 10;
|
|
5933
|
-
while (waitCount < maxWait) {
|
|
5934
|
-
const currentProcess = getService("litd")?.process ?? trackedProcess;
|
|
5935
|
-
if (!currentProcess || currentProcess.killed || currentProcess.exitCode !== null) {
|
|
5936
|
-
setServiceProcess("litd", null);
|
|
5937
|
-
return true;
|
|
5938
|
-
}
|
|
5939
|
-
await sleep(1e3);
|
|
5940
|
-
waitCount++;
|
|
5941
|
-
}
|
|
5942
|
-
logger2.warn("Process did not exit after RPC shutdown, proceeding with fallback...");
|
|
5943
|
-
} catch (error) {
|
|
5944
|
-
logger2.warn(`RPC shutdown failed: ${error.message}, falling back to process termination`);
|
|
5945
|
-
}
|
|
5946
|
-
} else {
|
|
5947
|
-
logger2.info("litd process already exited, skipping RPC shutdown");
|
|
5948
|
-
setServiceProcess("litd", null);
|
|
5949
|
-
}
|
|
5950
|
-
const fallbackService = getService("litd") ?? initialService;
|
|
5951
|
-
if (fallbackService.process) {
|
|
5952
|
-
return await killProcess(fallbackService.process, "litd");
|
|
5963
|
+
logger2.info("Stopping litd via SIGTERM...");
|
|
5964
|
+
return await killProcess(trackedProcess, "litd", 5e3);
|
|
5953
5965
|
}
|
|
5954
|
-
|
|
5966
|
+
logger2.info("litd process already exited, cleaning up...");
|
|
5967
|
+
setServiceProcess("litd", null);
|
|
5968
|
+
return await findAndKillProcess(initialService.command, "litd");
|
|
5955
5969
|
}
|
|
5956
5970
|
__name(stopLitdService, "stopLitdService");
|
|
5957
5971
|
async function stopTorService() {
|
|
@@ -6007,32 +6021,12 @@ var require_processManager = __commonJS({
|
|
|
6007
6021
|
if (!service) {
|
|
6008
6022
|
throw new Error("rgb service not found");
|
|
6009
6023
|
}
|
|
6010
|
-
try {
|
|
6011
|
-
logger2.info("Attempting graceful shutdown of RGB via SIGTERM...");
|
|
6012
|
-
const processList = await findProcess("name", "rgb-lightning-node");
|
|
6013
|
-
if (processList.length > 0) {
|
|
6014
|
-
processList.forEach((p) => terminateProcess(p.pid, false));
|
|
6015
|
-
await sleep(2e3);
|
|
6016
|
-
setServiceProcess("rgb", null);
|
|
6017
|
-
const remaining = await findProcess("name", "rgb-lightning-node");
|
|
6018
|
-
if (remaining.length === 0) {
|
|
6019
|
-
logger2.info("RGB stopped gracefully");
|
|
6020
|
-
return true;
|
|
6021
|
-
}
|
|
6022
|
-
logger2.warn(`${remaining.length} RGB process(es) still running after SIGTERM, force killing...`);
|
|
6023
|
-
remaining.forEach((p) => terminateProcess(p.pid, true));
|
|
6024
|
-
setServiceProcess("rgb", null);
|
|
6025
|
-
return true;
|
|
6026
|
-
}
|
|
6027
|
-
logger2.info("No RGB processes found via find-process, trying tracked process...");
|
|
6028
|
-
} catch (error) {
|
|
6029
|
-
logger2.warn(`RGB graceful shutdown failed: ${error.message}, falling back to process termination`);
|
|
6030
|
-
}
|
|
6031
6024
|
if (service.process) {
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
return await findAndKillProcess("rgb-lightning-node", "rgb");
|
|
6025
|
+
logger2.info("Stopping RGB via tracked process...");
|
|
6026
|
+
return await killProcess(service.process, "rgb", 5e3);
|
|
6035
6027
|
}
|
|
6028
|
+
logger2.info("No tracked RGB process, falling back to system scan...");
|
|
6029
|
+
return await findAndKillProcess("rgb-lightning-node", "rgb");
|
|
6036
6030
|
}
|
|
6037
6031
|
__name(stopRgbService, "stopRgbService");
|
|
6038
6032
|
async function stopService(name) {
|
|
@@ -6079,13 +6073,24 @@ var require_processManager = __commonJS({
|
|
|
6079
6073
|
};
|
|
6080
6074
|
}
|
|
6081
6075
|
__name(getServicesState, "getServicesState");
|
|
6076
|
+
function getServicePids() {
|
|
6077
|
+
const services = initializeServices();
|
|
6078
|
+
return {
|
|
6079
|
+
litd: services.litd?.process?.pid || null,
|
|
6080
|
+
tor: services.tor?.process?.pid || null,
|
|
6081
|
+
rgb: services.rgb?.process?.pid || null
|
|
6082
|
+
};
|
|
6083
|
+
}
|
|
6084
|
+
__name(getServicePids, "getServicePids");
|
|
6082
6085
|
module2.exports = {
|
|
6083
6086
|
startService,
|
|
6084
6087
|
stopService,
|
|
6085
6088
|
stopLitdService,
|
|
6086
6089
|
stopTorService,
|
|
6087
6090
|
stopRgbService,
|
|
6088
|
-
getServicesState
|
|
6091
|
+
getServicesState,
|
|
6092
|
+
getServicePids,
|
|
6093
|
+
setShuttingDown
|
|
6089
6094
|
};
|
|
6090
6095
|
}
|
|
6091
6096
|
});
|
|
@@ -6202,21 +6207,11 @@ var require_node = __commonJS({
|
|
|
6202
6207
|
tag: TASKS.EnableRGBNode
|
|
6203
6208
|
});
|
|
6204
6209
|
}
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
const status = await getNodeState();
|
|
6211
|
-
resolve({
|
|
6212
|
-
message: "Request submitted, current node status:",
|
|
6213
|
-
status
|
|
6214
|
-
});
|
|
6215
|
-
}, timeoutMs);
|
|
6216
|
-
});
|
|
6217
|
-
const result = await Promise.race([unlockPromise, timeoutPromise]);
|
|
6218
|
-
clearTimeout(timeoutId);
|
|
6219
|
-
return result || true;
|
|
6210
|
+
rgbClient.node.unlockNode(unlockNodeParams).then(() => {
|
|
6211
|
+
}).catch((err) => console.error("[rgb] unlockNode background error:", err.message));
|
|
6212
|
+
const linkCache = require_linkCache();
|
|
6213
|
+
linkCache.set("rgbState", 3);
|
|
6214
|
+
return { state: 3, message: "Unlock submitted, syncing..." };
|
|
6220
6215
|
}
|
|
6221
6216
|
__name(unlockNode, "unlockNode");
|
|
6222
6217
|
async function backupNode({ password }) {
|
|
@@ -6276,6 +6271,7 @@ var require_statusChecker = __commonJS({
|
|
|
6276
6271
|
var { getNodeState } = require_node();
|
|
6277
6272
|
var { getServiceConfig } = require_config2();
|
|
6278
6273
|
var { getServicesState } = require_processManager();
|
|
6274
|
+
var normalizePath = /* @__PURE__ */ __name((s) => s ? s.replace(/\\/g, "/") : "", "normalizePath");
|
|
6279
6275
|
function isExternalNodesMode() {
|
|
6280
6276
|
const config = getConfig2();
|
|
6281
6277
|
return config.LINK_EXTERNAL_NODES === "true" || config.LINK_EXTERNAL_NODES === true;
|
|
@@ -6313,10 +6309,26 @@ var require_statusChecker = __commonJS({
|
|
|
6313
6309
|
}
|
|
6314
6310
|
return ServiceStatus.STOPPED;
|
|
6315
6311
|
}
|
|
6312
|
+
const { LINK_DATA_PATH } = getConfig2();
|
|
6316
6313
|
const processList = await findProcess("name", "litd");
|
|
6314
|
+
if (!LINK_DATA_PATH) {
|
|
6315
|
+
if (processList.length > 0) {
|
|
6316
|
+
logger2.warn("LINK_DATA_PATH not set, cannot filter litd by ownership. Returning RUNNING based on process name match.");
|
|
6317
|
+
return ServiceStatus.RUNNING;
|
|
6318
|
+
}
|
|
6319
|
+
return ServiceStatus.STOPPED;
|
|
6320
|
+
}
|
|
6321
|
+
const lnlinkLitdDataDir = `${LINK_DATA_PATH}/.litd`;
|
|
6317
6322
|
if (processList.length > 0) {
|
|
6318
|
-
|
|
6319
|
-
|
|
6323
|
+
const targetDir = normalizePath(lnlinkLitdDataDir);
|
|
6324
|
+
const lnlinkLitdProcess = processList.find((p) => p.cmd && normalizePath(p.cmd).includes(targetDir));
|
|
6325
|
+
if (lnlinkLitdProcess) {
|
|
6326
|
+
logger2.info(`Found lnlink litd process: PID ${lnlinkLitdProcess.pid}`);
|
|
6327
|
+
return ServiceStatus.RUNNING;
|
|
6328
|
+
} else {
|
|
6329
|
+
logger2.debug(`Found ${processList.length} litd process(es), but none belong to lnlink (data dir: ${lnlinkLitdDataDir})`);
|
|
6330
|
+
return ServiceStatus.STOPPED;
|
|
6331
|
+
}
|
|
6320
6332
|
}
|
|
6321
6333
|
return ServiceStatus.STOPPED;
|
|
6322
6334
|
} catch (error) {
|
|
@@ -6341,10 +6353,26 @@ var require_statusChecker = __commonJS({
|
|
|
6341
6353
|
}
|
|
6342
6354
|
return ServiceStatus.STOPPED;
|
|
6343
6355
|
}
|
|
6356
|
+
const { LINK_DATA_PATH } = getConfig2();
|
|
6344
6357
|
const processList = await findProcess("name", "rgb-lightning-node");
|
|
6358
|
+
if (!LINK_DATA_PATH) {
|
|
6359
|
+
if (processList.length > 0) {
|
|
6360
|
+
logger2.warn("LINK_DATA_PATH not set, cannot filter RGB by ownership. Returning RUNNING based on process name match.");
|
|
6361
|
+
return ServiceStatus.RUNNING;
|
|
6362
|
+
}
|
|
6363
|
+
return ServiceStatus.STOPPED;
|
|
6364
|
+
}
|
|
6365
|
+
const lnlinkRgbDataDir = `${LINK_DATA_PATH}/.rgb`;
|
|
6345
6366
|
if (processList.length > 0) {
|
|
6346
|
-
|
|
6347
|
-
|
|
6367
|
+
const targetDir = normalizePath(lnlinkRgbDataDir);
|
|
6368
|
+
const lnlinkRgbProcess = processList.find((p) => p.cmd && normalizePath(p.cmd).includes(targetDir));
|
|
6369
|
+
if (lnlinkRgbProcess) {
|
|
6370
|
+
logger2.info(`Found lnlink RGB process: PID ${lnlinkRgbProcess.pid}`);
|
|
6371
|
+
return ServiceStatus.RUNNING;
|
|
6372
|
+
} else {
|
|
6373
|
+
logger2.debug(`Found ${processList.length} rgb-lightning-node process(es), but none belong to lnlink (data dir: ${lnlinkRgbDataDir})`);
|
|
6374
|
+
return ServiceStatus.STOPPED;
|
|
6375
|
+
}
|
|
6348
6376
|
}
|
|
6349
6377
|
return ServiceStatus.STOPPED;
|
|
6350
6378
|
} catch (error) {
|
|
@@ -6383,12 +6411,25 @@ var require_statusChecker = __commonJS({
|
|
|
6383
6411
|
}
|
|
6384
6412
|
}
|
|
6385
6413
|
__name(checkProcess, "checkProcess");
|
|
6386
|
-
|
|
6387
|
-
|
|
6414
|
+
var terminalStatusCache = {
|
|
6415
|
+
data: null,
|
|
6416
|
+
timestamp: 0,
|
|
6417
|
+
TTL_MS: 5e3
|
|
6418
|
+
// 5 seconds cache
|
|
6419
|
+
};
|
|
6420
|
+
async function getTerminalStatus(filter = "") {
|
|
6388
6421
|
const logger2 = new Logger("statusChecker");
|
|
6422
|
+
if (!filter && terminalStatusCache.data) {
|
|
6423
|
+
const age = Date.now() - terminalStatusCache.timestamp;
|
|
6424
|
+
if (age < terminalStatusCache.TTL_MS) {
|
|
6425
|
+
logger2.debug(`getTerminalStatus: returning cached result (age: ${age}ms)`);
|
|
6426
|
+
return [...terminalStatusCache.data];
|
|
6427
|
+
}
|
|
6428
|
+
}
|
|
6429
|
+
const services = getServiceConfig();
|
|
6389
6430
|
const shouldInclude = /* @__PURE__ */ __name((name) => name !== "rgb" && (!filter || name.includes(filter)), "shouldInclude");
|
|
6390
6431
|
const filteredServices = Object.keys(services).filter(shouldInclude);
|
|
6391
|
-
|
|
6432
|
+
const result = await Promise.all(
|
|
6392
6433
|
filteredServices.map(async (name) => {
|
|
6393
6434
|
try {
|
|
6394
6435
|
const state = await checkProcess(name);
|
|
@@ -6403,8 +6444,18 @@ var require_statusChecker = __commonJS({
|
|
|
6403
6444
|
}
|
|
6404
6445
|
})
|
|
6405
6446
|
);
|
|
6447
|
+
if (!filter) {
|
|
6448
|
+
terminalStatusCache.data = result;
|
|
6449
|
+
terminalStatusCache.timestamp = Date.now();
|
|
6450
|
+
}
|
|
6451
|
+
return result;
|
|
6406
6452
|
}
|
|
6407
6453
|
__name(getTerminalStatus, "getTerminalStatus");
|
|
6454
|
+
function invalidateTerminalStatusCache() {
|
|
6455
|
+
terminalStatusCache.data = null;
|
|
6456
|
+
terminalStatusCache.timestamp = 0;
|
|
6457
|
+
}
|
|
6458
|
+
__name(invalidateTerminalStatusCache, "invalidateTerminalStatusCache");
|
|
6408
6459
|
async function getRGBStatus() {
|
|
6409
6460
|
const logger2 = new Logger("statusChecker");
|
|
6410
6461
|
try {
|
|
@@ -6461,6 +6512,7 @@ var require_statusChecker = __commonJS({
|
|
|
6461
6512
|
checkProcess,
|
|
6462
6513
|
getRGBStatus,
|
|
6463
6514
|
getTerminalStatus,
|
|
6515
|
+
invalidateTerminalStatusCache,
|
|
6464
6516
|
isServiceRunning,
|
|
6465
6517
|
waitForServiceStatus
|
|
6466
6518
|
};
|
|
@@ -6486,6 +6538,7 @@ var require_nodeManage = __commonJS({
|
|
|
6486
6538
|
var { startService, stopService } = require_processManager();
|
|
6487
6539
|
var {
|
|
6488
6540
|
getTerminalStatus,
|
|
6541
|
+
invalidateTerminalStatusCache,
|
|
6489
6542
|
isServiceRunning,
|
|
6490
6543
|
getRGBStatus,
|
|
6491
6544
|
ServiceStatus
|
|
@@ -6546,22 +6599,30 @@ var require_nodeManage = __commonJS({
|
|
|
6546
6599
|
return { matched: false, statuses: lastStatuses };
|
|
6547
6600
|
}
|
|
6548
6601
|
__name(waitForRgbStatus, "waitForRgbStatus");
|
|
6602
|
+
var isStartingTerminal = false;
|
|
6603
|
+
var isStartingRGB = false;
|
|
6549
6604
|
async function startTerminal({ waitForRunning = true } = {}) {
|
|
6550
6605
|
const logger2 = new Logger("litdService");
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
const torStatus = startStatus.find((item) => item.service_name === "tor");
|
|
6557
|
-
logger2.info(`Current status - Litd: ${litdStatus?.status}, Tor: ${torStatus?.status}`);
|
|
6558
|
-
let torSucceeded = !isStartTor;
|
|
6606
|
+
if (isStartingTerminal) {
|
|
6607
|
+
logger2.warn("Terminal start already in progress, returning current status");
|
|
6608
|
+
return await getTerminalStatus();
|
|
6609
|
+
}
|
|
6610
|
+
isStartingTerminal = true;
|
|
6559
6611
|
try {
|
|
6612
|
+
const { LINK_ENABLE_TOR } = getConfig2();
|
|
6613
|
+
const isStartTor = LINK_ENABLE_TOR === "true" || LINK_ENABLE_TOR === true;
|
|
6614
|
+
logger2.info("Starting terminal services...");
|
|
6615
|
+
const startStatus = await getTerminalStatus();
|
|
6616
|
+
const litdStatus = startStatus.find((item) => item.service_name === "litd");
|
|
6617
|
+
const torStatus = startStatus.find((item) => item.service_name === "tor");
|
|
6618
|
+
logger2.info(`Current status - Litd: ${litdStatus?.status}, Tor: ${torStatus?.status}`);
|
|
6619
|
+
let torSucceeded = !isStartTor;
|
|
6560
6620
|
if (isStartTor && torStatus?.status === ServiceStatus.STOPPED) {
|
|
6561
6621
|
logger2.info("Starting Tor service...");
|
|
6562
6622
|
try {
|
|
6563
6623
|
const torArgs = buildTorArgs();
|
|
6564
6624
|
await startService("tor", torArgs);
|
|
6625
|
+
invalidateTerminalStatusCache();
|
|
6565
6626
|
torSucceeded = true;
|
|
6566
6627
|
logger2.info("Tor service started successfully");
|
|
6567
6628
|
} catch (torError) {
|
|
@@ -6579,6 +6640,7 @@ var require_nodeManage = __commonJS({
|
|
|
6579
6640
|
logger2.info(`Starting Litd service (Tor: ${useTor})...`);
|
|
6580
6641
|
const litdArgs = buildLitdArgs(useTor);
|
|
6581
6642
|
await startService("litd", litdArgs);
|
|
6643
|
+
invalidateTerminalStatusCache();
|
|
6582
6644
|
logger2.info("Litd service started successfully");
|
|
6583
6645
|
}
|
|
6584
6646
|
const endStatus = await getTerminalStatus();
|
|
@@ -6600,6 +6662,8 @@ var require_nodeManage = __commonJS({
|
|
|
6600
6662
|
} catch (error) {
|
|
6601
6663
|
logger2.error(`Failed to start terminal services: ${error.message}`);
|
|
6602
6664
|
throw error;
|
|
6665
|
+
} finally {
|
|
6666
|
+
isStartingTerminal = false;
|
|
6603
6667
|
}
|
|
6604
6668
|
}
|
|
6605
6669
|
__name(startTerminal, "startTerminal");
|
|
@@ -6613,6 +6677,7 @@ var require_nodeManage = __commonJS({
|
|
|
6613
6677
|
logger2.info("Stopping terminal services...");
|
|
6614
6678
|
try {
|
|
6615
6679
|
const stopRet = await stopService("litd");
|
|
6680
|
+
invalidateTerminalStatusCache();
|
|
6616
6681
|
if (!stopRet) {
|
|
6617
6682
|
logger2.warn("stopService returned a falsy result");
|
|
6618
6683
|
return false;
|
|
@@ -6706,6 +6771,11 @@ var require_nodeManage = __commonJS({
|
|
|
6706
6771
|
async function startRGB(args = {}) {
|
|
6707
6772
|
const { waitForRunning = true, lnlinkUser } = args;
|
|
6708
6773
|
const logger2 = new Logger("rgbService");
|
|
6774
|
+
if (isStartingRGB) {
|
|
6775
|
+
logger2.warn("RGB start already in progress, returning current status");
|
|
6776
|
+
return await getRGBStatus();
|
|
6777
|
+
}
|
|
6778
|
+
isStartingRGB = true;
|
|
6709
6779
|
logger2.info("Starting RGB service...");
|
|
6710
6780
|
try {
|
|
6711
6781
|
const startStatus = await getRGBStatus();
|
|
@@ -6740,6 +6810,8 @@ var require_nodeManage = __commonJS({
|
|
|
6740
6810
|
} catch (error) {
|
|
6741
6811
|
logger2.error(`Failed to start RGB service: ${error.message}`);
|
|
6742
6812
|
throw error;
|
|
6813
|
+
} finally {
|
|
6814
|
+
isStartingRGB = false;
|
|
6743
6815
|
}
|
|
6744
6816
|
}
|
|
6745
6817
|
__name(startRGB, "startRGB");
|
|
@@ -6848,24 +6920,6 @@ var require_nodeManage = __commonJS({
|
|
|
6848
6920
|
}
|
|
6849
6921
|
}
|
|
6850
6922
|
__name(updateNodeName, "updateNodeName");
|
|
6851
|
-
if (globalThis.addCleanupFunction) {
|
|
6852
|
-
const logger2 = new Logger("nodeManage");
|
|
6853
|
-
globalThis.addCleanupFunction(async () => {
|
|
6854
|
-
logger2.info("Cleaning up node processes...");
|
|
6855
|
-
try {
|
|
6856
|
-
for (const name of ["litd", "tor", "rgb"]) {
|
|
6857
|
-
try {
|
|
6858
|
-
await stopService(name);
|
|
6859
|
-
logger2.info(`${name} process stopped`);
|
|
6860
|
-
} catch (err) {
|
|
6861
|
-
logger2.warn(`Failed to stop ${name}: ${err.message}`);
|
|
6862
|
-
}
|
|
6863
|
-
}
|
|
6864
|
-
} catch (error) {
|
|
6865
|
-
logger2.error(`Error during node cleanup: ${error.message}`);
|
|
6866
|
-
}
|
|
6867
|
-
});
|
|
6868
|
-
}
|
|
6869
6923
|
module2.exports = {
|
|
6870
6924
|
// Terminal (Litd + Tor) management
|
|
6871
6925
|
startTerminal,
|
|
@@ -7127,7 +7181,7 @@ var require_package = __commonJS({
|
|
|
7127
7181
|
"package.json"(exports2, module2) {
|
|
7128
7182
|
module2.exports = {
|
|
7129
7183
|
name: "lnlink-server",
|
|
7130
|
-
version: "1.1.
|
|
7184
|
+
version: "1.1.4",
|
|
7131
7185
|
private: false,
|
|
7132
7186
|
main: "dist/index.js",
|
|
7133
7187
|
files: [
|
|
@@ -7137,13 +7191,13 @@ var require_package = __commonJS({
|
|
|
7137
7191
|
],
|
|
7138
7192
|
scripts: {
|
|
7139
7193
|
build: "node build.js && node build.js --mode development --external all --entry electron",
|
|
7140
|
-
"start:bin": "
|
|
7194
|
+
"start:bin": "node scripts/start-bin.js",
|
|
7141
7195
|
"start:docker:dev": "dotenv -e .env.dev -- docker compose -f ./docker-compose.dev.yml up --build",
|
|
7142
7196
|
"start:dev": 'dotenv -e .env.dev -- sh -c "prisma generate && (prisma migrate dev --name auto_update || prisma db push) && clinic heapprof -- node ./app.js"',
|
|
7143
7197
|
"start:regtest": "docker compose --env-file ./.env.regtest -f ./docker-compose-lnlink.yml up --build",
|
|
7144
7198
|
"start:testnet": "docker compose --env-file ./.env.testnet -f ./docker-compose-lnlink.yml up --build",
|
|
7145
7199
|
"start:mainnet": "docker compose --env-file ./.env.mainnet -f ./docker-compose-lnlink.yml up --build",
|
|
7146
|
-
"start:bin:dist": "
|
|
7200
|
+
"start:bin:dist": "node scripts/start-bin.js --dist",
|
|
7147
7201
|
lint: "eslint .",
|
|
7148
7202
|
"lint:fix": "eslint . --fix",
|
|
7149
7203
|
"lint:staged": "lint-staged",
|
|
@@ -7462,13 +7516,9 @@ var require_lndService = __commonJS({
|
|
|
7462
7516
|
LINK_NODE_ADDR,
|
|
7463
7517
|
LINK_LND_PEER_LISTEN_PORT
|
|
7464
7518
|
} = getConfig2();
|
|
7465
|
-
const currentWalletState = await getWalletState(true);
|
|
7466
|
-
const terminalStatus = await getTerminalStatus();
|
|
7467
|
-
const linkStatusObj = {};
|
|
7468
|
-
terminalStatus.forEach((item) => {
|
|
7469
|
-
linkStatusObj[item.service_name] = item.status;
|
|
7470
|
-
});
|
|
7471
7519
|
const logger2 = new Logger("lnd");
|
|
7520
|
+
const version = packageJSON.version;
|
|
7521
|
+
const currentWalletState = await getWalletState(true);
|
|
7472
7522
|
const timeoutMs = 15e3;
|
|
7473
7523
|
const fallbackCombineInfo = linkCache.get("combineNodeInfo") || {};
|
|
7474
7524
|
let timeoutId;
|
|
@@ -7481,16 +7531,34 @@ var require_lndService = __commonJS({
|
|
|
7481
7531
|
});
|
|
7482
7532
|
}, timeoutMs);
|
|
7483
7533
|
});
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7534
|
+
let results;
|
|
7535
|
+
try {
|
|
7536
|
+
results = await Promise.allSettled([
|
|
7537
|
+
Promise.race([
|
|
7538
|
+
combineNodeInfoAsync(currentWalletState).then((data2) => ({ fromCache: false, data: data2 })),
|
|
7539
|
+
timeoutPromise
|
|
7540
|
+
]),
|
|
7541
|
+
getTerminalStatus(),
|
|
7542
|
+
checkTprEnabled(),
|
|
7543
|
+
getLnlinkUser({ account_type: ACCOUNT_TYPE.READ_ONLY })
|
|
7544
|
+
]);
|
|
7545
|
+
} finally {
|
|
7546
|
+
clearTimeout(timeoutId);
|
|
7547
|
+
}
|
|
7548
|
+
const [combineSettled, terminalSettled, tprSettled, userSettled] = results;
|
|
7549
|
+
const combineInfo = combineSettled.value?.data || {};
|
|
7550
|
+
const terminalStatus = terminalSettled.status === "fulfilled" ? terminalSettled.value : [];
|
|
7551
|
+
const taprootAssetsEnabled = tprSettled.status === "fulfilled" ? tprSettled.value : false;
|
|
7552
|
+
const readOnlyAccount = userSettled.status === "fulfilled" ? userSettled.value : null;
|
|
7553
|
+
if (terminalSettled.status === "rejected") {
|
|
7554
|
+
logger2.warn(`getNodeInfo: getTerminalStatus failed: ${terminalSettled.reason?.message}`);
|
|
7555
|
+
}
|
|
7556
|
+
if (userSettled.status === "rejected") {
|
|
7557
|
+
logger2.warn(`getNodeInfo: getLnlinkUser failed: ${userSettled.reason?.message}`);
|
|
7558
|
+
}
|
|
7559
|
+
const linkStatusObj = {};
|
|
7560
|
+
terminalStatus.forEach((item) => {
|
|
7561
|
+
linkStatusObj[item.service_name] = item.status;
|
|
7494
7562
|
});
|
|
7495
7563
|
const uri = combineInfo?.uris?.[0];
|
|
7496
7564
|
const data = {
|
|
@@ -7722,6 +7790,9 @@ var require_lndService = __commonJS({
|
|
|
7722
7790
|
async function combineNodeInfoAsync(walletState) {
|
|
7723
7791
|
let retInfo = {};
|
|
7724
7792
|
const logger2 = new Logger("lnd");
|
|
7793
|
+
const CACHE_KEY = "combineNodeInfo";
|
|
7794
|
+
const CACHE_TTL_KEY = "combineNodeInfo_ts";
|
|
7795
|
+
const CACHE_TTL_MS = 5e3;
|
|
7725
7796
|
try {
|
|
7726
7797
|
const { isMacaroonDecrypted } = getCacheMacaroon();
|
|
7727
7798
|
let state = walletState;
|
|
@@ -7730,18 +7801,33 @@ var require_lndService = __commonJS({
|
|
|
7730
7801
|
state = WALLET_STATE_CODE.LOCKED;
|
|
7731
7802
|
}
|
|
7732
7803
|
}
|
|
7804
|
+
const cachedInfo = linkCache.get(CACHE_KEY);
|
|
7805
|
+
const cacheTimestamp = linkCache.get(CACHE_TTL_KEY);
|
|
7806
|
+
if (cachedInfo && cacheTimestamp && cachedInfo.state === state) {
|
|
7807
|
+
const age = Date.now() - cacheTimestamp;
|
|
7808
|
+
if (age < CACHE_TTL_MS) {
|
|
7809
|
+
logger2.debug(`combineNodeInfoAsync: returning cached result (age: ${age}ms)`);
|
|
7810
|
+
return cachedInfo;
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7733
7813
|
if (state >= WALLET_STATE_CODE.RPC_ACTIVE && isMacaroonDecrypted && state !== WALLET_STATE_CODE.WAITING_TO_START) {
|
|
7734
7814
|
const lightningService = getLightningService();
|
|
7735
|
-
const { settings } = await getMainLnlinkConfig();
|
|
7736
7815
|
const ret = await Promise.allSettled([
|
|
7816
|
+
getMainLnlinkConfig(),
|
|
7737
7817
|
lightningService.getInfo(),
|
|
7738
7818
|
lightningService.walletBalance(),
|
|
7739
7819
|
lightningService.listPeers({})
|
|
7740
7820
|
]);
|
|
7741
|
-
const [infoResult, balanceResult, peersResult] = ret;
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7821
|
+
const [configResult, infoResult, balanceResult, peersResult] = ret;
|
|
7822
|
+
let settings = null;
|
|
7823
|
+
if (configResult.status === "fulfilled") {
|
|
7824
|
+
settings = configResult.value?.settings;
|
|
7825
|
+
} else {
|
|
7826
|
+
logger2.warn(`combineNodeInfoAsync: getMainLnlinkConfig failed: ${configResult.reason?.message}`);
|
|
7827
|
+
}
|
|
7828
|
+
const nodeInfo = infoResult.status === "fulfilled" ? infoResult.value : null;
|
|
7829
|
+
const balance = balanceResult.status === "fulfilled" ? balanceResult.value : null;
|
|
7830
|
+
const retListpeers = peersResult.status === "fulfilled" ? peersResult.value : null;
|
|
7745
7831
|
const peers = retListpeers?.peers || [];
|
|
7746
7832
|
const mapPeers = peers.map((peer) => {
|
|
7747
7833
|
const isLnfiPeer = peer.pub_key === settings?.officialLndPeer;
|
|
@@ -7771,7 +7857,8 @@ var require_lndService = __commonJS({
|
|
|
7771
7857
|
...retInfo,
|
|
7772
7858
|
state
|
|
7773
7859
|
};
|
|
7774
|
-
linkCache.set(
|
|
7860
|
+
linkCache.set(CACHE_KEY, retInfo);
|
|
7861
|
+
linkCache.set(CACHE_TTL_KEY, Date.now());
|
|
7775
7862
|
return retInfo;
|
|
7776
7863
|
} catch (e) {
|
|
7777
7864
|
logger2.warn(`LND lndService combineNodeInfoAsync peer combineNodeInfo warn--->${e.message}`);
|
|
@@ -7931,6 +8018,10 @@ var require_lndService = __commonJS({
|
|
|
7931
8018
|
cipher_seed_mnemonic: seed
|
|
7932
8019
|
});
|
|
7933
8020
|
linkCache.set("tempPassword", password);
|
|
8021
|
+
try {
|
|
8022
|
+
await getWalletState(false);
|
|
8023
|
+
} catch (_refreshErr) {
|
|
8024
|
+
}
|
|
7934
8025
|
const cipherSeedMnemonic = linkCache.get("cipherSeedMnemonic");
|
|
7935
8026
|
const ret = {
|
|
7936
8027
|
message: "Init wallet success.",
|
|
@@ -8064,6 +8155,10 @@ var require_lndService = __commonJS({
|
|
|
8064
8155
|
});
|
|
8065
8156
|
setCacheMacaroon(decodeWalletPassword);
|
|
8066
8157
|
linkCache.set("tempPassword", wallet_password);
|
|
8158
|
+
try {
|
|
8159
|
+
await getWalletState(false);
|
|
8160
|
+
} catch (_refreshErr) {
|
|
8161
|
+
}
|
|
8067
8162
|
}
|
|
8068
8163
|
const ret = {
|
|
8069
8164
|
msg: "Unlock success."
|
|
@@ -8291,6 +8386,15 @@ var require_lndService = __commonJS({
|
|
|
8291
8386
|
}
|
|
8292
8387
|
logger2.info("Stopping litd before config reload (to free ports)...");
|
|
8293
8388
|
await stopTerminal({ lnlinkUser, waitForStopped: true });
|
|
8389
|
+
if (!enableTor && torRunning) {
|
|
8390
|
+
logger2.info("Stopping Tor service (was running standalone)...");
|
|
8391
|
+
try {
|
|
8392
|
+
await stopService("tor");
|
|
8393
|
+
logger2.info("Tor service stopped successfully");
|
|
8394
|
+
} catch (torError) {
|
|
8395
|
+
logger2.warn(`Failed to stop Tor service: ${torError.message}`);
|
|
8396
|
+
}
|
|
8397
|
+
}
|
|
8294
8398
|
logger2.info("Reloading config after services stopped...");
|
|
8295
8399
|
await reloadConfig();
|
|
8296
8400
|
logger2.info("Starting litd with new Tor configuration...");
|
|
@@ -11908,12 +12012,17 @@ var require_info = __commonJS({
|
|
|
11908
12012
|
LINK_RGB_LDK_PEER_LISTENING_PORT
|
|
11909
12013
|
} = getConfig2();
|
|
11910
12014
|
const logger2 = new Logger("rgb");
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
12015
|
+
const [statusResult, readOnlyAccountResult] = await Promise.allSettled([
|
|
12016
|
+
getRGBStatus(),
|
|
12017
|
+
getLnlinkUser({ account_type: ACCOUNT_TYPE.READ_ONLY })
|
|
12018
|
+
]);
|
|
12019
|
+
let statusEntries = {};
|
|
12020
|
+
if (statusResult.status === "fulfilled") {
|
|
12021
|
+
statusEntries = statusResult.value;
|
|
12022
|
+
} else {
|
|
12023
|
+
logger2.warn(`getCombinedNodeInfo - getRGBStatus failed: ${statusResult.reason?.message}`);
|
|
11916
12024
|
}
|
|
12025
|
+
const readOnlyAccount = readOnlyAccountResult.status === "fulfilled" ? readOnlyAccountResult.value : null;
|
|
11917
12026
|
const serviceRunning = statusEntries.status === ServiceStatus.RUNNING;
|
|
11918
12027
|
let nodeInfo = null;
|
|
11919
12028
|
let balance = {
|
|
@@ -11945,7 +12054,8 @@ var require_info = __commonJS({
|
|
|
11945
12054
|
] = await Promise.allSettled([
|
|
11946
12055
|
rgbClient.node.getNodeInfo(),
|
|
11947
12056
|
rgbClient.onchain.getBtcBalance({
|
|
11948
|
-
skip_sync:
|
|
12057
|
+
skip_sync: true
|
|
12058
|
+
// Skip sync for faster response
|
|
11949
12059
|
}),
|
|
11950
12060
|
rgbClient.lightning.listPeers({})
|
|
11951
12061
|
]);
|
|
@@ -11964,14 +12074,11 @@ var require_info = __commonJS({
|
|
|
11964
12074
|
} else {
|
|
11965
12075
|
logger2.warn(`getCombinedNodeInfo - listPeers failed: ${peersResult.reason?.message || peersResult.reason}`);
|
|
11966
12076
|
}
|
|
11967
|
-
rgbClient.rgb.refreshTransfers({ skip_sync:
|
|
12077
|
+
rgbClient.rgb.refreshTransfers({ skip_sync: true }).catch((error) => {
|
|
11968
12078
|
logger2.warn(`getCombinedNodeInfo - refreshTransfers failed: ${error.message}`);
|
|
11969
12079
|
});
|
|
11970
12080
|
}
|
|
11971
12081
|
}
|
|
11972
|
-
const readOnlyAccount = await getLnlinkUser({
|
|
11973
|
-
account_type: ACCOUNT_TYPE.READ_ONLY
|
|
11974
|
-
});
|
|
11975
12082
|
const data = {
|
|
11976
12083
|
pubkey: nodeInfo?.pubkey ?? null,
|
|
11977
12084
|
host: `${LINK_RGB_HOST}:${LINK_RGB_LDK_PEER_LISTENING_PORT}`,
|
|
@@ -19001,17 +19108,6 @@ var require_job = __commonJS({
|
|
|
19001
19108
|
logger2.info("Job system graceful shutdown completed");
|
|
19002
19109
|
}
|
|
19003
19110
|
__name(gracefulShutdown, "gracefulShutdown");
|
|
19004
|
-
process.on("SIGINT", gracefulShutdown);
|
|
19005
|
-
process.on("SIGTERM", gracefulShutdown);
|
|
19006
|
-
process.on("uncaughtException", (error) => {
|
|
19007
|
-
const logger2 = new Logger("job_uncaught");
|
|
19008
|
-
logger2.error(`Uncaught exception: ${error.message}`);
|
|
19009
|
-
gracefulShutdown();
|
|
19010
|
-
});
|
|
19011
|
-
process.on("unhandledRejection", (reason, promise) => {
|
|
19012
|
-
const logger2 = new Logger("job_unhandled");
|
|
19013
|
-
logger2.error(`Unhandled rejection at: ${promise}, reason: ${reason}`);
|
|
19014
|
-
});
|
|
19015
19111
|
module2.exports = {
|
|
19016
19112
|
initJobSystem,
|
|
19017
19113
|
startJobSystem,
|
|
@@ -19511,20 +19607,25 @@ var LnLink = class extends EventEmitter {
|
|
|
19511
19607
|
*/
|
|
19512
19608
|
async stop() {
|
|
19513
19609
|
try {
|
|
19514
|
-
|
|
19515
|
-
|
|
19516
|
-
|
|
19610
|
+
const { stopService, setShuttingDown } = require_processManager();
|
|
19611
|
+
setShuttingDown(true);
|
|
19612
|
+
console.info("Stopping LN-Link (jobs + rgb + litd + tor)...");
|
|
19613
|
+
await Promise.allSettled([
|
|
19614
|
+
// Job system shutdown (cron tasks, state monitoring)
|
|
19615
|
+
(async () => {
|
|
19616
|
+
const { gracefulShutdown: shutdownJobs } = require_job();
|
|
19617
|
+
await shutdownJobs();
|
|
19618
|
+
})().catch((err) => console.warn(`Job system shutdown failed: ${err.message}`)),
|
|
19619
|
+
// Stop all child processes in parallel
|
|
19620
|
+
...["rgb", "litd", "tor"].map(async (name) => {
|
|
19517
19621
|
try {
|
|
19518
|
-
console.info(`Stopping ${name} process...`);
|
|
19519
19622
|
await stopService(name);
|
|
19520
|
-
console.info(`${name}
|
|
19623
|
+
console.info(`${name} stopped`);
|
|
19521
19624
|
} catch (err) {
|
|
19522
19625
|
console.warn(`Failed to stop ${name}: ${err.message}`);
|
|
19523
19626
|
}
|
|
19524
|
-
}
|
|
19525
|
-
|
|
19526
|
-
console.warn(`Child process cleanup failed: ${err.message}`);
|
|
19527
|
-
}
|
|
19627
|
+
})
|
|
19628
|
+
]);
|
|
19528
19629
|
if (this.server) {
|
|
19529
19630
|
await new Promise((resolve) => {
|
|
19530
19631
|
this.server.close(() => {
|
|
@@ -19564,6 +19665,14 @@ var LnLink = class extends EventEmitter {
|
|
|
19564
19665
|
port: this.isRunning ? this.options.httpPort : null
|
|
19565
19666
|
};
|
|
19566
19667
|
}
|
|
19668
|
+
/**
|
|
19669
|
+
* Get PIDs of all managed child processes (litd, tor, rgb)
|
|
19670
|
+
* @returns {{ litd: number|null, tor: number|null, rgb: number|null }}
|
|
19671
|
+
*/
|
|
19672
|
+
getServicePids() {
|
|
19673
|
+
const { getServicePids } = require_processManager();
|
|
19674
|
+
return getServicePids();
|
|
19675
|
+
}
|
|
19567
19676
|
/**
|
|
19568
19677
|
* Get configuration
|
|
19569
19678
|
*/
|