CLN Forwarding history filter and lint fixes

CLN Forwarding history filter and lint fixes
pull/1099/head
ShahanaFarooqui 2 years ago
parent 6f13a03ec8
commit 86fd2a7b29

@ -14,7 +14,7 @@
"env": { "env": {
"NODE_ENV": "development" "NODE_ENV": "development"
}, },
"program": "${workspaceFolder}\\rtl.js" "program": "${workspaceFolder}/rtl.js"
} }
] ]
} }

@ -12,7 +12,7 @@ export const listChannels = (req, res, next) => {
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels'; options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
request(options).then((body) => { request(options).then((body) => {
body.map((channel) => { body === null || body === void 0 ? void 0 : body.map((channel) => {
if (!channel.alias || channel.alias === '') { if (!channel.alias || channel.alias === '') {
channel.alias = channel.id.substring(0, 20); channel.alias = channel.id.substring(0, 20);
} }
@ -129,9 +129,10 @@ export const funderUpdatePolicy = (req, res, next) => {
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
var _a, _b;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Funder Policy Received', data: 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.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')) ? +((_a = body.channel_fee_max_base_msat) === null || _a === void 0 ? void 0 : _a.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.lease_fee_base_msat = (body.lease_fee_base_msat && typeof body.lease_fee_base_msat === 'string' && body.lease_fee_base_msat.includes('msat')) ? +((_b = body.lease_fee_base_msat) === null || _b === void 0 ? void 0 : _b.replace('msat', '')) : body.channel_fee_max_base_msat;
res.status(200).json(body); res.status(200).json(body);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode); const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode);

@ -76,9 +76,10 @@ export const listNodes = (req, res, next) => {
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes Finished', data: body });
body.forEach((node) => { body.forEach((node) => {
var _a, _b;
if (node.option_will_fund) { 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 = (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')) ? (_a = node.option_will_fund.lease_fee_base_msat) === null || _a === void 0 ? void 0 : _a.replace('msat', '') : node.option_will_fund.lease_fee_base_msat;
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 = (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')) ? (_b = node.option_will_fund.channel_fee_max_base_msat) === null || _b === void 0 ? void 0 : _b.replace('msat', '') : node.option_will_fund.channel_fee_max_base_msat;
} }
return node; return node;
}); });

@ -35,9 +35,10 @@ function summaryReducer(accumulator, mpp) {
return accumulator; return accumulator;
} }
function groupBy(payments) { function groupBy(payments) {
const paymentsInGroups = payments.reduce(paymentReducer, {}); var _a;
const paymentsGrpArray = Object.keys(paymentsInGroups).map((key) => ((paymentsInGroups[key].length && paymentsInGroups[key].length > 1) ? common.sortDescByKey(paymentsInGroups[key], 'partid') : paymentsInGroups[key])); const paymentsInGroups = payments === null || payments === void 0 ? void 0 : payments.reduce(paymentReducer, {});
return paymentsGrpArray.reduce((acc, curr) => { const paymentsGrpArray = (_a = Object.keys(paymentsInGroups)) === null || _a === void 0 ? void 0 : _a.map((key) => ((paymentsInGroups[key].length && paymentsInGroups[key].length > 1) ? common.sortDescByKey(paymentsInGroups[key], 'partid') : paymentsInGroups[key]));
return paymentsGrpArray === null || paymentsGrpArray === void 0 ? void 0 : paymentsGrpArray.reduce((acc, curr) => {
let temp = {}; let temp = {};
if (curr.length && curr.length === 1) { if (curr.length && curr.length === 1) {
temp = JSON.parse(JSON.stringify(curr[0])); temp = JSON.parse(JSON.stringify(curr[0]));
@ -47,7 +48,7 @@ function groupBy(payments) {
delete temp.partid; delete temp.partid;
} }
else { else {
const paySummary = curr.reduce(summaryReducer, { msatoshi: 0, msatoshi_sent: 0, status: (curr[0] && curr[0].status) ? curr[0].status : 'failed' }); const paySummary = curr === null || curr === void 0 ? void 0 : curr.reduce(summaryReducer, { msatoshi: 0, msatoshi_sent: 0, status: (curr[0] && curr[0].status) ? curr[0].status : 'failed' });
temp = { temp = {
is_group: true, is_expanded: false, total_parts: (curr.length ? curr.length : 0), status: paySummary.status, payment_hash: curr[0].payment_hash, is_group: true, is_expanded: false, total_parts: (curr.length ? curr.length : 0), status: paySummary.status, payment_hash: curr[0].payment_hash,
destination: curr[0].destination, msatoshi: paySummary.msatoshi, msatoshi_sent: paySummary.msatoshi_sent, created_at: curr[0].created_at, destination: curr[0].destination, msatoshi: paySummary.msatoshi, msatoshi_sent: paySummary.msatoshi_sent, created_at: curr[0].created_at,

@ -19,7 +19,7 @@ export const decodePayments = (req, res, next) => {
} }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr === null || paymentsArr === void 0 ? void 0 : paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -47,8 +47,9 @@ export class CLWebSocketClient {
} }
}; };
this.connectWithClient = (clWsClt) => { this.connectWithClient = (clWsClt) => {
var _a;
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' }); this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
const WS_LINK = (clWsClt.selectedNode.ln_server_url).replace(/^http/, 'ws') + '/v1/ws'; const WS_LINK = ((_a = (clWsClt.selectedNode.ln_server_url)) === null || _a === void 0 ? void 0 : _a.replace(/^http/, 'ws')) + '/v1/ws';
const mcrnHexEncoded = Buffer.from(fs.readFileSync(join(clWsClt.selectedNode.macaroon_path, 'access.macaroon'))).toString('hex'); const mcrnHexEncoded = Buffer.from(fs.readFileSync(join(clWsClt.selectedNode.macaroon_path, 'access.macaroon'))).toString('hex');
clWsClt.webSocketClient = new WebSocket(WS_LINK, [mcrnHexEncoded, 'hex'], { rejectUnauthorized: false }); clWsClt.webSocketClient = new WebSocket(WS_LINK, [mcrnHexEncoded, 'hex'], { rejectUnauthorized: false });
clWsClt.webSocketClient.onopen = () => { clWsClt.webSocketClient.onopen = () => {

@ -32,7 +32,7 @@ export const simplifyAllChannels = (selNode, channels) => {
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Filtered Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Filtered Nodes Received', data: nodes });
let foundPeer = null; let foundPeer = null;
simplifiedChannels.map((channel) => { simplifiedChannels === null || simplifiedChannels === void 0 ? void 0 : simplifiedChannels.map((channel) => {
foundPeer = nodes.find((channelWithAlias) => channel.nodeId === channelWithAlias.nodeId); foundPeer = nodes.find((channelWithAlias) => channel.nodeId === channelWithAlias.nodeId);
channel.alias = foundPeer ? foundPeer.alias : channel.nodeId.substring(0, 20); channel.alias = foundPeer ? foundPeer.alias : channel.nodeId.substring(0, 20);
return channel; return channel;

@ -70,7 +70,7 @@ export const listInvoices = (req, res, next) => {
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
return Promise.all(invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). return Promise.all(invoices === null || invoices === void 0 ? void 0 : invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
then((values) => { then((values) => {
body = common.sortDescByKey(invoices, 'expiresAt'); body = common.sortDescByKey(invoices, 'expiresAt');
return res.status(200).json(invoices); return res.status(200).json(invoices);
@ -84,7 +84,7 @@ export const listInvoices = (req, res, next) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
if (invoices && invoices.length > 0) { if (invoices && invoices.length > 0) {
return Promise.all(invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). return Promise.all(invoices === null || invoices === void 0 ? void 0 : invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
then((values) => { then((values) => {
body = common.sortDescByKey(invoices, 'expiresAt'); body = common.sortDescByKey(invoices, 'expiresAt');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });

@ -22,7 +22,7 @@ export const getSentInfoFromPaymentRequest = (selNode, payment) => {
}; };
export const getQueryNodes = (selNode, nodeIds) => { export const getQueryNodes = (selNode, nodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.ln_server_url + '/nodes';
options.form = { nodeIds: nodeIds.reduce((acc, curr) => acc + ',' + curr) }; options.form = { nodeIds: nodeIds === null || nodeIds === void 0 ? void 0 : nodeIds.reduce((acc, curr) => acc + ',' + curr) };
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes });
return nodes; return nodes;
@ -77,14 +77,16 @@ export const queryPaymentRoute = (req, res, next) => {
}; };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Received', data: body });
if (body && body.routes && body.routes.length) { if (body && body.routes && body.routes.length) {
let allRoutesNodeIds = []; let allRoutesNodeIds = [];
allRoutesNodeIds = body.routes.reduce((accRoutes, currRoute) => [...new Set([...accRoutes, ...currRoute.nodeIds])], []); allRoutesNodeIds = (_a = body.routes) === null || _a === void 0 ? void 0 : _a.reduce((accRoutes, currRoute) => [...new Set([...accRoutes, ...currRoute.nodeIds])], []);
return getQueryNodes(req.session.selectedNode, allRoutesNodeIds).then((nodesWithAlias) => { return getQueryNodes(req.session.selectedNode, allRoutesNodeIds).then((nodesWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.routes.forEach((route, i) => { body.routes.forEach((route, i) => {
route.nodeIds.map((node, j) => { var _a;
(_a = route.nodeIds) === null || _a === void 0 ? void 0 : _a.map((node, j) => {
foundPeer = nodesWithAlias.find((nodeWithAlias) => node === nodeWithAlias.nodeId); foundPeer = nodesWithAlias.find((nodeWithAlias) => node === nodeWithAlias.nodeId);
body.routes[i].nodeIds[j] = { nodeId: node, alias: foundPeer ? foundPeer.alias : '' }; body.routes[i].nodeIds[j] = { nodeId: node, alias: foundPeer ? foundPeer.alias : '' };
return node; return node;
@ -111,7 +113,7 @@ export const getSentPaymentsInformation = (req, res, next) => {
} }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr === null || paymentsArr === void 0 ? void 0 : paymentsArr.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values });
return res.status(200).json(values); return res.status(200).json(values);

@ -32,7 +32,7 @@ export const getPeers = (req, res, next) => {
peersNodeIds = peersNodeIds.substring(1); peersNodeIds = peersNodeIds.substring(1);
return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => { return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.map((peer) => { body === null || body === void 0 ? void 0 : body.map((peer) => {
foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId); foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId);
peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20); peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20);
return peer; return peer;
@ -85,7 +85,7 @@ export const connectPeer = (req, res, next) => {
peersNodeIds = peersNodeIds.substring(1); peersNodeIds = peersNodeIds.substring(1);
return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => { return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.map((peer) => { body === null || body === void 0 ? void 0 : body.map((peer) => {
foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId); foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId);
peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20); peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20);
return peer; return peer;

@ -45,8 +45,9 @@ export class ECLWebSocketClient {
} }
}; };
this.connectWithClient = (eclWsClt) => { this.connectWithClient = (eclWsClt) => {
var _a;
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' });
const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url).replace(/^http/, 'ws'); const UpdatedLNServerURL = (_a = (eclWsClt.selectedNode.ln_server_url)) === null || _a === void 0 ? void 0 : _a.replace(/^http/, 'ws');
const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2); const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2);
const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient = new WebSocket(WS_LINK);

@ -28,9 +28,10 @@ export const getAllChannels = (req, res, next) => {
let remote = 0; let remote = 0;
let total = 0; let total = 0;
request(options).then((body) => { request(options).then((body) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body });
if (body.channels) { if (body.channels) {
return Promise.all(body.channels.map((channel) => { return Promise.all((_a = body.channels) === null || _a === void 0 ? void 0 : _a.map((channel) => {
local = (channel.local_balance) ? +channel.local_balance : 0; local = (channel.local_balance) ? +channel.local_balance : 0;
remote = (channel.remote_balance) ? +channel.remote_balance : 0; remote = (channel.remote_balance) ? +channel.remote_balance : 0;
total = local + remote; total = local + remote;
@ -64,21 +65,22 @@ export const getPendingChannels = (req, res, next) => {
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending'; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
var _a, _b, _c, _d;
if (!body.total_limbo_balance) { if (!body.total_limbo_balance) {
body.total_limbo_balance = 0; body.total_limbo_balance = 0;
} }
const promises = []; const promises = [];
if (body.pending_open_channels && body.pending_open_channels.length > 0) { if (body.pending_open_channels && body.pending_open_channels.length > 0) {
body.pending_open_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); (_a = body.pending_open_channels) === null || _a === void 0 ? void 0 : _a.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.pending_closing_channels && body.pending_closing_channels.length > 0) { if (body.pending_closing_channels && body.pending_closing_channels.length > 0) {
body.pending_closing_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); (_b = body.pending_closing_channels) === null || _b === void 0 ? void 0 : _b.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) { if (body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) {
body.pending_force_closing_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); (_c = body.pending_force_closing_channels) === null || _c === void 0 ? void 0 : _c.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.waiting_close_channels && body.waiting_close_channels.length > 0) { if (body.waiting_close_channels && body.waiting_close_channels.length > 0) {
body.waiting_close_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); (_d = body.waiting_close_channels) === null || _d === void 0 ? void 0 : _d.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
return Promise.all(promises).then((values) => { return Promise.all(promises).then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Pending Channels List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Pending Channels List Received', data: body });
@ -102,8 +104,9 @@ export const getClosedChannels = (req, res, next) => {
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed'; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
var _a;
if (body.channels && body.channels.length > 0) { if (body.channels && body.channels.length > 0) {
return Promise.all(body.channels.map((channel) => { return Promise.all((_a = body.channels) === null || _a === void 0 ? void 0 : _a.map((channel) => {
channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type; channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type;
return getAliasForChannel(req.session.selectedNode, channel); return getAliasForChannel(req.session.selectedNode, channel);
})).then((values) => { })).then((values) => {
@ -192,6 +195,7 @@ export const postTransactions = (req, res, next) => {
}); });
}; };
export const closeChannel = (req, res, next) => { export const closeChannel = (req, res, next) => {
var _a;
try { try {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' });
if (!req.session.selectedNode) { if (!req.session.selectedNode) {
@ -202,7 +206,7 @@ export const closeChannel = (req, res, next) => {
if (options.error) { if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error }); return res.status(options.statusCode).json({ message: options.message, error: options.error });
} }
const channelpoint = req.params.channelPoint.replace(':', '/'); const channelpoint = (_a = req.params.channelPoint) === null || _a === void 0 ? void 0 : _a.replace(':', '/');
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
if (req.query.target_conf) { if (req.query.target_conf) {
options.url = options.url + '&target_conf=' + req.query.target_conf; options.url = options.url + '&target_conf=' + req.query.target_conf;

@ -16,12 +16,13 @@ function getFilesList(channelBackupPath, callback) {
} }
if (files && files.length > 0) { if (files && files.length > 0) {
files.forEach((file) => { files.forEach((file) => {
var _a;
if (!file.includes('.restored')) { if (!file.includes('.restored')) {
if (file.toLowerCase() === 'channel-all.bak' || file.toLowerCase() === 'backup-channel-all.bak') { if (file.toLowerCase() === 'channel-all.bak' || file.toLowerCase() === 'backup-channel-all.bak') {
all_restore_exists = true; all_restore_exists = true;
} }
else { else {
files_list.push({ channel_point: file.substring(8, file.length - 4).replace('-', ':') }); files_list.push({ channel_point: (_a = file.substring(8, file.length - 4)) === null || _a === void 0 ? void 0 : _a.replace('-', ':') });
} }
} }
}); });
@ -31,6 +32,7 @@ function getFilesList(channelBackupPath, callback) {
}); });
} }
export const getBackup = (req, res, next) => { export const getBackup = (req, res, next) => {
var _a, _b;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Getting Channel Backup..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Getting Channel Backup..' });
options = common.getOptions(req); options = common.getOptions(req);
if (options.error) { if (options.error) {
@ -44,9 +46,9 @@ export const getBackup = (req, res, next) => {
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup'; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup';
} }
else { else {
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + ((_a = req.params.channelPoint) === null || _a === void 0 ? void 0 : _a.replace(':', '-')) + '.bak';
message = 'Channel Backup Successful.'; message = 'Channel Backup Successful.';
const channelpoint = req.params.channelPoint.replace(':', '/'); const channelpoint = (_b = req.params.channelPoint) === null || _b === void 0 ? void 0 : _b.replace(':', '/');
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint;
const exists = fs.existsSync(channel_backup_file); const exists = fs.existsSync(channel_backup_file);
if (exists) { if (exists) {
@ -81,6 +83,7 @@ export const getBackup = (req, res, next) => {
}); });
}; };
export const postBackupVerify = (req, res, next) => { export const postBackupVerify = (req, res, next) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Verifying Channel Backup..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Verifying Channel Backup..' });
options = common.getOptions(req); options = common.getOptions(req);
if (options.error) { if (options.error) {
@ -116,7 +119,7 @@ export const postBackupVerify = (req, res, next) => {
} }
else { else {
message = 'Channel Verify Successful.'; message = 'Channel Verify Successful.';
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + ((_a = req.params.channelPoint) === null || _a === void 0 ? void 0 : _a.replace(':', '-')) + '.bak';
const exists = fs.existsSync(channel_verify_file); const exists = fs.existsSync(channel_verify_file);
if (exists) { if (exists) {
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
@ -141,6 +144,7 @@ export const postBackupVerify = (req, res, next) => {
} }
}; };
export const postRestore = (req, res, next) => { export const postRestore = (req, res, next) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Restoring Channel Backup..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'ChannelBackup', msg: 'Restoring Channel Backup..' });
options = common.getOptions(req); options = common.getOptions(req);
if (options.error) { if (options.error) {
@ -188,7 +192,7 @@ export const postRestore = (req, res, next) => {
} }
else { else {
message = 'Channel Restore Successful.'; message = 'Channel Restore Successful.';
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + ((_a = req.params.channelPoint) === null || _a === void 0 ? void 0 : _a.replace(':', '-')) + '.bak';
const exists = fs.existsSync(channel_restore_file); const exists = fs.existsSync(channel_restore_file);
if (exists) { if (exists) {
restore_backup = fs.readFileSync(channel_restore_file, 'utf-8'); restore_backup = fs.readFileSync(channel_restore_file, 'utf-8');

@ -21,10 +21,11 @@ export const getFees = (req, res, next) => {
const week_start_time = current_time - 604800; const week_start_time = current_time - 604800;
const day_start_time = current_time - 86400; const day_start_time = current_time - 86400;
return getAllForwardingEvents(req, month_start_time, current_time, 0, 'fees', (history) => { return getAllForwardingEvents(req, month_start_time, current_time, 0, 'fees', (history) => {
var _a, _b, _c;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history });
const daily_sum = history.forwarding_events.reduce((acc, curr) => ((curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]); const daily_sum = (_a = history.forwarding_events) === null || _a === void 0 ? void 0 : _a.reduce((acc, curr) => ((curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]);
const weekly_sum = history.forwarding_events.reduce((acc, curr) => ((curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]); const weekly_sum = (_b = history.forwarding_events) === null || _b === void 0 ? void 0 : _b.reduce((acc, curr) => ((curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]);
const monthly_sum = history.forwarding_events.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]); const monthly_sum = (_c = history.forwarding_events) === null || _c === void 0 ? void 0 : _c.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]);
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum });

@ -9,6 +9,7 @@ const common = Common;
const lndWsClient = LNDWSClient; const lndWsClient = LNDWSClient;
const databaseService = Database; const databaseService = Database;
export const getInfo = (req, res, next) => { export const getInfo = (req, res, next) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Getting LND Node Information..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Getting LND Node Information..' });
common.logEnvVariables(req); common.logEnvVariables(req);
common.setOptions(req); common.setOptions(req);
@ -25,7 +26,7 @@ export const getInfo = (req, res, next) => {
return res.status(err.statusCode).json({ message: err.message, error: err.error }); return res.status(err.statusCode).json({ message: err.message, error: err.error });
} }
else { else {
common.nodes.map((node) => { (_a = common.nodes) === null || _a === void 0 ? void 0 : _a.map((node) => {
if (node.ln_implementation === 'LND') { if (node.ln_implementation === 'LND') {
common.getAllNodeAllChannelBackup(node); common.getAllNodeAllChannelBackup(node);
} }

@ -84,11 +84,13 @@ export const getQueryRoutes = (req, res, next) => {
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes URL', data: options.url });
request(options).then((body) => { request(options).then((body) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes Received', data: body });
if (body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) { if (body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) {
return Promise.all(body.routes[0].hops.map((hop) => getAliasFromPubkey(req.session.selectedNode, hop.pub_key))). return Promise.all((_a = body.routes[0].hops) === null || _a === void 0 ? void 0 : _a.map((hop) => getAliasFromPubkey(req.session.selectedNode, hop.pub_key))).
then((values) => { then((values) => {
body.routes[0].hops.map((hop, i) => { var _a;
(_a = body.routes[0].hops) === null || _a === void 0 ? void 0 : _a.map((hop, i) => {
hop.hop_sequence = i + 1; hop.hop_sequence = i + 1;
hop.pubkey_alias = values[i]; hop.pubkey_alias = values[i];
return hop; return hop;
@ -148,7 +150,7 @@ export const getAliasesForPubkeys = (req, res, next) => {
} }
if (req.query.pubkeys) { if (req.query.pubkeys) {
const pubkeyArr = req.query.pubkeys.split(','); const pubkeyArr = req.query.pubkeys.split(',');
return Promise.all(pubkeyArr.map((pubkey) => getAliasFromPubkey(req.session.selectedNode, pubkey))). return Promise.all(pubkeyArr === null || pubkeyArr === void 0 ? void 0 : pubkeyArr.map((pubkey) => getAliasFromPubkey(req.session.selectedNode, pubkey))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Node Alias', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Node Alias', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -34,7 +34,7 @@ export const decodePayments = (req, res, next) => {
} }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr === null || paymentsArr === void 0 ? void 0 : paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -25,7 +25,7 @@ export const getPeers = (req, res, next) => {
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
const peers = !body.peers ? [] : body.peers; const peers = !body.peers ? [] : body.peers;
return Promise.all(peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { return Promise.all(peers === null || peers === void 0 ? void 0 : peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers with Alias before Sort', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers with Alias before Sort', data: body });
if (body.peers) { if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias'); body.peers = common.sortDescByStrKey(body.peers, 'alias');
@ -54,7 +54,7 @@ export const postPeer = (req, res, next) => {
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.ln_server_url + '/v1/peers';
request(options).then((body) => { request(options).then((body) => {
const peers = (!body.peers) ? [] : body.peers; const peers = (!body.peers) ? [] : body.peers;
return Promise.all(peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { return Promise.all(peers === null || peers === void 0 ? void 0 : peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
if (body.peers) { if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias'); body.peers = common.sortDescByStrKey(body.peers, 'alias');
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey); body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);

@ -42,7 +42,8 @@ export class LNDWebSocketClient {
}); });
}; };
this.subscribeToInvoice = (options, selectedNode, rHash) => { this.subscribeToInvoice = (options, selectedNode, rHash) => {
rHash = rHash.replace(/\+/g, '-').replace(/[/]/g, '_'); var _a;
rHash = (_a = rHash === null || rHash === void 0 ? void 0 : rHash.replace(/\+/g, '-')) === null || _a === void 0 ? void 0 : _a.replace(/[/]/g, '_');
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' });
options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash; options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash;
request(options).then((msg) => { request(options).then((msg) => {

@ -226,6 +226,7 @@ export const getConfig = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Node Type', data: req.params.nodeType }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Node Type', data: req.params.nodeType });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: confFile }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: confFile });
fs.readFile(confFile, 'utf8', (errRes, data) => { fs.readFile(confFile, 'utf8', (errRes, data) => {
var _a;
if (errRes) { if (errRes) {
const errMsg = 'Reading Config Error'; const errMsg = 'Reading Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
@ -238,7 +239,7 @@ export const getConfig = (req, res, next) => {
} }
else { else {
fileFormat = 'INI'; fileFormat = 'INI';
data = data.replace('color=#', 'color='); data = data === null || data === void 0 ? void 0 : data.replace('color=#', 'color=');
jsonConfig = ini.parse(data); jsonConfig = ini.parse(data);
if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) { if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) {
jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color; jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color;
@ -249,15 +250,16 @@ export const getConfig = (req, res, next) => {
} }
} }
jsonConfig = maskPasswords(jsonConfig); jsonConfig = maskPasswords(jsonConfig);
const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig).replace('color=\\#', 'color=#'); const responseJSON = (fileFormat === 'JSON') ? jsonConfig : (_a = ini.stringify(jsonConfig)) === null || _a === void 0 ? void 0 : _a.replace('color=\\#', 'color=#');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON });
res.status(200).json({ format: fileFormat, data: responseJSON }); res.status(200).json({ format: fileFormat, data: responseJSON });
} }
}); });
}; };
export const getFile = (req, res, next) => { export const getFile = (req, res, next) => {
var _a;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel.replace(':', '-') + '.bak'); const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + ((_a = req.query.channel) === null || _a === void 0 ? void 0 : _a.replace(':', '-')) + '.bak');
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file });
fs.readFile(file, 'utf8', (errRes, data) => { fs.readFile(file, 'utf8', (errRes, data) => {

@ -18,14 +18,16 @@ export const isAuthenticated = (req, res, next) => {
} }
}; };
export const verifyWSUser = (info, next) => { export const verifyWSUser = (info, next) => {
var _a;
const headers = JSON.parse(JSON.stringify(info.req.headers)); const headers = JSON.parse(JSON.stringify(info.req.headers));
const protocols = !info.req.headers['sec-websocket-protocol'] ? [] : info.req.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); const protocols = !info.req.headers['sec-websocket-protocol'] ? [] : (_a = info.req.headers['sec-websocket-protocol'].split(',')) === null || _a === void 0 ? void 0 : _a.map((s) => s.trim());
const jwToken = (protocols && protocols.length > 0) ? protocols[0] : ''; const jwToken = (protocols && protocols.length > 0) ? protocols[0] : '';
if (!jwToken || jwToken === '') { if (!jwToken || jwToken === '') {
next(false, 401, 'Authentication Failed! Please Login First!'); next(false, 401, 'Authentication Failed! Please Login First!');
} }
else { else {
jwt.verify(jwToken, common.secret_key, (verificationErr) => { jwt.verify(jwToken, common.secret_key, (verificationErr) => {
var _a, _b, _c;
if (verificationErr) { if (verificationErr) {
next(false, 401, 'Authentication Failed! Please Login First!'); next(false, 401, 'Authentication Failed! Please Login First!');
} }
@ -40,7 +42,7 @@ export const verifyWSUser = (info, next) => {
} }
let cookies = null; let cookies = null;
try { try {
cookies = '{"' + headers.cookie.replace(/ /g, '').replace(/;/g, '","').trim().replace(/[=]/g, '":"') + '"}'; cookies = '{"' + ((_c = (_b = (_a = headers.cookie) === null || _a === void 0 ? void 0 : _a.replace(/ /g, '')) === null || _b === void 0 ? void 0 : _b.replace(/;/g, '","').trim()) === null || _c === void 0 ? void 0 : _c.replace(/[=]/g, '":"')) + '"}';
updatedReq['cookies'] = JSON.parse(cookies); updatedReq['cookies'] = JSON.parse(cookies);
} }
catch (err) { catch (err) {

@ -198,17 +198,18 @@ export class CommonService {
}; };
this.newestOnTop = (array, key, value) => { this.newestOnTop = (array, key, value) => {
const newlyAddedRecord = array.splice(array.findIndex((item) => item[key] === value), 1); const newlyAddedRecord = array.splice(array.findIndex((item) => item[key] === value), 1);
array.unshift(newlyAddedRecord[0]); array === null || array === void 0 ? void 0 : array.unshift(newlyAddedRecord[0]);
return array; return array;
}; };
this.camelCase = (str) => str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase())).replace(/\s+/g, '').replace(/-/g, ' '); this.camelCase = (str) => { var _a, _b; return (_b = (_a = str === null || str === void 0 ? void 0 : str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase()))) === null || _a === void 0 ? void 0 : _a.replace(/\s+/g, '')) === null || _b === void 0 ? void 0 : _b.replace(/-/g, ' '); };
this.titleCase = (str) => { this.titleCase = (str) => {
var _a, _b;
if (str.indexOf('!\n') > 0 || str.indexOf('.\n') > 0) { if (str.indexOf('!\n') > 0 || str.indexOf('.\n') > 0) {
return str.split('\n').reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + '\n', ''); return (_a = str.split('\n')) === null || _a === void 0 ? void 0 : _a.reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + '\n', '');
} }
else { else {
if (str.indexOf(' ') > 0) { if (str.indexOf(' ') > 0) {
return str.split(' ').reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + ' ', ''); return (_b = str.split(' ')) === null || _b === void 0 ? void 0 : _b.reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + ' ', '');
} }
else { else {
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase(); return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
@ -328,8 +329,9 @@ export class CommonService {
} }
}; };
this.createDirectory = (directoryName) => { this.createDirectory = (directoryName) => {
var _a;
const initDir = isAbsolute(directoryName) ? sep : ''; const initDir = isAbsolute(directoryName) ? sep : '';
directoryName.split(sep).reduce((parentDir, childDir) => { (_a = directoryName.split(sep)) === null || _a === void 0 ? void 0 : _a.reduce((parentDir, childDir) => {
const curDir = resolve(parentDir, childDir); const curDir = resolve(parentDir, childDir);
try { try {
if (!fs.existsSync(curDir)) { if (!fs.existsSync(curDir)) {
@ -398,8 +400,9 @@ export class CommonService {
}); });
}; };
this.isVersionCompatible = (currentVersion, checkVersion) => { this.isVersionCompatible = (currentVersion, checkVersion) => {
var _a;
if (currentVersion) { if (currentVersion) {
const versionsArr = currentVersion.trim().replace('v', '').split('-')[0].split('.') || []; const versionsArr = ((_a = currentVersion.trim()) === null || _a === void 0 ? void 0 : _a.replace('v', '').split('-')[0].split('.')) || [];
const checkVersionsArr = checkVersion.split('.'); const checkVersionsArr = checkVersion.split('.');
return (+versionsArr[0] > +checkVersionsArr[0]) || return (+versionsArr[0] > +checkVersionsArr[0]) ||
(+versionsArr[0] === +checkVersionsArr[0] && +versionsArr[1] > +checkVersionsArr[1]) || (+versionsArr[0] === +checkVersionsArr[0] && +versionsArr[1] > +checkVersionsArr[1]) ||

@ -31,6 +31,7 @@ export class RTLWebSocketServer {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' });
this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser }); this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser });
httpServer.on('upgrade', (request, socket, head) => { httpServer.on('upgrade', (request, socket, head) => {
var _a;
if (request.headers['upgrade'] !== 'websocket') { if (request.headers['upgrade'] !== 'websocket') {
socket.end('HTTP/1.1 400 Bad Request'); socket.end('HTTP/1.1 400 Bad Request');
return; return;
@ -38,7 +39,7 @@ export class RTLWebSocketServer {
const acceptKey = request.headers['sec-websocket-key']; const acceptKey = request.headers['sec-websocket-key'];
const hash = this.generateAcceptValue(acceptKey); const hash = this.generateAcceptValue(acceptKey);
const responseHeaders = ['HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + hash]; const responseHeaders = ['HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + hash];
const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); const protocols = !request.headers['sec-websocket-protocol'] ? [] : (_a = request.headers['sec-websocket-protocol'].split(',')) === null || _a === void 0 ? void 0 : _a.map((s) => s.trim());
if (protocols.includes('json')) { if (protocols.includes('json')) {
responseHeaders.push('Sec-WebSocket-Protocol: json'); responseHeaders.push('Sec-WebSocket-Protocol: json');
} }
@ -52,7 +53,8 @@ export class RTLWebSocketServer {
this.webSocketServer.emit('connection', websocket, request); this.webSocketServer.emit('connection', websocket, request);
}; };
this.mountEventsOnConnection = (websocket, request) => { this.mountEventsOnConnection = (websocket, request) => {
const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); var _a;
const protocols = !request.headers['sec-websocket-protocol'] ? [] : (_a = request.headers['sec-websocket-protocol'].split(',')) === null || _a === void 0 ? void 0 : _a.map((s) => s.trim());
const cookies = parse(request.headers.cookie); const cookies = parse(request.headers.cookie);
websocket.clientId = Date.now(); websocket.clientId = Date.now();
websocket.isAlive = true; websocket.isAlive = true;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -13,6 +13,6 @@
<style>@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.43515fc39338348b.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.43515fc39338348b.css"></noscript></head> <style>@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.43515fc39338348b.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.43515fc39338348b.css"></noscript></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.5eac349d49d4fc59.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.228f2037f60782fc.js" type="module"></script> <script src="runtime.2e2a4c6d6e08e8f6.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.053a5650605ae39e.js" type="module"></script>
</body></html> </body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(n,t,f,o)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,o]=e[i],s=!0,d=0;d<t.length;d++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(s=!1,o<a&&(a=o));if(s){e.splice(i--,1);var l=f();void 0!==l&&(n=l)}}return n}o=o||0;for(var i=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,f,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{564:"df2fbcc9f18685c7",636:"1aa5210b7043b6ea",893:"9a615c46b89a5a79",924:"da19686ce48bdb00"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,o,i)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==o)for(var d=document.getElementsByTagName("script"),l=0;l<d.length;l++){var u=d[l];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==n+o){a=u;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+o),a.src=r.tu(t)),e[t]=[f];var c=(m,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(_=>_(b)),m)return m(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:n=>n},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(f,o)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)o.push(i[2]);else if(666!=f){var a=new Promise((u,c)=>i=e[f]=[u,c]);o.push(i[2]=a);var s=r.p+r.u(f),d=new Error;r.l(s,u=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var c=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;d.message="Loading chunk "+f+" failed.\n("+c+": "+p+")",d.name="ChunkLoadError",d.type=c,d.request=p,i[1](d)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,o)=>{var d,l,[i,a,s]=o,u=0;if(i.some(p=>0!==e[p])){for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(s)var c=s(r)}for(f&&f(o);u<i.length;u++)r.o(e,l=i[u])&&e[l]&&e[l][0](),e[l]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})(); (()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(n,t,f,o)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,o]=e[i],s=!0,u=0;u<t.length;u++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[u]))?t.splice(u--,1):(s=!1,o<a&&(a=o));if(s){e.splice(i--,1);var l=f();void 0!==l&&(n=l)}}return n}o=o||0;for(var i=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,f,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{564:"fa1444f039e187d7",636:"76f584200eef7ef5",893:"9a615c46b89a5a79",924:"232c129a40707864"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,o,i)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==o)for(var u=document.getElementsByTagName("script"),l=0;l<u.length;l++){var d=u[l];if(d.getAttribute("src")==t||d.getAttribute("data-webpack")==n+o){a=d;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+o),a.src=r.tu(t)),e[t]=[f];var c=(m,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(_=>_(b)),m)return m(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:n=>n},"undefined"!=typeof trustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(f,o)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)o.push(i[2]);else if(666!=f){var a=new Promise((d,c)=>i=e[f]=[d,c]);o.push(i[2]=a);var s=r.p+r.u(f),u=new Error;r.l(s,d=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var c=d&&("load"===d.type?"missing":d.type),p=d&&d.target&&d.target.src;u.message="Loading chunk "+f+" failed.\n("+c+": "+p+")",u.name="ChunkLoadError",u.type=c,u.request=p,i[1](u)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,o)=>{var u,l,[i,a,s]=o,d=0;if(i.some(p=>0!==e[p])){for(u in a)r.o(a,u)&&(r.m[u]=a[u]);if(s)var c=s(r)}for(f&&f(o);d<i.length;d++)r.o(e,l=i[d])&&e[l]&&e[l][0](),e[l]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})();

@ -11,7 +11,7 @@ export const listChannels = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels'; options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
request(options).then((body) => { request(options).then((body) => {
body.map((channel) => { body?.map((channel) => {
if (!channel.alias || channel.alias === '') { channel.alias = channel.id.substring(0, 20); } if (!channel.alias || channel.alias === '') { channel.alias = channel.id.substring(0, 20); }
const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : 0; const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : 0;
const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : 0; const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : 0;
@ -117,8 +117,8 @@ export const funderUpdatePolicy = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Funder Policy Received', data: 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.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.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;
res.status(200).json(body); res.status(200).json(body);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode); const err = common.handleError(errRes, 'Channels', 'Funder Policy Error', req.session.selectedNode);

@ -72,8 +72,8 @@ export const listNodes = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes Finished', data: body });
body.forEach((node) => { body.forEach((node) => {
if (node.option_will_fund) { 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 = (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.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 = (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;
} }
return node; return node;
}); });

@ -32,9 +32,9 @@ function summaryReducer(accumulator, mpp) {
} }
function groupBy(payments) { function groupBy(payments) {
const paymentsInGroups = payments.reduce(paymentReducer, {}); const paymentsInGroups = payments?.reduce(paymentReducer, {});
const paymentsGrpArray = Object.keys(paymentsInGroups).map((key) => ((paymentsInGroups[key].length && paymentsInGroups[key].length > 1) ? common.sortDescByKey(paymentsInGroups[key], 'partid') : paymentsInGroups[key])); const paymentsGrpArray = Object.keys(paymentsInGroups)?.map((key) => ((paymentsInGroups[key].length && paymentsInGroups[key].length > 1) ? common.sortDescByKey(paymentsInGroups[key], 'partid') : paymentsInGroups[key]));
return paymentsGrpArray.reduce((acc, curr) => { return paymentsGrpArray?.reduce((acc, curr) => {
let temp: any = {}; let temp: any = {};
if (curr.length && curr.length === 1) { if (curr.length && curr.length === 1) {
temp = JSON.parse(JSON.stringify(curr[0])); temp = JSON.parse(JSON.stringify(curr[0]));
@ -43,7 +43,7 @@ function groupBy(payments) {
temp.total_parts = 1; temp.total_parts = 1;
delete temp.partid; delete temp.partid;
} else { } else {
const paySummary = curr.reduce(summaryReducer, { msatoshi: 0, msatoshi_sent: 0, status: (curr[0] && curr[0].status) ? curr[0].status : 'failed' }); const paySummary = curr?.reduce(summaryReducer, { msatoshi: 0, msatoshi_sent: 0, status: (curr[0] && curr[0].status) ? curr[0].status : 'failed' });
temp = { temp = {
is_group: true, is_expanded: false, total_parts: (curr.length ? curr.length : 0), status: paySummary.status, payment_hash: curr[0].payment_hash, is_group: true, is_expanded: false, total_parts: (curr.length ? curr.length : 0), status: paySummary.status, payment_hash: curr[0].payment_hash,
destination: curr[0].destination, msatoshi: paySummary.msatoshi, msatoshi_sent: paySummary.msatoshi_sent, created_at: curr[0].created_at, destination: curr[0].destination, msatoshi: paySummary.msatoshi, msatoshi_sent: paySummary.msatoshi_sent, created_at: curr[0].created_at,

@ -21,7 +21,7 @@ export const decodePayments = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr?.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment List Decoded', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -59,7 +59,7 @@ export class CLWebSocketClient {
public connectWithClient = (clWsClt) => { public connectWithClient = (clWsClt) => {
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' }); this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
const WS_LINK = (clWsClt.selectedNode.ln_server_url).replace(/^http/, 'ws') + '/v1/ws'; const WS_LINK = (clWsClt.selectedNode.ln_server_url)?.replace(/^http/, 'ws') + '/v1/ws';
const mcrnHexEncoded = Buffer.from(fs.readFileSync(join(clWsClt.selectedNode.macaroon_path, 'access.macaroon'))).toString('hex'); const mcrnHexEncoded = Buffer.from(fs.readFileSync(join(clWsClt.selectedNode.macaroon_path, 'access.macaroon'))).toString('hex');
clWsClt.webSocketClient = new WebSocket(WS_LINK, [mcrnHexEncoded, 'hex'], { rejectUnauthorized: false }); clWsClt.webSocketClient = new WebSocket(WS_LINK, [mcrnHexEncoded, 'hex'], { rejectUnauthorized: false });

@ -34,7 +34,7 @@ export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => {
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Filtered Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Filtered Nodes Received', data: nodes });
let foundPeer = null; let foundPeer = null;
simplifiedChannels.map((channel) => { simplifiedChannels?.map((channel) => {
foundPeer = nodes.find((channelWithAlias) => channel.nodeId === channelWithAlias.nodeId); foundPeer = nodes.find((channelWithAlias) => channel.nodeId === channelWithAlias.nodeId);
channel.alias = foundPeer ? foundPeer.alias : channel.nodeId.substring(0, 20); channel.alias = foundPeer ? foundPeer.alias : channel.nodeId.substring(0, 20);
return channel; return channel;

@ -66,7 +66,7 @@ export const listInvoices = (req, res, next) => {
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
return Promise.all(invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
then((values) => { then((values) => {
body = common.sortDescByKey(invoices, 'expiresAt'); body = common.sortDescByKey(invoices, 'expiresAt');
return res.status(200).json(invoices); return res.status(200).json(invoices);
@ -79,7 +79,7 @@ export const listInvoices = (req, res, next) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0]; const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1]; pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
if (invoices && invoices.length > 0) { if (invoices && invoices.length > 0) {
return Promise.all(invoices.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))). return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
then((values) => { then((values) => {
body = common.sortDescByKey(invoices, 'expiresAt'); body = common.sortDescByKey(invoices, 'expiresAt');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });

@ -21,7 +21,7 @@ export const getSentInfoFromPaymentRequest = (selNode: CommonSelectedNode, payme
export const getQueryNodes = (selNode: CommonSelectedNode, nodeIds) => { export const getQueryNodes = (selNode: CommonSelectedNode, nodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.ln_server_url + '/nodes';
options.form = { nodeIds: nodeIds.reduce((acc, curr) => acc + ',' + curr) }; options.form = { nodeIds: nodeIds?.reduce((acc, curr) => acc + ',' + curr) };
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes });
return nodes; return nodes;
@ -74,11 +74,11 @@ export const queryPaymentRoute = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Payment Route Received', data: body });
if (body && body.routes && body.routes.length) { if (body && body.routes && body.routes.length) {
let allRoutesNodeIds = []; let allRoutesNodeIds = [];
allRoutesNodeIds = body.routes.reduce((accRoutes, currRoute) => [...new Set([...accRoutes, ...currRoute.nodeIds])], []); allRoutesNodeIds = body.routes?.reduce((accRoutes, currRoute) => [...new Set([...accRoutes, ...currRoute.nodeIds])], []);
return getQueryNodes(req.session.selectedNode, allRoutesNodeIds).then((nodesWithAlias) => { return getQueryNodes(req.session.selectedNode, allRoutesNodeIds).then((nodesWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.routes.forEach((route, i) => { body.routes.forEach((route, i) => {
route.nodeIds.map((node, j) => { route.nodeIds?.map((node, j) => {
foundPeer = nodesWithAlias.find((nodeWithAlias) => node === nodeWithAlias.nodeId); foundPeer = nodesWithAlias.find((nodeWithAlias) => node === nodeWithAlias.nodeId);
body.routes[i].nodeIds[j] = { nodeId: node, alias: foundPeer ? foundPeer.alias : '' }; body.routes[i].nodeIds[j] = { nodeId: node, alias: foundPeer ? foundPeer.alias : '' };
return node; return node;
@ -103,7 +103,7 @@ export const getSentPaymentsInformation = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr?.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values });
return res.status(200).json(values); return res.status(200).json(values);

@ -32,7 +32,7 @@ export const getPeers = (req, res, next) => {
peersNodeIds = peersNodeIds.substring(1); peersNodeIds = peersNodeIds.substring(1);
return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => { return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.map((peer) => { body?.map((peer) => {
foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId); foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId);
peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20); peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20);
return peer; return peer;
@ -82,7 +82,7 @@ export const connectPeer = (req, res, next) => {
peersNodeIds = peersNodeIds.substring(1); peersNodeIds = peersNodeIds.substring(1);
return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => { return getFilteredNodes(req.session.selectedNode, peersNodeIds).then((peersWithAlias) => {
let foundPeer = null; let foundPeer = null;
body.map((peer) => { body?.map((peer) => {
foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId); foundPeer = peersWithAlias.find((peerWithAlias) => peer.nodeId === peerWithAlias.nodeId);
peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20); peer.alias = foundPeer ? foundPeer.alias : peer.nodeId.substring(0, 20);
return peer; return peer;

@ -57,7 +57,7 @@ export class ECLWebSocketClient {
public connectWithClient = (eclWsClt) => { public connectWithClient = (eclWsClt) => {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' });
const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url).replace(/^http/, 'ws'); const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url)?.replace(/^http/, 'ws');
const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2); const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2);
const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws'; const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient = new WebSocket(WS_LINK);

@ -32,7 +32,7 @@ export const getAllChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body });
if (body.channels) { if (body.channels) {
return Promise.all( return Promise.all(
body.channels.map((channel) => { body.channels?.map((channel) => {
local = (channel.local_balance) ? +channel.local_balance : 0; local = (channel.local_balance) ? +channel.local_balance : 0;
remote = (channel.remote_balance) ? +channel.remote_balance : 0; remote = (channel.remote_balance) ? +channel.remote_balance : 0;
total = local + remote; total = local + remote;
@ -70,16 +70,16 @@ export const getPendingChannels = (req, res, next) => {
} }
const promises = []; const promises = [];
if (body.pending_open_channels && body.pending_open_channels.length > 0) { if (body.pending_open_channels && body.pending_open_channels.length > 0) {
body.pending_open_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); body.pending_open_channels?.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.pending_closing_channels && body.pending_closing_channels.length > 0) { if (body.pending_closing_channels && body.pending_closing_channels.length > 0) {
body.pending_closing_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); body.pending_closing_channels?.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) { if (body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) {
body.pending_force_closing_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); body.pending_force_closing_channels?.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
if (body.waiting_close_channels && body.waiting_close_channels.length > 0) { if (body.waiting_close_channels && body.waiting_close_channels.length > 0) {
body.waiting_close_channels.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel))); body.waiting_close_channels?.map((channel) => promises.push(getAliasForChannel(req.session.selectedNode, channel.channel)));
} }
return Promise.all(promises).then((values) => { return Promise.all(promises).then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Pending Channels List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Pending Channels List Received', data: body });
@ -104,7 +104,7 @@ export const getClosedChannels = (req, res, next) => {
request(options).then((body) => { request(options).then((body) => {
if (body.channels && body.channels.length > 0) { if (body.channels && body.channels.length > 0) {
return Promise.all( return Promise.all(
body.channels.map((channel) => { body.channels?.map((channel) => {
channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type; channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type;
return getAliasForChannel(req.session.selectedNode, channel); return getAliasForChannel(req.session.selectedNode, channel);
}) })
@ -190,7 +190,7 @@ export const closeChannel = (req, res, next) => {
} }
options = common.getOptions(req); options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
const channelpoint = req.params.channelPoint.replace(':', '/'); const channelpoint = req.params.channelPoint?.replace(':', '/');
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
if (req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; } if (req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; }
if (req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; } if (req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; }

@ -22,7 +22,7 @@ function getFilesList(channelBackupPath, callback) {
if (file.toLowerCase() === 'channel-all.bak' || file.toLowerCase() === 'backup-channel-all.bak') { if (file.toLowerCase() === 'channel-all.bak' || file.toLowerCase() === 'backup-channel-all.bak') {
all_restore_exists = true; all_restore_exists = true;
} else { } else {
files_list.push({ channel_point: file.substring(8, file.length - 4).replace('-', ':') }); files_list.push({ channel_point: file.substring(8, file.length - 4)?.replace('-', ':') });
} }
} }
}); });
@ -43,9 +43,9 @@ export const getBackup = (req, res, next) => {
message = 'All Channels Backup Successful.'; message = 'All Channels Backup Successful.';
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup'; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup';
} else { } else {
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
message = 'Channel Backup Successful.'; message = 'Channel Backup Successful.';
const channelpoint = req.params.channelPoint.replace(':', '/'); const channelpoint = req.params.channelPoint?.replace(':', '/');
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint; options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint;
const exists = fs.existsSync(channel_backup_file); const exists = fs.existsSync(channel_backup_file);
if (exists) { if (exists) {
@ -108,7 +108,7 @@ export const postBackupVerify = (req, res, next) => {
} }
} else { } else {
message = 'Channel Verify Successful.'; message = 'Channel Verify Successful.';
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
const exists = fs.existsSync(channel_verify_file); const exists = fs.existsSync(channel_verify_file);
if (exists) { if (exists) {
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8'); verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
@ -173,7 +173,7 @@ export const postRestore = (req, res, next) => {
} }
} else { } else {
message = 'Channel Restore Successful.'; message = 'Channel Restore Successful.';
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak'; channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
const exists = fs.existsSync(channel_restore_file); const exists = fs.existsSync(channel_restore_file);
if (exists) { if (exists) {
restore_backup = fs.readFileSync(channel_restore_file, 'utf-8'); restore_backup = fs.readFileSync(channel_restore_file, 'utf-8');

@ -21,9 +21,9 @@ export const getFees = (req, res, next) => {
const day_start_time = current_time - 86400; const day_start_time = current_time - 86400;
return getAllForwardingEvents(req, month_start_time, current_time, 0, 'fees', (history) => { return getAllForwardingEvents(req, month_start_time, current_time, 0, 'fees', (history) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history });
const daily_sum = history.forwarding_events.reduce((acc, curr) => ((curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]); const daily_sum = history.forwarding_events?.reduce((acc, curr) => ((curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]);
const weekly_sum = history.forwarding_events.reduce((acc, curr) => ((curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]); const weekly_sum = history.forwarding_events?.reduce((acc, curr) => ((curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc), [0, 0]);
const monthly_sum = history.forwarding_events.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]); const monthly_sum = history.forwarding_events?.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]);
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum });

@ -24,7 +24,7 @@ export const getInfo = (req, res, next) => {
const err = common.handleError({ statusCode: 502, message: 'Bad or Missing Macaroon', error: errMsg }, 'GetInfo', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 502, message: 'Bad or Missing Macaroon', error: errMsg }, 'GetInfo', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error }); return res.status(err.statusCode).json({ message: err.message, error: err.error });
} else { } else {
common.nodes.map((node: any) => { common.nodes?.map((node: any) => {
if (node.ln_implementation === 'LND') { if (node.ln_implementation === 'LND') {
common.getAllNodeAllChannelBackup(node); common.getAllNodeAllChannelBackup(node);
} }

@ -83,9 +83,9 @@ export const getQueryRoutes = (req, res, next) => {
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes Received', data: body });
if (body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) { if (body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) {
return Promise.all(body.routes[0].hops.map((hop) => getAliasFromPubkey(req.session.selectedNode, hop.pub_key))). return Promise.all(body.routes[0].hops?.map((hop) => getAliasFromPubkey(req.session.selectedNode, hop.pub_key))).
then((values) => { then((values) => {
body.routes[0].hops.map((hop, i) => { body.routes[0].hops?.map((hop, i) => {
hop.hop_sequence = i + 1; hop.hop_sequence = i + 1;
hop.pubkey_alias = values[i]; hop.pubkey_alias = values[i];
return hop; return hop;
@ -141,7 +141,7 @@ export const getAliasesForPubkeys = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
if (req.query.pubkeys) { if (req.query.pubkeys) {
const pubkeyArr = req.query.pubkeys.split(','); const pubkeyArr = req.query.pubkeys.split(',');
return Promise.all(pubkeyArr.map((pubkey) => getAliasFromPubkey(req.session.selectedNode, pubkey))). return Promise.all(pubkeyArr?.map((pubkey) => getAliasFromPubkey(req.session.selectedNode, pubkey))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Node Alias', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Node Alias', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -35,7 +35,7 @@ export const decodePayments = (req, res, next) => {
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
if (req.body.payments) { if (req.body.payments) {
const paymentsArr = req.body.payments.split(','); const paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))). return Promise.all(paymentsArr?.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
then((values) => { then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values });
res.status(200).json(values); res.status(200).json(values);

@ -26,7 +26,7 @@ export const getPeers = (req, res, next) => {
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
const peers = !body.peers ? [] : body.peers; const peers = !body.peers ? [] : body.peers;
return Promise.all(peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers with Alias before Sort', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers with Alias before Sort', data: body });
if (body.peers) { if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias'); body.peers = common.sortDescByStrKey(body.peers, 'alias');
@ -54,7 +54,7 @@ export const postPeer = (req, res, next) => {
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.ln_server_url + '/v1/peers';
request(options).then((body) => { request(options).then((body) => {
const peers = (!body.peers) ? [] : body.peers; const peers = (!body.peers) ? [] : body.peers;
return Promise.all(peers.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => { return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
if (body.peers) { if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias'); body.peers = common.sortDescByStrKey(body.peers, 'alias');
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey); body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);

@ -56,7 +56,7 @@ export class LNDWebSocketClient {
}; };
public subscribeToInvoice = (options: any, selectedNode: CommonSelectedNode, rHash: string) => { public subscribeToInvoice = (options: any, selectedNode: CommonSelectedNode, rHash: string) => {
rHash = rHash.replace(/\+/g, '-').replace(/[/]/g, '_'); rHash = rHash?.replace(/\+/g, '-')?.replace(/[/]/g, '_');
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' });
options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash; options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash;
request(options).then((msg) => { request(options).then((msg) => {

@ -235,7 +235,7 @@ export const getConfig = (req, res, next) => {
jsonConfig = JSON.parse(data); jsonConfig = JSON.parse(data);
} else { } else {
fileFormat = 'INI'; fileFormat = 'INI';
data = data.replace('color=#', 'color='); data = data?.replace('color=#', 'color=');
jsonConfig = ini.parse(data); jsonConfig = ini.parse(data);
if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) { if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) {
jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color; jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color;
@ -246,7 +246,7 @@ export const getConfig = (req, res, next) => {
} }
} }
jsonConfig = maskPasswords(jsonConfig); jsonConfig = maskPasswords(jsonConfig);
const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig).replace('color=\\#', 'color=#'); const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig)?.replace('color=\\#', 'color=#');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON });
res.status(200).json({ format: fileFormat, data: responseJSON }); res.status(200).json({ format: fileFormat, data: responseJSON });
} }
@ -255,7 +255,7 @@ export const getConfig = (req, res, next) => {
export const getFile = (req, res, next) => { export const getFile = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel.replace(':', '-') + '.bak'); const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak');
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file });
fs.readFile(file, 'utf8', (errRes, data) => { fs.readFile(file, 'utf8', (errRes, data) => {

@ -21,7 +21,7 @@ export const isAuthenticated = (req, res, next) => {
export const verifyWSUser = (info, next) => { export const verifyWSUser = (info, next) => {
const headers = JSON.parse(JSON.stringify(info.req.headers)); const headers = JSON.parse(JSON.stringify(info.req.headers));
const protocols = !info.req.headers['sec-websocket-protocol'] ? [] : info.req.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); const protocols = !info.req.headers['sec-websocket-protocol'] ? [] : info.req.headers['sec-websocket-protocol'].split(',')?.map((s) => s.trim());
const jwToken = (protocols && protocols.length > 0) ? protocols[0] : ''; const jwToken = (protocols && protocols.length > 0) ? protocols[0] : '';
if (!jwToken || jwToken === '') { if (!jwToken || jwToken === '') {
next(false, 401, 'Authentication Failed! Please Login First!'); next(false, 401, 'Authentication Failed! Please Login First!');
@ -39,7 +39,7 @@ export const verifyWSUser = (info, next) => {
} }
let cookies = null; let cookies = null;
try { try {
cookies = '{"' + headers.cookie.replace(/ /g, '').replace(/;/g, '","').trim().replace(/[=]/g, '":"') + '"}'; cookies = '{"' + headers.cookie?.replace(/ /g, '')?.replace(/;/g, '","').trim()?.replace(/[=]/g, '":"') + '"}';
updatedReq['cookies'] = JSON.parse(cookies); updatedReq['cookies'] = JSON.parse(cookies);
} catch (err) { } catch (err) {
cookies = {}; cookies = {};

@ -214,18 +214,18 @@ export class CommonService {
public newestOnTop = (array, key, value) => { public newestOnTop = (array, key, value) => {
const newlyAddedRecord = array.splice(array.findIndex((item) => item[key] === value), 1); const newlyAddedRecord = array.splice(array.findIndex((item) => item[key] === value), 1);
array.unshift(newlyAddedRecord[0]); array?.unshift(newlyAddedRecord[0]);
return array; return array;
}; };
public camelCase = (str: string) => str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase())).replace(/\s+/g, '').replace(/-/g, ' '); public camelCase = (str: string) => str?.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase()))?.replace(/\s+/g, '')?.replace(/-/g, ' ');
public titleCase = (str: string) => { public titleCase = (str: string) => {
if (str.indexOf('!\n') > 0 || str.indexOf('.\n') > 0) { if (str.indexOf('!\n') > 0 || str.indexOf('.\n') > 0) {
return str.split('\n').reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + '\n', ''); return str.split('\n')?.reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + '\n', '');
} else { } else {
if (str.indexOf(' ') > 0) { if (str.indexOf(' ') > 0) {
return str.split(' ').reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + ' ', ''); return str.split(' ')?.reduce((accumulator, currentStr) => accumulator + currentStr.charAt(0).toUpperCase() + currentStr.substring(1).toLowerCase() + ' ', '');
} else { } else {
return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase(); return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
} }
@ -345,7 +345,7 @@ export class CommonService {
public createDirectory = (directoryName) => { public createDirectory = (directoryName) => {
const initDir = isAbsolute(directoryName) ? sep : ''; const initDir = isAbsolute(directoryName) ? sep : '';
directoryName.split(sep).reduce((parentDir, childDir) => { directoryName.split(sep)?.reduce((parentDir, childDir) => {
const curDir = resolve(parentDir, childDir); const curDir = resolve(parentDir, childDir);
try { try {
if (!fs.existsSync(curDir)) { if (!fs.existsSync(curDir)) {
@ -412,7 +412,7 @@ export class CommonService {
public isVersionCompatible = (currentVersion, checkVersion) => { public isVersionCompatible = (currentVersion, checkVersion) => {
if (currentVersion) { if (currentVersion) {
const versionsArr = currentVersion.trim().replace('v', '').split('-')[0].split('.') || []; const versionsArr = currentVersion.trim()?.replace('v', '').split('-')[0].split('.') || [];
const checkVersionsArr = checkVersion.split('.'); const checkVersionsArr = checkVersion.split('.');
return (+versionsArr[0] > +checkVersionsArr[0]) || return (+versionsArr[0] > +checkVersionsArr[0]) ||
(+versionsArr[0] === +checkVersionsArr[0] && +versionsArr[1] > +checkVersionsArr[1]) || (+versionsArr[0] === +checkVersionsArr[0] && +versionsArr[1] > +checkVersionsArr[1]) ||

@ -42,7 +42,7 @@ export class RTLWebSocketServer {
const acceptKey = request.headers['sec-websocket-key']; const acceptKey = request.headers['sec-websocket-key'];
const hash = this.generateAcceptValue(acceptKey); const hash = this.generateAcceptValue(acceptKey);
const responseHeaders = ['HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + hash]; const responseHeaders = ['HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + hash];
const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',')?.map((s) => s.trim());
if (protocols.includes('json')) { responseHeaders.push('Sec-WebSocket-Protocol: json'); } if (protocols.includes('json')) { responseHeaders.push('Sec-WebSocket-Protocol: json'); }
this.webSocketServer.handleUpgrade(request, socket, head, this.upgradeCallback); this.webSocketServer.handleUpgrade(request, socket, head, this.upgradeCallback);
}); });
@ -56,7 +56,7 @@ export class RTLWebSocketServer {
}; };
public mountEventsOnConnection = (websocket, request) => { public mountEventsOnConnection = (websocket, request) => {
const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',').map((s) => s.trim()); const protocols = !request.headers['sec-websocket-protocol'] ? [] : request.headers['sec-websocket-protocol'].split(',')?.map((s) => s.trim());
const cookies = parse(request.headers.cookie); const cookies = parse(request.headers.cookie);
websocket.clientId = Date.now(); websocket.clientId = Date.now();
websocket.isAlive = true; websocket.isAlive = true;

@ -155,8 +155,8 @@ export class CLNHomeComponent implements OnInit, OnDestroy {
this.totalOutboundLiquidity = 0; this.totalOutboundLiquidity = 0;
this.activeChannels = channelsSeletor.activeChannels; this.activeChannels = channelsSeletor.activeChannels;
this.activeChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels, 'balancedness'))) || []; this.activeChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels, 'balancedness'))) || [];
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels.filter((channel) => (channel.msatoshi_to_them ? channel.msatoshi_to_them > 0 : false)), 'msatoshi_to_them'))) || []; this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.msatoshi_to_them ? channel.msatoshi_to_them > 0 : false)), 'msatoshi_to_them'))) || [];
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels.filter((channel) => (channel.msatoshi_to_us ? channel.msatoshi_to_us > 0 : false)), 'msatoshi_to_us'))) || []; this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.msatoshi_to_us ? channel.msatoshi_to_us > 0 : false)), 'msatoshi_to_us'))) || [];
this.activeChannels.forEach((channel) => { this.activeChannels.forEach((channel) => {
this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil((channel.msatoshi_to_them || 0) / 1000); this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil((channel.msatoshi_to_them || 0) / 1000);
this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor((channel.msatoshi_to_us || 0) / 1000); this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor((channel.msatoshi_to_us || 0) / 1000);

@ -80,7 +80,7 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
subscribe({ subscribe({
next: ([infoSettingsBalSelector, nodeListRes]) => { next: ([infoSettingsBalSelector, nodeListRes]) => {
this.information = infoSettingsBalSelector.information; this.information = infoSettingsBalSelector.information;
this.totalBalance = infoSettingsBalSelector.balance.totalBalance; this.totalBalance = infoSettingsBalSelector.balance.totalBalance || 0;
this.logger.info(infoSettingsBalSelector); this.logger.info(infoSettingsBalSelector);
if (nodeListRes && !(<any[]>nodeListRes).length) { nodeListRes = []; } if (nodeListRes && !(<any[]>nodeListRes).length) { nodeListRes = []; }
this.logger.info('Received Liquidity Ads Enabled Nodes: ' + JSON.stringify(nodeListRes)); this.logger.info('Received Liquidity Ads Enabled Nodes: ' + JSON.stringify(nodeListRes));
@ -108,7 +108,7 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
onCalculateOpeningFee() { onCalculateOpeningFee() {
this.liquidityNodesData.forEach((lqNode) => { this.liquidityNodesData.forEach((lqNode) => {
if (lqNode.option_will_fund) { if (lqNode.option_will_fund) {
lqNode.channelOpeningFee = (+(lqNode.option_will_fund.lease_fee_base_msat) / 1000) + (this.channelAmount * (+lqNode.option_will_fund.lease_fee_basis) / 10000) + ((+lqNode.option_will_fund.funding_weight / 4) * this.channelOpeningFeeRate); lqNode.channelOpeningFee = (+(lqNode.option_will_fund.lease_fee_base_msat || 0) / 1000) + (this.channelAmount * (+(lqNode.option_will_fund.lease_fee_basis || 0)) / 10000) + ((+(lqNode.option_will_fund.funding_weight || 0) / 4) * this.channelOpeningFeeRate);
} }
}); });
if (this.paginator) { this.paginator.firstPage(); } if (this.paginator) { this.paginator.firstPage(); }
@ -124,7 +124,7 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
this.liquidityNodes.sort = this.sort; this.liquidityNodes.sort = this.sort;
this.liquidityNodes.paginator = this.paginator; this.liquidityNodes.paginator = this.paginator;
if (this.sort) { this.sort.sort({ id: 'channelOpeningFee', start: 'asc', disableClear: true }); } if (this.sort) { this.sort.sort({ id: 'channelOpeningFee', start: 'asc', disableClear: true }); }
this.liquidityNodes.filterPredicate = (node: LookupNode, fltr: string) => node.channelCount >= this.channelCount && node.nodeCapacity >= this.nodeCapacity; this.liquidityNodes.filterPredicate = (node: LookupNode, fltr: string) => (node.channelCount || 0) >= this.channelCount && (node.nodeCapacity || 0) >= this.nodeCapacity;
this.onFilter(); this.onFilter();
} }
@ -156,19 +156,19 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
} }
onViewLeaseInfo(lqNode: LookupNode) { onViewLeaseInfo(lqNode: LookupNode) {
const addArr = lqNode.addresses.reduce((acc, curr) => { const addArr = lqNode.addresses?.reduce((acc, curr) => {
if (curr.address && curr.address.length > 40) { curr.address = curr.address.substring(0, 39) + '...'; } if (curr.address && curr.address.length > 40) { curr.address = curr.address.substring(0, 39) + '...'; }
return acc.concat(JSON.stringify(curr).replace('{', '').replace('}', '').replace(/:/g, ': ').replace(/,/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;').replace(/"/g, '')); return acc.concat(JSON.stringify(curr)?.replace('{', '')?.replace('}', '')?.replace(/:/g, ': ')?.replace(/,/g, '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;')?.replace(/"/g, ''));
}, []); }, <any[]>[]);
const reorderedLQNode = [ const reorderedLQNode = [
[{ key: 'alias', value: lqNode.alias, title: 'Node Alias', width: 50, type: DataTypeEnum.STRING }, [{ key: 'alias', value: lqNode.alias, title: 'Node Alias', width: 50, type: DataTypeEnum.STRING },
{ key: 'last_timestamp', value: lqNode.last_timestamp, title: 'Last Timestamp', width: 50, type: DataTypeEnum.DATE_TIME }], { key: 'last_timestamp', value: lqNode.last_timestamp, title: 'Last Timestamp', width: 50, type: DataTypeEnum.DATE_TIME }],
[{ key: 'nodeid', value: lqNode.nodeid, title: 'Node ID', width: 100, type: DataTypeEnum.STRING }], [{ key: 'nodeid', value: lqNode.nodeid, title: 'Node ID', width: 100, type: DataTypeEnum.STRING }],
[{ key: 'base_fee', value: (lqNode.option_will_fund.lease_fee_base_msat / 1000), title: 'Lease Base Fee (Sats)', width: 50, type: DataTypeEnum.NUMBER }, [{ key: 'base_fee', value: ((lqNode.option_will_fund?.lease_fee_base_msat || 0) / 1000), title: 'Lease Base Fee (Sats)', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'fee_basis', value: lqNode.option_will_fund.lease_fee_basis, title: 'Lease Base Basis (bps)', width: 50, type: DataTypeEnum.NUMBER }], { key: 'fee_basis', value: lqNode.option_will_fund?.lease_fee_basis, title: 'Lease Base Basis (bps)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'channel_max_base', value: lqNode.option_will_fund.channel_fee_max_base_msat / 1000, title: 'Max Channel Routing Base Fee (Sats)', width: 50, type: DataTypeEnum.NUMBER }, [{ key: 'channel_max_base', value: (lqNode.option_will_fund?.channel_fee_max_base_msat || 0) / 1000, title: 'Max Channel Routing Base Fee (Sats)', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'channel_max_rate', value: lqNode.option_will_fund.channel_fee_max_proportional_thousandths * 1000, title: 'Max Channel Routing Fee Rate (ppm)', width: 50, type: DataTypeEnum.NUMBER }], { key: 'channel_max_rate', value: (lqNode.option_will_fund?.channel_fee_max_proportional_thousandths || 0) * 1000, title: 'Max Channel Routing Fee Rate (ppm)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'funding_rate', value: lqNode.option_will_fund.funding_weight, title: 'Funding Weight', width: 100, type: DataTypeEnum.NUMBER }], [{ key: 'funding_rate', value: (lqNode.option_will_fund?.funding_weight || 0), title: 'Funding Weight', width: 100, type: DataTypeEnum.NUMBER }],
[{ key: 'address', value: addArr, title: 'Address', width: 100, type: DataTypeEnum.ARRAY }] [{ key: 'address', value: addArr, title: 'Address', width: 100, type: DataTypeEnum.ARRAY }]
]; ];
this.store.dispatch(openConfirmation({ this.store.dispatch(openConfirmation({

@ -136,7 +136,7 @@ export class CLNOnChainSendModalComponent implements OnInit, OnDestroy {
}); });
this.store.select(utxos).pipe(takeUntil(this.unSubs[3])). this.store.select(utxos).pipe(takeUntil(this.unSubs[3])).
subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
this.utxos = this.commonService.sortAscByKey(utxosSeletor.utxos.filter((utxo) => utxo.status === 'confirmed'), 'value'); this.utxos = this.commonService.sortAscByKey(utxosSeletor.utxos?.filter((utxo) => utxo.status === 'confirmed'), 'value');
this.logger.info(utxosSeletor); this.logger.info(utxosSeletor);
}); });
this.actions.pipe( this.actions.pipe(
@ -274,7 +274,7 @@ export class CLNOnChainSendModalComponent implements OnInit, OnDestroy {
onUTXOSelectionChange(event: any) { onUTXOSelectionChange(event: any) {
const utxoNew = { value: 0 }; const utxoNew = { value: 0 };
if (this.selUTXOs.length && this.selUTXOs.length > 0) { if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => { this.totalSelectedUTXOAmount = this.selUTXOs?.reduce((a, b) => {
utxoNew.value = a.value + b.value; utxoNew.value = a.value + b.value;
return utxoNew; return utxoNew;
}).value; }).value;
@ -307,7 +307,7 @@ export class CLNOnChainSendModalComponent implements OnInit, OnDestroy {
subscribe({ subscribe({
next: (data) => { next: (data) => {
this.selAmountUnit = event.value; this.selAmountUnit = event.value;
self.transaction.satoshis = self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit]).replace(/,/g, ''); self.transaction.satoshis = self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit])?.replace(/,/g, '');
}, error: (err) => { }, error: (err) => {
self.transaction.satoshis = null; self.transaction.satoshis = null;
this.amountError = 'Conversion Error: ' + err; this.amountError = 'Conversion Error: ' + err;

@ -33,7 +33,7 @@ export class CLNUTXOTablesComponent implements OnInit, OnDestroy {
if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) { if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) {
this.utxos = utxosSeletor.utxos; this.utxos = utxosSeletor.utxos;
this.numUtxos = this.utxos.length; this.numUtxos = this.utxos.length;
this.dustUtxos = utxosSeletor.utxos.filter((utxo) => +utxo.value < 1000); this.dustUtxos = utxosSeletor.utxos?.filter((utxo) => +utxo.value < 1000);
this.numDustUtxos = this.dustUtxos.length; this.numDustUtxos = this.dustUtxos.length;
} }
if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) { if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) {

@ -56,7 +56,7 @@ export class CLNChannelsTablesComponent implements OnInit, OnDestroy {
}); });
this.store.select(utxos).pipe(takeUntil(this.unSubs[3])). this.store.select(utxos).pipe(takeUntil(this.unSubs[3])).
subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
this.utxos = this.commonService.sortAscByKey(utxosSeletor.utxos.filter((utxo) => utxo.status === 'confirmed'), 'value'); this.utxos = this.commonService.sortAscByKey(utxosSeletor.utxos?.filter((utxo) => utxo.status === 'confirmed'), 'value');
}); });
this.store.select(channels).pipe(takeUntil(this.unSubs[4])). this.store.select(channels).pipe(takeUntil(this.unSubs[4])).
subscribe((channelsSeletor: { activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((channelsSeletor: { activeChannels: Channel[], pendingChannels: Channel[], inactiveChannels: Channel[], apiCallStatus: ApiCallStatusPayload }) => {

@ -89,7 +89,7 @@ export class CLNOpenChannelComponent implements OnInit, OnDestroy {
} }
private filterPeers(newlySelectedPeer: string): Peer[] { private filterPeers(newlySelectedPeer: string): Peer[] {
return this.sortedPeers.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0); return this.sortedPeers?.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0);
} }
displayFn(peer: Peer): string { displayFn(peer: Peer): string {
@ -100,7 +100,7 @@ export class CLNOpenChannelComponent implements OnInit, OnDestroy {
this.channelConnectionError = ''; this.channelConnectionError = '';
this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.id) ? this.selectedPeer.value.id : null; this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.id) ? this.selectedPeer.value.id : null;
if (typeof this.selectedPeer.value === 'string') { if (typeof this.selectedPeer.value === 'string') {
const selPeer = this.peers.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0); const selPeer = this.peers?.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0);
if (selPeer.length === 1 && selPeer[0].id) { if (selPeer.length === 1 && selPeer[0].id) {
this.selectedPubkey = selPeer[0].id; this.selectedPubkey = selPeer[0].id;
} }
@ -152,7 +152,7 @@ export class CLNOpenChannelComponent implements OnInit, OnDestroy {
onUTXOSelectionChange(event: any) { onUTXOSelectionChange(event: any) {
const utxoNew = { value: 0 }; const utxoNew = { value: 0 };
if (this.selUTXOs.length && this.selUTXOs.length > 0) { if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => { this.totalSelectedUTXOAmount = this.selUTXOs?.reduce((a, b) => {
utxoNew.value = a.value + b.value; utxoNew.value = a.value + b.value;
return utxoNew; return utxoNew;
}).value; }).value;

@ -130,7 +130,7 @@ export class CLNRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const monthNumber = event.received_time ? new Date((+event.received_time) * 1000).getMonth() : 12; const monthNumber = event.received_time ? new Date((+event.received_time) * 1000).getMonth() : 12;
feeReport[monthNumber].value = event.fee ? feeReport[monthNumber].value + (+event.fee / 1000) : feeReport[monthNumber].value; feeReport[monthNumber].value = event.fee ? feeReport[monthNumber].value + (+event.fee / 1000) : feeReport[monthNumber].value;
feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1; feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1;
@ -141,7 +141,7 @@ export class CLNRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const dateNumber = event.received_time ? Math.floor((+event.received_time - startDateInSeconds) / this.secondsInADay) : 0; const dateNumber = event.received_time ? Math.floor((+event.received_time - startDateInSeconds) / this.secondsInADay) : 0;
feeReport[dateNumber].value = event.fee ? feeReport[dateNumber].value + (+event.fee / 1000) : feeReport[dateNumber].value; feeReport[dateNumber].value = event.fee ? feeReport[dateNumber].value + (+event.fee / 1000) : feeReport[dateNumber].value;
feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1; feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1;
@ -160,7 +160,7 @@ export class CLNRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const monthNumber = event.received_time ? new Date((+event.received_time) * 1000).getMonth() : 12; const monthNumber = event.received_time ? new Date((+event.received_time) * 1000).getMonth() : 12;
eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1; eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1;
eventsReport[monthNumber].extra.totalFees = event.fee ? eventsReport[monthNumber].extra.totalFees + (+event.fee / 1000) : eventsReport[monthNumber].extra.totalFees; eventsReport[monthNumber].extra.totalFees = event.fee ? eventsReport[monthNumber].extra.totalFees + (+event.fee / 1000) : eventsReport[monthNumber].extra.totalFees;
@ -171,7 +171,7 @@ export class CLNRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const dateNumber = event.received_time ? Math.floor((+event.received_time - startDateInSeconds) / this.secondsInADay) : 0; const dateNumber = event.received_time ? Math.floor((+event.received_time - startDateInSeconds) / this.secondsInADay) : 0;
eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1; eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1;
eventsReport[dateNumber].extra.totalFees = event.fee ? eventsReport[dateNumber].extra.totalFees + (+event.fee / 1000) : eventsReport[dateNumber].extra.totalFees; eventsReport[dateNumber].extra.totalFees = event.fee ? eventsReport[dateNumber].extra.totalFees + (+event.fee / 1000) : eventsReport[dateNumber].extra.totalFees;

@ -95,22 +95,22 @@ export class CLNTransactionsReportComponent implements OnInit, OnDestroy {
const endDateInSeconds = Math.round(end.getTime() / 1000); const endDateInSeconds = Math.round(end.getTime() / 1000);
const transactionsReport = []; const transactionsReport = [];
this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 }; this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 };
const filteredPayments = this.payments.filter((payment) => payment.status === 'complete' && payment.created_at >= startDateInSeconds && payment.created_at < endDateInSeconds); const filteredPayments = this.payments?.filter((payment) => payment.status === 'complete' && payment.created_at >= startDateInSeconds && payment.created_at < endDateInSeconds);
const filteredInvoices = this.invoices.filter((invoice) => invoice.status === 'paid' && invoice.paid_at >= startDateInSeconds && invoice.paid_at < endDateInSeconds); const filteredInvoices = this.invoices?.filter((invoice) => invoice.status === 'paid' && invoice.paid_at >= startDateInSeconds && invoice.paid_at < endDateInSeconds);
this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length; this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length;
this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length; this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length;
if (this.reportPeriod === SCROLL_RANGES[1]) { if (this.reportPeriod === SCROLL_RANGES[1]) {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const monthNumber = new Date((payment.created_at) * 1000).getMonth(); const monthNumber = new Date((payment.created_at) * 1000).getMonth();
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.msatoshi_sent; this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.msatoshi_sent;
transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + (payment.msatoshi_sent / 1000); transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + (payment.msatoshi_sent / 1000);
transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1; transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const monthNumber = new Date((+invoice.paid_at) * 1000).getMonth(); const monthNumber = new Date((+invoice.paid_at) * 1000).getMonth();
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.msatoshi_received; this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.msatoshi_received;
transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + (invoice.msatoshi_received / 1000); transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + (invoice.msatoshi_received / 1000);
@ -121,14 +121,14 @@ export class CLNTransactionsReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const dateNumber = Math.floor((+payment.created_at - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+payment.created_at - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.msatoshi_sent; this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.msatoshi_sent;
transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + (payment.msatoshi_sent / 1000); transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + (payment.msatoshi_sent / 1000);
transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1; transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const dateNumber = Math.floor((+invoice.paid_at - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+invoice.paid_at - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.msatoshi_received; this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.msatoshi_received;
transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + (invoice.msatoshi_received / 1000); transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + (invoice.msatoshi_received / 1000);
@ -140,7 +140,7 @@ export class CLNTransactionsReportComponent implements OnInit, OnDestroy {
} }
prepareTableData() { prepareTableData() {
return this.transactionsReportData.reduce((acc, curr) => { return this.transactionsReportData?.reduce((acc, curr) => {
if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) { if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) {
return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total }); return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total });
} }

@ -100,7 +100,7 @@ export class CLNFailedTransactionsComponent implements OnInit, AfterViewInit, On
{ key: 'fee', value: selFEvent.fee, title: 'Fee (mSats)', width: 34, type: DataTypeEnum.NUMBER }] { key: 'fee', value: selFEvent.fee, title: 'Fee (mSats)', width: 34, type: DataTypeEnum.NUMBER }]
]; ];
if (selFEvent.payment_hash) { if (selFEvent.payment_hash) {
reorderedFHEvent.unshift([{ key: 'payment_hash', value: selFEvent.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }]); reorderedFHEvent?.unshift([{ key: 'payment_hash', value: selFEvent.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }]);
} }
this.store.dispatch(openAlert({ this.store.dispatch(openAlert({
payload: { payload: {

@ -66,5 +66,5 @@
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> </table>
</div> </div>
<mat-paginator *ngIf="errorMessage === ''" [length]="totalForwardedTransactions" (page)="onPageChange($event)" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-1"></mat-paginator> <mat-paginator *ngIf="errorMessage === ''" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-1"></mat-paginator>
</div> </div>

@ -4,7 +4,7 @@ import { DatePipe } from '@angular/common';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil, take } from 'rxjs/operators'; import { takeUntil, take } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { MatPaginator, MatPaginatorIntl, PageEvent } from '@angular/material/paginator'; import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table';
@ -37,7 +37,6 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public forwardingHistoryEvents: any; public forwardingHistoryEvents: any;
public flgSticky = false; public flgSticky = false;
private indexOffset = -1;
public totalForwardedTransactions = 0; public totalForwardedTransactions = 0;
public pageSize = PAGE_SIZE; public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS; public pageSizeOptions = PAGE_SIZE_OPTIONS;
@ -81,7 +80,7 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
this.totalForwardedTransactions = fhSeletor.forwardingHistory.totalForwards || 0; this.totalForwardedTransactions = fhSeletor.forwardingHistory.totalForwards || 0;
this.successfulEvents = fhSeletor.forwardingHistory.listForwards || []; this.successfulEvents = fhSeletor.forwardingHistory.listForwards || [];
if (this.successfulEvents.length > 0 && this.sort && this.paginator) { if (this.successfulEvents.length > 0 && this.sort && this.paginator) {
this.loadForwardingEventsTable(this.successfulEvents.slice(0, this.pageSize)); this.loadForwardingEventsTable(this.successfulEvents);
} }
this.logger.info(fhSeletor); this.logger.info(fhSeletor);
} }
@ -90,7 +89,7 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
ngAfterViewInit() { ngAfterViewInit() {
if (this.successfulEvents.length > 0) { if (this.successfulEvents.length > 0) {
this.loadForwardingEventsTable(this.successfulEvents.slice(0, this.pageSize)); this.loadForwardingEventsTable(this.successfulEvents);
} }
} }
@ -99,11 +98,10 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
this.apiCallStatus = { status: APICallStatusEnum.COMPLETED, action: 'FetchForwardingHistory' }; this.apiCallStatus = { status: APICallStatusEnum.COMPLETED, action: 'FetchForwardingHistory' };
this.eventsData = changes.eventsData.currentValue; this.eventsData = changes.eventsData.currentValue;
this.successfulEvents = this.eventsData; this.successfulEvents = this.eventsData;
this.indexOffset = 0;
this.totalForwardedTransactions = this.eventsData.length; this.totalForwardedTransactions = this.eventsData.length;
if (this.paginator) { this.paginator.firstPage(); } if (this.paginator) { this.paginator.firstPage(); }
if (!changes.eventsData.firstChange) { if (!changes.eventsData.firstChange) {
this.loadForwardingEventsTable(this.successfulEvents.slice(0, this.pageSize)); this.loadForwardingEventsTable(this.successfulEvents);
} }
} }
if (changes.filterValue && !changes.filterValue.firstChange) { if (changes.filterValue && !changes.filterValue.firstChange) {
@ -146,6 +144,7 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
(event.in_msatoshi ? (event.in_msatoshi / 1000) + ' ' : '') + (event.out_msatoshi ? (event.out_msatoshi / 1000) + ' ' : '') + (event.fee ? event.fee + ' ' : ''); (event.in_msatoshi ? (event.in_msatoshi / 1000) + ' ' : '') + (event.out_msatoshi ? (event.out_msatoshi / 1000) + ' ' : '') + (event.fee ? event.fee + ' ' : '');
return newEvent.includes(fltr); return newEvent.includes(fltr);
}; };
this.forwardingHistoryEvents.paginator = this.paginator;
this.logger.info(this.forwardingHistoryEvents); this.logger.info(this.forwardingHistoryEvents);
} }
@ -161,16 +160,6 @@ export class CLNForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
} }
} }
onPageChange(event: PageEvent) {
if (this.pageSize !== event.pageSize) {
this.pageSize = event.pageSize;
this.indexOffset = 0;
} else {
this.indexOffset = event.pageIndex * this.pageSize;
}
this.loadForwardingEventsTable(this.successfulEvents.slice(this.indexOffset, (this.indexOffset + this.pageSize)));
}
ngOnDestroy() { ngOnDestroy() {
this.unSubs.forEach((completeSub) => { this.unSubs.forEach((completeSub) => {
completeSub.next(<any>null); completeSub.next(<any>null);

@ -7,7 +7,7 @@ import { GetInfo, Fees, Peer, Payment, QueryRoutes, Channel, FeeRates, Invoice,
export const updateCLAPICallStatus = createAction(CLNActions.UPDATE_API_CALL_STATUS_CLN, props<{ payload: ApiCallStatusPayload }>()); export const updateCLAPICallStatus = createAction(CLNActions.UPDATE_API_CALL_STATUS_CLN, props<{ payload: ApiCallStatusPayload }>());
export const resetCLStore = createAction(CLNActions.RESET_CLN_STORE, props<{ payload: SelNodeChild }>()); export const resetCLStore = createAction(CLNActions.RESET_CLN_STORE, props<{ payload: SelNodeChild | null }>());
export const setChildNodeSettingsCL = createAction(CLNActions.SET_CHILD_NODE_SETTINGS_CLN, props<{ payload: SelNodeChild }>()); export const setChildNodeSettingsCL = createAction(CLNActions.SET_CHILD_NODE_SETTINGS_CLN, props<{ payload: SelNodeChild }>());

@ -950,9 +950,9 @@ export class CLNEffects implements OnDestroy {
this.store.dispatch(setNodeData({ payload: node_data })); this.store.dispatch(setNodeData({ payload: node_data }));
let newRoute = this.location.path(); let newRoute = this.location.path();
if (newRoute.includes('/lnd/')) { if (newRoute.includes('/lnd/')) {
newRoute = newRoute.replace('/lnd/', '/cln/'); newRoute = newRoute?.replace('/lnd/', '/cln/');
} else if (newRoute.includes('/ecl/')) { } else if (newRoute.includes('/ecl/')) {
newRoute = newRoute.replace('/ecl/', '/cln/'); newRoute = newRoute?.replace('/ecl/', '/cln/');
} }
if (newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) { if (newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) {
newRoute = '/cln/home'; newRoute = '/cln/home';

@ -12,7 +12,7 @@ import { CLNForwardingEventsStatusEnum } from '../../shared/services/consts-enum
export const CLNReducer = createReducer(initCLNState, export const CLNReducer = createReducer(initCLNState,
on(updateCLAPICallStatus, (state, { payload }) => { on(updateCLAPICallStatus, (state, { payload }) => {
const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus)); const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus));
updatedApisCallStatus[payload.action] = { updatedApisCallStatus[payload.action || 0] = {
status: payload.status, status: payload.status,
statusCode: payload.statusCode, statusCode: payload.statusCode,
message: payload.message, message: payload.message,
@ -114,7 +114,7 @@ export const CLNReducer = createReducer(initCLNState,
switch (payload.status) { switch (payload.status) {
case CLNForwardingEventsStatusEnum.SETTLED: case CLNForwardingEventsStatusEnum.SETTLED:
const modifiedFeeWithTxCount = state.fees; const modifiedFeeWithTxCount = state.fees;
modifiedFeeWithTxCount.totalTxCount = payload.totalForwards | 0; modifiedFeeWithTxCount.totalTxCount = payload.totalForwards || 0;
return { return {
...state, ...state,
fees: modifiedFeeWithTxCount, fees: modifiedFeeWithTxCount,
@ -136,7 +136,7 @@ export const CLNReducer = createReducer(initCLNState,
}), }),
on(addInvoice, (state, { payload }) => { on(addInvoice, (state, { payload }) => {
const newInvoices = state.invoices; const newInvoices = state.invoices;
newInvoices.invoices.unshift(payload); newInvoices.invoices?.unshift(payload);
return { return {
...state, ...state,
invoices: newInvoices invoices: newInvoices
@ -148,7 +148,7 @@ export const CLNReducer = createReducer(initCLNState,
})), })),
on(updateInvoice, (state, { payload }) => { on(updateInvoice, (state, { payload }) => {
const modifiedInvoices = state.invoices; const modifiedInvoices = state.invoices;
modifiedInvoices.invoices = modifiedInvoices.invoices.map((invoice) => ((invoice.label === payload.label) ? payload : invoice)); modifiedInvoices.invoices = modifiedInvoices.invoices?.map((invoice) => ((invoice.label === payload.label) ? payload : invoice));
return { return {
...state, ...state,
invoices: modifiedInvoices invoices: modifiedInvoices
@ -164,7 +164,7 @@ export const CLNReducer = createReducer(initCLNState,
})), })),
on(addOffer, (state, { payload }) => { on(addOffer, (state, { payload }) => {
const newOffers = state.offers; const newOffers = state.offers;
newOffers.unshift(payload); newOffers?.unshift(payload);
return { return {
...state, ...state,
offers: newOffers offers: newOffers
@ -189,7 +189,7 @@ export const CLNReducer = createReducer(initCLNState,
const newOfferBMs: OfferBookmark[] = [...state.offersBookmarks]; const newOfferBMs: OfferBookmark[] = [...state.offersBookmarks];
const offerBMExistsIdx = newOfferBMs.findIndex((offer: OfferBookmark) => offer.bolt12 === payload.bolt12); const offerBMExistsIdx = newOfferBMs.findIndex((offer: OfferBookmark) => offer.bolt12 === payload.bolt12);
if (offerBMExistsIdx < 0) { if (offerBMExistsIdx < 0) {
newOfferBMs.unshift(payload); newOfferBMs?.unshift(payload);
} else { } else {
const updatedOffer = { ...newOfferBMs[offerBMExistsIdx] }; const updatedOffer = { ...newOfferBMs[offerBMExistsIdx] };
updatedOffer.title = payload.title; updatedOffer.title = payload.title;
@ -226,7 +226,7 @@ const mapAliases = (payload: any, storedChannels: Channel[]) => {
fhEvent.in_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : fhEvent.in_channel; fhEvent.in_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : fhEvent.in_channel;
if (fhEvent.out_channel_alias) { return; } if (fhEvent.out_channel_alias) { return; }
} }
if (storedChannels[idx].short_channel_id && storedChannels[idx].short_channel_id.toString() === fhEvent.out_channel) { if (storedChannels[idx].short_channel_id && storedChannels[idx].short_channel_id?.toString() === fhEvent.out_channel) {
fhEvent.out_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : fhEvent.out_channel; fhEvent.out_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : fhEvent.out_channel;
if (fhEvent.in_channel_alias) { return; } if (fhEvent.in_channel_alias) { return; }
} }

@ -5,7 +5,7 @@ import { ApiCallsListCL } from '../../shared/models/apiCallsPayload';
export interface CLNState { export interface CLNState {
apisCallStatus: ApiCallsListCL; apisCallStatus: ApiCallsListCL;
nodeSettings: SelNodeChild; nodeSettings: SelNodeChild | null;
information: GetInfo; information: GetInfo;
fees: Fees; fees: Fees;
feeRatesPerKB: FeeRates; feeRatesPerKB: FeeRates;

@ -214,7 +214,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
} }
updateInvoicesData(newInvoice: Invoice) { updateInvoicesData(newInvoice: Invoice) {
this.invoiceJSONArr = this.invoiceJSONArr.map((invoice) => ((invoice.label === newInvoice.label) ? newInvoice : invoice)); this.invoiceJSONArr = this.invoiceJSONArr?.map((invoice) => ((invoice.label === newInvoice.label) ? newInvoice : invoice));
} }
loadInvoicesTable(invs: Invoice[]) { loadInvoicesTable(invs: Invoice[]) {

@ -41,12 +41,12 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
public faHistory = faHistory; public faHistory = faHistory;
public newlyAddedPayment = ''; public newlyAddedPayment = '';
public selNode: SelNodeChild = {}; public selNode: SelNodeChild | null = {};
public information: GetInfo = {}; public information: GetInfo = {};
public payments: any; public payments: any;
public paymentJSONArr: Payment[] = []; public paymentJSONArr: Payment[] = [];
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public mppColumns = []; public mppColumns: string[] = [];
public paymentDecoded: PayRequest = {}; public paymentDecoded: PayRequest = {};
public paymentRequest = ''; public paymentRequest = '';
public paymentDecodedHint = ''; public paymentDecodedHint = '';
@ -83,7 +83,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
} }
ngOnInit() { ngOnInit() {
this.store.select(clnNodeSettings).pipe(takeUntil(this.unSubs[0])).subscribe((nodeSettings: SelNodeChild) => { this.store.select(clnNodeSettings).pipe(takeUntil(this.unSubs[0])).subscribe((nodeSettings: SelNodeChild | null) => {
this.selNode = nodeSettings; this.selNode = nodeSettings;
}); });
this.store.select(clnNodeInformation).pipe(takeUntil(this.unSubs[1])).subscribe((nodeInfo: GetInfo) => { this.store.select(clnNodeInformation).pipe(takeUntil(this.unSubs[1])).subscribe((nodeInfo: GetInfo) => {
@ -111,7 +111,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
} }
is_group(index: number, payment: Payment): boolean { is_group(index: number, payment: Payment): boolean {
return payment.is_group; return payment.is_group || false;
} }
onSendPayment(): boolean | void { onSendPayment(): boolean | void {
@ -137,7 +137,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
} }
sendPayment() { sendPayment() {
this.newlyAddedPayment = this.paymentDecoded.payment_hash; this.newlyAddedPayment = this.paymentDecoded?.payment_hash || '';
if (!this.paymentDecoded.msatoshi || this.paymentDecoded.msatoshi === 0) { if (!this.paymentDecoded.msatoshi || this.paymentDecoded.msatoshi === 0) {
const reorderedPaymentDecoded = [ const reorderedPaymentDecoded = [
[{ key: 'payment_hash', value: this.paymentDecoded.payment_hash, title: 'Payment Hash', width: 100 }], [{ key: 'payment_hash', value: this.paymentDecoded.payment_hash, title: 'Payment Hash', width: 100 }],
@ -213,8 +213,8 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
pipe(takeUntil(this.unSubs[1])).subscribe((decodedPayment: PayRequest) => { pipe(takeUntil(this.unSubs[1])).subscribe((decodedPayment: PayRequest) => {
this.paymentDecoded = decodedPayment; this.paymentDecoded = decodedPayment;
if (this.paymentDecoded.msatoshi) { if (this.paymentDecoded.msatoshi) {
if (this.selNode.fiatConversion) { if (this.selNode?.fiatConversion) {
this.commonService.convertCurrency(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, this.selNode.currencyUnits[2], this.selNode.fiatConversion). this.commonService.convertCurrency(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
pipe(takeUntil(this.unSubs[3])). pipe(takeUntil(this.unSubs[3])).
subscribe({ subscribe({
next: (data) => { next: (data) => {
@ -260,19 +260,19 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
{ key: 'msatoshi_sent', value: selPayment.msatoshi_sent, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER }] { key: 'msatoshi_sent', value: selPayment.msatoshi_sent, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER }]
]; ];
if (selPayment.bolt11 && selPayment.bolt11 !== '') { if (selPayment.bolt11 && selPayment.bolt11 !== '') {
reorderedPayment.unshift([{ key: 'bolt11', value: selPayment.bolt11, title: 'Bolt 11', width: 100, type: DataTypeEnum.STRING }]); reorderedPayment?.unshift([{ key: 'bolt11', value: selPayment.bolt11, title: 'Bolt 11', width: 100, type: DataTypeEnum.STRING }]);
} }
if (selPayment.bolt12 && selPayment.bolt12 !== '') { if (selPayment.bolt12 && selPayment.bolt12 !== '') {
reorderedPayment.unshift([{ key: 'bolt12', value: selPayment.bolt12, title: 'Bolt 12', width: 100, type: DataTypeEnum.STRING }]); reorderedPayment?.unshift([{ key: 'bolt12', value: selPayment.bolt12, title: 'Bolt 12', width: 100, type: DataTypeEnum.STRING }]);
} }
if (selPayment.memo && selPayment.memo !== '') { if (selPayment.memo && selPayment.memo !== '') {
reorderedPayment.splice(2, 0, [{ key: 'memo', value: selPayment.memo, title: 'Memo', width: 100, type: DataTypeEnum.STRING }]); reorderedPayment?.splice(2, 0, [{ key: 'memo', value: selPayment.memo, title: 'Memo', width: 100, type: DataTypeEnum.STRING }]);
} }
if (selPayment.hasOwnProperty('partid')) { if (selPayment.hasOwnProperty('partid')) {
reorderedPayment.unshift([{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 80, type: DataTypeEnum.STRING }, reorderedPayment?.unshift([{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 80, type: DataTypeEnum.STRING },
{ key: 'partid', value: selPayment.partid, title: 'Part ID', width: 20, type: DataTypeEnum.STRING }]); { key: 'partid', value: selPayment.partid, title: 'Part ID', width: 20, type: DataTypeEnum.STRING }]);
} else { } else {
reorderedPayment.unshift([{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }]); reorderedPayment?.unshift([{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }]);
} }
this.store.dispatch(openAlert({ this.store.dispatch(openAlert({
payload: { payload: {
@ -295,7 +295,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
this.payments.sort = this.sort; this.payments.sort = this.sort;
this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null); this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.payments.filterPredicate = (rowData: Payment, fltr: string) => { this.payments.filterPredicate = (rowData: Payment, fltr: string) => {
const newRowData = ((rowData.created_at) ? this.datePipe.transform(new Date(rowData.created_at * 1000), 'dd/MMM/YYYY HH:mm').toLowerCase() : '') + ((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase(); const newRowData = ((rowData.created_at) ? this.datePipe.transform(new Date(rowData.created_at * 1000), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + ((rowData.bolt12) ? 'bolt12' : (rowData.bolt11) ? 'bolt11' : 'keysend') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr); return newRowData.includes(fltr);
}; };
this.payments.paginator = this.paginator; this.payments.paginator = this.paginator;
@ -305,7 +305,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
onDownloadCSV() { onDownloadCSV() {
if (this.payments.data && this.payments.data.length > 0) { if (this.payments.data && this.payments.data.length > 0) {
const paymentsDataCopy = JSON.parse(JSON.stringify(this.payments.data)); const paymentsDataCopy = JSON.parse(JSON.stringify(this.payments.data));
const flattenedPayments = paymentsDataCopy.reduce((acc, curr) => { const flattenedPayments = paymentsDataCopy?.reduce((acc, curr) => {
if (curr.mpps) { if (curr.mpps) {
return acc.concat(curr.mpps); return acc.concat(curr.mpps);
} else { } else {

@ -167,8 +167,8 @@ export class ECLHomeComponent implements OnInit, OnDestroy {
this.totalInboundLiquidity = 0; this.totalInboundLiquidity = 0;
this.totalOutboundLiquidity = 0; this.totalOutboundLiquidity = 0;
this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels, 'balancedness'))); this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels, 'balancedness')));
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels.filter((channel) => channel.toRemote > 0), 'toRemote'))); this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels?.filter((channel) => channel.toRemote > 0), 'toRemote')));
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels.filter((channel) => channel.toLocal > 0), 'toLocal'))); this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.channels?.filter((channel) => channel.toLocal > 0), 'toLocal')));
this.channels.forEach((channel) => { this.channels.forEach((channel) => {
this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil(channel.toRemote); this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil(channel.toRemote);
this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor(channel.toLocal); this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor(channel.toLocal);

@ -112,7 +112,7 @@ export class ECLOnChainSendModalComponent implements OnInit, OnDestroy {
subscribe({ subscribe({
next: (data) => { next: (data) => {
this.selAmountUnit = event.value; this.selAmountUnit = event.value;
self.transaction.amount = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit]).replace(/,/g, ''); self.transaction.amount = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit])?.replace(/,/g, '');
}, error: (err) => { }, error: (err) => {
self.transaction.amount = null; self.transaction.amount = null;
this.amountError = 'Conversion Error: ' + err; this.amountError = 'Conversion Error: ' + err;

@ -73,7 +73,7 @@ export class ECLOpenChannelComponent implements OnInit, OnDestroy {
} }
private filterPeers(newlySelectedPeer: string): Peer[] { private filterPeers(newlySelectedPeer: string): Peer[] {
return this.sortedPeers.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0); return this.sortedPeers?.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0);
} }
displayFn(peer: Peer): string { displayFn(peer: Peer): string {
@ -84,7 +84,7 @@ export class ECLOpenChannelComponent implements OnInit, OnDestroy {
this.channelConnectionError = ''; this.channelConnectionError = '';
this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.nodeId) ? this.selectedPeer.value.nodeId : null; this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.nodeId) ? this.selectedPeer.value.nodeId : null;
if (typeof this.selectedPeer.value === 'string') { if (typeof this.selectedPeer.value === 'string') {
const selPeer = this.peers.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0); const selPeer = this.peers?.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0);
if (selPeer.length === 1 && selPeer[0].nodeId) { if (selPeer.length === 1 && selPeer[0].nodeId) {
this.selectedPubkey = selPeer[0].nodeId; this.selectedPubkey = selPeer[0].nodeId;
} }

@ -115,7 +115,7 @@ export class ECLRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const monthNumber = new Date(event.timestamp).getMonth(); const monthNumber = new Date(event.timestamp).getMonth();
feeReport[monthNumber].value = feeReport[monthNumber].value + (event.amountIn - event.amountOut); feeReport[monthNumber].value = feeReport[monthNumber].value + (event.amountIn - event.amountOut);
feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1; feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1;
@ -126,7 +126,7 @@ export class ECLRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const dateNumber = Math.floor((Math.floor(event.timestamp / 1000) - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((Math.floor(event.timestamp / 1000) - startDateInSeconds) / this.secondsInADay);
feeReport[dateNumber].value = feeReport[dateNumber].value + (event.amountIn - event.amountOut); feeReport[dateNumber].value = feeReport[dateNumber].value + (event.amountIn - event.amountOut);
feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1; feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1;
@ -147,7 +147,7 @@ export class ECLRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const monthNumber = new Date(event.timestamp).getMonth(); const monthNumber = new Date(event.timestamp).getMonth();
eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1; eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1;
eventsReport[monthNumber].extra.totalFees = eventsReport[monthNumber].extra.totalFees + (event.amountIn - event.amountOut); eventsReport[monthNumber].extra.totalFees = eventsReport[monthNumber].extra.totalFees + (event.amountIn - event.amountOut);
@ -158,7 +158,7 @@ export class ECLRoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } });
} }
this.filteredEventsBySelectedPeriod.map((event) => { this.filteredEventsBySelectedPeriod?.map((event) => {
const dateNumber = Math.floor((Math.floor(event.timestamp / 1000) - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((Math.floor(event.timestamp / 1000) - startDateInSeconds) / this.secondsInADay);
eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1; eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1;
eventsReport[dateNumber].extra.totalFees = eventsReport[dateNumber].extra.totalFees + (event.amountIn - event.amountOut); eventsReport[dateNumber].extra.totalFees = eventsReport[dateNumber].extra.totalFees + (event.amountIn - event.amountOut);

@ -97,22 +97,22 @@ export class ECLTransactionsReportComponent implements OnInit, OnDestroy {
const endDateInSeconds = Math.round(end.getTime() / 1000); const endDateInSeconds = Math.round(end.getTime() / 1000);
const transactionsReport = []; const transactionsReport = [];
this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 }; this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 };
const filteredPayments = this.payments.filter((payment) => Math.floor(payment.firstPartTimestamp / 1000) >= startDateInSeconds && Math.floor(payment.firstPartTimestamp / 1000) < endDateInSeconds); const filteredPayments = this.payments?.filter((payment) => Math.floor(payment.firstPartTimestamp / 1000) >= startDateInSeconds && Math.floor(payment.firstPartTimestamp / 1000) < endDateInSeconds);
const filteredInvoices = this.invoices.filter((invoice) => invoice.status === 'received' && invoice.timestamp >= startDateInSeconds && invoice.timestamp < endDateInSeconds); const filteredInvoices = this.invoices?.filter((invoice) => invoice.status === 'received' && invoice.timestamp >= startDateInSeconds && invoice.timestamp < endDateInSeconds);
this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length; this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length;
this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length; this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length;
if (this.reportPeriod === SCROLL_RANGES[1]) { if (this.reportPeriod === SCROLL_RANGES[1]) {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const monthNumber = new Date(payment.firstPartTimestamp).getMonth(); const monthNumber = new Date(payment.firstPartTimestamp).getMonth();
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.recipientAmount; this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.recipientAmount;
transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + payment.recipientAmount; transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + payment.recipientAmount;
transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1; transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const monthNumber = new Date((invoice.timestamp) * 1000).getMonth(); const monthNumber = new Date((invoice.timestamp) * 1000).getMonth();
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.amountSettled; this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.amountSettled;
transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + invoice.amountSettled; transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + invoice.amountSettled;
@ -123,14 +123,14 @@ export class ECLTransactionsReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const dateNumber = Math.floor((Math.floor(payment.firstPartTimestamp / 1000) - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((Math.floor(payment.firstPartTimestamp / 1000) - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.recipientAmount; this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + payment.recipientAmount;
transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + payment.recipientAmount; transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + payment.recipientAmount;
transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1; transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const dateNumber = Math.floor((invoice.timestamp - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((invoice.timestamp - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.amountSettled; this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + invoice.amountSettled;
transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + invoice.amountSettled; transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + invoice.amountSettled;
@ -142,7 +142,7 @@ export class ECLTransactionsReportComponent implements OnInit, OnDestroy {
} }
prepareTableData() { prepareTableData() {
return this.transactionsReportData.reduce((acc, curr) => { return this.transactionsReportData?.reduce((acc, curr) => {
if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) { if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) {
return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total }); return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total });
} }

@ -29,7 +29,7 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
@ViewChild(MatSort, { static: false }) sort: MatSort | undefined; @ViewChild(MatSort, { static: false }) sort: MatSort | undefined;
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined; @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator | undefined;
@Input() eventsData = []; @Input() eventsData: PaymentRelayed[] = [];
@Input() filterValue = ''; @Input() filterValue = '';
public displayedColumns: any[] = []; public displayedColumns: any[] = [];
public forwardingHistoryEvents: any; public forwardingHistoryEvents: any;
@ -100,8 +100,8 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
onForwardingEventClick(selFEvent: PaymentRelayed, event: any) { onForwardingEventClick(selFEvent: PaymentRelayed, event: any) {
const reorderedFHEvent = [ const reorderedFHEvent = [
[{ key: 'paymentHash', value: selFEvent.paymentHash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }], [{ key: 'paymentHash', value: selFEvent.paymentHash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }],
[{ key: 'timestamp', value: Math.round(selFEvent.timestamp / 1000), title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME }, [{ key: 'timestamp', value: Math.round((selFEvent.timestamp || 0) / 1000), title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME },
{ key: 'fee', value: (selFEvent.amountIn - selFEvent.amountOut), title: 'Fee Earned (Sats)', width: 50, type: DataTypeEnum.NUMBER }], { key: 'fee', value: ((selFEvent.amountIn || 0) - (selFEvent.amountOut || 0)), title: 'Fee Earned (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'amountIn', value: selFEvent.amountIn, title: 'Amount In (Sats)', width: 50, type: DataTypeEnum.NUMBER }, [{ key: 'amountIn', value: selFEvent.amountIn, title: 'Amount In (Sats)', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'amountOut', value: selFEvent.amountOut, title: 'Amount Out (Sats)', width: 50, type: DataTypeEnum.NUMBER }], { key: 'amountOut', value: selFEvent.amountOut, title: 'Amount Out (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'fromChannelAlias', value: selFEvent.fromChannelAlias, title: 'From Channel Alias', width: 50, type: DataTypeEnum.STRING }, [{ key: 'fromChannelAlias', value: selFEvent.fromChannelAlias, title: 'From Channel Alias', width: 50, type: DataTypeEnum.STRING },
@ -112,7 +112,7 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
[{ key: 'toChannelId', value: selFEvent.toChannelId, title: 'To Channel Id', width: 100, type: DataTypeEnum.STRING }] [{ key: 'toChannelId', value: selFEvent.toChannelId, title: 'To Channel Id', width: 100, type: DataTypeEnum.STRING }]
]; ];
if (selFEvent.type !== 'payment-relayed') { if (selFEvent.type !== 'payment-relayed') {
reorderedFHEvent.unshift([{ key: 'type', value: this.commonService.camelCase(selFEvent.type), title: 'Relay Type', width: 100, type: DataTypeEnum.STRING }]); reorderedFHEvent?.unshift([{ key: 'type', value: this.commonService.camelCase(selFEvent.type), title: 'Relay Type', width: 100, type: DataTypeEnum.STRING }]);
} }
this.store.dispatch(openAlert({ this.store.dispatch(openAlert({
payload: { payload: {
@ -138,7 +138,7 @@ export class ECLForwardingHistoryComponent implements OnInit, OnChanges, AfterVi
} }
}; };
this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => { this.forwardingHistoryEvents.filterPredicate = (rowData: PaymentRelayed, fltr: string) => {
const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp), 'dd/MMM/YYYY HH:mm').toLowerCase() : '') + JSON.stringify(rowData).toLowerCase(); const newRowData = ((rowData.timestamp) ? this.datePipe.transform(new Date(rowData.timestamp), 'dd/MMM/YYYY HH:mm')?.toLowerCase() : '') + JSON.stringify(rowData).toLowerCase();
return newRowData.includes(fltr); return newRowData.includes(fltr);
}; };
this.forwardingHistoryEvents.paginator = this.paginator; this.forwardingHistoryEvents.paginator = this.paginator;

@ -7,7 +7,7 @@ import { GetInfo, Channel, Fees, Peer, LightningBalance, OnChainBalance, Channel
export const updateECLAPICallStatus = createAction(ECLActions.UPDATE_API_CALL_STATUS_ECL, props<{ payload: ApiCallStatusPayload }>()); export const updateECLAPICallStatus = createAction(ECLActions.UPDATE_API_CALL_STATUS_ECL, props<{ payload: ApiCallStatusPayload }>());
export const resetECLStore = createAction(ECLActions.RESET_ECL_STORE, props<{ payload: SelNodeChild }>()); export const resetECLStore = createAction(ECLActions.RESET_ECL_STORE, props<{ payload: SelNodeChild | null }>());
export const setChildNodeSettingsECL = createAction(ECLActions.SET_CHILD_NODE_SETTINGS_ECL, props<{ payload: SelNodeChild }>()); export const setChildNodeSettingsECL = createAction(ECLActions.SET_CHILD_NODE_SETTINGS_ECL, props<{ payload: SelNodeChild }>());

@ -86,7 +86,7 @@ export class ECLEffects implements OnDestroy {
break; break;
case ECLWSEventTypeEnum.CHANNEL_STATE_CHANGED: case ECLWSEventTypeEnum.CHANNEL_STATE_CHANGED:
if ((<ChannelStateUpdate>newMessage).currentState === 'NORMAL' || (<ChannelStateUpdate>newMessage).currentState === 'CLOSED') { if ((<ChannelStateUpdate>newMessage).currentState === 'NORMAL' || (<ChannelStateUpdate>newMessage).currentState === 'CLOSED') {
this.rawChannelsList = this.rawChannelsList.map((channel) => { this.rawChannelsList = this.rawChannelsList?.map((channel) => {
if (channel.channelId === (<ChannelStateUpdate>newMessage).channelId && channel.nodeId === (<ChannelStateUpdate>newMessage).remoteNodeId) { if (channel.channelId === (<ChannelStateUpdate>newMessage).channelId && channel.nodeId === (<ChannelStateUpdate>newMessage).remoteNodeId) {
channel.state = (<ChannelStateUpdate>newMessage).currentState; channel.state = (<ChannelStateUpdate>newMessage).currentState;
} }
@ -663,12 +663,12 @@ export class ECLEffects implements OnDestroy {
channelStatus.active.channels = channelStatus.active.channels + 1; channelStatus.active.channels = channelStatus.active.channels + 1;
channelStatus.active.capacity = channelStatus.active.capacity + channel.toLocal; channelStatus.active.capacity = channelStatus.active.capacity + channel.toLocal;
} else if (channel.state.includes('WAIT') || channel.state.includes('CLOSING') || channel.state.includes('SYNCING')) { } else if (channel.state.includes('WAIT') || channel.state.includes('CLOSING') || channel.state.includes('SYNCING')) {
channel.state = channel.state.replace(/_/g, ' '); channel.state = channel.state?.replace(/_/g, ' ');
pendingChannels.push(channel); pendingChannels.push(channel);
channelStatus.pending.channels = channelStatus.pending.channels + 1; channelStatus.pending.channels = channelStatus.pending.channels + 1;
channelStatus.pending.capacity = channelStatus.pending.capacity + channel.toLocal; channelStatus.pending.capacity = channelStatus.pending.capacity + channel.toLocal;
} else { } else {
channel.state = channel.state.replace(/_/g, ' '); channel.state = channel.state?.replace(/_/g, ' ');
inactiveChannels.push(channel); inactiveChannels.push(channel);
channelStatus.inactive.channels = channelStatus.inactive.channels + 1; channelStatus.inactive.channels = channelStatus.inactive.channels + 1;
channelStatus.inactive.capacity = channelStatus.inactive.capacity + channel.toLocal; channelStatus.inactive.capacity = channelStatus.inactive.capacity + channel.toLocal;
@ -713,9 +713,9 @@ export class ECLEffects implements OnDestroy {
this.store.dispatch(setNodeData({ payload: node_data })); this.store.dispatch(setNodeData({ payload: node_data }));
let newRoute = this.location.path(); let newRoute = this.location.path();
if (newRoute.includes('/lnd/')) { if (newRoute.includes('/lnd/')) {
newRoute = newRoute.replace('/lnd/', '/ecl/'); newRoute = newRoute?.replace('/lnd/', '/ecl/');
} else if (newRoute.includes('/cln/')) { } else if (newRoute.includes('/cln/')) {
newRoute = newRoute.replace('/cln/', '/ecl/'); newRoute = newRoute?.replace('/cln/', '/ecl/');
} }
if (newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) { if (newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) {
newRoute = '/ecl/home'; newRoute = '/ecl/home';

@ -7,7 +7,7 @@ import { Channel, PaymentReceived, PaymentRelayed } from '../../shared/models/ec
export const ECLReducer = createReducer(initECLState, export const ECLReducer = createReducer(initECLState,
on(updateECLAPICallStatus, (state, { payload }) => { on(updateECLAPICallStatus, (state, { payload }) => {
const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus)); const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus));
updatedApisCallStatus[payload.action] = { updatedApisCallStatus[payload.action || 0] = {
status: payload.status, status: payload.status,
statusCode: payload.statusCode, statusCode: payload.statusCode,
message: payload.message, message: payload.message,
@ -88,11 +88,11 @@ export const ECLReducer = createReducer(initECLState,
on(setPayments, (state, { payload }) => { on(setPayments, (state, { payload }) => {
if (payload && payload.sent) { if (payload && payload.sent) {
const storedChannels = [...state.activeChannels, ...state.pendingChannels, ...state.inactiveChannels]; const storedChannels = [...state.activeChannels, ...state.pendingChannels, ...state.inactiveChannels];
payload.sent.map((sentPayment) => { payload.sent?.map((sentPayment) => {
const peerFound = state.peers.find((peer) => peer.nodeId === sentPayment.recipientNodeId); const peerFound = state.peers.find((peer) => peer.nodeId === sentPayment.recipientNodeId);
sentPayment.recipientNodeAlias = peerFound ? peerFound.alias : sentPayment.recipientNodeId; sentPayment.recipientNodeAlias = peerFound ? peerFound.alias : sentPayment.recipientNodeId;
if (sentPayment.parts) { if (sentPayment.parts) {
sentPayment.parts.map((part) => { sentPayment.parts?.map((part) => {
const channelFound = storedChannels.find((channel) => channel.channelId === part.toChannelId); const channelFound = storedChannels.find((channel) => channel.channelId === part.toChannelId);
part.toChannelAlias = channelFound ? channelFound.alias : part.toChannelId; part.toChannelAlias = channelFound ? channelFound.alias : part.toChannelId;
return sentPayment.parts; return sentPayment.parts;
@ -118,7 +118,7 @@ export const ECLReducer = createReducer(initECLState,
})), })),
on(addInvoice, (state, { payload }) => { on(addInvoice, (state, { payload }) => {
const newInvoices = state.invoices; const newInvoices = state.invoices;
newInvoices.unshift(payload); newInvoices?.unshift(payload);
return { return {
...state, ...state,
invoices: newInvoices invoices: newInvoices
@ -130,12 +130,12 @@ export const ECLReducer = createReducer(initECLState,
})), })),
on(updateInvoice, (state, { payload }) => { on(updateInvoice, (state, { payload }) => {
let modifiedInvoices = state.invoices; let modifiedInvoices = state.invoices;
modifiedInvoices = modifiedInvoices.map((invoice) => { modifiedInvoices = modifiedInvoices?.map((invoice) => {
if (invoice.paymentHash === payload.paymentHash) { if (invoice.paymentHash === payload.paymentHash) {
if (payload.hasOwnProperty('type')) { if (payload.hasOwnProperty('type')) {
const updatedInvoice = JSON.parse(JSON.stringify(invoice)); const updatedInvoice = JSON.parse(JSON.stringify(invoice));
updatedInvoice.amountSettled = ((<PaymentReceived>payload).parts && (<PaymentReceived>payload).parts.length && (<PaymentReceived>payload).parts.length > 0 && (<PaymentReceived>payload).parts[0].amount) ? (<PaymentReceived>payload).parts[0].amount / 1000 : 0; updatedInvoice.amountSettled = ((<PaymentReceived>payload).parts && (<PaymentReceived>payload).parts.length && (<PaymentReceived>payload).parts.length > 0 && (<PaymentReceived>payload).parts[0].amount) ? ((<PaymentReceived>payload).parts[0].amount || 0) / 1000 : 0;
updatedInvoice.receivedAt = ((<PaymentReceived>payload).parts && (<PaymentReceived>payload).parts.length && (<PaymentReceived>payload).parts.length > 0 && (<PaymentReceived>payload).parts[0].timestamp) ? Math.round((<PaymentReceived>payload).parts[0].timestamp / 1000) : 0; updatedInvoice.receivedAt = ((<PaymentReceived>payload).parts && (<PaymentReceived>payload).parts.length && (<PaymentReceived>payload).parts.length > 0 && (<PaymentReceived>payload).parts[0].timestamp) ? Math.round(((<PaymentReceived>payload).parts[0].timestamp || 0) / 1000) : 0;
updatedInvoice.status = 'received'; updatedInvoice.status = 'received';
return updatedInvoice; return updatedInvoice;
} else { } else {
@ -151,9 +151,9 @@ export const ECLReducer = createReducer(initECLState,
}), }),
on(updateChannelState, (state, { payload }) => { on(updateChannelState, (state, { payload }) => {
let modifiedPendingChannels = state.pendingChannels; let modifiedPendingChannels = state.pendingChannels;
modifiedPendingChannels = modifiedPendingChannels.map((pendingChannel) => { modifiedPendingChannels = modifiedPendingChannels?.map((pendingChannel) => {
if (pendingChannel.channelId === payload.channelId && pendingChannel.nodeId === payload.remoteNodeId) { if (pendingChannel.channelId === payload.channelId && pendingChannel.nodeId === payload.remoteNodeId) {
payload.currentState = payload.currentState.replace(/_/g, ' '); payload.currentState = payload.currentState?.replace(/_/g, ' ');
pendingChannel.state = payload.currentState; pendingChannel.state = payload.currentState;
} }
return pendingChannel; return pendingChannel;
@ -166,17 +166,19 @@ export const ECLReducer = createReducer(initECLState,
on(updateRelayedPayment, (state, { payload }) => { on(updateRelayedPayment, (state, { payload }) => {
const modifiedPayments = state.payments; const modifiedPayments = state.payments;
const updatedPayload = mapAliases(payload, [...state.activeChannels, ...state.pendingChannels, ...state.inactiveChannels]); const updatedPayload = mapAliases(payload, [...state.activeChannels, ...state.pendingChannels, ...state.inactiveChannels]);
updatedPayload.amountIn = Math.round(payload.amountIn / 1000); updatedPayload.amountIn = Math.round((payload.amountIn || 0) / 1000);
updatedPayload.amountOut = Math.round(payload.amountOut / 1000); updatedPayload.amountOut = Math.round((payload.amountOut || 0) / 1000);
modifiedPayments.relayed.unshift(updatedPayload); modifiedPayments.relayed?.unshift(updatedPayload);
const feeSats = payload.amountIn - payload.amountOut; const feeSats = (payload.amountIn ||0) - (payload.amountOut || 0);
const modifiedLightningBalance = { localBalance: (state.lightningBalance.localBalance + feeSats), remoteBalance: (state.lightningBalance.remoteBalance - feeSats) }; const modifiedLightningBalance = { localBalance: (state.lightningBalance.localBalance + feeSats), remoteBalance: (state.lightningBalance.remoteBalance - feeSats) };
const modifiedChannelStatus = state.channelsStatus; const modifiedChannelStatus = state.channelsStatus;
modifiedChannelStatus.active.capacity = state.channelsStatus.active.capacity + feeSats; if (modifiedChannelStatus.active) {
modifiedChannelStatus.active.capacity = (state.channelsStatus?.active?.capacity || 0) + feeSats;
}
const modifiedFees = { const modifiedFees = {
daily_fee: (state.fees.daily_fee + feeSats), daily_txs: (state.fees.daily_txs + 1), daily_fee: ((state.fees.daily_fee || 0) + feeSats), daily_txs: ((state.fees.daily_txs || 0) + 1),
weekly_fee: (state.fees.weekly_fee + feeSats), weekly_txs: (state.fees.weekly_txs + 1), weekly_fee: ((state.fees.weekly_fee || 0) + feeSats), weekly_txs: ((state.fees.weekly_txs || 0) + 1),
monthly_fee: (state.fees.monthly_fee + feeSats), monthly_txs: (state.fees.monthly_txs + 1) monthly_fee: ((state.fees.monthly_fee || 0) + feeSats), monthly_txs: ((state.fees.monthly_txs || 0) + 1)
}; };
const modifiedActiveChannels = state.activeChannels; const modifiedActiveChannels = state.activeChannels;
let foundFrom = false; let foundFrom = false;
@ -184,16 +186,16 @@ export const ECLReducer = createReducer(initECLState,
for (const channel of modifiedActiveChannels) { for (const channel of modifiedActiveChannels) {
if (channel.channelId === payload.fromChannelId) { if (channel.channelId === payload.fromChannelId) {
foundFrom = true; foundFrom = true;
const channelTotal = channel.toLocal + channel.toRemote; const channelTotal = (channel.toLocal || 0) + (channel.toRemote || 0);
channel.toLocal = channel.toLocal + updatedPayload.amountIn; channel.toLocal = (channel.toLocal || 0) + updatedPayload.amountIn;
channel.toRemote = channel.toRemote - updatedPayload.amountIn; channel.toRemote = (channel.toRemote || 0) - updatedPayload.amountIn;
channel.balancedness = (channelTotal === 0) ? 1 : +(1 - Math.abs((channel.toLocal - channel.toRemote) / channelTotal)).toFixed(3); channel.balancedness = (channelTotal === 0) ? 1 : +(1 - Math.abs((channel.toLocal - channel.toRemote) / channelTotal)).toFixed(3);
} }
if (channel.channelId === payload.toChannelId) { if (channel.channelId === payload.toChannelId) {
foundTo = true; foundTo = true;
const channelTotal = channel.toLocal + channel.toRemote; const channelTotal = (channel.toLocal || 0) + (channel.toRemote || 0);
channel.toLocal = channel.toLocal - updatedPayload.amountOut; channel.toLocal = (channel.toLocal || 0) - updatedPayload.amountOut;
channel.toRemote = channel.toRemote + updatedPayload.amountOut; channel.toRemote = (channel.toRemote || 0) + updatedPayload.amountOut;
channel.balancedness = (channelTotal === 0) ? 1 : +(1 - Math.abs((channel.toLocal - channel.toRemote) / channelTotal)).toFixed(3); channel.balancedness = (channelTotal === 0) ? 1 : +(1 - Math.abs((channel.toLocal - channel.toRemote) / channelTotal)).toFixed(3);
} }
if (foundTo && foundFrom) { if (foundTo && foundFrom) {
@ -215,14 +217,14 @@ const mapAliases = (rlEvent: PaymentRelayed, storedChannels: Channel[]) => {
if (rlEvent.type === 'payment-relayed') { if (rlEvent.type === 'payment-relayed') {
if (storedChannels && storedChannels.length > 0) { if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) { for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].channelId.toString() === rlEvent.fromChannelId) { if (storedChannels[idx].channelId?.toString() === rlEvent.fromChannelId) {
rlEvent.fromChannelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : rlEvent.fromChannelId; rlEvent.fromChannelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : rlEvent.fromChannelId;
rlEvent.fromShortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : ''; rlEvent.fromShortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : '';
if (rlEvent.toChannelAlias) { if (rlEvent.toChannelAlias) {
return rlEvent; return rlEvent;
} }
} }
if (storedChannels[idx].channelId.toString() === rlEvent.toChannelId) { if (storedChannels[idx].channelId?.toString() === rlEvent.toChannelId) {
rlEvent.toChannelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : rlEvent.toChannelId; rlEvent.toChannelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : rlEvent.toChannelId;
rlEvent.toShortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : ''; rlEvent.toShortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : '';
if (rlEvent.fromChannelAlias) { if (rlEvent.fromChannelAlias) {
@ -231,70 +233,70 @@ const mapAliases = (rlEvent: PaymentRelayed, storedChannels: Channel[]) => {
} }
if (idx === storedChannels.length - 1) { if (idx === storedChannels.length - 1) {
if (!rlEvent.fromChannelAlias) { if (!rlEvent.fromChannelAlias) {
rlEvent.fromChannelAlias = rlEvent.fromChannelId.substring(0, 17) + '...'; rlEvent.fromChannelAlias = rlEvent.fromChannelId?.substring(0, 17) + '...';
rlEvent.fromShortChannelId = ''; rlEvent.fromShortChannelId = '';
} }
if (!rlEvent.toChannelAlias) { if (!rlEvent.toChannelAlias) {
rlEvent.toChannelAlias = rlEvent.toChannelId.substring(0, 17) + '...'; rlEvent.toChannelAlias = rlEvent.toChannelId?.substring(0, 17) + '...';
rlEvent.toShortChannelId = ''; rlEvent.toShortChannelId = '';
} }
} }
} }
} else { } else {
rlEvent.fromChannelAlias = rlEvent.fromChannelId.substring(0, 17) + '...'; rlEvent.fromChannelAlias = rlEvent.fromChannelId?.substring(0, 17) + '...';
rlEvent.fromShortChannelId = ''; rlEvent.fromShortChannelId = '';
rlEvent.toChannelAlias = rlEvent.toChannelId.substring(0, 17) + '...'; rlEvent.toChannelAlias = rlEvent.toChannelId?.substring(0, 17) + '...';
rlEvent.toShortChannelId = ''; rlEvent.toShortChannelId = '';
} }
} else if (rlEvent.type = 'trampoline-payment-relayed') { } else if (rlEvent.type = 'trampoline-payment-relayed') {
if (storedChannels && storedChannels.length > 0) { if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) { for (let idx = 0; idx < storedChannels.length; idx++) {
rlEvent.incoming.forEach((incomingEvent) => { rlEvent.incoming?.forEach((incomingEvent) => {
if (storedChannels[idx].channelId.toString() === incomingEvent.channelId) { if (storedChannels[idx].channelId?.toString() === incomingEvent.channelId) {
incomingEvent.channelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : incomingEvent.channelId; incomingEvent.channelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : incomingEvent.channelId;
incomingEvent.shortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : ''; incomingEvent.shortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : '';
} }
}); });
rlEvent.outgoing.forEach((outgoingEvent) => { rlEvent.outgoing?.forEach((outgoingEvent) => {
if (storedChannels[idx].channelId.toString() === outgoingEvent.channelId) { if (storedChannels[idx].channelId?.toString() === outgoingEvent.channelId) {
outgoingEvent.channelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : outgoingEvent.channelId; outgoingEvent.channelAlias = storedChannels[idx].alias ? storedChannels[idx].alias : outgoingEvent.channelId;
outgoingEvent.shortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : ''; outgoingEvent.shortChannelId = storedChannels[idx].shortChannelId ? storedChannels[idx].shortChannelId : '';
} }
}); });
if (idx === storedChannels.length - 1) { if (idx === storedChannels.length - 1) {
if (!rlEvent.incoming[0].channelAlias) { if (rlEvent.incoming && rlEvent.incoming.length && rlEvent.incoming.length > 0 && !rlEvent.incoming[0].channelAlias) {
rlEvent.incoming.forEach((incomingEvent) => { rlEvent.incoming?.forEach((incomingEvent) => {
incomingEvent.channelAlias = incomingEvent.channelId.substring(0, 17) + '...'; incomingEvent.channelAlias = incomingEvent.channelId?.substring(0, 17) + '...';
incomingEvent.shortChannelId = ''; incomingEvent.shortChannelId = '';
}); });
} }
if (!rlEvent.outgoing[0].channelAlias) { if (rlEvent.outgoing && rlEvent.outgoing.length && rlEvent.outgoing.length > 0 && !rlEvent.outgoing[0].channelAlias) {
rlEvent.outgoing.forEach((outgoingEvent) => { rlEvent.outgoing?.forEach((outgoingEvent) => {
outgoingEvent.channelAlias = outgoingEvent.channelId.substring(0, 17) + '...'; outgoingEvent.channelAlias = outgoingEvent.channelId?.substring(0, 17) + '...';
outgoingEvent.shortChannelId = ''; outgoingEvent.shortChannelId = '';
}); });
} }
} }
} }
} else { } else {
rlEvent.incoming.forEach((incomingEvent) => { rlEvent.incoming?.forEach((incomingEvent) => {
incomingEvent.channelAlias = incomingEvent.channelId.substring(0, 17) + '...'; incomingEvent.channelAlias = incomingEvent.channelId?.substring(0, 17) + '...';
incomingEvent.shortChannelId = ''; incomingEvent.shortChannelId = '';
}); });
rlEvent.outgoing.forEach((outgoingEvent) => { rlEvent.outgoing?.forEach((outgoingEvent) => {
outgoingEvent.channelAlias = outgoingEvent.channelId.substring(0, 17) + '...'; outgoingEvent.channelAlias = outgoingEvent.channelId?.substring(0, 17) + '...';
outgoingEvent.shortChannelId = ''; outgoingEvent.shortChannelId = '';
}); });
} }
rlEvent.amountIn = rlEvent.incoming.reduce((acc, curr) => acc + curr.amount, 0); rlEvent.amountIn = rlEvent.incoming?.reduce((acc, curr) => acc + curr.amount, 0);
rlEvent.fromChannelId = rlEvent.incoming[0].channelId; rlEvent.fromChannelId = rlEvent.incoming && rlEvent.incoming.length ? rlEvent.incoming[0].channelId : '';
rlEvent.fromChannelAlias = rlEvent.incoming[0].channelAlias; rlEvent.fromChannelAlias = rlEvent.incoming && rlEvent.incoming.length ? rlEvent.incoming[0].channelAlias : '';
rlEvent.fromShortChannelId = rlEvent.incoming[0].shortChannelId; rlEvent.fromShortChannelId = rlEvent.incoming && rlEvent.incoming.length ? rlEvent.incoming[0].shortChannelId : '';
rlEvent.amountOut = rlEvent.outgoing.reduce((acc, curr) => acc + curr.amount, 0); rlEvent.amountOut = rlEvent.outgoing?.reduce((acc, curr) => acc + curr.amount, 0);
rlEvent.toChannelId = rlEvent.outgoing[0].channelId; rlEvent.toChannelId = rlEvent.outgoing && rlEvent.outgoing.length ? rlEvent.outgoing[0].channelId : '';
rlEvent.toChannelAlias = rlEvent.outgoing[0].channelAlias; rlEvent.toChannelAlias = rlEvent.outgoing && rlEvent.outgoing.length ? rlEvent.outgoing[0].channelAlias : '';
rlEvent.toShortChannelId = rlEvent.outgoing[0].shortChannelId; rlEvent.toShortChannelId = rlEvent.outgoing && rlEvent.outgoing.length ? rlEvent.outgoing[0].shortChannelId : '';
} }
return rlEvent; return rlEvent;
}; };

@ -5,7 +5,7 @@ import { APICallStatusEnum, UserPersonaEnum } from '../../shared/services/consts
export interface ECLState { export interface ECLState {
apisCallStatus: ApiCallsListECL; apisCallStatus: ApiCallsListECL;
nodeSettings: SelNodeChild; nodeSettings: SelNodeChild | null;
information: GetInfo; information: GetInfo;
fees: Fees; fees: Fees;
activeChannels: Channel[]; activeChannels: Channel[];

@ -162,7 +162,7 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
} }
updateInvoicesData(newInvoice: Invoice) { updateInvoicesData(newInvoice: Invoice) {
this.invoiceJSONArr = this.invoiceJSONArr.map((invoice) => ((invoice.paymentHash === newInvoice.paymentHash) ? newInvoice : invoice)); this.invoiceJSONArr = this.invoiceJSONArr?.map((invoice) => ((invoice.paymentHash === newInvoice.paymentHash) ? newInvoice : invoice));
} }
loadInvoicesTable(invs: Invoice[]) { loadInvoicesTable(invs: Invoice[]) {

@ -379,7 +379,7 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
onDownloadCSV() { onDownloadCSV() {
if (this.payments.data && this.payments.data.length > 0) { if (this.payments.data && this.payments.data.length > 0) {
const paymentsDataCopy: PaymentSent[] = JSON.parse(JSON.stringify(this.payments.data)); const paymentsDataCopy: PaymentSent[] = JSON.parse(JSON.stringify(this.payments.data));
const paymentRequests = paymentsDataCopy.reduce((paymentReqs, payment) => { const paymentRequests = paymentsDataCopy?.reduce((paymentReqs, payment) => {
if (payment.paymentHash && payment.paymentHash.trim() !== '') { if (payment.paymentHash && payment.paymentHash.trim() !== '') {
paymentReqs = (paymentReqs === '') ? payment.paymentHash : paymentReqs + ',' + payment.paymentHash; paymentReqs = (paymentReqs === '') ? payment.paymentHash : paymentReqs + ',' + payment.paymentHash;
} }
@ -393,7 +393,7 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
paymentsDataCopy[idx].description = decodedPayment[0].paymentRequest.description; paymentsDataCopy[idx].description = decodedPayment[0].paymentRequest.description;
} }
}); });
const flattenedPayments = paymentsDataCopy.reduce((acc, curr) => acc.concat(curr), []); const flattenedPayments = paymentsDataCopy?.reduce((acc, curr) => acc.concat(curr), []);
this.commonService.downloadFile(flattenedPayments, 'Payments'); this.commonService.downloadFile(flattenedPayments, 'Payments');
}); });
} }

@ -207,10 +207,10 @@ export class HomeComponent implements OnInit, OnDestroy {
this.channelsStatus.inactive = channelsSelector.channelsSummary.inactive; this.channelsStatus.inactive = channelsSelector.channelsSummary.inactive;
this.totalInboundLiquidity = 0; this.totalInboundLiquidity = 0;
this.totalOutboundLiquidity = 0; this.totalOutboundLiquidity = 0;
this.allChannels = channelsSelector.channels.filter((channel) => channel.active === true); this.allChannels = channelsSelector.channels?.filter((channel) => channel.active === true);
this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels, 'balancedness'))); this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels, 'balancedness')));
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter((channel) => channel.remote_balance > 0), 'remote_balance'))); this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels?.filter((channel) => channel.remote_balance > 0), 'remote_balance')));
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter((channel) => channel.local_balance > 0), 'local_balance'))); this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels?.filter((channel) => channel.local_balance > 0), 'local_balance')));
this.allChannels.forEach((channel) => { this.allChannels.forEach((channel) => {
this.totalInboundLiquidity = this.totalInboundLiquidity + +channel.remote_balance; this.totalInboundLiquidity = this.totalInboundLiquidity + +channel.remote_balance;
this.totalOutboundLiquidity = this.totalOutboundLiquidity + +channel.local_balance; this.totalOutboundLiquidity = this.totalOutboundLiquidity + +channel.local_balance;

@ -167,7 +167,7 @@ export class OnChainSendModalComponent implements OnInit, OnDestroy {
subscribe({ subscribe({
next: (data) => { next: (data) => {
this.selAmountUnit = CurrencyUnitEnum.SATS; this.selAmountUnit = CurrencyUnitEnum.SATS;
postTransaction.amount = +this.decimalPipe.transform(data[this.amountUnits[0]], this.currencyUnitFormats[this.amountUnits[0]]).replace(/,/g, ''); postTransaction.amount = +this.decimalPipe.transform(data[this.amountUnits[0]], this.currencyUnitFormats[this.amountUnits[0]])?.replace(/,/g, '');
this.store.dispatch(setChannelTransaction({ payload: postTransaction })); this.store.dispatch(setChannelTransaction({ payload: postTransaction }));
}, error: (err) => { }, error: (err) => {
this.transactionAmount = null; this.transactionAmount = null;
@ -245,7 +245,7 @@ export class OnChainSendModalComponent implements OnInit, OnDestroy {
subscribe({ subscribe({
next: (data) => { next: (data) => {
this.selAmountUnit = event.value; this.selAmountUnit = event.value;
self.transactionAmount = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit]).replace(/,/g, ''); self.transactionAmount = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit])?.replace(/,/g, '');
}, error: (err) => { }, error: (err) => {
self.transactionAmount = null; self.transactionAmount = null;
this.amountError = 'Conversion Error: ' + err; this.amountError = 'Conversion Error: ' + err;

@ -34,7 +34,7 @@ export class UTXOTablesComponent implements OnInit, OnDestroy {
subscribe((utxosSelector: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => { subscribe((utxosSelector: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
if (utxosSelector.utxos && utxosSelector.utxos.length > 0) { if (utxosSelector.utxos && utxosSelector.utxos.length > 0) {
this.numUtxos = utxosSelector.utxos.length; this.numUtxos = utxosSelector.utxos.length;
this.numDustUtxos = utxosSelector.utxos.filter((utxo) => +utxo.amount_sat < 1000).length; this.numDustUtxos = utxosSelector.utxos?.filter((utxo) => +utxo.amount_sat < 1000).length;
} }
this.logger.info(utxosSelector); this.logger.info(utxosSelector);
}); });

@ -77,7 +77,7 @@ export class OnChainUTXOsComponent implements OnInit, OnChanges, OnDestroy {
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message; this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
} }
if (utxosSelector.utxos && utxosSelector.utxos.length > 0) { if (utxosSelector.utxos && utxosSelector.utxos.length > 0) {
this.dustUtxos = utxosSelector.utxos.filter((utxo) => +utxo.amount_sat < 1000); this.dustUtxos = utxosSelector.utxos?.filter((utxo) => +utxo.amount_sat < 1000);
this.utxos = utxosSelector.utxos; this.utxos = utxosSelector.utxos;
this.loadUTXOsTable((this.isDustUTXO) ? this.dustUtxos : this.utxos); this.loadUTXOsTable((this.isDustUTXO) ? this.dustUtxos : this.utxos);
} }

@ -62,7 +62,7 @@ export class ChannelRebalanceComponent implements OnInit, OnDestroy {
let x = ''; let x = '';
let y = ''; let y = '';
this.selChannel = this.data.message.selChannel; this.selChannel = this.data.message.selChannel;
this.activeChannels = this.data.message.channels.filter((channel) => channel.active && channel.chan_id !== this.selChannel.chan_id && channel.remote_balance > 0); this.activeChannels = this.data.message.channels?.filter((channel) => channel.active && channel.chan_id !== this.selChannel.chan_id && channel.remote_balance > 0);
this.activeChannels = this.activeChannels.sort((c1: Channel, c2: Channel) => { this.activeChannels = this.activeChannels.sort((c1: Channel, c2: Channel) => {
x = c1.remote_alias ? c1.remote_alias.toLowerCase() : c1.chan_id ? c1.chan_id.toLowerCase() : ''; x = c1.remote_alias ? c1.remote_alias.toLowerCase() : c1.chan_id ? c1.chan_id.toLowerCase() : '';
y = c2.remote_alias ? c2.remote_alias.toLowerCase() : c1.chan_id.toLowerCase(); y = c2.remote_alias ? c2.remote_alias.toLowerCase() : c1.chan_id.toLowerCase();
@ -231,13 +231,13 @@ export class ChannelRebalanceComponent implements OnInit, OnDestroy {
} }
filterActiveChannels() { filterActiveChannels() {
return this.activeChannels.filter((channel) => channel.remote_balance >= this.inputFormGroup.controls.rebalanceAmount.value && return this.activeChannels?.filter((channel) => channel.remote_balance >= this.inputFormGroup.controls.rebalanceAmount.value &&
channel.chan_id !== this.selChannel.chan_id && ((channel.remote_alias.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0) || (channel.chan_id.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0))); channel.chan_id !== this.selChannel.chan_id && ((channel.remote_alias.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0) || (channel.chan_id.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0)));
} }
onSelectedPeerChanged() { onSelectedPeerChanged() {
if (this.inputFormGroup.controls.selRebalancePeer.value && this.inputFormGroup.controls.selRebalancePeer.value.length > 0 && typeof this.inputFormGroup.controls.selRebalancePeer.value === 'string') { if (this.inputFormGroup.controls.selRebalancePeer.value && this.inputFormGroup.controls.selRebalancePeer.value.length > 0 && typeof this.inputFormGroup.controls.selRebalancePeer.value === 'string') {
const foundChannels = this.activeChannels.filter((channel) => channel.remote_alias.length === this.inputFormGroup.controls.selRebalancePeer.value.length && channel.remote_alias.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0); const foundChannels = this.activeChannels?.filter((channel) => channel.remote_alias.length === this.inputFormGroup.controls.selRebalancePeer.value.length && channel.remote_alias.toLowerCase().indexOf(this.inputFormGroup.controls.selRebalancePeer.value ? this.inputFormGroup.controls.selRebalancePeer.value.toLowerCase() : '') === 0);
if (foundChannels && foundChannels.length > 0) { if (foundChannels && foundChannels.length > 0) {
this.inputFormGroup.controls.selRebalancePeer.setValue(foundChannels[0]); this.inputFormGroup.controls.selRebalancePeer.setValue(foundChannels[0]);
this.inputFormGroup.controls.selRebalancePeer.setErrors(null); this.inputFormGroup.controls.selRebalancePeer.setErrors(null);

@ -69,7 +69,7 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) { if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message; this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
} }
this.channelsJSONArr = channelsSelector.channels.filter((channel) => channel.pending_htlcs && channel.pending_htlcs.length > 0) || []; this.channelsJSONArr = channelsSelector.channels?.filter((channel) => channel.pending_htlcs && channel.pending_htlcs.length > 0) || [];
this.loadHTLCsTable(this.channelsJSONArr); this.loadHTLCsTable(this.channelsJSONArr);
this.logger.info(channelsSelector); this.logger.info(channelsSelector);
}); });
@ -142,7 +142,7 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
this.channels.paginator = this.paginator; this.channels.paginator = this.paginator;
this.channels.filterPredicate = (channel: Channel, fltr: string) => { this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = (channel.remote_alias ? channel.remote_alias.toLowerCase() : '') + const newChannel = (channel.remote_alias ? channel.remote_alias.toLowerCase() : '') +
channel.pending_htlcs.map((htlc) => JSON.stringify(htlc) + (htlc.incoming ? 'yes' : 'no')); channel.pending_htlcs?.map((htlc) => JSON.stringify(htlc) + (htlc.incoming ? 'yes' : 'no'));
return newChannel.includes(fltr); return newChannel.includes(fltr);
}; };
this.applyFilter(); this.applyFilter();
@ -156,7 +156,7 @@ export class ChannelActiveHTLCsTableComponent implements OnInit, AfterViewInit,
flattenHTLCs() { flattenHTLCs() {
const channelsDataCopy = JSON.parse(JSON.stringify(this.channels.data)); const channelsDataCopy = JSON.parse(JSON.stringify(this.channels.data));
const flattenedHTLCs = channelsDataCopy.reduce((acc, curr) => { const flattenedHTLCs = channelsDataCopy?.reduce((acc, curr) => {
if (curr.pending_htlcs) { if (curr.pending_htlcs) {
return acc.concat(curr.pending_htlcs); return acc.concat(curr.pending_htlcs);
} else { } else {

@ -45,7 +45,7 @@ export class ChannelsTablesComponent implements OnInit, OnDestroy {
this.store.select(channels).pipe(takeUntil(this.unSubs[2])). this.store.select(channels).pipe(takeUntil(this.unSubs[2])).
subscribe((channelsSelector: { channels: Channel[], channelsSummary: ChannelsSummary, lightningBalance: LightningBalance, apiCallStatus: ApiCallStatusPayload }) => { subscribe((channelsSelector: { channels: Channel[], channelsSummary: ChannelsSummary, lightningBalance: LightningBalance, apiCallStatus: ApiCallStatusPayload }) => {
this.numOpenChannels = (channelsSelector.channels && channelsSelector.channels.length) ? channelsSelector.channels.length : 0; this.numOpenChannels = (channelsSelector.channels && channelsSelector.channels.length) ? channelsSelector.channels.length : 0;
this.numActiveHTLCs = channelsSelector.channels.reduce((totalHTLCs, channel) => totalHTLCs + (channel.pending_htlcs && channel.pending_htlcs.length > 0 ? channel.pending_htlcs.length : 0), 0); this.numActiveHTLCs = channelsSelector.channels?.reduce((totalHTLCs, channel) => totalHTLCs + (channel.pending_htlcs && channel.pending_htlcs.length > 0 ? channel.pending_htlcs.length : 0), 0);
this.logger.info(channelsSelector); this.logger.info(channelsSelector);
}); });
this.store.select(pendingChannels).pipe(takeUntil(this.unSubs[3])). this.store.select(pendingChannels).pipe(takeUntil(this.unSubs[3])).

@ -77,7 +77,7 @@ export class OpenChannelComponent implements OnInit, OnDestroy {
} }
private filterPeers(newlySelectedPeer: string): Peer[] { private filterPeers(newlySelectedPeer: string): Peer[] {
return this.sortedPeers.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0); return this.sortedPeers?.filter((peer) => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0);
} }
displayFn(peer: Peer): string { displayFn(peer: Peer): string {
@ -88,7 +88,7 @@ export class OpenChannelComponent implements OnInit, OnDestroy {
this.channelConnectionError = ''; this.channelConnectionError = '';
this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.pub_key) ? this.selectedPeer.value.pub_key : null; this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.pub_key) ? this.selectedPeer.value.pub_key : null;
if (typeof this.selectedPeer.value === 'string') { if (typeof this.selectedPeer.value === 'string') {
const selPeer = this.peers.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0); const selPeer = this.peers?.filter((peer) => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0);
if (selPeer.length === 1 && selPeer[0].pub_key) { if (selPeer.length === 1 && selPeer[0].pub_key) {
this.selectedPubkey = selPeer[0].pub_key; this.selectedPubkey = selPeer[0].pub_key;
} }

@ -118,7 +118,7 @@ export class RoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: MONTHS[i].name, value: 0.0, extra: { totalEvents: 0 } });
} }
this.events.forwarding_events.map((event) => { this.events.forwarding_events?.map((event) => {
const monthNumber = new Date((+event.timestamp) * 1000).getMonth(); const monthNumber = new Date((+event.timestamp) * 1000).getMonth();
feeReport[monthNumber].value = feeReport[monthNumber].value + (+event.fee_msat / 1000); feeReport[monthNumber].value = feeReport[monthNumber].value + (+event.fee_msat / 1000);
feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1; feeReport[monthNumber].extra.totalEvents = feeReport[monthNumber].extra.totalEvents + 1;
@ -129,7 +129,7 @@ export class RoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } }); feeReport.push({ name: i + 1, value: 0.0, extra: { totalEvents: 0 } });
} }
this.events.forwarding_events.map((event) => { this.events.forwarding_events?.map((event) => {
const dateNumber = Math.floor((+event.timestamp - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+event.timestamp - startDateInSeconds) / this.secondsInADay);
feeReport[dateNumber].value = feeReport[dateNumber].value + (+event.fee_msat / 1000); feeReport[dateNumber].value = feeReport[dateNumber].value + (+event.fee_msat / 1000);
feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1; feeReport[dateNumber].extra.totalEvents = feeReport[dateNumber].extra.totalEvents + 1;
@ -148,7 +148,7 @@ export class RoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: MONTHS[i].name, value: 0, extra: { totalFees: 0.0 } });
} }
this.events.forwarding_events.map((event) => { this.events.forwarding_events?.map((event) => {
const monthNumber = new Date((+event.timestamp) * 1000).getMonth(); const monthNumber = new Date((+event.timestamp) * 1000).getMonth();
eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1; eventsReport[monthNumber].value = eventsReport[monthNumber].value + 1;
eventsReport[monthNumber].extra.totalFees = eventsReport[monthNumber].extra.totalFees + (+event.fee_msat / 1000); eventsReport[monthNumber].extra.totalFees = eventsReport[monthNumber].extra.totalFees + (+event.fee_msat / 1000);
@ -159,7 +159,7 @@ export class RoutingReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } }); eventsReport.push({ name: i + 1, value: 0, extra: { totalFees: 0.0 } });
} }
this.events.forwarding_events.map((event) => { this.events.forwarding_events?.map((event) => {
const dateNumber = Math.floor((+event.timestamp - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+event.timestamp - startDateInSeconds) / this.secondsInADay);
eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1; eventsReport[dateNumber].value = eventsReport[dateNumber].value + 1;
eventsReport[dateNumber].extra.totalFees = eventsReport[dateNumber].extra.totalFees + (+event.fee_msat / 1000); eventsReport[dateNumber].extra.totalFees = eventsReport[dateNumber].extra.totalFees + (+event.fee_msat / 1000);

@ -110,22 +110,22 @@ export class TransactionsReportComponent implements OnInit, OnDestroy {
const transactionsReport = []; const transactionsReport = [];
this.transactionsNonZeroReportData = []; this.transactionsNonZeroReportData = [];
this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 }; this.transactionsReportSummary = { paymentsSelectedPeriod: 0, invoicesSelectedPeriod: 0, amountPaidSelectedPeriod: 0, amountReceivedSelectedPeriod: 0 };
const filteredPayments = this.payments.filter((payment) => payment.status === 'SUCCEEDED' && payment.creation_date >= startDateInSeconds && payment.creation_date < endDateInSeconds); const filteredPayments = this.payments?.filter((payment) => payment.status === 'SUCCEEDED' && payment.creation_date >= startDateInSeconds && payment.creation_date < endDateInSeconds);
const filteredInvoices = this.invoices.filter((invoice) => invoice.settled && +invoice.creation_date >= startDateInSeconds && +invoice.creation_date < endDateInSeconds); const filteredInvoices = this.invoices?.filter((invoice) => invoice.settled && +invoice.creation_date >= startDateInSeconds && +invoice.creation_date < endDateInSeconds);
this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length; this.transactionsReportSummary.paymentsSelectedPeriod = filteredPayments.length;
this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length; this.transactionsReportSummary.invoicesSelectedPeriod = filteredInvoices.length;
if (this.reportPeriod === SCROLL_RANGES[1]) { if (this.reportPeriod === SCROLL_RANGES[1]) {
for (let i = 0; i < 12; i++) { for (let i = 0; i < 12; i++) {
transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: MONTHS[i].name, date: new Date(start.getFullYear(), i, 1, 0, 0, 0, 0), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const monthNumber = new Date((+payment.creation_date) * 1000).getMonth(); const monthNumber = new Date((+payment.creation_date) * 1000).getMonth();
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (+payment.value_msat) + (+payment.fee_msat); this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (+payment.value_msat) + (+payment.fee_msat);
transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + ((+payment.value_msat + +payment.fee_msat) / 1000); transactionsReport[monthNumber].series[0].value = transactionsReport[monthNumber].series[0].value + ((+payment.value_msat + +payment.fee_msat) / 1000);
transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1; transactionsReport[monthNumber].series[0].extra.total = transactionsReport[monthNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const monthNumber = new Date((+invoice.creation_date) * 1000).getMonth(); const monthNumber = new Date((+invoice.creation_date) * 1000).getMonth();
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (+invoice.amt_paid_msat); this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (+invoice.amt_paid_msat);
transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + (+invoice.amt_paid_msat / 1000); transactionsReport[monthNumber].series[1].value = transactionsReport[monthNumber].series[1].value + (+invoice.amt_paid_msat / 1000);
@ -136,14 +136,14 @@ export class TransactionsReportComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) { for (let i = 0; i < this.getMonthDays(start.getMonth(), start.getFullYear()); i++) {
transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] }); transactionsReport.push({ name: (i + 1).toString(), date: new Date((((i) * this.secondsInADay) + startDateInSeconds) * 1000), series: [{ name: 'Paid', value: 0, extra: { total: 0 } }, { name: 'Received', value: 0, extra: { total: 0 } }] });
} }
filteredPayments.map((payment) => { filteredPayments?.map((payment) => {
const dateNumber = Math.floor((+payment.creation_date - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+payment.creation_date - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (+payment.value_msat) + (+payment.fee_msat); this.transactionsReportSummary.amountPaidSelectedPeriod = this.transactionsReportSummary.amountPaidSelectedPeriod + (+payment.value_msat) + (+payment.fee_msat);
transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + ((+payment.value_msat + +payment.fee_msat) / 1000); transactionsReport[dateNumber].series[0].value = transactionsReport[dateNumber].series[0].value + ((+payment.value_msat + +payment.fee_msat) / 1000);
transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1; transactionsReport[dateNumber].series[0].extra.total = transactionsReport[dateNumber].series[0].extra.total + 1;
return this.transactionsReportSummary; return this.transactionsReportSummary;
}); });
filteredInvoices.map((invoice) => { filteredInvoices?.map((invoice) => {
const dateNumber = Math.floor((+invoice.creation_date - startDateInSeconds) / this.secondsInADay); const dateNumber = Math.floor((+invoice.creation_date - startDateInSeconds) / this.secondsInADay);
this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (+invoice.amt_paid_msat); this.transactionsReportSummary.amountReceivedSelectedPeriod = this.transactionsReportSummary.amountReceivedSelectedPeriod + (+invoice.amt_paid_msat);
transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + (+invoice.amt_paid_msat / 1000); transactionsReport[dateNumber].series[1].value = transactionsReport[dateNumber].series[1].value + (+invoice.amt_paid_msat / 1000);
@ -155,7 +155,7 @@ export class TransactionsReportComponent implements OnInit, OnDestroy {
} }
prepareTableData() { prepareTableData() {
return this.transactionsReportData.reduce((acc, curr) => { return this.transactionsReportData?.reduce((acc, curr) => {
if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) { if (curr.series[0].extra.total > 0 || curr.series[1].extra.total > 0) {
return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total }); return acc.concat({ date: curr.date, amount_paid: curr.series[0].value, num_payments: curr.series[0].extra.total, amount_received: curr.series[1].value, num_invoices: curr.series[1].extra.total });
} }

@ -128,7 +128,7 @@ export class NonRoutingPeersComponent implements OnInit, AfterViewInit, OnDestro
loadNonRoutingPeersTable(forwardingEvents: ForwardingEvent[]) { loadNonRoutingPeersTable(forwardingEvents: ForwardingEvent[]) {
if (forwardingEvents.length > 0) { if (forwardingEvents.length > 0) {
// const grpdRoutingPeers = this.groupRoutingPeers(forwardingEvents); // const grpdRoutingPeers = this.groupRoutingPeers(forwardingEvents);
const filteredNonRoutingChannels = this.activeChannels.filter((actvChnl) => forwardingEvents.findIndex((evnt) => (evnt.chan_id_in === actvChnl.chan_id || evnt.chan_id_out === actvChnl.chan_id)) < 0); const filteredNonRoutingChannels = this.activeChannels?.filter((actvChnl) => forwardingEvents.findIndex((evnt) => (evnt.chan_id_in === actvChnl.chan_id || evnt.chan_id_out === actvChnl.chan_id)) < 0);
this.NonRoutingPeers = new MatTableDataSource<Channel>(filteredNonRoutingChannels); this.NonRoutingPeers = new MatTableDataSource<Channel>(filteredNonRoutingChannels);
this.NonRoutingPeers.sort = this.sort; this.NonRoutingPeers.sort = this.sort;
this.NonRoutingPeers.filterPredicate = (nrchnl: Channel, fltr: string) => JSON.stringify(nrchnl).toLowerCase().includes(fltr); this.NonRoutingPeers.filterPredicate = (nrchnl: Channel, fltr: string) => JSON.stringify(nrchnl).toLowerCase().includes(fltr);

@ -10,7 +10,7 @@ import {
export const updateLNDAPICallStatus = createAction(LNDActions.UPDATE_API_CALL_STATUS_LND, props<{ payload: ApiCallStatusPayload }>()); export const updateLNDAPICallStatus = createAction(LNDActions.UPDATE_API_CALL_STATUS_LND, props<{ payload: ApiCallStatusPayload }>());
export const resetLNDStore = createAction(LNDActions.RESET_LND_STORE, props<{ payload: SelNodeChild }>()); export const resetLNDStore = createAction(LNDActions.RESET_LND_STORE, props<{ payload: SelNodeChild | null }>());
export const setChildNodeSettingsLND = createAction(LNDActions.SET_CHILD_NODE_SETTINGS_LND, props<{ payload: SelNodeChild }>()); export const setChildNodeSettingsLND = createAction(LNDActions.SET_CHILD_NODE_SETTINGS_LND, props<{ payload: SelNodeChild }>());

@ -1202,9 +1202,9 @@ export class LNDEffects implements OnDestroy {
this.store.dispatch(setNodeData({ payload: node_data })); this.store.dispatch(setNodeData({ payload: node_data }));
let newRoute = this.location.path(); let newRoute = this.location.path();
if (newRoute.includes('/cln/')) { if (newRoute.includes('/cln/')) {
newRoute = newRoute.replace('/cln/', '/lnd/'); newRoute = newRoute?.replace('/cln/', '/lnd/');
} else if (newRoute.includes('/ecl/')) { } else if (newRoute.includes('/ecl/')) {
newRoute = newRoute.replace('/ecl/', '/lnd/'); newRoute = newRoute?.replace('/ecl/', '/lnd/');
} }
if (newRoute.includes('/unlock') || newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) { if (newRoute.includes('/unlock') || newRoute.includes('/login') || newRoute.includes('/error') || newRoute === '' || landingPage === 'HOME' || newRoute.includes('?access-key=')) {
newRoute = '/lnd/home'; newRoute = '/lnd/home';

@ -10,7 +10,7 @@ let flgUTXOsSet = false;
export const LNDReducer = createReducer(initLNDState, export const LNDReducer = createReducer(initLNDState,
on(updateLNDAPICallStatus, (state, { payload }) => { on(updateLNDAPICallStatus, (state, { payload }) => {
const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus)); const updatedApisCallStatus = JSON.parse(JSON.stringify(state.apisCallStatus));
updatedApisCallStatus[payload.action] = { updatedApisCallStatus[payload.action || 0] = {
status: payload.status, status: payload.status,
statusCode: payload.statusCode, statusCode: payload.statusCode,
message: payload.message, message: payload.message,
@ -51,7 +51,7 @@ export const LNDReducer = createReducer(initLNDState,
}), }),
on(addInvoice, (state, { payload }) => { on(addInvoice, (state, { payload }) => {
const newListInvoices = state.listInvoices; const newListInvoices = state.listInvoices;
newListInvoices.invoices.unshift(payload); newListInvoices.invoices?.unshift(payload);
return { return {
...state, ...state,
listInvoices: newListInvoices listInvoices: newListInvoices
@ -59,7 +59,7 @@ export const LNDReducer = createReducer(initLNDState,
}), }),
on(updateInvoice, (state, { payload }) => { on(updateInvoice, (state, { payload }) => {
const modifiedListInvoices = state.listInvoices; const modifiedListInvoices = state.listInvoices;
modifiedListInvoices.invoices = modifiedListInvoices.invoices.map((invoice) => ((invoice.payment_request === payload.payment_request) ? payload : invoice)); modifiedListInvoices.invoices = modifiedListInvoices.invoices?.map((invoice) => ((invoice.payment_request === payload.payment_request) ? payload : invoice));
return { return {
...state, ...state,
listInvoices: modifiedListInvoices listInvoices: modifiedListInvoices
@ -67,7 +67,7 @@ export const LNDReducer = createReducer(initLNDState,
}), }),
on(updatePayment, (state, { payload }) => { on(updatePayment, (state, { payload }) => {
const modifiedListPayments = state.listPayments; const modifiedListPayments = state.listPayments;
modifiedListPayments.payments = modifiedListPayments.payments.map((payment) => ((payment.payment_hash === payload.payment_hash) ? payload : payment)); modifiedListPayments.payments = modifiedListPayments.payments?.map((payment) => ((payment.payment_hash === payload.payment_hash) ? payload : payment));
return { return {
...state, ...state,
listPayments: modifiedListPayments listPayments: modifiedListPayments
@ -157,7 +157,7 @@ export const LNDReducer = createReducer(initLNDState,
if (payload.length && flgUTXOsSet) { if (payload.length && flgUTXOsSet) {
const modifiedUTXOs = [...state.utxos]; const modifiedUTXOs = [...state.utxos];
modifiedUTXOs.forEach((utxo) => { modifiedUTXOs.forEach((utxo) => {
const foundTransaction = payload.find((transaction) => transaction.tx_hash === utxo.outpoint.txid_str); const foundTransaction = payload.find((transaction) => transaction.tx_hash === utxo.outpoint?.txid_str);
utxo.label = foundTransaction && foundTransaction.label ? foundTransaction.label : ''; utxo.label = foundTransaction && foundTransaction.label ? foundTransaction.label : '';
}); });
return { return {
@ -176,7 +176,7 @@ export const LNDReducer = createReducer(initLNDState,
if (payload.length && flgTransactionsSet) { if (payload.length && flgTransactionsSet) {
const transactions = [...state.transactions]; const transactions = [...state.transactions];
payload.forEach((utxo) => { payload.forEach((utxo) => {
const foundTransaction = transactions.find((transaction) => transaction.tx_hash === utxo.outpoint.txid_str); const foundTransaction = transactions.find((transaction) => transaction.tx_hash === utxo.outpoint?.txid_str);
utxo.label = foundTransaction && foundTransaction.label ? foundTransaction.label : ''; utxo.label = foundTransaction && foundTransaction.label ? foundTransaction.label : '';
}); });
} }
@ -225,13 +225,13 @@ const mapAliases = (payload: any, storedChannels: (Channel | ClosedChannel)[]) =
payload.forwarding_events.forEach((fhEvent) => { payload.forwarding_events.forEach((fhEvent) => {
if (storedChannels && storedChannels.length > 0) { if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) { for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].chan_id.toString() === fhEvent.chan_id_in) { if (storedChannels[idx].chan_id?.toString() === fhEvent.chan_id_in) {
fhEvent.alias_in = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : fhEvent.chan_id_in; fhEvent.alias_in = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : fhEvent.chan_id_in;
if (fhEvent.alias_out) { if (fhEvent.alias_out) {
return; return;
} }
} }
if (storedChannels[idx].chan_id.toString() === fhEvent.chan_id_out) { if (storedChannels[idx].chan_id?.toString() === fhEvent.chan_id_out) {
fhEvent.alias_out = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : fhEvent.chan_id_out; fhEvent.alias_out = storedChannels[idx].remote_alias ? storedChannels[idx].remote_alias : fhEvent.chan_id_out;
if (fhEvent.alias_in) { if (fhEvent.alias_in) {
return; return;

@ -5,7 +5,7 @@ import { GetInfo, Peer, Fees, NetworkInfo, BlockchainBalance, Channel, ListInvoi
export interface LNDState { export interface LNDState {
apisCallStatus: ApiCallsListLND; apisCallStatus: ApiCallsListLND;
nodeSettings: SelNodeChild; nodeSettings: SelNodeChild | null;
information: GetInfo; information: GetInfo;
peers: Peer[]; peers: Peer[];
fees: Fees; fees: Fees;

@ -145,11 +145,11 @@ export class LightningInvoicesComponent implements OnInit, AfterViewInit, OnDest
} }
onRefreshInvoice(selInvoice: Invoice) { onRefreshInvoice(selInvoice: Invoice) {
this.store.dispatch(invoiceLookup({ payload: { openSnackBar: true, paymentHash: Buffer.from(selInvoice.r_hash.trim(), 'hex').toString('base64').replace(/\+/g, '-').replace(/[/]/g, '_') } })); this.store.dispatch(invoiceLookup({ payload: { openSnackBar: true, paymentHash: Buffer.from(selInvoice.r_hash.trim(), 'hex').toString('base64')?.replace(/\+/g, '-')?.replace(/[/]/g, '_') } }));
} }
updateInvoicesData(newInvoice: Invoice) { updateInvoicesData(newInvoice: Invoice) {
this.invoicesData = this.invoicesData.map((invoice) => ((invoice.r_hash === newInvoice.r_hash) ? newInvoice : invoice)); this.invoicesData = this.invoicesData?.map((invoice) => ((invoice.r_hash === newInvoice.r_hash) ? newInvoice : invoice));
} }
loadInvoicesTable(invoices) { loadInvoicesTable(invoices) {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save