From 9f877c276285a179264e4b08bf1c0937b5ffc515 Mon Sep 17 00:00:00 2001 From: ShahanaFarooqui Date: Mon, 6 Nov 2023 22:31:27 -0800 Subject: [PATCH] msat and alias fixes --- backend/controllers/cln/channels.js | 49 +++++++--------------- backend/controllers/cln/getInfo.js | 2 +- backend/controllers/cln/network.js | 29 ++++++------- backend/controllers/cln/peers.js | 11 +++-- backend/controllers/cln/webSocketClient.js | 6 +-- server/controllers/cln/channels.ts | 49 +++++++--------------- server/controllers/cln/getInfo.ts | 2 +- server/controllers/cln/network.ts | 29 ++++++------- server/controllers/cln/peers.ts | 11 +++-- server/controllers/cln/webSocketClient.ts | 6 +-- 10 files changed, 76 insertions(+), 118 deletions(-) diff --git a/backend/controllers/cln/channels.js b/backend/controllers/cln/channels.js index efff40e3..68c7d3e4 100644 --- a/backend/controllers/cln/channels.js +++ b/backend/controllers/cln/channels.js @@ -12,40 +12,19 @@ export const listPeerChannels = (req, res, next) => { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; - return request.post(options).then((body) => { - body.channels.forEach((channel) => { - const local = channel.to_us_msat || 0; - const remote = (channel.total_msat - local) || 0; - const total = channel.total_msat || 0; - channel = { - peer_id: channel.peer_id, - peer_connected: channel.peer_connected, - opener: channel.opener, - owner: channel.owner, - short_channel_id: channel.short_channel_id, - channel_id: channel.channel_id, - funding_txid: channel.funding_txid, - private: channel.private, - to_us_msat: channel.to_us_msat, - total_msat: channel.total_msat, - their_reserve_msat: channel.their_reserve_msat, - our_reserve_msat: channel.our_reserve_msat, - spendable_msat: channel.spendable_msat, - receivable_msat: channel.receivable_msat, - funding: channel.funding, - state: channel.state, - fee_base_msat: channel.fee_base_msat, - fee_proportional_millionths: channel.fee_proportional_millionths, - dust_limit_msat: channel.dust_limit_msat, - htlcs: channel.htlcs, - features: channel.features, - alias: getAlias(req.session.selectedNode, channel.peer_id).then((callRes) => callRes), - to_them_msat: remote, - balancedness: (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3) - }; - }); + request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); - return res.status(200).json(body.channels); + return Promise.all(body.channels?.map((channel) => { + const local = (channel.to_us_msat && typeof channel.to_us_msat === 'string' && channel.to_us_msat.includes('msat')) ? +channel.to_us_msat.replace('msat', '') : channel.to_us_msat ? channel.to_us_msat : 0; + const total = (channel.total_msat && typeof channel.total_msat === 'string' && channel.total_msat.includes('msat')) ? +channel.total_msat.replace('msat', '') : channel.total_msat ? channel.total_msat : 0; + const remote = total - local; + channel.to_them_msat = remote; + channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3); + return getAlias(req.session.selectedNode, channel, 'peer_id'); + })).then((values) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List With Aliases Received', data: body.channels }); + return res.status(200).json(body.channels || []); + }); }).catch((errRes) => { const err = common.handleError(errRes, 'Channels', 'List Peer Channels Error', req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); @@ -130,8 +109,8 @@ export const funderUpdatePolicy = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Funder Policy Received', data: body }); - body.channel_fee_max_base_msat = (body.channel_fee_max_base_msat && typeof body.channel_fee_max_base_msat === 'string' && body.channel_fee_max_base_msat.includes('msat')) ? +body.channel_fee_max_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat; - body.lease_fee_base_msat = (body.lease_fee_base_msat && typeof body.lease_fee_base_msat === 'string' && body.lease_fee_base_msat.includes('msat')) ? +body.lease_fee_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat; + body.channel_fee_max_base_msat = (body.channel_fee_max_base_msat && typeof body.channel_fee_max_base_msat === 'string' && body.channel_fee_max_base_msat.includes('msat')) ? +body.channel_fee_max_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat ? body.channel_fee_max_base_msat : 0; + body.lease_fee_base_msat = (body.lease_fee_base_msat && typeof body.lease_fee_base_msat === 'string' && body.lease_fee_base_msat.includes('msat')) ? +body.lease_fee_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat ? body.channel_fee_max_base_msat : 0; res.status(200).json(body); }).catch((errRes) => { const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode); diff --git a/backend/controllers/cln/getInfo.js b/backend/controllers/cln/getInfo.js index cfc162c3..9ceaa069 100644 --- a/backend/controllers/cln/getInfo.js +++ b/backend/controllers/cln/getInfo.js @@ -48,7 +48,7 @@ export const getInfo = (req, res, next) => { body.uris.push(body.id + '@' + addr.address + ':' + addr.port); }); } - body.fees_collected_msat = (body.fees_collected_msat && body.fees_collected_msat.includes('msat')) ? body.fees_collected_msat.substring(0, body.fees_collected_msat.length - 4) : 0; + body.fees_collected_msat = (body.fees_collected_msat && typeof body.fees_collected_msat === 'string' && body.fees_collected_msat.includes('msat')) ? body.fees_collected_msat?.replace('msat', '') : body.fees_collected_msat ? body.fees_collected_msat : 0; req.session.selectedNode.ln_version = body.version || ''; req.session.selectedNode.api_version = body.api_version || ''; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); diff --git a/backend/controllers/cln/network.js b/backend/controllers/cln/network.js index a27fb577..39e9cfd7 100644 --- a/backend/controllers/cln/network.js +++ b/backend/controllers/cln/network.js @@ -67,9 +67,9 @@ export const listNodes = (req, res, next) => { response = body.nodes.filter((node) => { if (node.option_will_fund) { node.option_will_fund.lease_fee_base_msat = (node.option_will_fund.lease_fee_base_msat && typeof node.option_will_fund.lease_fee_base_msat === 'string' && - node.option_will_fund.lease_fee_base_msat.includes('msat')) ? node.option_will_fund.lease_fee_base_msat?.replace('msat', '') : node.option_will_fund.lease_fee_base_msat; + node.option_will_fund.lease_fee_base_msat.includes('msat')) ? node.option_will_fund.lease_fee_base_msat?.replace('msat', '') : node.option_will_fund.lease_fee_base_msat ? node.option_will_fund.lease_fee_base_msat : 0; node.option_will_fund.channel_fee_max_base_msat = (node.option_will_fund.channel_fee_max_base_msat && typeof node.option_will_fund.channel_fee_max_base_msat === 'string' && - node.option_will_fund.channel_fee_max_base_msat.includes('msat')) ? node.option_will_fund.channel_fee_max_base_msat?.replace('msat', '') : node.option_will_fund.channel_fee_max_base_msat; + node.option_will_fund.channel_fee_max_base_msat.includes('msat')) ? node.option_will_fund.channel_fee_max_base_msat?.replace('msat', '') : node.option_will_fund.channel_fee_max_base_msat ? node.option_will_fund.channel_fee_max_base_msat : 0; } return node; }); @@ -80,20 +80,21 @@ export const listNodes = (req, res, next) => { return res.status(err.statusCode).json({ message: err.message, error: err.error }); }); }; -export const getAlias = (selNode, id) => { +export const getAlias = (selNode, peer, id) => { options.url = selNode.ln_server_url + '/v1/listnodes'; - if (!id) { + if (!peer[id]) { logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); - return Promise.resolve(''); + peer.alias = ''; + return peer; } - options.body = { id }; - return new Promise((resolve, reject) => { - request.post(options).then((body) => { - logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Network', msg: 'Peer Alias Finished', data: body }); - resolve(body.nodes[0] ? body.nodes[0].alias : id.substring(0, 20)); - }).catch((errRes) => { - common.handleError(errRes, 'Network', 'Peer Alias Error', selNode); - resolve(id.substring(0, 20)); - }); + options.body = { id: peer[id] }; + return request.post(options).then((body) => { + logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Network', msg: 'Peer Alias Finished', data: body }); + peer.alias = body.nodes[0] && body.nodes[0].alias ? body.nodes[0].alias : peer[id].substring(0, 20); + return peer; + }).catch((errRes) => { + common.handleError(errRes, 'Network', 'Peer Alias Error', selNode); + peer.alias = peer[id].substring(0, 20); + return peer; }); }; diff --git a/backend/controllers/cln/peers.js b/backend/controllers/cln/peers.js index d667df89..70a01a33 100644 --- a/backend/controllers/cln/peers.js +++ b/backend/controllers/cln/peers.js @@ -13,12 +13,11 @@ export const getPeers = (req, res, next) => { } options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; request.post(options).then((body) => { - Promise.all(body.peers.map((peer) => getAlias(req.session.selectedNode, peer.id))).then((peerList) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers with Alias Received', data: body }); - res.status(200).json(peerList || []); - }).catch((errRes) => { - const err = common.handleError(errRes, 'Peers', 'List Peers Alias Error', req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.message, error: err.error }); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); + const peers = !body.peers ? [] : body.peers; + return Promise.all(peers?.map((peer) => getAlias(req.session.selectedNode, peer, 'id'))).then((values) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Sorted Peers List Received', data: body.peers }); + res.status(200).json(body.peers || []); }); }).catch((errRes) => { const err = common.handleError(errRes, 'Peers', 'List Peers Error', req.session.selectedNode); diff --git a/backend/controllers/cln/webSocketClient.js b/backend/controllers/cln/webSocketClient.js index 18f818ba..51135d5c 100644 --- a/backend/controllers/cln/webSocketClient.js +++ b/backend/controllers/cln/webSocketClient.js @@ -10,7 +10,7 @@ export class CLWebSocketClient { this.webSocketClients = []; this.reconnectTimeOut = null; this.waitTime = 0.5; - this.reconnet = (clWsClt) => { + this.reconnect = (clWsClt) => { if (this.reconnectTimeOut) { return; } @@ -69,7 +69,7 @@ export class CLWebSocketClient { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); clWsClt.webSocketClient.close(); if (clWsClt.reConnect) { - this.reconnet(clWsClt); + this.reconnect(clWsClt); } } }); @@ -83,7 +83,7 @@ export class CLWebSocketClient { this.wsServer.sendErrorToAllLNClients(errStr, clWsClt.selectedNode); clWsClt.webSocketClient.close(); if (clWsClt.reConnect) { - this.reconnet(clWsClt); + this.reconnect(clWsClt); } }); }; diff --git a/server/controllers/cln/channels.ts b/server/controllers/cln/channels.ts index a2739ec8..094c3f32 100644 --- a/server/controllers/cln/channels.ts +++ b/server/controllers/cln/channels.ts @@ -12,40 +12,19 @@ export const listPeerChannels = (req, res, next) => { options = common.getOptions(req); if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; - return request.post(options).then((body) => { - body.channels.forEach((channel) => { - const local = channel.to_us_msat || 0; - const remote = (channel.total_msat - local) || 0; - const total = channel.total_msat || 0; - channel = { - peer_id: channel.peer_id, - peer_connected: channel.peer_connected, - opener: channel.opener, - owner: channel.owner, - short_channel_id: channel.short_channel_id, - channel_id: channel.channel_id, - funding_txid: channel.funding_txid, - private: channel.private, - to_us_msat: channel.to_us_msat, - total_msat: channel.total_msat, - their_reserve_msat: channel.their_reserve_msat, - our_reserve_msat: channel.our_reserve_msat, - spendable_msat: channel.spendable_msat, - receivable_msat: channel.receivable_msat, - funding: channel.funding, - state: channel.state, - fee_base_msat: channel.fee_base_msat, - fee_proportional_millionths: channel.fee_proportional_millionths, - dust_limit_msat: channel.dust_limit_msat, - htlcs: channel.htlcs, - features: channel.features, - alias: getAlias(req.session.selectedNode, channel.peer_id).then((callRes: string) => callRes), - to_them_msat: remote, - balancedness: (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3) - }; - }); + request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); - return res.status(200).json(body.channels); + return Promise.all(body.channels?.map((channel) => { + const local = (channel.to_us_msat && typeof channel.to_us_msat === 'string' && channel.to_us_msat.includes('msat')) ? +channel.to_us_msat.replace('msat', '') : channel.to_us_msat ? channel.to_us_msat : 0; + const total = (channel.total_msat && typeof channel.total_msat === 'string' && channel.total_msat.includes('msat')) ? +channel.total_msat.replace('msat', '') : channel.total_msat ? channel.total_msat : 0; + const remote = total - local; + channel.to_them_msat = remote; + channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3); + return getAlias(req.session.selectedNode, channel, 'peer_id'); + })).then((values) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List With Aliases Received', data: body.channels }); + return res.status(200).json(body.channels || []); + }); }).catch((errRes) => { const err = common.handleError(errRes, 'Channels', 'List Peer Channels Error', req.session.selectedNode); return res.status(err.statusCode).json({ message: err.message, error: err.error }); @@ -125,8 +104,8 @@ export const funderUpdatePolicy = (req, res, next) => { logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); request.post(options).then((body) => { logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Funder Policy Received', data: body }); - body.channel_fee_max_base_msat = (body.channel_fee_max_base_msat && typeof body.channel_fee_max_base_msat === 'string' && body.channel_fee_max_base_msat.includes('msat')) ? +body.channel_fee_max_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat; - body.lease_fee_base_msat = (body.lease_fee_base_msat && typeof body.lease_fee_base_msat === 'string' && body.lease_fee_base_msat.includes('msat')) ? +body.lease_fee_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat; + body.channel_fee_max_base_msat = (body.channel_fee_max_base_msat && typeof body.channel_fee_max_base_msat === 'string' && body.channel_fee_max_base_msat.includes('msat')) ? +body.channel_fee_max_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat ? body.channel_fee_max_base_msat : 0; + body.lease_fee_base_msat = (body.lease_fee_base_msat && typeof body.lease_fee_base_msat === 'string' && body.lease_fee_base_msat.includes('msat')) ? +body.lease_fee_base_msat?.replace('msat', '') : body.channel_fee_max_base_msat ? body.channel_fee_max_base_msat : 0; res.status(200).json(body); }).catch((errRes) => { const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode); diff --git a/server/controllers/cln/getInfo.ts b/server/controllers/cln/getInfo.ts index f8383d98..9028273c 100644 --- a/server/controllers/cln/getInfo.ts +++ b/server/controllers/cln/getInfo.ts @@ -45,7 +45,7 @@ export const getInfo = (req, res, next) => { body.uris.push(body.id + '@' + addr.address + ':' + addr.port); }); } - body.fees_collected_msat = (body.fees_collected_msat && body.fees_collected_msat.includes('msat')) ? body.fees_collected_msat.substring(0, body.fees_collected_msat.length - 4) : 0; + body.fees_collected_msat = (body.fees_collected_msat && typeof body.fees_collected_msat === 'string' && body.fees_collected_msat.includes('msat')) ? body.fees_collected_msat?.replace('msat', '') : body.fees_collected_msat ? body.fees_collected_msat : 0; req.session.selectedNode.ln_version = body.version || ''; req.session.selectedNode.api_version = body.api_version || ''; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); diff --git a/server/controllers/cln/network.ts b/server/controllers/cln/network.ts index 74a331cf..c23023c4 100644 --- a/server/controllers/cln/network.ts +++ b/server/controllers/cln/network.ts @@ -65,9 +65,9 @@ export const listNodes = (req, res, next) => { response = body.nodes.filter((node) => { if (node.option_will_fund) { node.option_will_fund.lease_fee_base_msat = (node.option_will_fund.lease_fee_base_msat && typeof node.option_will_fund.lease_fee_base_msat === 'string' && - node.option_will_fund.lease_fee_base_msat.includes('msat')) ? node.option_will_fund.lease_fee_base_msat?.replace('msat', '') : node.option_will_fund.lease_fee_base_msat; + node.option_will_fund.lease_fee_base_msat.includes('msat')) ? node.option_will_fund.lease_fee_base_msat?.replace('msat', '') : node.option_will_fund.lease_fee_base_msat ? node.option_will_fund.lease_fee_base_msat : 0; node.option_will_fund.channel_fee_max_base_msat = (node.option_will_fund.channel_fee_max_base_msat && typeof node.option_will_fund.channel_fee_max_base_msat === 'string' && - node.option_will_fund.channel_fee_max_base_msat.includes('msat')) ? node.option_will_fund.channel_fee_max_base_msat?.replace('msat', '') : node.option_will_fund.channel_fee_max_base_msat; + node.option_will_fund.channel_fee_max_base_msat.includes('msat')) ? node.option_will_fund.channel_fee_max_base_msat?.replace('msat', '') : node.option_will_fund.channel_fee_max_base_msat ? node.option_will_fund.channel_fee_max_base_msat : 0; } return node; }); @@ -79,20 +79,21 @@ export const listNodes = (req, res, next) => { }); }; -export const getAlias = (selNode: CommonSelectedNode, id: string) => { +export const getAlias = (selNode: CommonSelectedNode, peer: any, id: string) => { options.url = selNode.ln_server_url + '/v1/listnodes'; - if (!id) { + if (!peer[id]) { logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); - return Promise.resolve(''); + peer.alias = ''; + return peer; } - options.body = { id }; - return new Promise((resolve, reject) => { - request.post(options).then((body) => { - logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Network', msg: 'Peer Alias Finished', data: body }); - resolve(body.nodes[0] ? body.nodes[0].alias : id.substring(0, 20)); - }).catch((errRes) => { - common.handleError(errRes, 'Network', 'Peer Alias Error', selNode); - resolve(id.substring(0, 20)); - }); + options.body = { id : peer[id] }; + return request.post(options).then((body) => { + logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Network', msg: 'Peer Alias Finished', data: body }); + peer.alias = body.nodes[0] && body.nodes[0].alias ? body.nodes[0].alias : peer[id].substring(0, 20); + return peer; + }).catch((errRes) => { + common.handleError(errRes, 'Network', 'Peer Alias Error', selNode); + peer.alias = peer[id].substring(0, 20); + return peer; }); }; diff --git a/server/controllers/cln/peers.ts b/server/controllers/cln/peers.ts index fe3ddc17..24e19a02 100644 --- a/server/controllers/cln/peers.ts +++ b/server/controllers/cln/peers.ts @@ -13,12 +13,11 @@ export const getPeers = (req, res, next) => { if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; request.post(options).then((body) => { - Promise.all(body.peers.map((peer) => getAlias(req.session.selectedNode, peer.id))).then((peerList) => { - logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers with Alias Received', data: body }); - res.status(200).json(peerList || []); - }).catch((errRes) => { - const err = common.handleError(errRes, 'Peers', 'List Peers Alias Error', req.session.selectedNode); - return res.status(err.statusCode).json({ message: err.message, error: err.error }); + logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); + const peers = !body.peers ? [] : body.peers; + return Promise.all(peers?.map((peer) => getAlias(req.session.selectedNode, peer, 'id'))).then((values) => { + logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Sorted Peers List Received', data: body.peers }); + res.status(200).json(body.peers || []); }); }).catch((errRes) => { const err = common.handleError(errRes, 'Peers', 'List Peers Error', req.session.selectedNode); diff --git a/server/controllers/cln/webSocketClient.ts b/server/controllers/cln/webSocketClient.ts index 31f42224..ad41fe1d 100644 --- a/server/controllers/cln/webSocketClient.ts +++ b/server/controllers/cln/webSocketClient.ts @@ -22,7 +22,7 @@ export class CLWebSocketClient { }); } - public reconnet = (clWsClt) => { + public reconnect = (clWsClt) => { if (this.reconnectTimeOut) { return; } this.waitTime = (this.waitTime >= 64) ? 64 : (this.waitTime * 2); this.reconnectTimeOut = setTimeout(() => { @@ -79,7 +79,7 @@ export class CLWebSocketClient { if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') { this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); clWsClt.webSocketClient.close(); - if (clWsClt.reConnect) { this.reconnet(clWsClt); } + if (clWsClt.reConnect) { this.reconnect(clWsClt); } } }); @@ -93,7 +93,7 @@ export class CLWebSocketClient { const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }')); this.wsServer.sendErrorToAllLNClients(errStr, clWsClt.selectedNode); clWsClt.webSocketClient.close(); - if (clWsClt.reConnect) { this.reconnet(clWsClt); } + if (clWsClt.reConnect) { this.reconnect(clWsClt); } }); };