Updating Common Application Configuration

pull/1382/head
ShahanaFarooqui 1 month ago
parent 61c4cf3019
commit 244bc706c4

@ -11,7 +11,7 @@ export const listPeerChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
return Promise.all(body.channels?.map((channel) => { return Promise.all(body.channels?.map((channel) => {
@ -33,7 +33,7 @@ export const openChannel = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -50,7 +50,7 @@ export const setChannelFee = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -68,7 +68,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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/close'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -86,7 +86,7 @@ export const listForwards = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body });
@ -103,7 +103,7 @@ export const funderUpdatePolicy = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate';
options.body = req.body; options.body = req.body;
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) => {

@ -16,8 +16,8 @@ export const getInfo = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
if (!options.headers || !options.headers.rune) { if (!options.headers || !options.headers.rune) {
const errMsg = 'Core lightning get info failed due to missing rune!'; const errMsg = 'Core lightning get info failed due to missing rune!';
@ -48,7 +48,7 @@ export const getInfo = (req, res, next) => {
body.uris.push(body.id + '@' + addr.address + ':' + addr.port); body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
}); });
} }
req.session.selectedNode.ln_version = body.version || ''; req.session.selectedNode.lnVersion = body.version || '';
req.session.selectedNode.api_version = body.api_version || ''; req.session.selectedNode.api_version = body.api_version || '';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
clWsClient.updateSelectedNode(req.session.selectedNode); clWsClient.updateSelectedNode(req.session.selectedNode);

@ -10,7 +10,7 @@ export const deleteExpiredInvoice = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
@ -26,7 +26,7 @@ export const listInvoices = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -43,7 +43,7 @@ export const addInvoice = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });

@ -10,7 +10,7 @@ export const getRoute = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/getroute'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
@ -29,7 +29,7 @@ export const listChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
@ -46,7 +46,7 @@ export const feeRates = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/feerates'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body });
@ -64,7 +64,7 @@ export const listNodes = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -80,7 +80,7 @@ export const listNodes = (req, res, next) => {
}); });
}; };
export const getAlias = (selNode, peer, id) => { export const getAlias = (selNode, peer, id) => {
options.url = selNode.ln_server_url + '/v1/listnodes'; options.url = selNode.settings.lnServerUrl + '/v1/listnodes';
if (!peer[id]) { if (!peer[id]) {
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
peer.alias = ''; peer.alias = '';

@ -34,7 +34,7 @@ export const listOffers = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
@ -50,7 +50,7 @@ export const createOffer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/offer'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
@ -66,7 +66,7 @@ export const fetchOfferInvoice = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -83,7 +83,7 @@ export const disableOffer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });

@ -10,7 +10,7 @@ export const getNewAddress = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
@ -26,7 +26,7 @@ export const onChainWithdraw = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -43,7 +43,7 @@ export const getUTXOs = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
// Local Remote Balance Calculation // Local Remote Balance Calculation

@ -8,7 +8,7 @@ const logger = Logger;
const common = Common; const common = Common;
const databaseService = Database; const databaseService = Database;
export const getMemo = (selNode, payment) => { export const getMemo = (selNode, payment) => {
options.url = selNode.ln_server_url + '/v1/decode'; options.url = selNode.settings.lnServerUrl + '/v1/decode';
options.body = { string: payment.bolt11 }; options.body = { string: payment.bolt11 };
return request.post(options).then((res) => { return request.post(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
@ -81,7 +81,7 @@ export const listPayments = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : []; body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
@ -103,7 +103,7 @@ export const postPayment = (req, res, next) => {
const options_body = JSON.parse(JSON.stringify(req.body)); const options_body = JSON.parse(JSON.stringify(req.body));
if (paymentType === 'KEYSEND') { if (paymentType === 'KEYSEND') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend';
delete options_body.uiMessage; delete options_body.uiMessage;
delete options_body.fromDialog; delete options_body.fromDialog;
delete options_body.paymentType; delete options_body.paymentType;
@ -144,7 +144,7 @@ export const postPayment = (req, res, next) => {
delete options_body.pubkey; delete options_body.pubkey;
delete options_body.saveToDB; delete options_body.saveToDB;
options.body = options_body; options.body = options_body;
options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay';
} }
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });

@ -11,7 +11,7 @@ export const getPeers = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
request.post(options).then((body) => { request.post(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;
@ -30,12 +30,12 @@ export const postPeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/connect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect';
options.body = req.body; options.body = req.body;
request.post(options).then((connectRes) => { request.post(options).then((connectRes) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
const listOptions = common.getOptions(req); const listOptions = common.getOptions(req);
listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
request.post(listOptions).then((listPeersRes) => { request.post(listOptions).then((listPeersRes) => {
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : []; const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
@ -55,7 +55,7 @@ export const deletePeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });

@ -10,7 +10,7 @@ export const decodePayment = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/decode'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
@ -26,7 +26,7 @@ export const signMessage = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
@ -42,7 +42,7 @@ export const verifyMessage = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage';
options.body = req.body; options.body = req.body;
request.post(options, (error, response, body) => { request.post(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
@ -58,7 +58,7 @@ export const listConfigs = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
res.status(200).json(body); res.status(200).json(body);

@ -27,14 +27,14 @@ export class CLWebSocketClient {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists) { if (!clientExists) {
if (selectedNode.ln_server_url) { if (selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
this.connectWithClient(newWebSocketClient); this.connectWithClient(newWebSocketClient);
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
} }
else { else {
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) { if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) {
clientExists.reConnect = true; clientExists.reConnect = true;
this.connectWithClient(clientExists); this.connectWithClient(clientExists);
} }
@ -47,11 +47,11 @@ export class CLWebSocketClient {
this.connectWithClient = (clWsClt) => { this.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..' });
try { try {
if (!clWsClt.selectedNode.rune_value) { if (!clWsClt.selectedNode.authentication.runeValue) {
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath);
} }
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, {
extraHeaders: { rune: clWsClt.selectedNode.rune_value }, extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue },
transports: ['websocket'], transports: ['websocket'],
secure: true, secure: true,
rejectUnauthorized: false rejectUnauthorized: false
@ -65,7 +65,7 @@ export class CLWebSocketClient {
this.waitTime = 0.5; this.waitTime = 0.5;
}); });
clWsClt.webSocketClient.on('disconnect', (reason) => { clWsClt.webSocketClient.on('disconnect', (reason) => {
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') { if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') {
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
clWsClt.webSocketClient.close(); clWsClt.webSocketClient.close();
if (clWsClt.reConnect) { if (clWsClt.reConnect) {

@ -27,7 +27,7 @@ export const simplifyAllChannels = (selNode, channels) => {
}); });
}); });
channelNodeIds = channelNodeIds.substring(1); channelNodeIds = channelNodeIds.substring(1);
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: channelNodeIds }; options.form = { nodeIds: channelNodeIds };
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
@ -47,7 +47,7 @@ export const getChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/channels';
options.form = {}; options.form = {};
if (req.query && req.query.nodeId) { if (req.query && req.query.nodeId) {
options.form = req.query; options.form = req.query;
@ -55,7 +55,7 @@ export const getChannels = (req, res, next) => {
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
} }
else { else {
request.post(options).then((body) => { request.post(options).then((body) => {
@ -83,7 +83,7 @@ export const getChannelStats = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/channelstats'; options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats';
const today = new Date(Date.now()); const today = new Date(Date.now());
const tillToday = (Math.round(today.getTime() / 1000)).toString(); const tillToday = (Math.round(today.getTime() / 1000)).toString();
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
@ -105,7 +105,7 @@ export const openChannel = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/open'; options.url = req.session.selectedNode.settings.lnServerUrl + '/open';
options.form = req.body; options.form = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -122,7 +122,7 @@ export const updateChannelRelayFee = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee'; options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee';
options.form = req.query; options.form = req.query;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -140,11 +140,11 @@ export const closeChannel = (req, res, next) => {
} }
if (req.query.force !== 'true') { if (req.query.force !== 'true') {
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..' });
options.url = req.session.selectedNode.ln_server_url + '/close'; options.url = req.session.selectedNode.settings.lnServerUrl + '/close';
} }
else { else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
options.url = req.session.selectedNode.ln_server_url + '/forceclose'; options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose';
} }
options.form = { channelId: req.query.channelId }; options.form = { channelId: req.query.channelId };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });

@ -99,7 +99,7 @@ export const getFees = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/audit'; options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const today = new Date(Date.now()); const today = new Date(Date.now());
const tillToday = (Math.round(today.getTime() / 1000)).toString(); const tillToday = (Math.round(today.getTime() / 1000)).toString();
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
@ -109,7 +109,7 @@ export const getFees = (req, res, next) => {
}; };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
} }
else { else {
request.post(options).then((body) => { request.post(options).then((body) => {
@ -127,11 +127,11 @@ export const getPayments = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/audit'; options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday }; options.form = { from: 0, to: tillToday };
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
} }
else { else {
request.post(options).then((body) => { request.post(options).then((body) => {

@ -16,12 +16,12 @@ export const getInfo = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo';
options.form = {}; options.form = {};
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data) => { common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data) => {
data.lnImplementation = 'Eclair'; data.lnImplementation = 'Eclair';
return res.status(200).json(data); return res.status(200).json(data);
}); });
@ -36,7 +36,7 @@ export const getInfo = (req, res, next) => {
return request.post(options).then((body) => { return request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
body.lnImplementation = 'Eclair'; body.lnImplementation = 'Eclair';
req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
eclWsClient.updateSelectedNode(req.session.selectedNode); eclWsClient.updateSelectedNode(req.session.selectedNode);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
return res.status(200).json(body); return res.status(200).json(body);

@ -39,7 +39,7 @@ export const getInvoice = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/getinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice';
options.form = { paymentHash: req.params.paymentHash }; options.form = { paymentHash: req.params.paymentHash };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
@ -55,8 +55,8 @@ export const getInvoice = (req, res, next) => {
}; };
export const listPendingInvoicesRequestCall = (selectedNode) => { export const listPendingInvoicesRequestCall = (selectedNode) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/listpendinginvoices'; options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() }; options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((pendingInvoicesResponse) => { request.post(options).then((pendingInvoicesResponse) => {
@ -76,16 +76,16 @@ export const listInvoices = (req, res, next) => {
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday }; options.form = { from: 0, to: tillToday };
const options1 = JSON.parse(JSON.stringify(options)); const options1 = JSON.parse(JSON.stringify(options));
options1.url = req.session.selectedNode.ln_server_url + '/listinvoices'; options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
options1.form = { from: 0, to: tillToday }; options1.form = { from: 0, to: tillToday };
const options2 = JSON.parse(JSON.stringify(options)); const options2 = JSON.parse(JSON.stringify(options));
options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices'; options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options2.form = { from: 0, to: tillToday }; options2.form = { from: 0, to: tillToday };
if (common.read_dummy_data) { if (common.read_dummy_data) {
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).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.settings.lnServerUrl, invoice))).
then((values) => res.status(200).json(invoices)); then((values) => res.status(200).json(invoices));
}); });
} }
@ -96,7 +96,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.settings.lnServerUrl, invoice))).
then((values) => { then((values) => {
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 });
return res.status(200).json(invoices); return res.status(200).json(invoices);
@ -119,8 +119,8 @@ export const listInvoices = (req, res, next) => {
}; };
export const createInvoiceRequestCall = (selectedNode, description, amount) => { export const createInvoiceRequestCall = (selectedNode, description, amount) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/createinvoice'; options.url = selectedNode.settings.lnServerUrl + '/createinvoice';
options.form = { description: description, amountMsat: amount }; options.form = { description: description, amountMsat: amount };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((invResponse) => { request.post(options).then((invResponse) => {

@ -10,7 +10,7 @@ export const getNodes = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/nodes'; options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: req.params.id }; options.form = { nodeIds: req.params.id };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
@ -22,8 +22,8 @@ export const getNodes = (req, res, next) => {
}; };
export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds = [], format = 'shortChannelId') => { export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds = [], format = 'shortChannelId') => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/findroutebetweennodes'; options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes';
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format }; options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((body) => { request.post(options).then((body) => {

@ -21,7 +21,7 @@ export const getNewAddress = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/getnewaddress'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getnewaddress';
options.form = {}; options.form = {};
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
@ -37,10 +37,10 @@ export const getBalance = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/onchainbalance'; options.url = req.session.selectedNode.settings.lnServerUrl + '/onchainbalance';
options.form = {}; options.form = {};
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('OnChainBalance', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); common.getDummyData('OnChainBalance', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeBalances(data)); });
} }
else { else {
request.post(options).then((body) => { request.post(options).then((body) => {
@ -59,7 +59,7 @@ export const getTransactions = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/onchaintransactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/onchaintransactions';
options.form = { options.form = {
count: req.query.count, count: req.query.count,
skip: req.query.skip skip: req.query.skip
@ -80,7 +80,7 @@ export const sendFunds = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/sendonchain'; options.url = req.session.selectedNode.settings.lnServerUrl + '/sendonchain';
options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks }; options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {

@ -5,7 +5,7 @@ let options = null;
const logger = Logger; const logger = Logger;
const common = Common; const common = Common;
export const getSentInfoFromPaymentRequest = (selNode, payment) => { export const getSentInfoFromPaymentRequest = (selNode, payment) => {
options.url = selNode.ln_server_url + '/getsentinfo'; options.url = selNode.settings.lnServerUrl + '/getsentinfo';
options.form = { paymentHash: payment }; options.form = { paymentHash: payment };
return request.post(options).then((body) => { return request.post(options).then((body) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body });
@ -21,7 +21,7 @@ export const getSentInfoFromPaymentRequest = (selNode, payment) => {
}).catch((err) => err); }).catch((err) => err);
}; };
export const getQueryNodes = (selNode, nodeIds) => { export const getQueryNodes = (selNode, nodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/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 });
@ -34,7 +34,7 @@ export const decodePayment = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/parseinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/parseinvoice';
options.form = { invoice: req.params.invoice }; options.form = { invoice: req.params.invoice };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
@ -53,7 +53,7 @@ export const postPayment = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/payinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/payinvoice';
options.form = req.body; options.form = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -70,7 +70,7 @@ export const queryPaymentRoute = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/findroutetonode'; options.url = req.session.selectedNode.settings.lnServerUrl + '/findroutetonode';
options.form = { options.form = {
nodeId: req.query.nodeId, nodeId: req.query.nodeId,
amountMsat: req.query.amountMsat amountMsat: req.query.amountMsat
@ -129,8 +129,8 @@ export const getSentPaymentsInformation = (req, res, next) => {
}; };
export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, invoice, amountMsat) => { export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, invoice, amountMsat) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/sendtoroute'; options.url = selectedNode.settings.lnServerUrl + '/sendtoroute';
options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice }; options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form }); logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form });

@ -5,7 +5,7 @@ let options = null;
const logger = Logger; const logger = Logger;
const common = Common; const common = Common;
export const getFilteredNodes = (selNode, peersNodeIds) => { export const getFilteredNodes = (selNode, peersNodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: peersNodeIds }; options.form = { nodeIds: peersNodeIds };
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes });
@ -18,10 +18,10 @@ export const getPeers = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
options.form = {}; options.form = {};
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Peers', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); common.getDummyData('Peers', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
} }
else { else {
request.post(options).then((body) => { request.post(options).then((body) => {
@ -58,7 +58,7 @@ export const connectPeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/connect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/connect';
options.form = {}; options.form = {};
if (req.query) { if (req.query) {
options.form = req.query; options.form = req.query;
@ -74,7 +74,7 @@ export const connectPeer = (req, res, next) => {
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, 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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
options.form = {}; options.form = {};
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body });
@ -112,7 +112,7 @@ export const deletePeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/disconnect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/disconnect';
options.form = {}; options.form = {};
if (req.params.nodeId) { if (req.params.nodeId) {
options.form = { nodeId: req.params.nodeId }; options.form = { nodeId: req.params.nodeId };

@ -28,14 +28,14 @@ export class ECLWebSocketClient {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists) { if (!clientExists) {
if (selectedNode.ln_server_url) { if (selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
this.connectWithClient(newWebSocketClient); this.connectWithClient(newWebSocketClient);
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
} }
else { else {
if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.ln_server_url) { if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.settings.lnServerUrl) {
clientExists.reConnect = true; clientExists.reConnect = true;
this.connectWithClient(clientExists); this.connectWithClient(clientExists);
} }
@ -47,9 +47,9 @@ export class ECLWebSocketClient {
}; };
this.connectWithClient = (eclWsClt) => { this.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.settings.lnServerUrl)?.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.authentication.lnApiPassword + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient = new WebSocket(WS_LINK);
eclWsClt.webSocketClient.onopen = () => { eclWsClt.webSocketClient.onopen = () => {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' });
@ -57,7 +57,7 @@ export class ECLWebSocketClient {
this.heartbeat(eclWsClt); this.heartbeat(eclWsClt);
}; };
eclWsClt.webSocketClient.onclose = (e) => { eclWsClt.webSocketClient.onclose = (e) => {
if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.ln_implementation === 'ECL') { if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.lnImplementation === 'ECL') {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' });
eclWsClt.webSocketClient.close(); eclWsClt.webSocketClient.close();
if (eclWsClt.reConnect) { if (eclWsClt.reConnect) {
@ -75,7 +75,7 @@ export class ECLWebSocketClient {
} }
}; };
eclWsClt.webSocketClient.onerror = (err) => { eclWsClt.webSocketClient.onerror = (err) => {
if (eclWsClt.selectedNode.ln_version === '' || !eclWsClt.selectedNode.ln_version || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { if (eclWsClt.selectedNode.lnVersion === '' || !eclWsClt.selectedNode.lnVersion || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err });
const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }')); const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }'));
this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode); this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode);

@ -10,7 +10,7 @@ export const getBlockchainBalance = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/balance/blockchain'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/balance/blockchain';
options.qs = req.query; options.qs = req.query;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query });

@ -6,7 +6,7 @@ const logger = Logger;
const common = Common; const common = Common;
export const getAliasForChannel = (selNode, channel) => { export const getAliasForChannel = (selNode, channel) => {
const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : ''; const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : '';
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
return request(options).then((aliasBody) => { return request(options).then((aliasBody) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias });
channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20); channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20);
@ -22,7 +22,7 @@ export const getAllChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
options.qs = req.query; options.qs = req.query;
let local = 0; let local = 0;
let remote = 0; let remote = 0;
@ -60,7 +60,7 @@ export const getPendingChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/pending';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
if (!body.total_limbo_balance) { if (!body.total_limbo_balance) {
@ -98,7 +98,7 @@ export const getClosedChannels = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/closed';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
if (body.channels && body.channels.length > 0) { if (body.channels && body.channels.length > 0) {
@ -129,7 +129,7 @@ export const postChannel = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
options.form = { options.form = {
node_pubkey_string: node_pubkey, node_pubkey_string: node_pubkey,
local_funding_amount: local_funding_amount, local_funding_amount: local_funding_amount,
@ -162,7 +162,7 @@ export const postTransactions = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/transaction-stream'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/transaction-stream';
options.form = { payment_request: paymentReq }; options.form = { payment_request: paymentReq };
if (paymentAmount) { if (paymentAmount) {
options.form.amt = paymentAmount; options.form.amt = paymentAmount;
@ -208,7 +208,7 @@ export const closeChannel = (req, res, next) => {
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 = req.params.channelPoint?.replace(':', '/');
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force; options.url = req.session.selectedNode.settings.lnServerUrl + '/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;
} }
@ -232,7 +232,7 @@ export const postChanPolicy = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/chanpolicy'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/chanpolicy';
if (chanPoint === 'all') { if (chanPoint === 'all') {
options.form = JSON.stringify({ options.form = JSON.stringify({
global: true, global: true,

@ -39,15 +39,15 @@ export const getBackup = (req, res, next) => {
let channel_backup_file = ''; let channel_backup_file = '';
let message = ''; let message = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak';
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.settings.lnServerUrl + '/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.settings.channelBackupPath + 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.settings.lnServerUrl + '/v1/channels/backup/' + channelpoint;
const exists = fs.existsSync(channel_backup_file); const exists = fs.existsSync(channel_backup_file);
if (exists) { if (exists) {
fs.writeFile(channel_backup_file, '', () => { }); fs.writeFile(channel_backup_file, '', () => { });
@ -86,13 +86,13 @@ export const postBackupVerify = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/verify'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/verify';
let channel_verify_file = ''; let channel_verify_file = '';
let message = ''; let message = '';
let verify_backup = ''; let verify_backup = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
message = 'All Channels Verify Successful.'; message = 'All Channels Verify Successful.';
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.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');
@ -116,7 +116,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.settings.channelBackupPath + 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');
@ -146,13 +146,13 @@ export const postRestore = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/restore'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/restore';
let channel_restore_file = ''; let channel_restore_file = '';
let message = ''; let message = '';
let restore_backup = ''; let restore_backup = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
message = 'All Channels Restore Successful.'; message = 'All Channels Restore Successful.';
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep; channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep;
const exists = fs.existsSync(channel_restore_file + 'channel-all.bak'); const exists = fs.existsSync(channel_restore_file + 'channel-all.bak');
const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak'); const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak');
if (exists) { if (exists) {
@ -188,7 +188,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.settings.channelBackupPath + 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');
@ -208,7 +208,7 @@ export const postRestore = (req, res, next) => {
channel_restore_file = channel_restore_file + 'channel-all.bak'; channel_restore_file = channel_restore_file + 'channel-all.bak';
} }
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => { fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
if (getFilesListRes.error) { if (getFilesListRes.error) {
const errMsg = getFilesListRes.error; const errMsg = getFilesListRes.error;
const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode);
@ -228,7 +228,7 @@ export const postRestore = (req, res, next) => {
} }
}; };
export const getRestoreList = (req, res, next) => { export const getRestoreList = (req, res, next) => {
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
if (getFilesListRes.error) { if (getFilesListRes.error) {
return res.status(getFilesListRes.statusCode).json(getFilesListRes); return res.status(getFilesListRes.statusCode).json(getFilesListRes);
} }

@ -11,7 +11,7 @@ export const getFees = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/fees'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fees';
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
const today = new Date(Date.now()); const today = new Date(Date.now());

@ -16,8 +16,8 @@ export const getInfo = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url });
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) { if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!'; const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!';
@ -26,7 +26,7 @@ export const getInfo = (req, res, next) => {
} }
else { else {
common.nodes?.map((node) => { common.nodes?.map((node) => {
if (node.ln_implementation === 'LND') { if (node.lnImplementation === 'LND') {
common.getAllNodeAllChannelBackup(node); common.getAllNodeAllChannelBackup(node);
} }
return node; return node;
@ -42,7 +42,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 {
req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
lndWsClient.updateSelectedNode(req.session.selectedNode); lndWsClient.updateSelectedNode(req.session.selectedNode);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
return res.status(200).json(body); return res.status(200).json(body);

@ -5,7 +5,7 @@ let options = null;
const logger = Logger; const logger = Logger;
const common = Common; const common = Common;
export const getAliasFromPubkey = (selNode, pubkey) => { export const getAliasFromPubkey = (selNode, pubkey) => {
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
return request(options).then((res) => { return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias });
return res.node.alias; return res.node.alias;
@ -18,7 +18,7 @@ export const getDescribeGraph = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph';
request.get(options).then((body) => { request.get(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -33,7 +33,7 @@ export const getGraphInfo = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/info'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/info';
request.get(options).then((body) => { request.get(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -48,7 +48,7 @@ export const getGraphNode = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/node/' + req.params.pubKey; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/node/' + req.params.pubKey;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -63,7 +63,7 @@ export const getGraphEdge = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -78,7 +78,7 @@ export const getQueryRoutes = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount;
if (req.query.outgoing_chan_id) { if (req.query.outgoing_chan_id) {
options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id; options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id;
} }
@ -116,7 +116,7 @@ export const getRemoteFeePolicy = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body });
let remoteNodeFee = {}; let remoteNodeFee = {};

@ -12,7 +12,7 @@ export const invoiceLookup = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/invoices/lookup'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/invoices/lookup';
if (req.query.payment_addr) { if (req.query.payment_addr) {
options.url = options.url + '?payment_addr=' + req.query.payment_addr; options.url = options.url + '?payment_addr=' + req.query.payment_addr;
} }
@ -36,7 +36,7 @@ export const listInvoices = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset +
'&reversed=' + req.query.reversed; '&reversed=' + req.query.reversed;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
@ -60,7 +60,7 @@ export const addInvoice = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices';
options.form = JSON.stringify(req.body); options.form = JSON.stringify(req.body);
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body });

@ -11,7 +11,7 @@ export const signMessage = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
options.form = JSON.stringify({ options.form = JSON.stringify({
msg: Buffer.from(message).toString('base64') msg: Buffer.from(message).toString('base64')
}); });
@ -30,7 +30,7 @@ export const verifyMessage = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/verifymessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/verifymessage';
options.form = JSON.stringify({ options.form = JSON.stringify({
msg: Buffer.from(message).toString('base64'), msg: Buffer.from(message).toString('base64'),
signature: signature signature: signature

@ -10,7 +10,7 @@ export const getNewAddress = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddress?type=' + req.query.type; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddress?type=' + req.query.type;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body });
res.status(200).json(body); res.status(200).json(body);

@ -5,7 +5,7 @@ let options = null;
const logger = Logger; const logger = Logger;
const common = Common; const common = Common;
export const decodePaymentFromPaymentRequest = (selNode, payment) => { export const decodePaymentFromPaymentRequest = (selNode, payment) => {
options.url = selNode.ln_server_url + '/v1/payreq/' + payment; options.url = selNode.settings.lnServerUrl + '/v1/payreq/' + payment;
return request(options).then((res) => { return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description });
return res; return res;
@ -17,7 +17,7 @@ export const decodePayment = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/payreq/' + req.params.payRequest; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payreq/' + req.params.payRequest;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -56,7 +56,7 @@ export const getPayments = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -69,8 +69,8 @@ export const getAllLightningTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' });
const options1 = JSON.parse(JSON.stringify(common.getOptions(req))); const options1 = JSON.parse(JSON.stringify(common.getOptions(req)));
const options2 = JSON.parse(JSON.stringify(common.getOptions(req))); const options2 = JSON.parse(JSON.stringify(common.getOptions(req)));
// options1.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; // options1.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=100000&index_offset=0&reversed=true';
options2.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; options2.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 });
// return Promise.all([request(options1), request(options2)]).then((values) => { // return Promise.all([request(options1), request(options2)]).then((values) => {
@ -88,7 +88,7 @@ export const paymentLookup = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/router/track/' + req.params.paymentHash; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/router/track/' + req.params.paymentHash;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body });
res.status(200).json(body.result || body); res.status(200).json(body.result || body);

@ -5,7 +5,7 @@ let options = null;
const logger = Logger; const logger = Logger;
const common = Common; const common = Common;
export const getAliasForPeers = (selNode, peer) => { export const getAliasForPeers = (selNode, peer) => {
options.url = selNode.ln_server_url + '/v1/graph/node/' + peer.pub_key; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + peer.pub_key;
return request(options).then((aliasBody) => { return request(options).then((aliasBody) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias });
peer.alias = aliasBody.node.alias; peer.alias = aliasBody.node.alias;
@ -21,7 +21,7 @@ export const getPeers = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
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;
@ -41,14 +41,14 @@ export const postPeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
options.form = JSON.stringify({ options.form = JSON.stringify({
addr: { host: host, pubkey: pubkey }, addr: { host: host, pubkey: pubkey },
perm: perm perm: perm
}); });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body });
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/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) => {
@ -76,7 +76,7 @@ export const deletePeer = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers/' + req.params.peerPubKey; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers/' + req.params.peerPubKey;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey });
request.delete(options).then((body) => { request.delete(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body });

@ -27,7 +27,7 @@ export const getAllForwardingEvents = (req, start, end, offset, caller, callback
return callback({ message: err.message, error: err.error, statusCode: err.statusCode }); return callback({ message: err.message, error: err.error, statusCode: err.statusCode });
} }
options = common.getOptions(req); options = common.getOptions(req);
options.url = req.session.selectedNode.ln_server_url + '/v1/switch'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/switch';
options.form = {}; options.form = {};
if (start) { if (start) {
options.form.start_time = start; options.form.start_time = start;

@ -10,7 +10,7 @@ export const getTransactions = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body });
res.status(200).json(body.transactions); res.status(200).json(body.transactions);
@ -26,7 +26,7 @@ export const postTransactions = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
options.form = { options.form = {
amount: amount, amount: amount,
addr: address, addr: address,

@ -12,10 +12,10 @@ export const genSeed = (req, res, next) => {
return res.status(options.statusCode).json({ message: options.message, error: options.error }); return res.status(options.statusCode).json({ message: options.message, error: options.error });
} }
if (req.params.passphrase) { if (req.params.passphrase) {
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64');
} }
else { else {
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed';
} }
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body });
@ -35,7 +35,7 @@ export const operateWallet = (req, res, next) => {
options.method = 'POST'; options.method = 'POST';
if (!req.params.operation || req.params.operation === 'unlockwallet') { if (!req.params.operation || req.params.operation === 'unlockwallet') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/unlockwallet'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/unlockwallet';
options.form = JSON.stringify({ options.form = JSON.stringify({
wallet_password: Buffer.from(atob(wallet_password)).toString('base64') wallet_password: Buffer.from(atob(wallet_password)).toString('base64')
}); });
@ -43,7 +43,7 @@ export const operateWallet = (req, res, next) => {
} }
else { else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/initwallet'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/initwallet';
if (aezeed_passphrase && aezeed_passphrase !== '') { if (aezeed_passphrase && aezeed_passphrase !== '') {
options.form = JSON.stringify({ options.form = JSON.stringify({
wallet_password: Buffer.from(atob(wallet_password)).toString('base64'), wallet_password: Buffer.from(atob(wallet_password)).toString('base64'),
@ -104,8 +104,8 @@ export const getUTXOs = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos';
if (common.isVersionCompatible(req.session.selectedNode.ln_version, '0.14.0')) { if (common.isVersionCompatible(req.session.selectedNode.lnVersion, '0.14.0')) {
options.form = JSON.stringify({ max_confs: req.query.max_confs }); options.form = JSON.stringify({ max_confs: req.query.max_confs });
} }
else { else {
@ -126,7 +126,7 @@ export const bumpFee = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/bumpfee'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/bumpfee';
options.form = {}; options.form = {};
options.form.outpoint = { options.form.outpoint = {
txid_str: txid, txid_str: txid,
@ -153,7 +153,7 @@ export const labelTransaction = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/tx/label'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/tx/label';
options.form = JSON.parse(JSON.stringify(options.form)); options.form = JSON.parse(JSON.stringify(options.form));
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -171,7 +171,7 @@ export const leaseUTXO = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/lease'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/lease';
options.form = {}; options.form = {};
options.form.id = txid; options.form.id = txid;
options.form.outpoint = { options.form.outpoint = {
@ -195,7 +195,7 @@ export const releaseUTXO = (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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/release'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/release';
options.form = {}; options.form = {};
options.form.id = txid; options.form.id = txid;
options.form.outpoint = { options.form.outpoint = {

@ -13,7 +13,7 @@ export class LNDWebSocketClient {
this.connect = (selectedNode) => { this.connect = (selectedNode) => {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists && selectedNode.ln_server_url) { if (!clientExists && selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode }; const newWebSocketClient = { selectedNode: selectedNode };
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
@ -25,7 +25,7 @@ export class LNDWebSocketClient {
this.fetchUnpaidInvoices = (selectedNode) => { this.fetchUnpaidInvoices = (selectedNode) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' });
const options = this.setOptionsForSelNode(selectedNode); const options = this.setOptionsForSelNode(selectedNode);
options.url = selectedNode.ln_server_url + '/v1/invoices?pending_only=true'; options.url = selectedNode.settings.lnServerUrl + '/v1/invoices?pending_only=true';
return request(options).then((body) => { return request(options).then((body) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body });
if (body.invoices && body.invoices.length > 0) { if (body.invoices && body.invoices.length > 0) {
@ -44,7 +44,7 @@ export class LNDWebSocketClient {
this.subscribeToInvoice = (options, selectedNode, rHash) => { this.subscribeToInvoice = (options, selectedNode, rHash) => {
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.settings.lnServerUrl + '/v2/invoices/subscribe/' + rHash;
request(options).then((msg) => { request(options).then((msg) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash });
if (typeof msg === 'string') { if (typeof msg === 'string') {
@ -67,7 +67,7 @@ export class LNDWebSocketClient {
}; };
this.subscribeToPayment = (options, selectedNode, paymentHash) => { this.subscribeToPayment = (options, selectedNode, paymentHash) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' });
options.url = selectedNode.ln_server_url + '/v2/router/track/' + paymentHash; options.url = selectedNode.settings.lnServerUrl + '/v2/router/track/' + paymentHash;
request(options).then((msg) => { request(options).then((msg) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash });
msg['type'] = 'payment'; msg['type'] = 'payment';
@ -84,7 +84,7 @@ export class LNDWebSocketClient {
this.setOptionsForSelNode = (selectedNode) => { this.setOptionsForSelNode = (selectedNode) => {
const options = { url: '', rejectUnauthorized: false, json: true, form: null }; const options = { url: '', rejectUnauthorized: false, json: true, form: null };
try { try {
options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) }); this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) });
@ -107,7 +107,7 @@ export class LNDWebSocketClient {
} }
newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode)); newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode));
this.webSocketClients[clientIdx] = newClient; this.webSocketClients[clientIdx] = newClient;
if (this.webSocketClients[clientIdx].selectedNode.ln_version === '' || !this.webSocketClients[clientIdx].selectedNode.ln_version || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.ln_version, '0.11.0')) { if (this.webSocketClients[clientIdx].selectedNode.lnVersion === '' || !this.webSocketClients[clientIdx].selectedNode.lnVersion || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.lnVersion, '0.11.0')) {
this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode); this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode);
} }
}; };

@ -12,208 +12,102 @@ const logger = Logger;
const common = Common; const common = Common;
const wsServer = WSServer; const wsServer = WSServer;
const databaseService = Database; const databaseService = Database;
export const updateSelectedNode = (req, res, next) => { export const maskPasswords = (obj) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); const keys = Object.keys(obj);
const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.initSelectedNode ? +common.initSelectedNode.index : 1; const length = keys.length;
req.session.selectedNode = common.findNode(selNodeIndex); if (length !== 0) {
if (req.headers && req.headers.authorization && req.headers.authorization !== '') { for (let i = 0; i < length; i++) {
wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); if (typeof obj[keys[i]] === 'object') {
if (req.params.prevNodeIndex !== '-1') { keys[keys[i]] = maskPasswords(obj[keys[i]]);
databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); }
} if (typeof keys[i] === 'string' &&
if (req.params.currNodeIndex !== '-1') { (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') ||
databaseService.loadDatabase(req.session); keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
keys[i].toLowerCase().includes('rpcuser'))) {
obj[keys[i]] = '*'.repeat(20);
}
} }
} }
const responseVal = !req.session.selectedNode.ln_node ? '' : req.session.selectedNode.ln_node; return obj;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal });
res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' });
}; };
export const getRTLConfigInitial = (req, res, next) => { export const getCurrencyRates = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' });
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; options.url = 'https://blockchain.info/ticker';
fs.readFile(confFile, 'utf8', (errRes, data) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body });
res.status(200).json(JSON.parse(body));
}).catch((errRes) => {
const errMsg = 'Get Rates Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
});
};
export const getFile = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
const file = req.query.path ? req.query.path : (req.session.selectedNode.settings.channelBackupPath + 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: 'File Path', data: file });
fs.readFile(file, 'utf8', (errRes, data) => {
if (errRes) { if (errRes) {
if (errRes.code === 'ENOENT') { if (errRes.code && errRes.code === 'ENOENT') {
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); errRes.code = 'File Not Found!';
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] });
}
else {
const errMsg = 'Get Node Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
const errMsg = 'Reading File Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
else { else {
const nodeConfData = JSON.parse(data); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data });
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; res.status(200).json(data);
const enable2FA = !!common.rtl_secret2fa;
const allowPasswordUpdate = common.flg_allow_password_update;
const nodesArr = [];
if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, i) => {
const settings = { unannouncedChannels: false };
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
settings.unannouncedChannels = !!node.unannounced_channels || false;
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
settings.currencyUnit = node.currency_unit;
nodesArr.push({
index: node.index,
lnNode: node.ln_node,
lnImplementation: node.ln_implementation,
settings: settings,
authentication: {}
});
});
}
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr };
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received', data: body });
res.status(200).json(body);
} }
}); });
}; };
export const getRTLConfig = (req, res, next) => { export const getRTLConfig = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' });
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
fs.readFile(confFile, 'utf8', (errRes, data) => { fs.readFile(confFile, 'utf8', (errRes, data) => {
if (errRes) { if (errRes) {
if (errRes.code === 'ENOENT') { const errMsg = 'Get Node Config Error';
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
else {
const errMsg = 'Get Node Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
} }
else { else {
const nodeConfData = JSON.parse(data); const nodeConfData = JSON.parse(data);
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link };
const enable2FA = !!common.rtl_secret2fa;
const allowPasswordUpdate = common.flg_allow_password_update;
const nodesArr = []; const nodesArr = [];
if (common.nodes && common.nodes.length > 0) { if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, i) => { common.nodes.forEach((node, i) => {
const authentication = {};
authentication.configPath = (node.config_path) ? node.config_path : '';
authentication.swapMacaroonPath = (node.swap_macaroon_path) ? node.swap_macaroon_path : '';
authentication.boltzMacaroonPath = (node.boltz_macaroon_path) ? node.boltz_macaroon_path : '';
const settings = { unannouncedChannels: false };
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
settings.unannouncedChannels = !!node.unannounced_channels || false;
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
settings.bitcoindConfigPath = node.bitcoind_config_path;
settings.logLevel = node.log_level ? node.log_level : 'ERROR';
settings.lnServerUrl = node.ln_server_url;
settings.swapServerUrl = node.swap_server_url;
settings.boltzServerUrl = node.boltz_server_url;
settings.enableOffers = node.enable_offers;
settings.enablePeerswap = node.enable_peerswap;
settings.channelBackupPath = node.channel_backup_path;
settings.currencyUnit = node.currency_unit;
nodesArr.push({ nodesArr.push({
index: node.index, index: node.index,
lnNode: node.ln_node, lnNode: node.lnNode,
lnImplementation: node.ln_implementation, lnImplementation: node.lnImplementation,
settings: settings, settings: node.settings,
authentication: authentication authentication: req.params.init ? {} : node.authentication
}); });
}); });
} }
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index),
sso: common.appConfig.sso, enable2FA: !!common.appConfig.rtlSecret2fa, allowPasswordUpdate: common.appConfig.allowPasswordUpdate, nodes: nodesArr };
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body });
res.status(200).json(body); res.status(200).json(body);
} }
}); });
}; };
export const updateUISettings = (req, res, next) => { export const updateSelectedNode = (req, res, next) => {
const { updatedSettings } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1;
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; req.session.selectedNode = common.findNode(selNodeIndex);
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); if (req.headers && req.headers.authorization && req.headers.authorization !== '') {
const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex);
if (node && node.Settings) { if (req.params.prevNodeIndex !== '-1') {
node.Settings.userPersona = updatedSettings.userPersona; databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id);
node.Settings.themeMode = updatedSettings.themeMode;
node.Settings.themeColor = updatedSettings.themeColor;
node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels;
node.Settings.fiatConversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
}
else {
delete node.Settings.currencyUnit;
}
const selectedNode = common.findNode(req.session.selectedNode.index);
selectedNode.user_persona = updatedSettings.userPersona;
selectedNode.theme_mode = updatedSettings.themeMode;
selectedNode.theme_color = updatedSettings.themeColor;
selectedNode.unannounced_channels = updatedSettings.unannouncedChannels;
selectedNode.fiat_conversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
selectedNode.currency_unit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} }
else { if (req.params.currNodeIndex !== '-1') {
delete selectedNode.currency_unit; databaseService.loadDatabase(req.session);
} }
common.replaceNode(req, selectedNode);
}
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Node Settings Updated Successfully' });
}
catch (errRes) {
const errMsg = 'Update Node Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
};
export const update2FASettings = (req, res, next) => {
const { secret2fa } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
if (secret2fa && secret2fa.trim() !== '') {
config.secret2fa = secret2fa;
}
else {
delete config.secret2fa;
}
const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.';
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.rtl_secret2fa = config.secret2fa;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message });
res.status(201).json({ message: message });
}
catch (errRes) {
const errMsg = 'Update 2FA Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
};
export const updateDefaultNode = (req, res, next) => {
const { defaultNodeIndex } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.defaultNodeIndex = defaultNodeIndex;
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Default Node Updated Successfully' });
}
catch (errRes) {
const errMsg = 'Update Default Node Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
const responseVal = !req.session.selectedNode.lnNode ? '' : req.session.selectedNode.lnNode;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal });
res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' });
}; };
export const getConfig = (req, res, next) => { export const getConfig = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' });
@ -221,14 +115,14 @@ export const getConfig = (req, res, next) => {
let fileFormat = 'INI'; let fileFormat = 'INI';
switch (req.params.nodeType) { switch (req.params.nodeType) {
case 'ln': case 'ln':
confFile = req.session.selectedNode.config_path; confFile = req.session.selectedNode.authentication.configPath;
break; break;
case 'bitcoind': case 'bitcoind':
confFile = req.session.selectedNode.bitcoind_config_path; confFile = req.session.selectedNode.settings.bitcoindConfigPath;
break; break;
case 'rtl': case 'rtl':
fileFormat = 'JSON'; fileFormat = 'JSON';
confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
break; break;
default: default:
confFile = ''; confFile = '';
@ -254,7 +148,7 @@ export const getConfig = (req, res, next) => {
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;
} }
if (req.params.nodeType === 'ln' && req.session.selectedNode.ln_implementation === 'ECL' && !jsonConfig['eclair.api.password']) { if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) {
fileFormat = 'HOCON'; fileFormat = 'HOCON';
jsonConfig = parseHocon(data); jsonConfig = parseHocon(data);
} }
@ -266,42 +160,94 @@ export const getConfig = (req, res, next) => {
} }
}); });
}; };
export const getFile = (req, res, next) => { export const updateNodeSettings = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); const { updatedSettings } = req.body;
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: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
fs.readFile(file, 'utf8', (errRes, data) => { const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index));
if (errRes) { if (node && node.Settings) {
if (errRes.code && errRes.code === 'ENOENT') { node.Settings.userPersona = updatedSettings.userPersona;
errRes.code = 'File Not Found!'; node.Settings.themeMode = updatedSettings.themeMode;
} node.Settings.themeColor = updatedSettings.themeColor;
const errMsg = 'Reading File Error'; node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels;
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); node.Settings.fiatConversion = updatedSettings.fiatConversion;
return res.status(err.statusCode).json({ message: err.error, error: err.error }); if (updatedSettings.fiatConversion) {
node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} }
else { else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); delete node.Settings.currencyUnit;
res.status(200).json(data);
} }
}); const selectedNode = common.findNode(req.session.selectedNode.index);
selectedNode.settings.userPersona = updatedSettings.userPersona;
selectedNode.settings.themeMode = updatedSettings.themeMode;
selectedNode.settings.themeColor = updatedSettings.themeColor;
selectedNode.settings.unannouncedChannels = updatedSettings.unannouncedChannels;
selectedNode.settings.fiatConversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
selectedNode.settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
}
else {
delete selectedNode.settings.currencyUnit;
}
common.replaceNode(req, selectedNode);
}
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Node Settings Updated Successfully' });
}
catch (errRes) {
const errMsg = 'Update Node Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
}; };
export const getCurrencyRates = (req, res, next) => { export const updateApplicationSettings = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); const { defaultNodeIndex } = req.body;
options.url = 'https://blockchain.info/ticker'; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' });
request(options).then((body) => { const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
res.status(200).json(JSON.parse(body)); config.defaultNodeIndex = defaultNodeIndex;
}).catch((errRes) => { try {
const errMsg = 'Get Rates Error'; fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Default Node Updated Successfully' });
}
catch (errRes) {
const errMsg = 'Update Default Node 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);
return res.status(err.statusCode).json({ message: err.error, error: err.error }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
}); }
};
export const update2FASettings = (req, res, next) => {
const { secret2fa } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' });
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
if (secret2fa && secret2fa.trim() !== '') {
config.secret2fa = secret2fa;
}
else {
delete config.secret2fa;
}
const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.';
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.appConfig.rtlSecret2fa = config.secret2fa;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message });
res.status(201).json({ message: message });
}
catch (errRes) {
const errMsg = 'Update 2FA Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
}; };
export const updateSSO = (req, res, next) => { export const updateSSO = (req, res, next) => {
const { SSO } = req.body; const { SSO } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
delete config.SSO; delete config.SSO;
config.SSO = SSO; config.SSO = SSO;
@ -319,7 +265,7 @@ export const updateSSO = (req, res, next) => {
export const updateServiceSettings = (req, res, next) => { export const updateServiceSettings = (req, res, next) => {
const { service, settings } = req.body; const { service, settings } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
const selectedNode = common.findNode(req.session.selectedNode.index); const selectedNode = common.findNode(req.session.selectedNode.index);
config.nodes.forEach((node) => { config.nodes.forEach((node) => {
@ -329,37 +275,37 @@ export const updateServiceSettings = (req, res, next) => {
if (settings.enable) { if (settings.enable) {
node.Settings.swapServerUrl = settings.serverUrl; node.Settings.swapServerUrl = settings.serverUrl;
node.Authentication.swapMacaroonPath = settings.macaroonPath; node.Authentication.swapMacaroonPath = settings.macaroonPath;
selectedNode.swap_server_url = settings.serverUrl; selectedNode.settings.swapServerUrl = settings.serverUrl;
selectedNode.swap_macaroon_path = settings.macaroonPath; selectedNode.authentication.swapMacaroonPath = settings.macaroonPath;
} }
else { else {
delete node.Settings.swapServerUrl; delete node.Settings.swapServerUrl;
delete node.Authentication.swapMacaroonPath; delete node.Authentication.swapMacaroonPath;
delete selectedNode.swap_server_url; delete selectedNode.settings.swapServerUrl;
delete selectedNode.swap_macaroon_path; delete selectedNode.authentication.swapMacaroonPath;
} }
break; break;
case 'BOLTZ': case 'BOLTZ':
if (settings.enable) { if (settings.enable) {
node.Settings.boltzServerUrl = settings.serverUrl; node.Settings.boltzServerUrl = settings.serverUrl;
node.Authentication.boltzMacaroonPath = settings.macaroonPath; node.Authentication.boltzMacaroonPath = settings.macaroonPath;
selectedNode.boltz_server_url = settings.serverUrl; selectedNode.settings.boltzServerUrl = settings.serverUrl;
selectedNode.boltz_macaroon_path = settings.macaroonPath; selectedNode.authentication.boltzMacaroonPath = settings.macaroonPath;
} }
else { else {
delete node.Settings.boltzServerUrl; delete node.Settings.boltzServerUrl;
delete node.Authentication.boltzMacaroonPath; delete node.Authentication.boltzMacaroonPath;
delete selectedNode.boltz_server_url; delete selectedNode.settings.boltzServerUrl;
delete selectedNode.boltz_macaroon_path; delete selectedNode.authentication.boltzMacaroonPath;
} }
break; break;
case 'OFFERS': case 'OFFERS':
node.Settings.enableOffers = settings.enableOffers; node.Settings.enableOffers = settings.enableOffers;
selectedNode.enable_offers = settings.enableOffers; selectedNode.settings.enableOffers = settings.enableOffers;
break; break;
case 'PEERSWAP': case 'PEERSWAP':
node.Settings.enablePeerswap = settings.enablePeerswap; node.Settings.enablePeerswap = settings.enablePeerswap;
selectedNode.enable_peerswap = settings.enablePeerswap; selectedNode.settings.enablePeerswap = settings.enablePeerswap;
break; break;
default: default:
break; break;
@ -379,21 +325,3 @@ export const updateServiceSettings = (req, res, next) => {
return res.status(err.statusCode).json({ message: err.error, error: err.error }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
}; };
export const maskPasswords = (obj) => {
const keys = Object.keys(obj);
const length = keys.length;
if (length !== 0) {
for (let i = 0; i < length; i++) {
if (typeof obj[keys[i]] === 'object') {
keys[keys[i]] = maskPasswords(obj[keys[i]]);
}
if (typeof keys[i] === 'string' &&
(keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') ||
keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
keys[i].toLowerCase().includes('rpcuser'))) {
obj[keys[i]] = '********************';
}
}
}
return obj;
};

@ -44,20 +44,20 @@ const handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => {
}; };
} }
}; };
export const verifyToken = (twoFAToken) => !!(common.rtl_secret2fa && common.rtl_secret2fa !== '' && otplib.authenticator.check(twoFAToken, common.rtl_secret2fa)); export const verifyToken = (twoFAToken) => !!(common.appConfig.rtlSecret2fa && common.appConfig.rtlSecret2fa !== '' && otplib.authenticator.check(twoFAToken, common.appConfig.rtlSecret2fa));
export const authenticateUser = (req, res, next) => { export const authenticateUser = (req, res, next) => {
const { authenticateWith, authenticationValue, twoFAToken } = req.body; const { authenticateWith, authenticationValue, twoFAToken } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' });
if (+common.rtl_sso) { if (+common.appConfig.sso.rtlSso) {
if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) { if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' }); res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' });
} }
else if (authenticateWith === 'PASSWORD') { else if (authenticateWith === 'PASSWORD') {
if (common.cookie_value.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie_value).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { if (common.appConfig.sso.cookieValue.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.appConfig.sso.cookieValue).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) {
common.refreshCookie(); common.refreshCookie();
if (!req.session.selectedNode) { if (!req.session.selectedNode) {
req.session.selectedNode = common.initSelectedNode; req.session.selectedNode = common.selectedNode;
} }
const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key); const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
@ -75,7 +75,7 @@ export const authenticateUser = (req, res, next) => {
const reqIP = common.getRequestIP(req); const reqIP = common.getRequestIP(req);
const failed = getFailedInfo(reqIP, currentTime); const failed = getFailedInfo(reqIP, currentTime);
const password = authenticationValue; const password = authenticationValue;
if (common.rtl_pass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { if (common.appConfig.rtlPass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) {
if (twoFAToken && twoFAToken !== '') { if (twoFAToken && twoFAToken !== '') {
if (!verifyToken(twoFAToken)) { if (!verifyToken(twoFAToken)) {
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } }); logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } });
@ -85,7 +85,7 @@ export const authenticateUser = (req, res, next) => {
} }
} }
if (!req.session.selectedNode) { if (!req.session.selectedNode) {
req.session.selectedNode = common.initSelectedNode; req.session.selectedNode = common.selectedNode;
} }
delete failedLoginAttempts[reqIP]; delete failedLoginAttempts[reqIP];
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
@ -94,8 +94,8 @@ export const authenticateUser = (req, res, next) => {
} }
else { else {
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } }); logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } });
failed.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count; failed.count = common.appConfig.rtlPass !== password ? (failed.count + 1) : failed.count;
failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried; failed.lastTried = common.appConfig.rtlPass !== password ? currentTime : failed.lastTried;
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!')); return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!'));
} }
} }
@ -103,14 +103,14 @@ export const authenticateUser = (req, res, next) => {
export const resetPassword = (req, res, next) => { export const resetPassword = (req, res, next) => {
const { currPassword, newPassword } = req.body; const { currPassword, newPassword } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' });
if (+common.rtl_sso) { if (+common.appConfig.sso.rtlSso) {
const errMsg = 'Password cannot be reset for SSO authentication'; const errMsg = 'Password cannot be reset for SSO authentication';
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', 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 {
if (common.rtl_pass === currPassword) { if (common.appConfig.rtlPass === currPassword) {
common.rtl_pass = common.replacePasswordWithHash(newPassword); common.appConfig.rtlPass = common.replacePasswordWithHash(newPassword);
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' });
res.status(200).json({ token: token }); res.status(200).json({ token: token });

@ -1,62 +1,69 @@
export class CommonSelectedNode { export class NodeSettings {
constructor(options, ln_server_url, macaroon_path, macaroon_value, rune_path, rune_value, ln_api_password, swap_server_url, boltz_server_url, config_path, rtl_conf_file_path, swap_macaroon_path, boltz_macaroon_path, bitcoind_config_path, channel_backup_path, log_level, log_file, index, ln_node, ln_implementation, user_persona, theme_mode, theme_color, unannounced_channels, fiat_conversion, currency_unit, ln_version, api_version, enable_offers, enable_peerswap) { constructor(lnServerUrl, swapServerUrl, boltzServerUrl, bitcoindConfigPath, channelBackupPath, logLevel, logFile, userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, enableOffers, enablePeerswap) {
this.options = options; this.lnServerUrl = lnServerUrl;
this.ln_server_url = ln_server_url; this.swapServerUrl = swapServerUrl;
this.macaroon_path = macaroon_path; this.boltzServerUrl = boltzServerUrl;
this.macaroon_value = macaroon_value; this.bitcoindConfigPath = bitcoindConfigPath;
this.rune_path = rune_path; this.channelBackupPath = channelBackupPath;
this.rune_value = rune_value; this.logLevel = logLevel;
this.ln_api_password = ln_api_password; this.logFile = logFile;
this.swap_server_url = swap_server_url;
this.boltz_server_url = boltz_server_url;
this.config_path = config_path;
this.rtl_conf_file_path = rtl_conf_file_path;
this.swap_macaroon_path = swap_macaroon_path;
this.boltz_macaroon_path = boltz_macaroon_path;
this.bitcoind_config_path = bitcoind_config_path;
this.channel_backup_path = channel_backup_path;
this.log_level = log_level;
this.log_file = log_file;
this.index = index;
this.ln_node = ln_node;
this.ln_implementation = ln_implementation;
this.user_persona = user_persona;
this.theme_mode = theme_mode;
this.theme_color = theme_color;
this.unannounced_channels = unannounced_channels;
this.fiat_conversion = fiat_conversion;
this.currency_unit = currency_unit;
this.ln_version = ln_version;
this.api_version = api_version;
this.enable_offers = enable_offers;
this.enable_peerswap = enable_peerswap;
}
}
export class AuthenticationConfiguration {
constructor(configPath, swapMacaroonPath, boltzMacaroonPath) {
this.configPath = configPath;
this.swapMacaroonPath = swapMacaroonPath;
this.boltzMacaroonPath = boltzMacaroonPath;
}
}
export class NodeSettingsConfiguration {
constructor(userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, bitcoindConfigPath, logLevel, lnServerUrl, swapServerUrl, boltzServerUrl, channelBackupPath, enableOffers, enablePeerswap) {
this.userPersona = userPersona; this.userPersona = userPersona;
this.themeMode = themeMode; this.themeMode = themeMode;
this.themeColor = themeColor; this.themeColor = themeColor;
this.unannouncedChannels = unannouncedChannels; this.unannouncedChannels = unannouncedChannels;
this.fiatConversion = fiatConversion; this.fiatConversion = fiatConversion;
this.currencyUnit = currencyUnit; this.currencyUnit = currencyUnit;
this.bitcoindConfigPath = bitcoindConfigPath;
this.logLevel = logLevel;
this.lnServerUrl = lnServerUrl;
this.swapServerUrl = swapServerUrl;
this.boltzServerUrl = boltzServerUrl;
this.channelBackupPath = channelBackupPath;
this.enableOffers = enableOffers; this.enableOffers = enableOffers;
this.enablePeerswap = enablePeerswap; this.enablePeerswap = enablePeerswap;
} }
} }
export class NodeAuthentication {
constructor(options, configPath, macaroonPath, macaroonValue, runePath, runeValue, lnApiPassword, swapMacaroonPath, boltzMacaroonPath) {
this.options = options;
this.configPath = configPath;
this.macaroonPath = macaroonPath;
this.macaroonValue = macaroonValue;
this.runePath = runePath;
this.runeValue = runeValue;
this.lnApiPassword = lnApiPassword;
this.swapMacaroonPath = swapMacaroonPath;
this.boltzMacaroonPath = boltzMacaroonPath;
}
}
export class SelectedNode {
constructor(logLevel, logFile, index, lnNode, lnImplementation, lnVersion, apiVersion, settings, authentication) {
this.logLevel = logLevel;
this.logFile = logFile;
this.index = index;
this.lnNode = lnNode;
this.lnImplementation = lnImplementation;
this.lnVersion = lnVersion;
this.apiVersion = apiVersion;
this.settings = settings;
this.authentication = authentication;
}
}
export class SSO {
constructor(rtlSso, rtlCookiePath, logoutRedirectLink, cookieValue) {
this.rtlSso = rtlSso;
this.rtlCookiePath = rtlCookiePath;
this.logoutRedirectLink = logoutRedirectLink;
this.cookieValue = cookieValue;
}
}
export class ApplicationConfig {
constructor(defaultNodeIndex, selectedNodeIndex, dbDirectoryPath, rtlConfFilePath, rtlPass, allowPasswordUpdate, rtlSecret2fa, sso, nodes) {
this.defaultNodeIndex = defaultNodeIndex;
this.selectedNodeIndex = selectedNodeIndex;
this.dbDirectoryPath = dbDirectoryPath;
this.rtlConfFilePath = rtlConfFilePath;
this.rtlPass = rtlPass;
this.allowPasswordUpdate = allowPasswordUpdate;
this.rtlSecret2fa = rtlSecret2fa;
this.sso = sso;
this.nodes = nodes;
}
}
export class LogJSONObj { export class LogJSONObj {
constructor(level, msg, data, error, fileName, selectedNode) { constructor(level, msg, data, error, fileName, selectedNode) {
this.level = level; this.level = level;

@ -1,17 +1,13 @@
import exprs from 'express'; import exprs from 'express';
const { Router } = exprs; const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js'; import { isAuthenticated } from '../../utils/authCheck.js';
import { getRTLConfigInitial, getRTLConfig, updateUISettings, update2FASettings, getConfig, getFile, updateSelectedNode, updateDefaultNode, updateServiceSettings, updateSSO, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; import { getRTLConfig, updateNodeSettings, getConfig, getFile, updateSelectedNode, updateApplicationSettings, getCurrencyRates } from '../../controllers/shared/RTLConf.js';
const router = Router(); const router = Router();
router.get('/rtlconfinit', getRTLConfigInitial); router.get('/rates', getCurrencyRates);
router.get('/rtlconf', isAuthenticated, getRTLConfig);
router.post('/', isAuthenticated, updateUISettings);
router.post('/update2FA', isAuthenticated, update2FASettings);
router.get('/config/:nodeType', isAuthenticated, getConfig);
router.get('/file', isAuthenticated, getFile); router.get('/file', isAuthenticated, getFile);
router.get('/rtlconf/:init', isAuthenticated, getRTLConfig);
router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode); router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode);
router.post('/updateDefaultNode', updateDefaultNode); router.get('/config/:nodeType', isAuthenticated, getConfig);
router.post('/updateServiceSettings', updateServiceSettings); router.post('/node', isAuthenticated, updateNodeSettings);
router.post('/updateSSO', updateSSO); router.post('/application', isAuthenticated, updateApplicationSettings);
router.get('/rates', getCurrencyRates);
export default router; export default router;

@ -30,7 +30,7 @@ export class ExpressApplication {
this.setCORS = () => { CORS.mount(this.app); }; this.setCORS = () => { CORS.mount(this.app); };
this.setCSRF = () => { CSRF.mount(this.app); }; this.setCSRF = () => { CSRF.mount(this.app); };
this.setApplicationRoutes = () => { this.setApplicationRoutes = () => {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' });
this.app.use(this.common.baseHref + '/api', sharedRoutes); this.app.use(this.common.baseHref + '/api', sharedRoutes);
this.app.use(this.common.baseHref + '/api/lnd', lndRoutes); this.app.use(this.common.baseHref + '/api/lnd', lndRoutes);
this.app.use(this.common.baseHref + '/api/cln', clnRoutes); this.app.use(this.common.baseHref + '/api/cln', clnRoutes);
@ -45,33 +45,33 @@ export class ExpressApplication {
this.handleApplicationErrors(err, res); this.handleApplicationErrors(err, res);
next(); next();
}); });
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' });
}; };
this.handleApplicationErrors = (err, res) => { this.handleApplicationErrors = (err, res) => {
switch (err.code) { switch (err.code) {
case 'EACCES': case 'EACCES':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' });
res.status(406).send('Server requires elevated privileges.'); res.status(406).send('Server requires elevated privileges.');
break; break;
case 'EADDRINUSE': case 'EADDRINUSE':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' });
res.status(409).send('Server is already in use.'); res.status(409).send('Server is already in use.');
break; break;
case 'ECONNREFUSED': case 'ECONNREFUSED':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' });
res.status(401).send('Server is down/locked.'); res.status(401).send('Server is down/locked.');
break; break;
case 'EBADCSRFTOKEN': case 'EBADCSRFTOKEN':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' });
res.status(403).send('Invalid CSRF token, form tempered.'); res.status(403).send('Invalid CSRF token, form tempered.');
break; break;
default: default:
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err });
res.status(400).send(JSON.stringify(err)); res.status(400).send(JSON.stringify(err));
break; break;
} }
}; };
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' });
this.app.set('trust proxy', true); this.app.set('trust proxy', true);
this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false })); this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false }));
this.app.use(cookieParser(this.common.secret_key)); this.app.use(cookieParser(this.common.secret_key));

@ -46,7 +46,7 @@ export const verifyWSUser = (info, next) => {
catch (err) { catch (err) {
cookies = {}; cookies = {};
updatedReq['cookies'] = JSON.parse(cookies); updatedReq['cookies'] = JSON.parse(cookies);
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err });
} }
csurfProtection(updatedReq, null, (err) => { csurfProtection(updatedReq, null, (err) => {
if (err) { if (err) {
@ -58,7 +58,7 @@ export const verifyWSUser = (info, next) => {
}); });
} }
catch (err) { catch (err) {
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err });
next(true); next(true);
} }
} }

@ -8,20 +8,11 @@ export class CommonService {
constructor() { constructor() {
this.logger = Logger; this.logger = Logger;
this.nodes = []; this.nodes = [];
this.initSelectedNode = null; this.selectedNode = null;
this.rtl_conf_file_path = ''; this.ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' };
this.appConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, rtlSecret2fa: '', sso: this.ssoInit, nodes: [] };
this.port = 3000; this.port = 3000;
this.host = ''; this.host = '';
this.db_directory_path = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
this.rtl_pass = '';
this.flg_allow_password_update = true;
this.rtl_secret2fa = '';
this.rtl_sso = 0;
this.rtl_cookie_path = '';
this.logout_redirect_link = '';
this.cookie_value = '';
this.ln_version = '';
this.api_version = '';
this.secret_key = crypto.randomBytes(64).toString('hex'); this.secret_key = crypto.randomBytes(64).toString('hex');
this.read_dummy_data = false; this.read_dummy_data = false;
this.baseHref = '/rtl'; this.baseHref = '/rtl';
@ -32,96 +23,96 @@ export class CommonService {
]; ];
this.setSwapServerOptions = (req) => { this.setSwapServerOptions = (req) => {
const swapOptions = { const swapOptions = {
baseUrl: req.session.selectedNode.swap_server_url, baseUrl: req.session.selectedNode.settings.swapServerUrl,
uri: '', uri: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': '' } headers: { 'Grpc-Metadata-macaroon': '' }
}; };
if (req.session.selectedNode.swap_macaroon_path) { if (req.session.selectedNode.authentication.swapMacaroonPath) {
try { try {
swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.swap_macaroon_path, 'loop.macaroon')).toString('hex') }; swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.swapMacaroonPath, 'loop.macaroon')).toString('hex') };
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err });
} }
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions });
return swapOptions; return swapOptions;
}; };
this.getBoltzServerOptions = (req) => { this.getBoltzServerOptions = (req) => {
const boltzOptions = { const boltzOptions = {
url: req.session.selectedNode.boltz_server_url, url: req.session.selectedNode.settings.boltzServerUrl,
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': '' } headers: { 'Grpc-Metadata-macaroon': '' }
}; };
if (req.session.selectedNode.boltz_macaroon_path) { if (req.session.selectedNode.authentication.boltzMacaroonPath) {
try { try {
boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.boltz_macaroon_path, 'admin.macaroon')).toString('hex') }; boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.boltzMacaroonPath, 'admin.macaroon')).toString('hex') };
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err });
} }
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions });
return boltzOptions; return boltzOptions;
}; };
this.getOptions = (req) => { this.getOptions = (req) => {
if (req.session.selectedNode && req.session.selectedNode.options) { if (req.session.selectedNode && req.session.selectedNode.authentication.options) {
req.session.selectedNode.options.method = (req.session.selectedNode.ln_implementation && req.session.selectedNode.ln_implementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; req.session.selectedNode.authentication.options.method = (req.session.selectedNode.lnImplementation && req.session.selectedNode.lnImplementation.toUpperCase() === 'LND') ? 'GET' : 'POST';
delete req.session.selectedNode.options.form; delete req.session.selectedNode.authentication.options.form;
delete req.session.selectedNode.options.body; delete req.session.selectedNode.authentication.options.body;
req.session.selectedNode.options.qs = {}; req.session.selectedNode.authentication.options.qs = {};
return req.session.selectedNode.options; return req.session.selectedNode.authentication.options;
} }
return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.initSelectedNode); return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.selectedNode);
}; };
this.updateSelectedNodeOptions = (req) => { this.updateSelectedNodeOptions = (req) => {
if (!req.session.selectedNode) { if (!req.session.selectedNode) {
req.session.selectedNode = {}; req.session.selectedNode = {};
} }
req.session.selectedNode.options = { req.session.selectedNode.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
try { try {
if (req.session.selectedNode && req.session.selectedNode.ln_implementation) { if (req.session.selectedNode && req.session.selectedNode.lnImplementation) {
switch (req.session.selectedNode.ln_implementation.toUpperCase()) { switch (req.session.selectedNode.lnImplementation.toUpperCase()) {
case 'CLN': case 'CLN':
try { try {
if (!req.session.selectedNode.rune_value) { if (!req.session.selectedNode.authentication.runeValue) {
req.session.selectedNode.rune_value = this.getRuneValue(req.session.selectedNode.rune_path); req.session.selectedNode.authentication.runeValue = this.getRuneValue(req.session.selectedNode.authentication.runePath);
} }
req.session.selectedNode.options.headers = { rune: req.session.selectedNode.rune_value }; req.session.selectedNode.authentication.options.headers = { rune: req.session.selectedNode.authentication.runeValue };
} }
catch (err) { catch (err) {
throw new Error(err); throw new Error(err);
} }
break; break;
case 'ECL': case 'ECL':
req.session.selectedNode.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.ln_api_password).toString('base64') }; req.session.selectedNode.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.authentication.lnApiPassword).toString('base64') };
break; break;
default: default:
req.session.selectedNode.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; req.session.selectedNode.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
break; break;
} }
} }
if (req.session.selectedNode) { if (req.session.selectedNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.ln_node, data: req.session.selectedNode.options }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.lnNode, data: req.session.selectedNode.authentication.options });
} }
return { status: 200, message: 'Updated Successfully' }; return { status: 200, message: 'Updated Successfully' };
} }
catch (err) { catch (err) {
req.session.selectedNode.options = { req.session.selectedNode.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err });
return { status: 502, message: err }; return { status: 502, message: err };
} }
}; };
@ -137,50 +128,50 @@ export class CommonService {
} }
}; };
this.setOptions = (req) => { this.setOptions = (req) => {
if (this.nodes[0].options && this.nodes[0].options.headers) { if (this.nodes[0].authentication.options && this.nodes[0].authentication.options.headers) {
return; return;
} }
if (this.nodes && this.nodes.length > 0) { if (this.nodes && this.nodes.length > 0) {
this.nodes.forEach((node) => { this.nodes.forEach((node) => {
node.options = { node.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
try { try {
if (node.ln_implementation) { if (node.lnImplementation) {
switch (node.ln_implementation.toUpperCase()) { switch (node.lnImplementation.toUpperCase()) {
case 'CLN': case 'CLN':
try { try {
if (!node.rune_value) { if (!node.authentication.runeValue) {
node.rune_value = this.getRuneValue(node.rune_path); node.authentication.runeValue = this.getRuneValue(node.authentication.runePath);
} }
node.options.headers = { rune: node.rune_value }; node.authentication.options.headers = { rune: node.authentication.runeValue };
} }
catch (err) { catch (err) {
throw new Error(err); throw new Error(err);
} }
break; break;
case 'ECL': case 'ECL':
node.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.ln_api_password).toString('base64') }; node.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.authentication.lnApiPassword).toString('base64') };
break; break;
default: default:
node.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.macaroon_path, 'admin.macaroon')).toString('hex') }; node.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
break; break;
} }
} }
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err });
node.options = { node.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: '' form: ''
}; };
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.ln_node, data: node.options }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.lnNode, data: node.authentication.options });
}); });
this.updateSelectedNodeOptions(req); this.updateSelectedNodeOptions(req);
} }
@ -260,9 +251,9 @@ export class CommonService {
err = JSON.parse(JSON.stringify(errRes)); err = JSON.parse(JSON.stringify(errRes));
} }
if (!selectedNode) { if (!selectedNode) {
selectedNode = this.initSelectedNode; selectedNode = this.selectedNode;
} }
switch (selectedNode.ln_implementation) { switch (selectedNode.lnImplementation) {
case 'LND': case 'LND':
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon']; delete err.options.headers['Grpc-Metadata-macaroon'];
@ -314,7 +305,7 @@ export class CommonService {
(err.message && typeof err.message === 'string') ? err.message : (typeof err === 'string') ? err : 'Unknown Error') (err.message && typeof err.message === 'string') ? err.message : (typeof err === 'string') ? err : 'Unknown Error')
}; };
} }
if (selectedNode.ln_implementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { if (selectedNode.lnImplementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') {
newErrorObj.statusCode = 500; newErrorObj.statusCode = 500;
} }
return newErrorObj; return newErrorObj;
@ -325,16 +316,16 @@ export class CommonService {
req.socket.remoteAddress || req.socket.remoteAddress ||
(req.connection.socket ? req.connection.socket.remoteAddress : null)); (req.connection.socket ? req.connection.socket.remoteAddress : null));
this.getDummyData = (dataKey, lnImplementation) => { this.getDummyData = (dataKey, lnImplementation) => {
const dummyDataFile = this.rtl_conf_file_path + sep + 'ECLDummyData.log'; const dummyDataFile = this.appConfig.rtlConfFilePath + sep + 'ECLDummyData.log';
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.dummy_data_array_from_file.length === 0) { if (this.dummy_data_array_from_file.length === 0) {
fs.readFile(dummyDataFile, 'utf8', (err, data) => { fs.readFile(dummyDataFile, 'utf8', (err, data) => {
if (err) { if (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' });
} }
else { else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' });
} }
} }
else { else {
@ -349,36 +340,36 @@ export class CommonService {
}); });
}; };
this.readCookie = () => { this.readCookie = () => {
const exists = fs.existsSync(this.rtl_cookie_path); const exists = fs.existsSync(this.appConfig.sso.rtlCookiePath);
if (exists) { if (exists) {
try { try {
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err });
throw new Error(err); throw new Error(err);
} }
} }
else { else {
try { try {
const directoryName = dirname(this.rtl_cookie_path); const directoryName = dirname(this.appConfig.sso.rtlCookiePath);
this.createDirectory(directoryName); this.createDirectory(directoryName);
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err });
throw new Error(err); throw new Error(err);
} }
} }
}; };
this.refreshCookie = () => { this.refreshCookie = () => {
try { try {
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err });
throw new Error(err); throw new Error(err);
} }
}; };
@ -405,50 +396,50 @@ export class CommonService {
}, initDir); }, initDir);
}; };
this.replacePasswordWithHash = (multiPassHashed) => { this.replacePasswordWithHash = (multiPassHashed) => {
this.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); this.appConfig.rtlConfFilePath = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..');
try { try {
const RTLConfFile = this.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = this.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.multiPassHashed = multiPassHashed; config.multiPassHashed = multiPassHashed;
delete config.multiPass; delete config.multiPass;
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' });
return config.multiPassHashed; return config.multiPassHashed;
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err });
} }
}; };
this.getAllNodeAllChannelBackup = (node) => { this.getAllNodeAllChannelBackup = (node) => {
const channel_backup_file = node.channel_backup_path + sep + 'channel-all.bak'; const channel_backup_file = node.settings.channelBackupPath + sep + 'channel-all.bak';
const options = { const options = {
url: node.ln_server_url + '/v1/channels/backup', url: node.settings.lnServerUrl + '/v1/channels/backup',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') } headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.authentication.macaroonPath + '/admin.macaroon').toString('hex') }
}; };
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.ln_node + '..' }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.lnNode + '..' });
request(options).then((body) => { request(options).then((body) => {
fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => { fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => {
if (err) { if (err) {
if (node.ln_node) { if (node.lnNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
} }
else { else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err });
} }
} }
else { else {
if (node.ln_node) { if (node.lnNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.ln_node, data: body }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.lnNode, data: body });
} }
else { else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body });
} }
} }
}); });
}, (err) => { }, (err) => {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
fs.writeFile(channel_backup_file, '', () => { }); fs.writeFile(channel_backup_file, '', () => { });
}); });
}; };
@ -458,8 +449,8 @@ export class CommonService {
const pattern = /v?(\d+(\.\d+)*)/; const pattern = /v?(\d+(\.\d+)*)/;
const match = currentVersion.match(pattern); const match = currentVersion.match(pattern);
if (match && match.length && match.length > 1) { if (match && match.length && match.length > 1) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] });
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion });
const currentVersionArr = match[1].split('.') || []; const currentVersionArr = match[1].split('.') || [];
currentVersionArr[1] = currentVersionArr[1].substring(0, 2); currentVersionArr[1] = currentVersionArr[1].substring(0, 2);
const checkVersionsArr = checkVersion.split('.'); const checkVersionsArr = checkVersion.split('.');
@ -469,7 +460,7 @@ export class CommonService {
(+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]); (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]);
} }
else { else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion });
return false; return false;
} }
} }
@ -481,16 +472,16 @@ export class CommonService {
if (selNode && selNode.index) { if (selNode && selNode.index) {
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.db_directory_path }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.appConfig.dbDirectoryPath });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.rtl_sso }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.appConfig.sso.rtlSso });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.ln_node }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.lnNode });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.ln_implementation }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.lnImplementation });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.fiat_conversion }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.settings.fiatConversion });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.currency_unit }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.settings.currencyUnit });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.ln_server_url }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.settings.lnServerUrl });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.logout_redirect_link + '\r\n' }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.appConfig.sso.logoutRedirectLink + '\r\n' });
} }
}; };
this.filterData = (dataKey, lnImplementation) => { this.filterData = (dataKey, lnImplementation) => {

@ -95,9 +95,9 @@ export class ConfigService {
}; };
this.updateLogByLevel = () => { this.updateLogByLevel = () => {
let updateLogFlag = false; let updateLogFlag = false;
this.common.rtl_conf_file_path = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); this.common.appConfig.rtlConfFilePath = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
try { try {
const RTLConfFile = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.nodes.forEach((node) => { config.nodes.forEach((node) => {
if (node.Settings.hasOwnProperty('enableLogging')) { if (node.Settings.hasOwnProperty('enableLogging')) {
@ -117,19 +117,19 @@ export class ConfigService {
this.validateNodeConfig = (config) => { this.validateNodeConfig = (config) => {
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
this.common.rtl_pass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); this.common.appConfig.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
this.common.flg_allow_password_update = false; this.common.appConfig.allowPasswordUpdate = false;
} }
else if (config.multiPassHashed && config.multiPassHashed !== '') { else if (config.multiPassHashed && config.multiPassHashed !== '') {
this.common.rtl_pass = config.multiPassHashed; this.common.appConfig.rtlPass = config.multiPassHashed;
} }
else if (config.multiPass && config.multiPass !== '') { else if (config.multiPass && config.multiPass !== '') {
this.common.rtl_pass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); this.common.appConfig.rtlPass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex'));
} }
else { else {
this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json'; this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json';
} }
this.common.rtl_secret2fa = config.secret2fa; this.common.appConfig.rtlSecret2fa = config.secret2fa;
} }
else { else {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
@ -138,23 +138,23 @@ export class ConfigService {
} }
this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000; this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000;
this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null; this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null;
this.common.db_directory_path = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); this.common.appConfig.dbDirectoryPath = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..');
if (config.nodes && config.nodes.length > 0) { if (config.nodes && config.nodes.length > 0) {
config.nodes.forEach((node, idx) => { config.nodes.forEach((node, idx) => {
this.common.nodes[idx] = {}; this.common.nodes[idx] = {};
this.common.nodes[idx].index = node.index; this.common.nodes[idx].index = node.index;
this.common.nodes[idx].ln_node = node.lnNode; this.common.nodes[idx].lnNode = node.lnNode;
this.common.nodes[idx].ln_implementation = (process?.env?.LN_IMPLEMENTATION) ? process?.env?.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND'; this.common.nodes[idx].lnImplementation = (process?.env?.lnImplementation) ? process?.env?.lnImplementation : node.lnImplementation ? node.lnImplementation : 'LND';
if (this.common.nodes[idx].ln_implementation === 'CLT') { if (this.common.nodes[idx].lnImplementation === 'CLT') {
this.common.nodes[idx].ln_implementation = 'CLN'; this.common.nodes[idx].lnImplementation = 'CLN';
} }
switch (this.common.nodes[idx].ln_implementation) { switch (this.common.nodes[idx].lnImplementation) {
case 'CLN': case 'CLN':
if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') { if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') {
this.common.nodes[idx].rune_path = process?.env?.RUNE_PATH; this.common.nodes[idx].authentication.runePath = process?.env?.RUNE_PATH;
} }
else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') { else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') {
this.common.nodes[idx].rune_path = node.Authentication.runePath; this.common.nodes[idx].authentication.runePath = node.Authentication.runePath;
} }
else { else {
this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!';
@ -162,21 +162,21 @@ export class ConfigService {
break; break;
case 'ECL': case 'ECL':
if (process?.env?.LN_API_PASSWORD) { if (process?.env?.LN_API_PASSWORD) {
this.common.nodes[idx].ln_api_password = process?.env?.LN_API_PASSWORD; this.common.nodes[idx].authentication.lnApiPassword = process?.env?.LN_API_PASSWORD;
} }
else if (node.Authentication && node.Authentication.lnApiPassword) { else if (node.Authentication && node.Authentication.lnApiPassword) {
this.common.nodes[idx].ln_api_password = node.Authentication.lnApiPassword; this.common.nodes[idx].authentication.lnApiPassword = node.Authentication.lnApiPassword;
} }
else { else {
this.common.nodes[idx].ln_api_password = ''; this.common.nodes[idx].authentication.lnApiPassword = '';
} }
break; break;
default: default:
if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') { if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') {
this.common.nodes[idx].macaroon_path = process?.env?.MACAROON_PATH; this.common.nodes[idx].authentication.macaroonPath = process?.env?.MACAROON_PATH;
} }
else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') { else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') {
this.common.nodes[idx].macaroon_path = node.Authentication.macaroonPath; this.common.nodes[idx].authentication.macaroonPath = node.Authentication.macaroonPath;
} }
else { else {
this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!';
@ -184,114 +184,114 @@ export class ConfigService {
break; break;
} }
if (process?.env?.CONFIG_PATH) { if (process?.env?.CONFIG_PATH) {
this.common.nodes[idx].config_path = process?.env?.CONFIG_PATH; this.common.nodes[idx].authentication.configPath = process?.env?.CONFIG_PATH;
} }
else if (node.Authentication && node.Authentication.configPath) { else if (node.Authentication && node.Authentication.configPath) {
this.common.nodes[idx].config_path = node.Authentication.configPath; this.common.nodes[idx].authentication.configPath = node.Authentication.configPath;
} }
else { else {
this.common.nodes[idx].config_path = ''; this.common.nodes[idx].authentication.configPath = '';
} }
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '' && this.common.nodes[idx].config_path !== '') { if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '' && this.common.nodes[idx].authentication.configPath !== '') {
try { try {
const exists = fs.existsSync(this.common.nodes[idx].config_path || ''); const exists = fs.existsSync(this.common.nodes[idx].authentication.configPath || '');
if (exists) { if (exists) {
try { try {
const configFile = fs.readFileSync((this.common.nodes[idx].config_path || ''), 'utf-8'); const configFile = fs.readFileSync((this.common.nodes[idx].authentication.configPath || ''), 'utf-8');
const iniParsed = ini.parse(configFile); const iniParsed = ini.parse(configFile);
this.common.nodes[idx].ln_api_password = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; this.common.nodes[idx].authentication.lnApiPassword = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password;
} }
catch (err) { catch (err) {
this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err; this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err;
} }
} }
else { else {
this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].config_path; this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].authentication.configPath;
} }
} }
catch (err) { catch (err) {
this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err; this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err;
} }
} }
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '') { if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '') {
this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!'; this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!';
} }
if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') { if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') {
this.common.nodes[idx].ln_server_url = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; this.common.nodes[idx].settings.lnServerUrl = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL;
} }
else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') { else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') {
this.common.nodes[idx].ln_server_url = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; this.common.nodes[idx].settings.lnServerUrl = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL;
} }
else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') { else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') {
this.common.nodes[idx].ln_server_url = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; this.common.nodes[idx].settings.lnServerUrl = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl;
} }
else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') { else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') {
this.common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; this.common.nodes[idx].settings.lnServerUrl = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl;
} }
else { else {
this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!';
} }
this.common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; this.common.nodes[idx].settings.userPersona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT';
this.common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; this.common.nodes[idx].settings.themeMode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY';
this.common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; this.common.nodes[idx].settings.themeColor = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE';
this.common.nodes[idx].unannounced_channels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; this.common.nodes[idx].settings.unannouncedChannels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false;
this.common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; this.common.nodes[idx].settings.logLevel = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR';
this.common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; this.common.nodes[idx].settings.fiatConversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false;
if (this.common.nodes[idx].fiat_conversion) { if (this.common.nodes[idx].settings.fiatConversion) {
this.common.nodes[idx].currency_unit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; this.common.nodes[idx].settings.currencyUnit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD';
} }
if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') { if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') {
this.common.nodes[idx].swap_server_url = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; this.common.nodes[idx].settings.swapServerUrl = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL;
this.common.nodes[idx].swap_macaroon_path = process?.env?.SWAP_MACAROON_PATH; this.common.nodes[idx].authentication.swapMacaroonPath = process?.env?.SWAP_MACAROON_PATH;
} }
else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') { else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') {
this.common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; this.common.nodes[idx].settings.swapServerUrl = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl;
this.common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; this.common.nodes[idx].authentication.swapMacaroonPath = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : '';
} }
else { else {
this.common.nodes[idx].swap_server_url = ''; this.common.nodes[idx].settings.swapServerUrl = '';
this.common.nodes[idx].swap_macaroon_path = ''; this.common.nodes[idx].authentication.swapMacaroonPath = '';
} }
if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') { if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') {
this.common.nodes[idx].boltz_server_url = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; this.common.nodes[idx].settings.boltzServerUrl = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL;
this.common.nodes[idx].boltz_macaroon_path = process?.env?.BOLTZ_MACAROON_PATH; this.common.nodes[idx].authentication.boltzMacaroonPath = process?.env?.BOLTZ_MACAROON_PATH;
} }
else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') { else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') {
this.common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; this.common.nodes[idx].settings.boltzServerUrl = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl;
this.common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; this.common.nodes[idx].authentication.boltzMacaroonPath = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : '';
} }
else { else {
this.common.nodes[idx].boltz_server_url = ''; this.common.nodes[idx].settings.boltzServerUrl = '';
this.common.nodes[idx].boltz_macaroon_path = ''; this.common.nodes[idx].authentication.boltzMacaroonPath = '';
} }
this.common.nodes[idx].enable_offers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; this.common.nodes[idx].settings.enableOffers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false;
this.common.nodes[idx].enable_peerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; this.common.nodes[idx].settings.enablePeerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false;
this.common.nodes[idx].bitcoind_config_path = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; this.common.nodes[idx].settings.bitcoindConfigPath = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
this.common.nodes[idx].channel_backup_path = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index; this.common.nodes[idx].settings.channelBackupPath = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.appConfig.rtlConfFilePath + sep + 'channels-backup' + sep + 'node-' + node.index;
try { try {
this.common.createDirectory(this.common.nodes[idx].channel_backup_path); this.common.createDirectory(this.common.nodes[idx].settings.channelBackupPath);
const exists = fs.existsSync(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); const exists = fs.existsSync(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
if (!exists) { if (!exists) {
try { try {
if (this.common.nodes[idx].ln_implementation === 'LND') { if (this.common.nodes[idx].lnImplementation === 'LND') {
this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]); this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]);
} }
else { else {
const createStream = fs.createWriteStream(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); const createStream = fs.createWriteStream(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
createStream.end(); createStream.end();
} }
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err });
} }
} }
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err });
} }
this.common.nodes[idx].log_file = this.common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log'; this.common.nodes[idx].settings.logFile = this.common.appConfig.rtlConfFilePath + '/logs/RTL-Node-' + node.index + '.log';
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) });
const log_file = this.common.nodes[idx].log_file; const log_file = this.common.nodes[idx].settings.logFile;
if (fs.existsSync(log_file || '')) { if (fs.existsSync(log_file || '')) {
fs.writeFile((log_file || ''), '', () => { }); fs.writeFile((log_file || ''), '', () => { });
} }
@ -303,7 +303,7 @@ export class ConfigService {
createStream.end(); createStream.end();
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err });
} }
} }
}); });
@ -315,28 +315,28 @@ export class ConfigService {
}; };
this.setSSOParams = (config) => { this.setSSOParams = (config) => {
if (process?.env?.RTL_SSO) { if (process?.env?.RTL_SSO) {
this.common.rtl_sso = +process?.env?.RTL_SSO; this.common.appConfig.sso.rtlSso = +process?.env?.RTL_SSO;
} }
else if (config.SSO && config.SSO.rtlSSO) { else if (config.SSO && config.SSO.rtlSSO) {
this.common.rtl_sso = config.SSO.rtlSSO; this.common.appConfig.sso.rtlSso = config.SSO.rtlSSO;
} }
if (process?.env?.RTL_COOKIE_PATH) { if (process?.env?.RTL_COOKIE_PATH) {
this.common.rtl_cookie_path = process?.env?.RTL_COOKIE_PATH; this.common.appConfig.sso.rtlCookiePath = process?.env?.RTL_COOKIE_PATH;
} }
else if (config.SSO && config.SSO.rtlCookiePath) { else if (config.SSO && config.SSO.rtlCookiePath) {
this.common.rtl_cookie_path = config.SSO.rtlCookiePath; this.common.appConfig.sso.rtlCookiePath = config.SSO.rtlCookiePath;
} }
else { else {
this.common.rtl_cookie_path = ''; this.common.appConfig.sso.rtlCookiePath = '';
} }
if (process?.env?.LOGOUT_REDIRECT_LINK) { if (process?.env?.LOGOUT_REDIRECT_LINK) {
this.common.logout_redirect_link = process?.env?.LOGOUT_REDIRECT_LINK; this.common.appConfig.sso.logoutRedirectLink = process?.env?.LOGOUT_REDIRECT_LINK;
} }
else if (config.SSO && config.SSO.logoutRedirectLink) { else if (config.SSO && config.SSO.logoutRedirectLink) {
this.common.logout_redirect_link = config.SSO.logoutRedirectLink; this.common.appConfig.sso.logoutRedirectLink = config.SSO.logoutRedirectLink;
} }
if (+this.common.rtl_sso) { if (+this.common.appConfig.sso.rtlSso) {
if (!this.common.rtl_cookie_path || this.common.rtl_cookie_path.trim() === '') { if (!this.common.appConfig.sso.rtlCookiePath || this.common.appConfig.sso.rtlCookiePath.trim() === '') {
this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; this.errMsg = 'Please set rtlCookiePath value for single sign on option!';
} }
else { else {
@ -346,16 +346,16 @@ export class ConfigService {
}; };
this.setSelectedNode = (config) => { this.setSelectedNode = (config) => {
if (config.defaultNodeIndex) { if (config.defaultNodeIndex) {
this.common.initSelectedNode = this.common.findNode(config.defaultNodeIndex) || {}; this.common.selectedNode = this.common.findNode(config.defaultNodeIndex) || {};
} }
else { else {
this.common.initSelectedNode = this.common.findNode(this.common.nodes[0].index) || {}; this.common.selectedNode = this.common.findNode(this.common.nodes[0].index) || {};
} }
}; };
this.setServerConfiguration = () => { this.setServerConfiguration = () => {
try { try {
this.common.rtl_conf_file_path = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
const confFileFullPath = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
if (!fs.existsSync(confFileFullPath)) { if (!fs.existsSync(confFileFullPath)) {
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig()));
} }
@ -365,7 +365,7 @@ export class ConfigService {
this.setSelectedNode(config); this.setSelectedNode(config);
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err });
throw new Error(err); throw new Error(err);
} }
}; };

@ -6,7 +6,7 @@ class CORS {
this.common = Common; this.common = Common;
} }
mount(app) { mount(app) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' });
app.use((req, res, next) => { app.use((req, res, next) => {
res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath');
@ -17,7 +17,7 @@ class CORS {
} }
next(); next();
}); });
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' });
return app; return app;
} }
; ;

@ -8,11 +8,11 @@ class CSRF {
this.common = Common; this.common = Common;
} }
mount(app) { mount(app) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development') {
app.use((req, res, next) => this.csrfProtection(req, res, next)); app.use((req, res, next) => this.csrfProtection(req, res, next));
} }
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' });
return app; return app;
} }
; ;

@ -7,12 +7,12 @@ export class DatabaseService {
constructor() { constructor() {
this.common = Common; this.common = Common;
this.logger = Logger; this.logger = Logger;
this.dbDirectory = join(this.common.db_directory_path, 'database'); this.dbDirectory = join(this.common.appConfig.dbDirectoryPath, 'database');
this.nodeDatabase = {}; this.nodeDatabase = {};
} }
migrateDatabase() { migrateDatabase() {
this.common.nodes?.map((node) => { this.common.nodes?.map((node) => {
if (node.ln_implementation === 'ECL') { if (node.lnImplementation === 'ECL') {
this.nodeDatabase[node.index] = { adapter: null, data: {} }; this.nodeDatabase[node.index] = { adapter: null, data: {} };
this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node); this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node);
this.fetchNodeData(node); this.fetchNodeData(node);
@ -80,7 +80,7 @@ export class DatabaseService {
} }
} }
fetchNodeData(selectedNode) { fetchNodeData(selectedNode) {
switch (selectedNode.ln_implementation) { switch (selectedNode.lnImplementation) {
case 'CLN': case 'CLN':
for (const collectionName in CLNCollection) { for (const collectionName in CLNCollection) {
if (CLNCollection.hasOwnProperty(collectionName)) { if (CLNCollection.hasOwnProperty(collectionName)) {
@ -250,14 +250,14 @@ export class DatabaseAdapter {
this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index; this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index;
// For backward compatibility Start // For backward compatibility Start
const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json'; const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json';
if (selNode.ln_implementation === 'CLN' && fs.existsSync(oldFilePath)) { if (selNode.lnImplementation === 'CLN' && fs.existsSync(oldFilePath)) {
this.renameOldDB(oldFilePath, selNode); this.renameOldDB(oldFilePath, selNode);
} }
// For backward compatibility End // For backward compatibility End
this.insertSession(id); this.insertSession(id);
} }
renameOldDB(oldFilePath, selNode = null) { renameOldDB(oldFilePath, selNode = null) {
const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.ln_implementation + '-Offers.json'; const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.lnImplementation + '-Offers.json';
try { try {
this.common.createDirectory(this.dbFilePath); this.common.createDirectory(this.dbFilePath);
const oldOffers = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8')); const oldOffers = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8'));
@ -277,7 +277,7 @@ export class DatabaseAdapter {
catch (err) { catch (err) {
throw new Error(JSON.stringify(err)); throw new Error(JSON.stringify(err));
} }
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
try { try {
if (!fs.existsSync(collectionFilePath)) { if (!fs.existsSync(collectionFilePath)) {
fs.writeFileSync(collectionFilePath, '[]'); fs.writeFileSync(collectionFilePath, '[]');
@ -290,15 +290,15 @@ export class DatabaseAdapter {
const otherFiles = fs.readdirSync(this.dbFilePath); const otherFiles = fs.readdirSync(this.dbFilePath);
otherFiles.forEach((oFileName) => { otherFiles.forEach((oFileName) => {
let collectionValid = false; let collectionValid = false;
switch (this.selNode.ln_implementation) { switch (this.selNode.lnImplementation) {
case 'CLN': case 'CLN':
collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
case 'ECL': case 'ECL':
collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
default: default:
collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
} }
if (oFileName.endsWith('.json') && !collectionValid) { if (oFileName.endsWith('.json') && !collectionValid) {
@ -324,7 +324,7 @@ export class DatabaseAdapter {
saveData(collectionName, collectionData) { saveData(collectionName, collectionData) {
try { try {
if (collectionData) { if (collectionData) {
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
const tempFile = collectionFilePath + '.tmp'; const tempFile = collectionFilePath + '.tmp';
fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2)); fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2));
fs.renameSync(tempFile, collectionFilePath); fs.renameSync(tempFile, collectionFilePath);

@ -16,15 +16,15 @@ export class LoggerService {
msgStr = msgStr + '.\r\n'; msgStr = msgStr + '.\r\n';
} }
console.error(msgStr); console.error(msgStr);
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
break; break;
case 'WARN': case 'WARN':
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
if (!msgJSON.selectedNode || msgJSON.selectedNode.log_level === 'WARN' || msgJSON.selectedNode.log_level === 'INFO' || msgJSON.selectedNode.log_level === 'DEBUG') { if (!msgJSON.selectedNode || msgJSON.selectedNode.settings.logLevel === 'WARN' || msgJSON.selectedNode.settings.logLevel === 'INFO' || msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;
@ -32,18 +32,18 @@ export class LoggerService {
if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') { if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') {
console.log(msgStr + '.\r\n'); console.log(msgStr + '.\r\n');
} }
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'INFO') { else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'INFO') {
msgStr = msgStr + '.\r\n'; msgStr = msgStr + '.\r\n';
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;
@ -51,11 +51,11 @@ export class LoggerService {
if (!msgJSON.selectedNode) { if (!msgJSON.selectedNode) {
console.log(msgStr + '.\r\n'); console.log(msgStr + '.\r\n');
} }
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;

@ -28,7 +28,7 @@ export class RTLWebSocketServer {
} }
}, 1000 * 60 * 60); // Terminate broken connections every hour }, 1000 * 60 * 60); // Terminate broken connections every hour
this.mount = (httpServer) => { this.mount = (httpServer) => {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); this.logger.log({ selectedNode: this.common.selectedNode, 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) => {
if (request.headers['upgrade'] !== 'websocket') { if (request.headers['upgrade'] !== 'websocket') {
@ -46,7 +46,7 @@ export class RTLWebSocketServer {
}); });
this.webSocketServer.on('connection', this.mountEventsOnConnection); this.webSocketServer.on('connection', this.mountEventsOnConnection);
this.webSocketServer.on('close', () => clearInterval(this.pingInterval)); this.webSocketServer.on('close', () => clearInterval(this.pingInterval));
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' });
}; };
this.upgradeCallback = (websocket, request) => { this.upgradeCallback = (websocket, request) => {
this.webSocketServer.emit('connection', websocket, request); this.webSocketServer.emit('connection', websocket, request);
@ -58,13 +58,13 @@ export class RTLWebSocketServer {
websocket.isAlive = true; websocket.isAlive = true;
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null; websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
websocket.clientNodeIndex = +protocols[1]; websocket.clientNodeIndex = +protocols[1];
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
websocket.on('error', this.sendErrorToAllLNClients); websocket.on('error', this.sendErrorToAllLNClients);
websocket.on('message', this.sendEventsToAllLNClients); websocket.on('message', this.sendEventsToAllLNClients);
websocket.on('pong', () => { websocket.isAlive = true; }); websocket.on('pong', () => { websocket.isAlive = true; });
websocket.on('close', (code, reason) => { websocket.on('close', (code, reason) => {
this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex); this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex);
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
}); });
}; };
this.updateLNWSClientDetails = (sessionId, currNodeIndex, prevNodeIndex) => { this.updateLNWSClientDetails = (sessionId, currNodeIndex, prevNodeIndex) => {
@ -85,7 +85,7 @@ export class RTLWebSocketServer {
} }
else { else {
const selectedNode = this.common.findNode(currNodeIndex); const selectedNode = this.common.findNode(currNodeIndex);
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' });
} }
}; };
this.disconnectFromNodeClient = (sessionId, prevNodeIndex) => { this.disconnectFromNodeClient = (sessionId, prevNodeIndex) => {
@ -99,8 +99,8 @@ export class RTLWebSocketServer {
const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex); const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex);
this.clientDetails.splice(foundClientIdx, 1); this.clientDetails.splice(foundClientIdx, 1);
const prevSelectedNode = this.common.findNode(prevNodeIndex); const prevSelectedNode = this.common.findNode(prevNodeIndex);
if (prevSelectedNode && prevSelectedNode.ln_implementation) { if (prevSelectedNode && prevSelectedNode.lnImplementation) {
switch (prevSelectedNode.ln_implementation) { switch (prevSelectedNode.lnImplementation) {
case 'LND': case 'LND':
this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex); this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex);
break; break;
@ -129,8 +129,8 @@ export class RTLWebSocketServer {
const currSelectedNode = this.common.findNode(currNodeIndex); const currSelectedNode = this.common.findNode(currNodeIndex);
foundClient = { index: currNodeIndex, sessionIds: [sessionId] }; foundClient = { index: currNodeIndex, sessionIds: [sessionId] };
this.clientDetails.push(foundClient); this.clientDetails.push(foundClient);
if (currSelectedNode && currSelectedNode.ln_implementation) { if (currSelectedNode && currSelectedNode.lnImplementation) {
switch (currSelectedNode.ln_implementation) { switch (currSelectedNode.lnImplementation) {
case 'LND': case 'LND':
this.eventEmitterLND.emit('CONNECT', currNodeIndex); this.eventEmitterLND.emit('CONNECT', currNodeIndex);
break; break;
@ -149,27 +149,27 @@ export class RTLWebSocketServer {
this.sendErrorToAllLNClients = (serverError, selectedNode) => { this.sendErrorToAllLNClients = (serverError, selectedNode) => {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError });
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
client.send(serverError); client.send(serverError);
} }
}); });
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
} }
}; };
this.sendEventsToAllLNClients = (newMessage, selectedNode) => { this.sendEventsToAllLNClients = (newMessage, selectedNode) => {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
client.send(newMessage); client.send(newMessage);
} }
}); });
} }
catch (err) { catch (err) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
} }
}; };
this.generateAcceptValue = (acceptKey) => crypto.createHash('sha1').update(acceptKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64'); this.generateAcceptValue = (acceptKey) => crypto.createHash('sha1').update(acceptKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64');

@ -11,7 +11,7 @@ export const listPeerChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
return Promise.all(body.channels?.map((channel) => { return Promise.all(body.channels?.map((channel) => {
@ -32,7 +32,7 @@ export const openChannel = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -48,7 +48,7 @@ export const setChannelFee = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Setting Channel Fee..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Setting Channel Fee..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -65,7 +65,7 @@ export const closeChannel = (req, res, next) => {
req.setTimeout(60000 * 10); // timeout 10 mins req.setTimeout(60000 * 10); // timeout 10 mins
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/close'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -82,7 +82,7 @@ export const listForwards = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body });
@ -98,7 +98,7 @@ export const funderUpdatePolicy = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting or Updating Funder Policy..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting or Updating Funder Policy..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate';
options.body = req.body; options.body = req.body;
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) => {

@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => {
common.setOptions(req); common.setOptions(req);
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
if (!options.headers || !options.headers.rune) { if (!options.headers || !options.headers.rune) {
const errMsg = 'Core lightning get info failed due to missing rune!'; const errMsg = 'Core lightning get info failed due to missing rune!';
@ -45,7 +45,7 @@ export const getInfo = (req, res, next) => {
body.uris.push(body.id + '@' + addr.address + ':' + addr.port); body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
}); });
} }
req.session.selectedNode.ln_version = body.version || ''; req.session.selectedNode.lnVersion = body.version || '';
req.session.selectedNode.api_version = body.api_version || ''; req.session.selectedNode.api_version = body.api_version || '';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
clWsClient.updateSelectedNode(req.session.selectedNode); clWsClient.updateSelectedNode(req.session.selectedNode);

@ -9,7 +9,7 @@ export const deleteExpiredInvoice = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Deleting Expired Invoices..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Deleting Expired Invoices..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
@ -24,7 +24,7 @@ export const listInvoices = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting Invoices..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting Invoices..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -40,7 +40,7 @@ export const addInvoice = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });

@ -1,7 +1,7 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
@ -11,7 +11,7 @@ export const getRoute = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/getroute'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
@ -29,7 +29,7 @@ export const listChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
@ -45,7 +45,7 @@ export const feeRates = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/feerates'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body });
@ -62,7 +62,7 @@ export const listNodes = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -78,8 +78,8 @@ export const listNodes = (req, res, next) => {
}); });
}; };
export const getAlias = (selNode: CommonSelectedNode, peer: any, id: string) => { export const getAlias = (selNode: SelectedNode, peer: any, id: string) => {
options.url = selNode.ln_server_url + '/v1/listnodes'; options.url = selNode.settings.lnServerUrl + '/v1/listnodes';
if (!peer[id]) { if (!peer[id]) {
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' }); logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
peer.alias = ''; peer.alias = '';

@ -36,7 +36,7 @@ export const listOffers = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offers..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offers..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
@ -51,7 +51,7 @@ export const createOffer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Creating Offer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Creating Offer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/offer'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
@ -66,7 +66,7 @@ export const fetchOfferInvoice = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Invoice..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Invoice..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -82,7 +82,7 @@ export const disableOffer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Disabling Offer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Disabling Offer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });

@ -9,7 +9,7 @@ export const getNewAddress = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
@ -24,7 +24,7 @@ export const onChainWithdraw = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Withdrawing from On Chain..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Withdrawing from On Chain..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw';
options.body = req.body; options.body = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -40,7 +40,7 @@ export const getUTXOs = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Listing Funds..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Listing Funds..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
// Local Remote Balance Calculation // Local Remote Balance Calculation

@ -3,15 +3,15 @@ import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { Database, DatabaseService } from '../../utils/database.js'; import { Database, DatabaseService } from '../../utils/database.js';
import { CollectionFieldsEnum, CollectionsEnum, Offer } from '../../models/database.model.js'; import { CollectionFieldsEnum, CollectionsEnum, Offer } from '../../models/database.model.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
const databaseService: DatabaseService = Database; const databaseService: DatabaseService = Database;
export const getMemo = (selNode: CommonSelectedNode, payment: any) => { export const getMemo = (selNode: SelectedNode, payment: any) => {
options.url = selNode.ln_server_url + '/v1/decode'; options.url = selNode.settings.lnServerUrl + '/v1/decode';
options.body = { string: payment.bolt11 }; options.body = { string: payment.bolt11 };
return request.post(options).then((res) => { return request.post(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
@ -74,7 +74,7 @@ export const listPayments = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'List Payments..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'List Payments..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : []; body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
@ -95,7 +95,7 @@ export const postPayment = (req, res, next) => {
const options_body = JSON.parse(JSON.stringify(req.body)); const options_body = JSON.parse(JSON.stringify(req.body));
if (paymentType === 'KEYSEND') { if (paymentType === 'KEYSEND') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend';
delete options_body.uiMessage; delete options_body.uiMessage;
delete options_body.fromDialog; delete options_body.fromDialog;
delete options_body.paymentType; delete options_body.paymentType;
@ -134,7 +134,7 @@ export const postPayment = (req, res, next) => {
delete options_body.pubkey; delete options_body.pubkey;
delete options_body.saveToDB; delete options_body.saveToDB;
options.body = options_body; options.body = options_body;
options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay';
} }
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });

@ -11,7 +11,7 @@ export const getPeers = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'List Peers..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'List Peers..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
request.post(options).then((body) => { request.post(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;
@ -29,12 +29,12 @@ export const postPeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/connect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect';
options.body = req.body; options.body = req.body;
request.post(options).then((connectRes) => { request.post(options).then((connectRes) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
const listOptions = common.getOptions(req); const listOptions = common.getOptions(req);
listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers'; listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
request.post(listOptions).then((listPeersRes) => { request.post(listOptions).then((listPeersRes) => {
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : []; const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
@ -53,7 +53,7 @@ export const deletePeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });

@ -10,7 +10,7 @@ export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/decode'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
@ -25,7 +25,7 @@ export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
options.body = req.body; options.body = req.body;
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
@ -40,7 +40,7 @@ export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage';
options.body = req.body; options.body = req.body;
request.post(options, (error, response, body) => { request.post(options, (error, response, body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
@ -55,7 +55,7 @@ export const listConfigs = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs';
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
res.status(200).json(body); res.status(200).json(body);

@ -2,14 +2,14 @@ import socketIOClient from 'socket.io-client';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { WSServer } from '../../utils/webSocketServer.js'; import { WSServer } from '../../utils/webSocketServer.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
export class CLWebSocketClient { export class CLWebSocketClient {
public logger: LoggerService = Logger; public logger: LoggerService = Logger;
public common: CommonService = Common; public common: CommonService = Common;
public wsServer = WSServer; public wsServer = WSServer;
public webSocketClients: Array<{ selectedNode: CommonSelectedNode, reConnect: boolean, webSocketClient: any }> = []; public webSocketClients: Array<{ selectedNode: SelectedNode, reConnect: boolean, webSocketClient: any }> = [];
public reconnectTimeOut = null; public reconnectTimeOut = null;
public waitTime = 0.5; public waitTime = 0.5;
@ -34,17 +34,17 @@ export class CLWebSocketClient {
}, this.waitTime * 1000); }, this.waitTime * 1000);
}; };
public connect = (selectedNode: CommonSelectedNode) => { public connect = (selectedNode: SelectedNode) => {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists) { if (!clientExists) {
if (selectedNode.ln_server_url) { if (selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
this.connectWithClient(newWebSocketClient); this.connectWithClient(newWebSocketClient);
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
} else { } else {
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) { if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) {
clientExists.reConnect = true; clientExists.reConnect = true;
this.connectWithClient(clientExists); this.connectWithClient(clientExists);
} }
@ -57,11 +57,11 @@ 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..' });
try { try {
if (!clWsClt.selectedNode.rune_value) { if (!clWsClt.selectedNode.authentication.runeValue) {
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath);
} }
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, {
extraHeaders: { rune: clWsClt.selectedNode.rune_value }, extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue },
transports: ['websocket'], transports: ['websocket'],
secure: true, secure: true,
rejectUnauthorized: false rejectUnauthorized: false
@ -76,7 +76,7 @@ export class CLWebSocketClient {
}); });
clWsClt.webSocketClient.on('disconnect', (reason) => { clWsClt.webSocketClient.on('disconnect', (reason) => {
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') { if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') {
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason }); this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
clWsClt.webSocketClient.close(); clWsClt.webSocketClient.close();
if (clWsClt.reConnect) { this.reconnect(clWsClt); } if (clWsClt.reConnect) { this.reconnect(clWsClt); }
@ -97,7 +97,7 @@ export class CLWebSocketClient {
}); });
}; };
public disconnect = (selectedNode: CommonSelectedNode) => { public disconnect = (selectedNode: SelectedNode) => {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.connected) { if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.connected) {
this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the Core Lightning\'s Websocket Server..' }); this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the Core Lightning\'s Websocket Server..' });
@ -108,7 +108,7 @@ export class CLWebSocketClient {
} }
}; };
public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { public updateSelectedNode = (newSelectedNode: SelectedNode) => {
const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index);
let newClient = this.webSocketClients[clientIdx]; let newClient = this.webSocketClients[clientIdx];
if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; } if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; }

@ -1,7 +1,7 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
import { createInvoiceRequestCall, listPendingInvoicesRequestCall } from './invoices.js'; import { createInvoiceRequestCall, listPendingInvoicesRequestCall } from './invoices.js';
import { findRouteBetweenNodesRequestCall } from './network.js'; import { findRouteBetweenNodesRequestCall } from './network.js';
import { getSentInfoFromPaymentRequest, sendPaymentToRouteRequestCall } from './payments.js'; import { getSentInfoFromPaymentRequest, sendPaymentToRouteRequestCall } from './payments.js';
@ -10,7 +10,7 @@ let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => { export const simplifyAllChannels = (selNode: SelectedNode, channels) => {
let channelNodeIds = ''; let channelNodeIds = '';
const simplifiedChannels = []; const simplifiedChannels = [];
channels.forEach((channel) => { channels.forEach((channel) => {
@ -30,7 +30,7 @@ export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => {
}); });
}); });
channelNodeIds = channelNodeIds.substring(1); channelNodeIds = channelNodeIds.substring(1);
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: channelNodeIds }; options.form = { nodeIds: channelNodeIds };
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
@ -49,7 +49,7 @@ export const getChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'List Channels..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'List Channels..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/channels';
options.form = {}; options.form = {};
if (req.query && req.query.nodeId) { if (req.query && req.query.nodeId) {
options.form = req.query; options.form = req.query;
@ -57,7 +57,7 @@ export const getChannels = (req, res, next) => {
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
} else { } else {
request.post(options).then((body) => { request.post(options).then((body) => {
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 });
@ -82,7 +82,7 @@ export const getChannelStats = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel States..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel States..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/channelstats'; options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats';
const today = new Date(Date.now()); const today = new Date(Date.now());
const tillToday = (Math.round(today.getTime() / 1000)).toString(); const tillToday = (Math.round(today.getTime() / 1000)).toString();
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
@ -103,7 +103,7 @@ export const openChannel = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/open'; options.url = req.session.selectedNode.settings.lnServerUrl + '/open';
options.form = req.body; options.form = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -119,7 +119,7 @@ export const updateChannelRelayFee = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Relay Fee..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Relay Fee..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee'; options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee';
options.form = req.query; options.form = req.query;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -136,10 +136,10 @@ export const closeChannel = (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.force !== 'true') { if (req.query.force !== 'true') {
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..' });
options.url = req.session.selectedNode.ln_server_url + '/close'; options.url = req.session.selectedNode.settings.lnServerUrl + '/close';
} else { } else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
options.url = req.session.selectedNode.ln_server_url + '/forceclose'; options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose';
} }
options.form = { channelId: req.query.channelId }; options.form = { channelId: req.query.channelId };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });

@ -1,12 +1,12 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) => { export const arrangeFees = (selNode: SelectedNode, body, current_time) => {
const fees = { daily_fee: 0, daily_txs: 0, weekly_fee: 0, weekly_txs: 0, monthly_fee: 0, monthly_txs: 0 }; const fees = { daily_fee: 0, daily_txs: 0, weekly_fee: 0, weekly_txs: 0, monthly_fee: 0, monthly_txs: 0 };
const week_start_time = current_time - 604800000; const week_start_time = current_time - 604800000;
const day_start_time = current_time - 86400000; const day_start_time = current_time - 86400000;
@ -42,7 +42,7 @@ export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) =>
return fees; return fees;
}; };
export const arrangePayments = (selNode: CommonSelectedNode, body) => { export const arrangePayments = (selNode: SelectedNode, body) => {
const payments = { const payments = {
sent: body && body.sent ? body.sent : [], sent: body && body.sent ? body.sent : [],
received: body && body.received ? body.received : [], received: body && body.received ? body.received : [],
@ -84,7 +84,7 @@ export const getFees = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/audit'; options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const today = new Date(Date.now()); const today = new Date(Date.now());
const tillToday = (Math.round(today.getTime() / 1000)).toString(); const tillToday = (Math.round(today.getTime() / 1000)).toString();
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString(); const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
@ -94,7 +94,7 @@ export const getFees = (req, res, next) => {
}; };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); }); common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
} else { } else {
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
@ -110,11 +110,11 @@ export const getPayments = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Payments..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Payments..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/audit'; options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday }; options.form = { from: 0, to: tillToday };
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); }); common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
} else { } else {
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Payments Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Payments Received', data: body });

@ -16,12 +16,12 @@ export const getInfo = (req, res, next) => {
common.setOptions(req); common.setOptions(req);
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo';
options.form = {}; options.form = {};
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data: any) => { common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data: any) => {
data.lnImplementation = 'Eclair'; data.lnImplementation = 'Eclair';
return res.status(200).json(data); return res.status(200).json(data);
}); });
@ -34,7 +34,7 @@ export const getInfo = (req, res, next) => {
return request.post(options).then((body) => { return request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
body.lnImplementation = 'Eclair'; body.lnImplementation = 'Eclair';
req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
eclWsClient.updateSelectedNode(req.session.selectedNode); eclWsClient.updateSelectedNode(req.session.selectedNode);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
return res.status(200).json(body); return res.status(200).json(body);

@ -1,7 +1,7 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from 'server/models/config.model.js'; import { SelectedNode } from 'server/models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
@ -37,7 +37,7 @@ export const getInvoice = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/getinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice';
options.form = { paymentHash: req.params.paymentHash }; options.form = { paymentHash: req.params.paymentHash };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
@ -52,10 +52,10 @@ export const getInvoice = (req, res, next) => {
}); });
}; };
export const listPendingInvoicesRequestCall = (selectedNode: CommonSelectedNode) => { export const listPendingInvoicesRequestCall = (selectedNode: SelectedNode) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/listpendinginvoices'; options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() }; options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((pendingInvoicesResponse) => { request.post(options).then((pendingInvoicesResponse) => {
@ -74,16 +74,16 @@ export const listInvoices = (req, res, next) => {
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString(); const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday }; options.form = { from: 0, to: tillToday };
const options1 = JSON.parse(JSON.stringify(options)); const options1 = JSON.parse(JSON.stringify(options));
options1.url = req.session.selectedNode.ln_server_url + '/listinvoices'; options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
options1.form = { from: 0, to: tillToday }; options1.form = { from: 0, to: tillToday };
const options2 = JSON.parse(JSON.stringify(options)); const options2 = JSON.parse(JSON.stringify(options));
options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices'; options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options2.form = { from: 0, to: tillToday }; options2.form = { from: 0, to: tillToday };
if (common.read_dummy_data) { if (common.read_dummy_data) {
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => { return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).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.settings.lnServerUrl, invoice))).
then((values) => res.status(200).json(invoices)); then((values) => res.status(200).json(invoices));
}); });
} else { } else {
@ -93,7 +93,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.settings.lnServerUrl, invoice))).
then((values) => { then((values) => {
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 });
return res.status(200).json(invoices); return res.status(200).json(invoices);
@ -114,10 +114,10 @@ export const listInvoices = (req, res, next) => {
} }
}; };
export const createInvoiceRequestCall = (selectedNode: CommonSelectedNode, description: string, amount: number) => { export const createInvoiceRequestCall = (selectedNode: SelectedNode, description: string, amount: number) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/createinvoice'; options.url = selectedNode.settings.lnServerUrl + '/createinvoice';
options.form = { description: description, amountMsat: amount }; options.form = { description: description, amountMsat: amount };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((invResponse) => { request.post(options).then((invResponse) => {

@ -1,7 +1,7 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from 'server/models/config.model.js'; import { SelectedNode } from 'server/models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
@ -10,7 +10,7 @@ export const getNodes = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/nodes'; options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: req.params.id }; options.form = { nodeIds: req.params.id };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
@ -21,10 +21,10 @@ export const getNodes = (req, res, next) => {
}); });
}; };
export const findRouteBetweenNodesRequestCall = (selectedNode: CommonSelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => { export const findRouteBetweenNodesRequestCall = (selectedNode: SelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/findroutebetweennodes'; options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes';
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format }; options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
request.post(options).then((body) => { request.post(options).then((body) => {

@ -17,7 +17,7 @@ export const getNewAddress = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/getnewaddress'; options.url = req.session.selectedNode.settings.lnServerUrl + '/getnewaddress';
options.form = {}; options.form = {};
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
@ -32,10 +32,10 @@ export const getBalance = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Balance..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Balance..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/onchainbalance'; options.url = req.session.selectedNode.settings.lnServerUrl + '/onchainbalance';
options.form = {}; options.form = {};
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('OnChainBalance', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeBalances(data)); }); common.getDummyData('OnChainBalance', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeBalances(data)); });
} else { } else {
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'On Chain Balance Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'On Chain Balance Received', data: body });
@ -52,7 +52,7 @@ export const getTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Transactions..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Getting On Chain Transactions..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/onchaintransactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/onchaintransactions';
options.form = { options.form = {
count: req.query.count, count: req.query.count,
skip: req.query.skip skip: req.query.skip
@ -72,7 +72,7 @@ export const sendFunds = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Sending On Chain Funds..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Sending On Chain Funds..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/sendonchain'; options.url = req.session.selectedNode.settings.lnServerUrl + '/sendonchain';
options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks }; options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks };
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {

@ -1,13 +1,13 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const getSentInfoFromPaymentRequest = (selNode: CommonSelectedNode, payment) => { export const getSentInfoFromPaymentRequest = (selNode: SelectedNode, payment) => {
options.url = selNode.ln_server_url + '/getsentinfo'; options.url = selNode.settings.lnServerUrl + '/getsentinfo';
options.form = { paymentHash: payment }; options.form = { paymentHash: payment };
return request.post(options).then((body) => { return request.post(options).then((body) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body });
@ -19,8 +19,8 @@ export const getSentInfoFromPaymentRequest = (selNode: CommonSelectedNode, payme
}).catch((err) => err); }).catch((err) => err);
}; };
export const getQueryNodes = (selNode: CommonSelectedNode, nodeIds) => { export const getQueryNodes = (selNode: SelectedNode, nodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/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 });
@ -32,7 +32,7 @@ export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/parseinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/parseinvoice';
options.form = { invoice: req.params.invoice }; options.form = { invoice: req.params.invoice };
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
@ -48,7 +48,7 @@ export const postPayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Paying Invoice..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Paying Invoice..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/payinvoice'; options.url = req.session.selectedNode.settings.lnServerUrl + '/payinvoice';
options.form = req.body; options.form = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -64,7 +64,7 @@ export const queryPaymentRoute = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Querying Payment Route..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Querying Payment Route..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/findroutetonode'; options.url = req.session.selectedNode.settings.lnServerUrl + '/findroutetonode';
options.form = { options.form = {
nodeId: req.query.nodeId, nodeId: req.query.nodeId,
amountMsat: req.query.amountMsat amountMsat: req.query.amountMsat
@ -119,10 +119,10 @@ export const getSentPaymentsInformation = (req, res, next) => {
} }
}; };
export const sendPaymentToRouteRequestCall = (selectedNode: CommonSelectedNode, shortChannelIds: string, invoice: string, amountMsat: number) => { export const sendPaymentToRouteRequestCall = (selectedNode: SelectedNode, shortChannelIds: string, invoice: string, amountMsat: number) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' }); logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
options = selectedNode.options; options = selectedNode.authentication.options;
options.url = selectedNode.ln_server_url + '/sendtoroute'; options.url = selectedNode.settings.lnServerUrl + '/sendtoroute';
options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice }; options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice };
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form }); logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form });

@ -1,13 +1,13 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const getFilteredNodes = (selNode: CommonSelectedNode, peersNodeIds) => { export const getFilteredNodes = (selNode: SelectedNode, peersNodeIds) => {
options.url = selNode.ln_server_url + '/nodes'; options.url = selNode.settings.lnServerUrl + '/nodes';
options.form = { nodeIds: peersNodeIds }; options.form = { nodeIds: peersNodeIds };
return request.post(options).then((nodes) => { return request.post(options).then((nodes) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes });
@ -19,10 +19,10 @@ export const getPeers = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
options.form = {}; options.form = {};
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('Peers', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); }); common.getDummyData('Peers', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
} else { } else {
request.post(options).then((body) => { request.post(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 });
@ -56,7 +56,7 @@ export const connectPeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Conneting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Conneting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/connect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/connect';
options.form = {}; options.form = {};
if (req.query) { if (req.query) {
options.form = req.query; options.form = req.query;
@ -71,7 +71,7 @@ export const connectPeer = (req, res, next) => {
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, 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 });
} }
options.url = req.session.selectedNode.ln_server_url + '/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
options.form = {}; options.form = {};
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body });
@ -107,7 +107,7 @@ export const deletePeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconneting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconneting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/disconnect'; options.url = req.session.selectedNode.settings.lnServerUrl + '/disconnect';
options.form = {}; options.form = {};
if (req.params.nodeId) { if (req.params.nodeId) {
options.form = { nodeId: req.params.nodeId }; options.form = { nodeId: req.params.nodeId };

@ -3,7 +3,7 @@ import WebSocket from 'ws';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { WSServer } from '../../utils/webSocketServer.js'; import { WSServer } from '../../utils/webSocketServer.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
import { ECLWSEventsEnum } from '../../models/ecl.model.js'; import { ECLWSEventsEnum } from '../../models/ecl.model.js';
export class ECLWebSocketClient { export class ECLWebSocketClient {
@ -11,7 +11,7 @@ export class ECLWebSocketClient {
public logger: LoggerService = Logger; public logger: LoggerService = Logger;
public common: CommonService = Common; public common: CommonService = Common;
public wsServer = WSServer; public wsServer = WSServer;
public webSocketClients: Array<{ selectedNode: CommonSelectedNode, reConnect: boolean, webSocketClient: any }> = []; public webSocketClients: Array<{ selectedNode: SelectedNode, reConnect: boolean, webSocketClient: any }> = [];
public reconnectTimeOut = null; public reconnectTimeOut = null;
public waitTime = 0.5; public waitTime = 0.5;
@ -36,17 +36,17 @@ export class ECLWebSocketClient {
}, this.waitTime * 1000); }, this.waitTime * 1000);
}; };
public connect = (selectedNode: CommonSelectedNode) => { public connect = (selectedNode: SelectedNode) => {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists) { if (!clientExists) {
if (selectedNode.ln_server_url) { if (selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null }; const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
this.connectWithClient(newWebSocketClient); this.connectWithClient(newWebSocketClient);
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
} else { } else {
if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.ln_server_url) { if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.settings.lnServerUrl) {
clientExists.reConnect = true; clientExists.reConnect = true;
this.connectWithClient(clientExists); this.connectWithClient(clientExists);
} }
@ -58,9 +58,9 @@ 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.settings.lnServerUrl)?.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.authentication.lnApiPassword + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
eclWsClt.webSocketClient = new WebSocket(WS_LINK); eclWsClt.webSocketClient = new WebSocket(WS_LINK);
eclWsClt.webSocketClient.onopen = () => { eclWsClt.webSocketClient.onopen = () => {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' });
@ -69,7 +69,7 @@ export class ECLWebSocketClient {
}; };
eclWsClt.webSocketClient.onclose = (e) => { eclWsClt.webSocketClient.onclose = (e) => {
if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.ln_implementation === 'ECL') { if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.lnImplementation === 'ECL') {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' });
eclWsClt.webSocketClient.close(); eclWsClt.webSocketClient.close();
if (eclWsClt.reConnect) { this.reconnet(eclWsClt); } if (eclWsClt.reConnect) { this.reconnet(eclWsClt); }
@ -87,7 +87,7 @@ export class ECLWebSocketClient {
}; };
eclWsClt.webSocketClient.onerror = (err) => { eclWsClt.webSocketClient.onerror = (err) => {
if (eclWsClt.selectedNode.ln_version === '' || !eclWsClt.selectedNode.ln_version || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) { if (eclWsClt.selectedNode.lnVersion === '' || !eclWsClt.selectedNode.lnVersion || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) {
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err }); this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err });
const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }')); const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }'));
this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode); this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode);
@ -99,7 +99,7 @@ export class ECLWebSocketClient {
}; };
}; };
public disconnect = (selectedNode: CommonSelectedNode) => { public disconnect = (selectedNode: SelectedNode) => {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.readyState === WebSocket.OPEN) { if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.readyState === WebSocket.OPEN) {
this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Disconnecting from the Eclair\'s Websocket Server..' }); this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Disconnecting from the Eclair\'s Websocket Server..' });
@ -110,7 +110,7 @@ export class ECLWebSocketClient {
} }
}; };
public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { public updateSelectedNode = (newSelectedNode: SelectedNode) => {
const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index);
let newClient = this.webSocketClients[clientIdx]; let newClient = this.webSocketClients[clientIdx];
if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; } if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; }

@ -9,7 +9,7 @@ export const getBlockchainBalance = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/balance/blockchain'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/balance/blockchain';
options.qs = req.query; options.qs = req.query;
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query });

@ -1,14 +1,14 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const getAliasForChannel = (selNode: CommonSelectedNode, channel) => { export const getAliasForChannel = (selNode: SelectedNode, channel) => {
const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : ''; const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : '';
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
return request(options).then((aliasBody) => { return request(options).then((aliasBody) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias });
channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20); channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20);
@ -23,7 +23,7 @@ export const getAllChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channels..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channels..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
options.qs = req.query; options.qs = req.query;
let local = 0; let local = 0;
let remote = 0; let remote = 0;
@ -61,7 +61,7 @@ export const getPendingChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Pending Channels..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Pending Channels..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/pending';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
if (!body.total_limbo_balance) { if (!body.total_limbo_balance) {
@ -98,7 +98,7 @@ export const getClosedChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Closed Channels..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Closed Channels..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/closed';
options.qs = req.query; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
if (body.channels && body.channels.length > 0) { if (body.channels && body.channels.length > 0) {
@ -129,7 +129,7 @@ export const postChannel = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
options.form = { options.form = {
node_pubkey_string: node_pubkey, node_pubkey_string: node_pubkey,
local_funding_amount: local_funding_amount, local_funding_amount: local_funding_amount,
@ -160,7 +160,7 @@ export const postTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Sending Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Sending Payment..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/transaction-stream'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/transaction-stream';
options.form = { payment_request: paymentReq }; options.form = { payment_request: paymentReq };
if (paymentAmount) { if (paymentAmount) {
options.form.amt = paymentAmount; options.form.amt = paymentAmount;
@ -196,7 +196,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.settings.lnServerUrl + '/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; }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel Options URL', data: options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel Options URL', data: options.url });
@ -214,7 +214,7 @@ export const postChanPolicy = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/chanpolicy'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/chanpolicy';
if (chanPoint === 'all') { if (chanPoint === 'all') {
options.form = JSON.stringify({ options.form = JSON.stringify({
global: true, global: true,

@ -39,14 +39,14 @@ export const getBackup = (req, res, next) => {
let channel_backup_file = ''; let channel_backup_file = '';
let message = ''; let message = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak';
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.settings.lnServerUrl + '/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.settings.channelBackupPath + 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.settings.lnServerUrl + '/v1/channels/backup/' + channelpoint;
const exists = fs.existsSync(channel_backup_file); const exists = fs.existsSync(channel_backup_file);
if (exists) { if (exists) {
fs.writeFile(channel_backup_file, '', () => { }); fs.writeFile(channel_backup_file, '', () => { });
@ -81,13 +81,13 @@ export const postBackupVerify = (req, res, next) => {
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) { 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/channels/backup/verify'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/verify';
let channel_verify_file = ''; let channel_verify_file = '';
let message = ''; let message = '';
let verify_backup = ''; let verify_backup = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
message = 'All Channels Verify Successful.'; message = 'All Channels Verify Successful.';
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak'; channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.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');
@ -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.settings.channelBackupPath + 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');
@ -136,13 +136,13 @@ export const postRestore = (req, res, next) => {
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) { 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/channels/backup/restore'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/restore';
let channel_restore_file = ''; let channel_restore_file = '';
let message = ''; let message = '';
let restore_backup = ''; let restore_backup = '';
if (req.params.channelPoint === 'ALL') { if (req.params.channelPoint === 'ALL') {
message = 'All Channels Restore Successful.'; message = 'All Channels Restore Successful.';
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep; channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep;
const exists = fs.existsSync(channel_restore_file + 'channel-all.bak'); const exists = fs.existsSync(channel_restore_file + 'channel-all.bak');
const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak'); const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak');
if (exists) { if (exists) {
@ -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.settings.channelBackupPath + 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');
@ -190,7 +190,7 @@ export const postRestore = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'ChannelBackup', msg: 'Channel Restored', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'ChannelBackup', msg: 'Channel Restored', data: body });
if (req.params.channelPoint === 'ALL') { channel_restore_file = channel_restore_file + 'channel-all.bak'; } if (req.params.channelPoint === 'ALL') { channel_restore_file = channel_restore_file + 'channel-all.bak'; }
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => { fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
if (getFilesListRes.error) { if (getFilesListRes.error) {
const errMsg = getFilesListRes.error; const errMsg = getFilesListRes.error;
const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode);
@ -210,7 +210,7 @@ export const postRestore = (req, res, next) => {
}; };
export const getRestoreList = (req, res, next) => { export const getRestoreList = (req, res, next) => {
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => { getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
if (getFilesListRes.error) { if (getFilesListRes.error) {
return res.status(getFilesListRes.statusCode).json(getFilesListRes); return res.status(getFilesListRes.statusCode).json(getFilesListRes);
} else { } else {

@ -10,7 +10,7 @@ export const getFees = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/fees'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fees';
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
const today = new Date(Date.now()); const today = new Date(Date.now());

@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => {
common.setOptions(req); common.setOptions(req);
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url });
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) { if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!'; const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!';
@ -25,7 +25,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: any) => { common.nodes?.map((node: any) => {
if (node.ln_implementation === 'LND') { if (node.lnImplementation === 'LND') {
common.getAllNodeAllChannelBackup(node); common.getAllNodeAllChannelBackup(node);
} }
return node; return node;
@ -38,7 +38,7 @@ export const getInfo = (req, res, next) => {
const err = common.handleError(body, 'GetInfo', 'Get Info Error', req.session.selectedNode); const err = common.handleError(body, 'GetInfo', 'Get Info Error', 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 {
req.session.selectedNode.ln_version = body.version.split('-')[0] || ''; req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
lndWsClient.updateSelectedNode(req.session.selectedNode); lndWsClient.updateSelectedNode(req.session.selectedNode);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
return res.status(200).json(body); return res.status(200).json(body);

@ -1,13 +1,13 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const getAliasFromPubkey = (selNode: CommonSelectedNode, pubkey) => { export const getAliasFromPubkey = (selNode: SelectedNode, pubkey) => {
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
return request(options).then((res) => { return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias });
return res.node.alias; return res.node.alias;
@ -19,7 +19,7 @@ export const getDescribeGraph = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Network Graph..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Network Graph..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph';
request.get(options).then((body) => { request.get(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -33,7 +33,7 @@ export const getGraphInfo = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Information..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Information..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/info'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/info';
request.get(options).then((body) => { request.get(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -47,7 +47,7 @@ export const getGraphNode = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Node Information..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Node Information..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/node/' + req.params.pubKey; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/node/' + req.params.pubKey;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -61,7 +61,7 @@ export const getGraphEdge = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Edge Information..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Edge Information..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -75,7 +75,7 @@ export const getQueryRoutes = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Routes..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Routes..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount;
if (req.query.outgoing_chan_id) { if (req.query.outgoing_chan_id) {
options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id; options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id;
} }
@ -111,7 +111,7 @@ export const getRemoteFeePolicy = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Remote Fee Policy..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Getting Remote Fee Policy..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body });
let remoteNodeFee = {}; let remoteNodeFee = {};

@ -12,7 +12,7 @@ export const invoiceLookup = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting Invoice Information..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting Invoice Information..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/invoices/lookup'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/invoices/lookup';
if (req.query.payment_addr) { if (req.query.payment_addr) {
options.url = options.url + '?payment_addr=' + req.query.payment_addr; options.url = options.url + '?payment_addr=' + req.query.payment_addr;
} else { } else {
@ -34,7 +34,7 @@ export const listInvoices = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting List Invoices..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Getting List Invoices..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset + options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset +
'&reversed=' + req.query.reversed; '&reversed=' + req.query.reversed;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
@ -57,7 +57,7 @@ export const addInvoice = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Adding Invoice..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Adding Invoice..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices';
options.form = JSON.stringify(req.body); options.form = JSON.stringify(req.body);
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body });

@ -10,7 +10,7 @@ export const signMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
options.form = JSON.stringify({ options.form = JSON.stringify({
msg: Buffer.from(message).toString('base64') msg: Buffer.from(message).toString('base64')
}); });
@ -28,7 +28,7 @@ export const verifyMessage = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/verifymessage'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/verifymessage';
options.form = JSON.stringify({ options.form = JSON.stringify({
msg: Buffer.from(message).toString('base64'), msg: Buffer.from(message).toString('base64'),
signature: signature signature: signature

@ -9,7 +9,7 @@ export const getNewAddress = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'Getting New Address..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'Getting New Address..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddress?type=' + req.query.type; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddress?type=' + req.query.type;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body });
res.status(200).json(body); res.status(200).json(body);

@ -1,14 +1,14 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const decodePaymentFromPaymentRequest = (selNode: CommonSelectedNode, payment) => { export const decodePaymentFromPaymentRequest = (selNode: SelectedNode, payment) => {
options.url = selNode.ln_server_url + '/v1/payreq/' + payment; options.url = selNode.settings.lnServerUrl + '/v1/payreq/' + payment;
return request(options).then((res) => { return request(options).then((res) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description });
return res; return res;
@ -19,7 +19,7 @@ export const decodePayment = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Decoding Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Decoding Payment..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/payreq/' + req.params.payRequest; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payreq/' + req.params.payRequest;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -55,7 +55,7 @@ export const getPayments = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting Payments List..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting Payments List..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body });
res.status(200).json(body); res.status(200).json(body);
@ -69,8 +69,8 @@ export const getAllLightningTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' });
const options1 = JSON.parse(JSON.stringify(common.getOptions(req))); const options1 = JSON.parse(JSON.stringify(common.getOptions(req)));
const options2 = JSON.parse(JSON.stringify(common.getOptions(req))); const options2 = JSON.parse(JSON.stringify(common.getOptions(req)));
// options1.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=100000&index_offset=0&reversed=true'; // options1.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=100000&index_offset=0&reversed=true';
options2.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true'; options2.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 });
// return Promise.all([request(options1), request(options2)]).then((values) => { // return Promise.all([request(options1), request(options2)]).then((values) => {
@ -87,7 +87,7 @@ export const paymentLookup = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Looking up Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Looking up Payment..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/router/track/' + req.params.paymentHash; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/router/track/' + req.params.paymentHash;
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body });
res.status(200).json(body.result || body); res.status(200).json(body.result || body);

@ -1,13 +1,13 @@
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
let options = null; let options = null;
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
const common: CommonService = Common; const common: CommonService = Common;
export const getAliasForPeers = (selNode: CommonSelectedNode, peer) => { export const getAliasForPeers = (selNode: SelectedNode, peer) => {
options.url = selNode.ln_server_url + '/v1/graph/node/' + peer.pub_key; options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + peer.pub_key;
return request(options).then((aliasBody) => { return request(options).then((aliasBody) => {
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias }); logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias });
peer.alias = aliasBody.node.alias; peer.alias = aliasBody.node.alias;
@ -22,7 +22,7 @@ export const getPeers = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Getting Peers..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
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;
@ -41,14 +41,14 @@ export const postPeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
options.form = JSON.stringify({ options.form = JSON.stringify({
addr: { host: host, pubkey: pubkey }, addr: { host: host, pubkey: pubkey },
perm: perm perm: perm
}); });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body });
options.url = req.session.selectedNode.ln_server_url + '/v1/peers'; options.url = req.session.selectedNode.settings.lnServerUrl + '/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) => {
@ -75,7 +75,7 @@ export const deletePeer = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/peers/' + req.params.peerPubKey; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers/' + req.params.peerPubKey;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey });
request.delete(options).then((body) => { request.delete(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body });

@ -25,7 +25,7 @@ export const getAllForwardingEvents = (req, start, end, offset, caller, callback
const err = common.handleError({ message: 'Session Expired after a day\'s inactivity.', statusCode: 401 }, 'Balance', 'Get Balance Error', req.session.selectedNode); const err = common.handleError({ message: 'Session Expired after a day\'s inactivity.', statusCode: 401 }, 'Balance', 'Get Balance Error', req.session.selectedNode);
return callback({ message: err.message, error: err.error, statusCode: err.statusCode }); return callback({ message: err.message, error: err.error, statusCode: err.statusCode });
} options = common.getOptions(req); } options = common.getOptions(req);
options.url = req.session.selectedNode.ln_server_url + '/v1/switch'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/switch';
options.form = {}; options.form = {};
if (start) { options.form.start_time = start; } if (start) { options.form.start_time = start; }
if (end) { options.form.end_time = end; } if (end) { options.form.end_time = end; }

@ -9,7 +9,7 @@ export const getTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Getting Transactions..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Getting Transactions..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body });
res.status(200).json(body.transactions); res.status(200).json(body.transactions);
@ -24,7 +24,7 @@ export const postTransactions = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Sending Transaction..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Sending Transaction..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
options.form = { options.form = {
amount: amount, amount: amount,
addr: address, addr: address,

@ -11,9 +11,9 @@ export const genSeed = (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 }); }
if (req.params.passphrase) { if (req.params.passphrase) {
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64'); options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64');
} else { } else {
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed';
} }
request(options).then((body) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body });
@ -32,14 +32,14 @@ export const operateWallet = (req, res, next) => {
options.method = 'POST'; options.method = 'POST';
if (!req.params.operation || req.params.operation === 'unlockwallet') { if (!req.params.operation || req.params.operation === 'unlockwallet') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/unlockwallet'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/unlockwallet';
options.form = JSON.stringify({ options.form = JSON.stringify({
wallet_password: Buffer.from(atob(wallet_password)).toString('base64') wallet_password: Buffer.from(atob(wallet_password)).toString('base64')
}); });
err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!'; err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!';
} else { } else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/initwallet'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/initwallet';
if (aezeed_passphrase && aezeed_passphrase !== '') { if (aezeed_passphrase && aezeed_passphrase !== '') {
options.form = JSON.stringify({ options.form = JSON.stringify({
wallet_password: Buffer.from(atob(wallet_password)).toString('base64'), wallet_password: Buffer.from(atob(wallet_password)).toString('base64'),
@ -94,8 +94,8 @@ export const getUTXOs = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Getting UTXOs..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Getting UTXOs..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos';
if (common.isVersionCompatible(req.session.selectedNode.ln_version, '0.14.0')) { if (common.isVersionCompatible(req.session.selectedNode.lnVersion, '0.14.0')) {
options.form = JSON.stringify({ max_confs: req.query.max_confs }); options.form = JSON.stringify({ max_confs: req.query.max_confs });
} else { } else {
options.url = options.url + '?max_confs=' + req.query.max_confs; options.url = options.url + '?max_confs=' + req.query.max_confs;
@ -114,7 +114,7 @@ export const bumpFee = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Bumping Fee..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Bumping Fee..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/bumpfee'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/bumpfee';
options.form = {}; options.form = {};
options.form.outpoint = { options.form.outpoint = {
txid_str: txid, txid_str: txid,
@ -139,7 +139,7 @@ export const labelTransaction = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Labelling Transaction..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Labelling Transaction..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/tx/label'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/tx/label';
options.form = JSON.parse(JSON.stringify(options.form)); options.form = JSON.parse(JSON.stringify(options.form));
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
@ -156,7 +156,7 @@ export const leaseUTXO = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Leasing UTXO..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Leasing UTXO..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/lease'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/lease';
options.form = {}; options.form = {};
options.form.id = txid; options.form.id = txid;
options.form.outpoint = { options.form.outpoint = {
@ -179,7 +179,7 @@ export const releaseUTXO = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Releasing UTXO..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Releasing UTXO..' });
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 }); }
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/release'; options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/release';
options.form = {}; options.form = {};
options.form.id = txid; options.form.id = txid;
options.form.outpoint = { options.form.outpoint = {

@ -5,14 +5,14 @@ import { join } from 'path';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { WSServer } from '../../utils/webSocketServer.js'; import { WSServer } from '../../utils/webSocketServer.js';
import { CommonSelectedNode } from '../../models/config.model.js'; import { SelectedNode } from '../../models/config.model.js';
export class LNDWebSocketClient { export class LNDWebSocketClient {
public logger: LoggerService = Logger; public logger: LoggerService = Logger;
public common: CommonService = Common; public common: CommonService = Common;
public wsServer = WSServer; public wsServer = WSServer;
public webSocketClients: Array<{ selectedNode: CommonSelectedNode }> = []; public webSocketClients: Array<{ selectedNode: SelectedNode }> = [];
constructor() { constructor() {
this.wsServer.eventEmitterLND.on('CONNECT', (nodeIndex) => { this.wsServer.eventEmitterLND.on('CONNECT', (nodeIndex) => {
@ -23,10 +23,10 @@ export class LNDWebSocketClient {
}); });
} }
public connect = (selectedNode: CommonSelectedNode) => { public connect = (selectedNode: SelectedNode) => {
try { try {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (!clientExists && selectedNode.ln_server_url) { if (!clientExists && selectedNode.settings.lnServerUrl) {
const newWebSocketClient = { selectedNode: selectedNode }; const newWebSocketClient = { selectedNode: selectedNode };
this.webSocketClients.push(newWebSocketClient); this.webSocketClients.push(newWebSocketClient);
} }
@ -35,10 +35,10 @@ export class LNDWebSocketClient {
} }
}; };
public fetchUnpaidInvoices = (selectedNode: CommonSelectedNode) => { public fetchUnpaidInvoices = (selectedNode: SelectedNode) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' });
const options = this.setOptionsForSelNode(selectedNode); const options = this.setOptionsForSelNode(selectedNode);
options.url = selectedNode.ln_server_url + '/v1/invoices?pending_only=true'; options.url = selectedNode.settings.lnServerUrl + '/v1/invoices?pending_only=true';
return request(options).then((body) => { return request(options).then((body) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body });
if (body.invoices && body.invoices.length > 0) { if (body.invoices && body.invoices.length > 0) {
@ -55,10 +55,10 @@ export class LNDWebSocketClient {
}); });
}; };
public subscribeToInvoice = (options: any, selectedNode: CommonSelectedNode, rHash: string) => { public subscribeToInvoice = (options: any, selectedNode: SelectedNode, 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.settings.lnServerUrl + '/v2/invoices/subscribe/' + rHash;
request(options).then((msg) => { request(options).then((msg) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash });
if (typeof msg === 'string') { if (typeof msg === 'string') {
@ -80,9 +80,9 @@ export class LNDWebSocketClient {
}); });
}; };
public subscribeToPayment = (options: any, selectedNode: CommonSelectedNode, paymentHash: string) => { public subscribeToPayment = (options: any, selectedNode: SelectedNode, paymentHash: string) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' });
options.url = selectedNode.ln_server_url + '/v2/router/track/' + paymentHash; options.url = selectedNode.settings.lnServerUrl + '/v2/router/track/' + paymentHash;
request(options).then((msg) => { request(options).then((msg) => {
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash }); this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash });
msg['type'] = 'payment'; msg['type'] = 'payment';
@ -97,17 +97,17 @@ export class LNDWebSocketClient {
}); });
}; };
public setOptionsForSelNode = (selectedNode: CommonSelectedNode) => { public setOptionsForSelNode = (selectedNode: SelectedNode) => {
const options = { url: '', rejectUnauthorized: false, json: true, form: null }; const options = { url: '', rejectUnauthorized: false, json: true, form: null };
try { try {
options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) }); this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) });
} }
return options; return options;
}; };
public disconnect = (selectedNode: CommonSelectedNode) => { public disconnect = (selectedNode: SelectedNode) => {
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index); const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
if (clientExists) { if (clientExists) {
this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the LND\'s Websocket Server..' }); this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the LND\'s Websocket Server..' });
@ -116,13 +116,13 @@ export class LNDWebSocketClient {
} }
}; };
public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => { public updateSelectedNode = (newSelectedNode: SelectedNode) => {
const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index); const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index);
let newClient = this.webSocketClients[clientIdx]; let newClient = this.webSocketClients[clientIdx];
if (!newClient) { newClient = { selectedNode: null }; } if (!newClient) { newClient = { selectedNode: null }; }
newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode)); newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode));
this.webSocketClients[clientIdx] = newClient; this.webSocketClients[clientIdx] = newClient;
if (this.webSocketClients[clientIdx].selectedNode.ln_version === '' || !this.webSocketClients[clientIdx].selectedNode.ln_version || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.ln_version, '0.11.0')) { if (this.webSocketClients[clientIdx].selectedNode.lnVersion === '' || !this.webSocketClients[clientIdx].selectedNode.lnVersion || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.lnVersion, '0.11.0')) {
this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode); this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode);
} }
}; };

@ -7,7 +7,7 @@ import { Database, DatabaseService } from '../../utils/database.js';
import { Logger, LoggerService } from '../../utils/logger.js'; import { Logger, LoggerService } from '../../utils/logger.js';
import { Common, CommonService } from '../../utils/common.js'; import { Common, CommonService } from '../../utils/common.js';
import { WSServer } from '../../utils/webSocketServer.js'; import { WSServer } from '../../utils/webSocketServer.js';
import { AuthenticationConfiguration, NodeSettingsConfiguration } from '../../models/config.model.js'; import { NodeAuthentication, NodeSettings } from '../../models/config.model.js';
const options = { url: '' }; const options = { url: '' };
const logger: LoggerService = Logger; const logger: LoggerService = Logger;
@ -15,203 +15,103 @@ const common: CommonService = Common;
const wsServer = WSServer; const wsServer = WSServer;
const databaseService: DatabaseService = Database; const databaseService: DatabaseService = Database;
export const updateSelectedNode = (req, res, next) => { export const maskPasswords = (obj) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' }); const keys = Object.keys(obj);
const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.initSelectedNode ? +common.initSelectedNode.index : 1; const length = keys.length;
req.session.selectedNode = common.findNode(selNodeIndex); if (length !== 0) {
if (req.headers && req.headers.authorization && req.headers.authorization !== '') { for (let i = 0; i < length; i++) {
wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex); if (typeof obj[keys[i]] === 'object') {
if (req.params.prevNodeIndex !== '-1') { keys[keys[i]] = maskPasswords(obj[keys[i]]);
databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id); }
} if (typeof keys[i] === 'string' &&
if (req.params.currNodeIndex !== '-1') { (keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') ||
databaseService.loadDatabase(req.session); keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
keys[i].toLowerCase().includes('rpcuser'))
) {
obj[keys[i]] = '*'.repeat(20);
}
} }
} }
const responseVal = !req.session.selectedNode.ln_node ? '' : req.session.selectedNode.ln_node; return obj;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal });
res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' });
}; };
export const getRTLConfigInitial = (req, res, next) => { export const getCurrencyRates = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' });
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; options.url = 'https://blockchain.info/ticker';
fs.readFile(confFile, 'utf8', (errRes, data) => { request(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body });
res.status(200).json(JSON.parse(body));
}).catch((errRes) => {
const errMsg = 'Get Rates Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
});
};
export const getFile = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
const file = req.query.path ? req.query.path : (req.session.selectedNode.settings.channelBackupPath + 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: 'File Path', data: file });
fs.readFile(file, 'utf8', (errRes, data) => {
if (errRes) { if (errRes) {
if (errRes.code === 'ENOENT') { if (errRes.code && errRes.code === 'ENOENT') { errRes.code = 'File Not Found!'; }
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); const errMsg = 'Reading File Error';
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
} else { return res.status(err.statusCode).json({ message: err.error, error: err.error });
const errMsg = 'Get Node Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
} else { } else {
const nodeConfData = JSON.parse(data); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data });
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link }; res.status(200).json(data);
const enable2FA = !!common.rtl_secret2fa;
const allowPasswordUpdate = common.flg_allow_password_update;
const nodesArr = [];
if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, i) => {
const settings: NodeSettingsConfiguration = { unannouncedChannels: false };
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
settings.unannouncedChannels = !!node.unannounced_channels || false;
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
settings.currencyUnit = node.currency_unit;
nodesArr.push({
index: node.index,
lnNode: node.ln_node,
lnImplementation: node.ln_implementation,
settings: settings,
authentication: {}
});
});
}
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr };
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received', data: body });
res.status(200).json(body);
} }
}); });
}; };
export const getRTLConfig = (req, res, next) => { export const getRTLConfig = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' });
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
fs.readFile(confFile, 'utf8', (errRes, data) => { fs.readFile(confFile, 'utf8', (errRes, data) => {
if (errRes) { if (errRes) {
if (errRes.code === 'ENOENT') { const errMsg = 'Get Node Config Error';
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } }); const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
} else {
const errMsg = 'Get Node Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
} else { } else {
const nodeConfData = JSON.parse(data); const nodeConfData = JSON.parse(data);
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link };
const enable2FA = !!common.rtl_secret2fa;
const allowPasswordUpdate = common.flg_allow_password_update;
const nodesArr = []; const nodesArr = [];
if (common.nodes && common.nodes.length > 0) { if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, i) => { common.nodes.forEach((node, i) => {
const authentication: AuthenticationConfiguration = {};
authentication.configPath = (node.config_path) ? node.config_path : '';
authentication.swapMacaroonPath = (node.swap_macaroon_path) ? node.swap_macaroon_path : '';
authentication.boltzMacaroonPath = (node.boltz_macaroon_path) ? node.boltz_macaroon_path : '';
const settings: NodeSettingsConfiguration = { unannouncedChannels: false };
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
settings.unannouncedChannels = !!node.unannounced_channels || false;
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
settings.bitcoindConfigPath = node.bitcoind_config_path;
settings.logLevel = node.log_level ? node.log_level : 'ERROR';
settings.lnServerUrl = node.ln_server_url;
settings.swapServerUrl = node.swap_server_url;
settings.boltzServerUrl = node.boltz_server_url;
settings.enableOffers = node.enable_offers;
settings.enablePeerswap = node.enable_peerswap;
settings.channelBackupPath = node.channel_backup_path;
settings.currencyUnit = node.currency_unit;
nodesArr.push({ nodesArr.push({
index: node.index, index: node.index,
lnNode: node.ln_node, lnNode: node.lnNode,
lnImplementation: node.ln_implementation, lnImplementation: node.lnImplementation,
settings: settings, settings: node.settings,
authentication: authentication authentication: req.params.init ? {} : node.authentication
}); });
}); });
} }
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr }; const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index),
sso: common.appConfig.sso, enable2FA: !!common.appConfig.rtlSecret2fa, allowPasswordUpdate: common.appConfig.allowPasswordUpdate, nodes: nodesArr };
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body });
res.status(200).json(body); res.status(200).json(body);
} }
}); });
}; };
export const updateUISettings = (req, res, next) => { export const updateSelectedNode = (req, res, next) => {
const { updatedSettings } = req.body; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' });
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' }); const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1;
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; req.session.selectedNode = common.findNode(selNodeIndex);
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); if (req.headers && req.headers.authorization && req.headers.authorization !== '') {
const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index)); wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex);
if (node && node.Settings) { if (req.params.prevNodeIndex !== '-1') {
node.Settings.userPersona = updatedSettings.userPersona; databaseService.unloadDatabase(req.params.prevNodeIndex, req.session.id);
node.Settings.themeMode = updatedSettings.themeMode;
node.Settings.themeColor = updatedSettings.themeColor;
node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels;
node.Settings.fiatConversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} else {
delete node.Settings.currencyUnit;
} }
const selectedNode = common.findNode(req.session.selectedNode.index); if (req.params.currNodeIndex !== '-1') {
selectedNode.user_persona = updatedSettings.userPersona; databaseService.loadDatabase(req.session);
selectedNode.theme_mode = updatedSettings.themeMode;
selectedNode.theme_color = updatedSettings.themeColor;
selectedNode.unannounced_channels = updatedSettings.unannouncedChannels;
selectedNode.fiat_conversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
selectedNode.currency_unit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} else {
delete selectedNode.currency_unit;
} }
common.replaceNode(req, selectedNode);
}
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Node Settings Updated Successfully' });
} catch (errRes) {
const errMsg = 'Update Node Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
};
export const update2FASettings = (req, res, next) => {
const { secret2fa } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
if (secret2fa && secret2fa.trim() !== '') {
config.secret2fa = secret2fa;
} else {
delete config.secret2fa;
}
const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.';
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.rtl_secret2fa = config.secret2fa;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message });
res.status(201).json({ message: message });
} catch (errRes) {
const errMsg = 'Update 2FA Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
};
export const updateDefaultNode = (req, res, next) => {
const { defaultNodeIndex } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.defaultNodeIndex = defaultNodeIndex;
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Default Node Updated Successfully' });
} catch (errRes) {
const errMsg = 'Update Default Node Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
const responseVal = !req.session.selectedNode.lnNode ? '' : req.session.selectedNode.lnNode;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal });
res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' });
}; };
export const getConfig = (req, res, next) => { export const getConfig = (req, res, next) => {
@ -220,14 +120,14 @@ export const getConfig = (req, res, next) => {
let fileFormat = 'INI'; let fileFormat = 'INI';
switch (req.params.nodeType) { switch (req.params.nodeType) {
case 'ln': case 'ln':
confFile = req.session.selectedNode.config_path; confFile = req.session.selectedNode.authentication.configPath;
break; break;
case 'bitcoind': case 'bitcoind':
confFile = req.session.selectedNode.bitcoind_config_path; confFile = req.session.selectedNode.settings.bitcoindConfigPath;
break; break;
case 'rtl': case 'rtl':
fileFormat = 'JSON'; fileFormat = 'JSON';
confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
break; break;
default: default:
confFile = ''; confFile = '';
@ -251,7 +151,7 @@ export const getConfig = (req, res, next) => {
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;
} }
if (req.params.nodeType === 'ln' && req.session.selectedNode.ln_implementation === 'ECL' && !jsonConfig['eclair.api.password']) { if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) {
fileFormat = 'HOCON'; fileFormat = 'HOCON';
jsonConfig = parseHocon(data); jsonConfig = parseHocon(data);
} }
@ -264,41 +164,91 @@ export const getConfig = (req, res, next) => {
}); });
}; };
export const getFile = (req, res, next) => { export const updateNodeSettings = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' }); const { updatedSettings } = req.body;
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: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' });
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel }); const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file }); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
fs.readFile(file, 'utf8', (errRes, data) => { const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index));
if (errRes) { if (node && node.Settings) {
if (errRes.code && errRes.code === 'ENOENT') { errRes.code = 'File Not Found!'; } node.Settings.userPersona = updatedSettings.userPersona;
const errMsg = 'Reading File Error'; node.Settings.themeMode = updatedSettings.themeMode;
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode); node.Settings.themeColor = updatedSettings.themeColor;
return res.status(err.statusCode).json({ message: err.error, error: err.error }); node.Settings.unannouncedChannels = updatedSettings.unannouncedChannels;
node.Settings.fiatConversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
node.Settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} else { } else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data }); delete node.Settings.currencyUnit;
res.status(200).json(data);
} }
}); const selectedNode = common.findNode(req.session.selectedNode.index);
selectedNode.settings.userPersona = updatedSettings.userPersona;
selectedNode.settings.themeMode = updatedSettings.themeMode;
selectedNode.settings.themeColor = updatedSettings.themeColor;
selectedNode.settings.unannouncedChannels = updatedSettings.unannouncedChannels;
selectedNode.settings.fiatConversion = updatedSettings.fiatConversion;
if (updatedSettings.fiatConversion) {
selectedNode.settings.currencyUnit = updatedSettings.currencyUnit ? updatedSettings.currencyUnit : 'USD';
} else {
delete selectedNode.settings.currencyUnit;
}
common.replaceNode(req, selectedNode);
}
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Node Settings Updated Successfully' });
} catch (errRes) {
const errMsg = 'Update Node Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
}; };
export const getCurrencyRates = (req, res, next) => { export const updateApplicationSettings = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' }); const { defaultNodeIndex } = req.body;
options.url = 'https://blockchain.info/ticker'; logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' });
request(options).then((body) => { const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body }); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
res.status(200).json(JSON.parse(body)); config.defaultNodeIndex = defaultNodeIndex;
}).catch((errRes) => { try {
const errMsg = 'Get Rates Error'; fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) });
res.status(201).json({ message: 'Default Node Updated Successfully' });
} catch (errRes) {
const errMsg = 'Update Default Node 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);
return res.status(err.statusCode).json({ message: err.error, error: err.error }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
}); }
};
export const update2FASettings = (req, res, next) => {
const { secret2fa } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' });
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
if (secret2fa && secret2fa.trim() !== '') {
config.secret2fa = secret2fa;
} else {
delete config.secret2fa;
}
const message = secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.';
try {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
common.appConfig.rtlSecret2fa = config.secret2fa;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message });
res.status(201).json({ message: message });
} catch (errRes) {
const errMsg = 'Update 2FA Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.error, error: err.error });
}
}; };
export const updateSSO = (req, res, next) => { export const updateSSO = (req, res, next) => {
const { SSO } = req.body; const { SSO } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
delete config.SSO; delete config.SSO;
config.SSO = SSO; config.SSO = SSO;
@ -316,7 +266,7 @@ export const updateSSO = (req, res, next) => {
export const updateServiceSettings = (req, res, next) => { export const updateServiceSettings = (req, res, next) => {
const { service, settings } = req.body; const { service, settings } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' });
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
const selectedNode = common.findNode(req.session.selectedNode.index); const selectedNode = common.findNode(req.session.selectedNode.index);
config.nodes.forEach((node) => { config.nodes.forEach((node) => {
@ -326,13 +276,13 @@ export const updateServiceSettings = (req, res, next) => {
if (settings.enable) { if (settings.enable) {
node.Settings.swapServerUrl = settings.serverUrl; node.Settings.swapServerUrl = settings.serverUrl;
node.Authentication.swapMacaroonPath = settings.macaroonPath; node.Authentication.swapMacaroonPath = settings.macaroonPath;
selectedNode.swap_server_url = settings.serverUrl; selectedNode.settings.swapServerUrl = settings.serverUrl;
selectedNode.swap_macaroon_path = settings.macaroonPath; selectedNode.authentication.swapMacaroonPath = settings.macaroonPath;
} else { } else {
delete node.Settings.swapServerUrl; delete node.Settings.swapServerUrl;
delete node.Authentication.swapMacaroonPath; delete node.Authentication.swapMacaroonPath;
delete selectedNode.swap_server_url; delete selectedNode.settings.swapServerUrl;
delete selectedNode.swap_macaroon_path; delete selectedNode.authentication.swapMacaroonPath;
} }
break; break;
@ -340,24 +290,24 @@ export const updateServiceSettings = (req, res, next) => {
if (settings.enable) { if (settings.enable) {
node.Settings.boltzServerUrl = settings.serverUrl; node.Settings.boltzServerUrl = settings.serverUrl;
node.Authentication.boltzMacaroonPath = settings.macaroonPath; node.Authentication.boltzMacaroonPath = settings.macaroonPath;
selectedNode.boltz_server_url = settings.serverUrl; selectedNode.settings.boltzServerUrl = settings.serverUrl;
selectedNode.boltz_macaroon_path = settings.macaroonPath; selectedNode.authentication.boltzMacaroonPath = settings.macaroonPath;
} else { } else {
delete node.Settings.boltzServerUrl; delete node.Settings.boltzServerUrl;
delete node.Authentication.boltzMacaroonPath; delete node.Authentication.boltzMacaroonPath;
delete selectedNode.boltz_server_url; delete selectedNode.settings.boltzServerUrl;
delete selectedNode.boltz_macaroon_path; delete selectedNode.authentication.boltzMacaroonPath;
} }
break; break;
case 'OFFERS': case 'OFFERS':
node.Settings.enableOffers = settings.enableOffers; node.Settings.enableOffers = settings.enableOffers;
selectedNode.enable_offers = settings.enableOffers; selectedNode.settings.enableOffers = settings.enableOffers;
break; break;
case 'PEERSWAP': case 'PEERSWAP':
node.Settings.enablePeerswap = settings.enablePeerswap; node.Settings.enablePeerswap = settings.enablePeerswap;
selectedNode.enable_peerswap = settings.enablePeerswap; selectedNode.settings.enablePeerswap = settings.enablePeerswap;
break; break;
default: default:
@ -377,23 +327,3 @@ export const updateServiceSettings = (req, res, next) => {
return res.status(err.statusCode).json({ message: err.error, error: err.error }); return res.status(err.statusCode).json({ message: err.error, error: err.error });
} }
}; };
export const maskPasswords = (obj) => {
const keys = Object.keys(obj);
const length = keys.length;
if (length !== 0) {
for (let i = 0; i < length; i++) {
if (typeof obj[keys[i]] === 'object') {
keys[keys[i]] = maskPasswords(obj[keys[i]]);
}
if (typeof keys[i] === 'string' &&
(keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') ||
keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
keys[i].toLowerCase().includes('rpcuser'))
) {
obj[keys[i]] = '********************';
}
}
}
return obj;
};

@ -47,19 +47,19 @@ const handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => {
} }
}; };
export const verifyToken = (twoFAToken) => !!(common.rtl_secret2fa && common.rtl_secret2fa !== '' && otplib.authenticator.check(twoFAToken, common.rtl_secret2fa)); export const verifyToken = (twoFAToken) => !!(common.appConfig.rtlSecret2fa && common.appConfig.rtlSecret2fa !== '' && otplib.authenticator.check(twoFAToken, common.appConfig.rtlSecret2fa));
export const authenticateUser = (req, res, next) => { export const authenticateUser = (req, res, next) => {
const { authenticateWith, authenticationValue, twoFAToken } = req.body; const { authenticateWith, authenticationValue, twoFAToken } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' });
if (+common.rtl_sso) { if (+common.appConfig.sso.rtlSso) {
if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) { if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' }); res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' });
} else if (authenticateWith === 'PASSWORD') { } else if (authenticateWith === 'PASSWORD') {
if (common.cookie_value.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie_value).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) { if (common.appConfig.sso.cookieValue.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.appConfig.sso.cookieValue).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) {
common.refreshCookie(); common.refreshCookie();
if (!req.session.selectedNode) { req.session.selectedNode = common.initSelectedNode; } if (!req.session.selectedNode) { req.session.selectedNode = common.selectedNode; }
const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key); const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
res.status(200).json({ token: token }); res.status(200).json({ token: token });
@ -74,7 +74,7 @@ export const authenticateUser = (req, res, next) => {
const reqIP = common.getRequestIP(req); const reqIP = common.getRequestIP(req);
const failed = getFailedInfo(reqIP, currentTime); const failed = getFailedInfo(reqIP, currentTime);
const password = authenticationValue; const password = authenticationValue;
if (common.rtl_pass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) { if (common.appConfig.rtlPass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) {
if (twoFAToken && twoFAToken !== '') { if (twoFAToken && twoFAToken !== '') {
if (!verifyToken(twoFAToken)) { if (!verifyToken(twoFAToken)) {
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } }); logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } });
@ -83,15 +83,15 @@ export const authenticateUser = (req, res, next) => {
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid 2FA Token!')); return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid 2FA Token!'));
} }
} }
if (!req.session.selectedNode) { req.session.selectedNode = common.initSelectedNode; } if (!req.session.selectedNode) { req.session.selectedNode = common.selectedNode; }
delete failedLoginAttempts[reqIP]; delete failedLoginAttempts[reqIP];
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
res.status(200).json({ token: token }); res.status(200).json({ token: token });
} else { } else {
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } }); logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } });
failed.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count; failed.count = common.appConfig.rtlPass !== password ? (failed.count + 1) : failed.count;
failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried; failed.lastTried = common.appConfig.rtlPass !== password ? currentTime : failed.lastTried;
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!')); return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!'));
} }
} }
@ -100,13 +100,13 @@ export const authenticateUser = (req, res, next) => {
export const resetPassword = (req, res, next) => { export const resetPassword = (req, res, next) => {
const { currPassword, newPassword } = req.body; const { currPassword, newPassword } = req.body;
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' });
if (+common.rtl_sso) { if (+common.appConfig.sso.rtlSso) {
const errMsg = 'Password cannot be reset for SSO authentication'; const errMsg = 'Password cannot be reset for SSO authentication';
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode); const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', 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 {
if (common.rtl_pass === currPassword) { if (common.appConfig.rtlPass === currPassword) {
common.rtl_pass = common.replacePasswordWithHash(newPassword); common.appConfig.rtlPass = common.replacePasswordWithHash(newPassword);
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key); const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' });
res.status(200).json({ token: token }); res.status(200).json({ token: token });

@ -1,71 +1,84 @@
export class CommonSelectedNode { export class NodeSettings {
constructor( constructor(
public options?: any, public lnServerUrl?: string,
public ln_server_url?: string, public swapServerUrl?: string,
public macaroon_path?: string, public boltzServerUrl?: string,
public macaroon_value?: string, public bitcoindConfigPath?: string,
public rune_path?: string, public channelBackupPath?: string,
public rune_value?: string, public logLevel?: string,
public ln_api_password?: string, public logFile?: string,
public swap_server_url?: string, public userPersona?: string,
public boltz_server_url?: string, public themeMode?: string,
public config_path?: string, public themeColor?: string,
public rtl_conf_file_path?: string, public unannouncedChannels?: boolean,
public swap_macaroon_path?: string, public fiatConversion?: boolean,
public boltz_macaroon_path?: string, public currencyUnit?: string,
public bitcoind_config_path?: string, public enableOffers?: boolean,
public channel_backup_path?: string, public enablePeerswap?: boolean
public log_level?: string,
public log_file?: string,
public index?: string,
public ln_node?: string,
public ln_implementation?: string,
public user_persona?: string,
public theme_mode?: string,
public theme_color?: string,
public unannounced_channels?: boolean,
public fiat_conversion?: boolean,
public currency_unit?: string,
public ln_version?: string,
public api_version?: string,
public enable_offers?: boolean,
public enable_peerswap?: boolean
) { } ) { }
} }
export class AuthenticationConfiguration { export class NodeAuthentication {
constructor( constructor(
public options?: any,
public configPath?: string, public configPath?: string,
public macaroonPath?: string,
public macaroonValue?: string,
public runePath?: string,
public runeValue?: string,
public lnApiPassword?: string,
public swapMacaroonPath?: string, public swapMacaroonPath?: string,
public boltzMacaroonPath?: string public boltzMacaroonPath?: string
) { } ) { }
} }
export class NodeSettingsConfiguration { export class SelectedNode {
constructor( constructor(
public userPersona?: string,
public themeMode?: string,
public themeColor?: string,
public unannouncedChannels?: boolean,
public fiatConversion?: boolean,
public currencyUnit?: string,
public bitcoindConfigPath?: string,
public logLevel?: string, public logLevel?: string,
public lnServerUrl?: string, public logFile?: string,
public swapServerUrl?: string, public index?: string,
public boltzServerUrl?: string, public lnNode?: string,
public channelBackupPath?: string, public lnImplementation?: string,
public enableOffers?: boolean, public lnVersion?: string,
public enablePeerswap?: boolean public apiVersion?: string,
public settings?: NodeSettings,
public authentication?: NodeAuthentication
) { } ) { }
} }
export class SSO {
constructor(
public rtlSso: number,
public rtlCookiePath: string,
public logoutRedirectLink: string,
public cookieValue: string
) { }
}
export class ApplicationConfig {
constructor(
public defaultNodeIndex: number,
public selectedNodeIndex: number,
public dbDirectoryPath?: string,
public rtlConfFilePath?: string,
public rtlPass?: string,
public allowPasswordUpdate?: boolean,
public rtlSecret2fa?: string,
public sso?: SSO,
public nodes?: SelectedNode[]
) {}
}
export class LogJSONObj { export class LogJSONObj {
constructor( constructor(
@ -74,7 +87,7 @@ export class LogJSONObj {
public data?: string | any | any[], public data?: string | any | any[],
public error?: string | any, public error?: string | any,
public fileName?: string, public fileName?: string,
public selectedNode?: CommonSelectedNode public selectedNode?: SelectedNode
) { } ) { }
} }

@ -1,20 +1,16 @@
import exprs from 'express'; import exprs from 'express';
const { Router } = exprs; const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js'; import { isAuthenticated } from '../../utils/authCheck.js';
import { getRTLConfigInitial, getRTLConfig, updateUISettings, update2FASettings, getConfig, getFile, updateSelectedNode, updateDefaultNode, updateServiceSettings, updateSSO, getCurrencyRates } from '../../controllers/shared/RTLConf.js'; import { getRTLConfig, updateNodeSettings, getConfig, getFile, updateSelectedNode, updateApplicationSettings, getCurrencyRates } from '../../controllers/shared/RTLConf.js';
const router = Router(); const router = Router();
router.get('/rtlconfinit', getRTLConfigInitial); router.get('/rates', getCurrencyRates);
router.get('/rtlconf', isAuthenticated, getRTLConfig);
router.post('/', isAuthenticated, updateUISettings);
router.post('/update2FA', isAuthenticated, update2FASettings);
router.get('/config/:nodeType', isAuthenticated, getConfig);
router.get('/file', isAuthenticated, getFile); router.get('/file', isAuthenticated, getFile);
router.get('/rtlconf/:init', isAuthenticated, getRTLConfig);
router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode); router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode);
router.post('/updateDefaultNode', updateDefaultNode); router.get('/config/:nodeType', isAuthenticated, getConfig);
router.post('/updateServiceSettings', updateServiceSettings); router.post('/node', isAuthenticated, updateNodeSettings);
router.post('/updateSSO', updateSSO); router.post('/application', isAuthenticated, updateApplicationSettings);
router.get('/rates', getCurrencyRates);
export default router; export default router;

@ -32,7 +32,7 @@ export class ExpressApplication {
public directoryName = dirname(fileURLToPath(import.meta.url)); public directoryName = dirname(fileURLToPath(import.meta.url));
constructor() { constructor() {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' });
this.app.set('trust proxy', true); this.app.set('trust proxy', true);
this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false })); this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false }));
this.app.use(cookieParser(this.common.secret_key)); this.app.use(cookieParser(this.common.secret_key));
@ -52,7 +52,7 @@ export class ExpressApplication {
public setCSRF = () => { CSRF.mount(this.app); }; public setCSRF = () => { CSRF.mount(this.app); };
public setApplicationRoutes = () => { public setApplicationRoutes = () => {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' });
this.app.use(this.common.baseHref + '/api', sharedRoutes); this.app.use(this.common.baseHref + '/api', sharedRoutes);
this.app.use(this.common.baseHref + '/api/lnd', lndRoutes); this.app.use(this.common.baseHref + '/api/lnd', lndRoutes);
this.app.use(this.common.baseHref + '/api/cln', clnRoutes); this.app.use(this.common.baseHref + '/api/cln', clnRoutes);
@ -67,29 +67,29 @@ export class ExpressApplication {
this.handleApplicationErrors(err, res); this.handleApplicationErrors(err, res);
next(); next();
}); });
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' });
}; };
public handleApplicationErrors = (err, res) => { public handleApplicationErrors = (err, res) => {
switch (err.code) { switch (err.code) {
case 'EACCES': case 'EACCES':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' });
res.status(406).send('Server requires elevated privileges.'); res.status(406).send('Server requires elevated privileges.');
break; break;
case 'EADDRINUSE': case 'EADDRINUSE':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' });
res.status(409).send('Server is already in use.'); res.status(409).send('Server is already in use.');
break; break;
case 'ECONNREFUSED': case 'ECONNREFUSED':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' });
res.status(401).send('Server is down/locked.'); res.status(401).send('Server is down/locked.');
break; break;
case 'EBADCSRFTOKEN': case 'EBADCSRFTOKEN':
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' });
res.status(403).send('Invalid CSRF token, form tempered.'); res.status(403).send('Invalid CSRF token, form tempered.');
break; break;
default: default:
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err });
res.status(400).send(JSON.stringify(err)); res.status(400).send(JSON.stringify(err));
break; break;
} }

@ -44,7 +44,7 @@ export const verifyWSUser = (info, next) => {
} catch (err) { } catch (err) {
cookies = {}; cookies = {};
updatedReq['cookies'] = JSON.parse(cookies); updatedReq['cookies'] = JSON.parse(cookies);
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err }); logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err });
} }
csurfProtection(updatedReq, null, (err) => { csurfProtection(updatedReq, null, (err) => {
if (err) { if (err) {
@ -54,7 +54,7 @@ export const verifyWSUser = (info, next) => {
} }
}); });
} catch (err) { } catch (err) {
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err }); logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err });
next(true); next(true);
} }
} }

@ -4,26 +4,17 @@ import { fileURLToPath } from 'url';
import * as crypto from 'crypto'; import * as crypto from 'crypto';
import request from 'request-promise'; import request from 'request-promise';
import { Logger, LoggerService } from './logger.js'; import { Logger, LoggerService } from './logger.js';
import { CommonSelectedNode } from '../models/config.model.js'; import { ApplicationConfig, SelectedNode } from '../models/config.model.js';
export class CommonService { export class CommonService {
public logger: LoggerService = Logger; public logger: LoggerService = Logger;
public nodes: CommonSelectedNode[] = []; public nodes: SelectedNode[] = [];
public initSelectedNode: CommonSelectedNode = null; public selectedNode: SelectedNode = null;
public rtl_conf_file_path = ''; public ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' };
public appConfig: ApplicationConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, rtlSecret2fa: '', sso: this.ssoInit, nodes: [] };
public port = 3000; public port = 3000;
public host = ''; public host = '';
public db_directory_path = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
public rtl_pass = '';
public flg_allow_password_update = true;
public rtl_secret2fa = '';
public rtl_sso = 0;
public rtl_cookie_path = '';
public logout_redirect_link = '';
public cookie_value = '';
public ln_version = '';
public api_version = '';
public secret_key = crypto.randomBytes(64).toString('hex'); public secret_key = crypto.randomBytes(64).toString('hex');
public read_dummy_data = false; public read_dummy_data = false;
public baseHref = '/rtl'; public baseHref = '/rtl';
@ -33,101 +24,101 @@ export class CommonService {
{ name: 'JUL', days: 31 }, { name: 'AUG', days: 31 }, { name: 'SEP', days: 30 }, { name: 'OCT', days: 31 }, { name: 'NOV', days: 30 }, { name: 'DEC', days: 31 } { name: 'JUL', days: 31 }, { name: 'AUG', days: 31 }, { name: 'SEP', days: 30 }, { name: 'OCT', days: 31 }, { name: 'NOV', days: 30 }, { name: 'DEC', days: 31 }
]; ];
constructor() { } constructor() {}
public setSwapServerOptions = (req) => { public setSwapServerOptions = (req) => {
const swapOptions = { const swapOptions = {
baseUrl: req.session.selectedNode.swap_server_url, baseUrl: req.session.selectedNode.settings.swapServerUrl,
uri: '', uri: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': '' } headers: { 'Grpc-Metadata-macaroon': '' }
}; };
if (req.session.selectedNode.swap_macaroon_path) { if (req.session.selectedNode.authentication.swapMacaroonPath) {
try { try {
swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.swap_macaroon_path, 'loop.macaroon')).toString('hex') }; swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.swapMacaroonPath, 'loop.macaroon')).toString('hex') };
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err });
} }
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions });
return swapOptions; return swapOptions;
}; };
public getBoltzServerOptions = (req) => { public getBoltzServerOptions = (req) => {
const boltzOptions = { const boltzOptions = {
url: req.session.selectedNode.boltz_server_url, url: req.session.selectedNode.settings.boltzServerUrl,
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': '' } headers: { 'Grpc-Metadata-macaroon': '' }
}; };
if (req.session.selectedNode.boltz_macaroon_path) { if (req.session.selectedNode.authentication.boltzMacaroonPath) {
try { try {
boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.boltz_macaroon_path, 'admin.macaroon')).toString('hex') }; boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.boltzMacaroonPath, 'admin.macaroon')).toString('hex') };
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err });
} }
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions });
return boltzOptions; return boltzOptions;
}; };
public getOptions = (req) => { public getOptions = (req) => {
if (req.session.selectedNode && req.session.selectedNode.options) { if (req.session.selectedNode && req.session.selectedNode.authentication.options) {
req.session.selectedNode.options.method = (req.session.selectedNode.ln_implementation && req.session.selectedNode.ln_implementation.toUpperCase() === 'LND') ? 'GET' : 'POST'; req.session.selectedNode.authentication.options.method = (req.session.selectedNode.lnImplementation && req.session.selectedNode.lnImplementation.toUpperCase() === 'LND') ? 'GET' : 'POST';
delete req.session.selectedNode.options.form; delete req.session.selectedNode.authentication.options.form;
delete req.session.selectedNode.options.body; delete req.session.selectedNode.authentication.options.body;
req.session.selectedNode.options.qs = {}; req.session.selectedNode.authentication.options.qs = {};
return req.session.selectedNode.options; return req.session.selectedNode.authentication.options;
} }
return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.initSelectedNode); return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.selectedNode);
}; };
public updateSelectedNodeOptions = (req) => { public updateSelectedNodeOptions = (req) => {
if (!req.session.selectedNode) { if (!req.session.selectedNode) {
req.session.selectedNode = {}; req.session.selectedNode = {};
} }
req.session.selectedNode.options = { req.session.selectedNode.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
try { try {
if (req.session.selectedNode && req.session.selectedNode.ln_implementation) { if (req.session.selectedNode && req.session.selectedNode.lnImplementation) {
switch (req.session.selectedNode.ln_implementation.toUpperCase()) { switch (req.session.selectedNode.lnImplementation.toUpperCase()) {
case 'CLN': case 'CLN':
try { try {
if (!req.session.selectedNode.rune_value) { if (!req.session.selectedNode.authentication.runeValue) {
req.session.selectedNode.rune_value = this.getRuneValue(req.session.selectedNode.rune_path); req.session.selectedNode.authentication.runeValue = this.getRuneValue(req.session.selectedNode.authentication.runePath);
} }
req.session.selectedNode.options.headers = { rune: req.session.selectedNode.rune_value }; req.session.selectedNode.authentication.options.headers = { rune: req.session.selectedNode.authentication.runeValue };
} catch (err) { } catch (err) {
throw new Error(err); throw new Error(err);
} }
break; break;
case 'ECL': case 'ECL':
req.session.selectedNode.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.ln_api_password).toString('base64') }; req.session.selectedNode.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.authentication.lnApiPassword).toString('base64') };
break; break;
default: default:
req.session.selectedNode.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') }; req.session.selectedNode.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
break; break;
} }
} }
if (req.session.selectedNode) { if (req.session.selectedNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.ln_node, data: req.session.selectedNode.options }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.lnNode, data: req.session.selectedNode.authentication.options });
} }
return { status: 200, message: 'Updated Successfully' }; return { status: 200, message: 'Updated Successfully' };
} catch (err) { } catch (err) {
req.session.selectedNode.options = { req.session.selectedNode.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err });
return { status: 502, message: err }; return { status: 502, message: err };
} }
}; };
@ -144,48 +135,48 @@ export class CommonService {
}; };
public setOptions = (req) => { public setOptions = (req) => {
if (this.nodes[0].options && this.nodes[0].options.headers) { return; } if (this.nodes[0].authentication.options && this.nodes[0].authentication.options.headers) { return; }
if (this.nodes && this.nodes.length > 0) { if (this.nodes && this.nodes.length > 0) {
this.nodes.forEach((node) => { this.nodes.forEach((node) => {
node.options = { node.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: null form: null
}; };
try { try {
if (node.ln_implementation) { if (node.lnImplementation) {
switch (node.ln_implementation.toUpperCase()) { switch (node.lnImplementation.toUpperCase()) {
case 'CLN': case 'CLN':
try { try {
if (!node.rune_value) { if (!node.authentication.runeValue) {
node.rune_value = this.getRuneValue(node.rune_path); node.authentication.runeValue = this.getRuneValue(node.authentication.runePath);
} }
node.options.headers = { rune: node.rune_value }; node.authentication.options.headers = { rune: node.authentication.runeValue };
} catch (err) { } catch (err) {
throw new Error(err); throw new Error(err);
} }
break; break;
case 'ECL': case 'ECL':
node.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.ln_api_password).toString('base64') }; node.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.authentication.lnApiPassword).toString('base64') };
break; break;
default: default:
node.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.macaroon_path, 'admin.macaroon')).toString('hex') }; node.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
break; break;
} }
} }
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err });
node.options = { node.authentication.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
form: '' form: ''
}; };
} }
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.ln_node, data: node.options }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.lnNode, data: node.authentication.options });
}); });
this.updateSelectedNodeOptions(req); this.updateSelectedNodeOptions(req);
} }
@ -264,7 +255,7 @@ export class CommonService {
} }
}; };
public handleError = (errRes, fileName, errMsg, selectedNode: CommonSelectedNode) => { public handleError = (errRes, fileName, errMsg, selectedNode: SelectedNode) => {
let err = JSON.parse(JSON.stringify(errRes)); let err = JSON.parse(JSON.stringify(errRes));
if (err && err.error && Object.keys(err.error).length === 0 && errRes.error && (errRes.error.stack || errRes.error.message)) { if (err && err.error && Object.keys(err.error).length === 0 && errRes.error && (errRes.error.stack || errRes.error.message)) {
errRes.error = errRes.error.stack || errRes.error.message; errRes.error = errRes.error.stack || errRes.error.message;
@ -273,8 +264,8 @@ export class CommonService {
errRes.error = errRes.message || errRes.stack; errRes.error = errRes.message || errRes.stack;
err = JSON.parse(JSON.stringify(errRes)); err = JSON.parse(JSON.stringify(errRes));
} }
if (!selectedNode) { selectedNode = this.initSelectedNode; } if (!selectedNode) { selectedNode = this.selectedNode; }
switch (selectedNode.ln_implementation) { switch (selectedNode.lnImplementation) {
case 'LND': case 'LND':
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon']; delete err.options.headers['Grpc-Metadata-macaroon'];
@ -328,7 +319,7 @@ export class CommonService {
) )
}; };
} }
if (selectedNode.ln_implementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { newErrorObj.statusCode = 500; } if (selectedNode.lnImplementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') { newErrorObj.statusCode = 500; }
return newErrorObj; return newErrorObj;
}; };
@ -339,15 +330,15 @@ export class CommonService {
(req.connection.socket ? req.connection.socket.remoteAddress : null)); (req.connection.socket ? req.connection.socket.remoteAddress : null));
public getDummyData = (dataKey, lnImplementation) => { public getDummyData = (dataKey, lnImplementation) => {
const dummyDataFile = this.rtl_conf_file_path + sep + 'ECLDummyData.log'; const dummyDataFile = this.appConfig.rtlConfFilePath + sep + 'ECLDummyData.log';
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.dummy_data_array_from_file.length === 0) { if (this.dummy_data_array_from_file.length === 0) {
fs.readFile(dummyDataFile, 'utf8', (err, data) => { fs.readFile(dummyDataFile, 'utf8', (err, data) => {
if (err) { if (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' });
} else { } else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' });
} }
} else { } else {
this.dummy_data_array_from_file = data.split('\n'); this.dummy_data_array_from_file = data.split('\n');
@ -361,22 +352,22 @@ export class CommonService {
}; };
public readCookie = () => { public readCookie = () => {
const exists = fs.existsSync(this.rtl_cookie_path); const exists = fs.existsSync(this.appConfig.sso.rtlCookiePath);
if (exists) { if (exists) {
try { try {
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err });
throw new Error(err); throw new Error(err);
} }
} else { } else {
try { try {
const directoryName = dirname(this.rtl_cookie_path); const directoryName = dirname(this.appConfig.sso.rtlCookiePath);
this.createDirectory(directoryName); this.createDirectory(directoryName);
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err });
throw new Error(err); throw new Error(err);
} }
} }
@ -384,10 +375,10 @@ export class CommonService {
public refreshCookie = () => { public refreshCookie = () => {
try { try {
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex')); fs.writeFileSync(this.appConfig.sso.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8'); this.appConfig.sso.cookieValue = fs.readFileSync(this.appConfig.sso.rtlCookiePath, 'utf-8');
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err });
throw new Error(err); throw new Error(err);
} }
}; };
@ -414,47 +405,47 @@ export class CommonService {
}; };
public replacePasswordWithHash = (multiPassHashed) => { public replacePasswordWithHash = (multiPassHashed) => {
this.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..'); this.appConfig.rtlConfFilePath = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..');
try { try {
const RTLConfFile = this.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = this.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.multiPassHashed = multiPassHashed; config.multiPassHashed = multiPassHashed;
delete config.multiPass; delete config.multiPass;
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8'); fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' });
return config.multiPassHashed; return config.multiPassHashed;
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err });
} }
}; };
public getAllNodeAllChannelBackup = (node: CommonSelectedNode) => { public getAllNodeAllChannelBackup = (node: SelectedNode) => {
const channel_backup_file = node.channel_backup_path + sep + 'channel-all.bak'; const channel_backup_file = node.settings.channelBackupPath + sep + 'channel-all.bak';
const options = { const options = {
url: node.ln_server_url + '/v1/channels/backup', url: node.settings.lnServerUrl + '/v1/channels/backup',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') } headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.authentication.macaroonPath + '/admin.macaroon').toString('hex') }
}; };
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.ln_node + '..' }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.lnNode + '..' });
request(options).then((body) => { request(options).then((body) => {
fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => { fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => {
if (err) { if (err) {
if (node.ln_node) { if (node.lnNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
} else { } else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err });
} }
} else { } else {
if (node.ln_node) { if (node.lnNode) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.ln_node, data: body }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.lnNode, data: body });
} else { } else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body });
} }
} }
}); });
}, (err) => { }, (err) => {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
fs.writeFile(channel_backup_file, '', () => { }); fs.writeFile(channel_backup_file, '', () => { });
}); });
}; };
@ -465,8 +456,8 @@ export class CommonService {
const pattern = /v?(\d+(\.\d+)*)/; const pattern = /v?(\d+(\.\d+)*)/;
const match = currentVersion.match(pattern); const match = currentVersion.match(pattern);
if (match && match.length && match.length > 1) { if (match && match.length && match.length > 1) {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] });
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion }); this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion });
const currentVersionArr = match[1].split('.') || []; const currentVersionArr = match[1].split('.') || [];
currentVersionArr[1] = currentVersionArr[1].substring(0, 2); currentVersionArr[1] = currentVersionArr[1].substring(0, 2);
const checkVersionsArr = checkVersion.split('.'); const checkVersionsArr = checkVersion.split('.');
@ -475,7 +466,7 @@ export class CommonService {
(+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] > +checkVersionsArr[1]) || (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] > +checkVersionsArr[1]) ||
(+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]); (+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]);
} else { } else {
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion }); this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion });
return false; return false;
} }
} }
@ -485,20 +476,20 @@ export class CommonService {
public getMonthDays = (selMonth, selYear) => ((selMonth === 1 && selYear % 4 === 0) ? (this.MONTHS[selMonth].days + 1) : this.MONTHS[selMonth].days); public getMonthDays = (selMonth, selYear) => ((selMonth === 1 && selYear % 4 === 0) ? (this.MONTHS[selMonth].days + 1) : this.MONTHS[selMonth].days);
public logEnvVariables = (req) => { public logEnvVariables = (req) => {
const selNode = <CommonSelectedNode>req.session.selectedNode; const selNode = <SelectedNode>req.session.selectedNode;
if (selNode && selNode.index) { if (selNode && selNode.index) {
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.db_directory_path }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.appConfig.dbDirectoryPath });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.rtl_sso }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.appConfig.sso.rtlSso });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.ln_node }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.lnNode });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.ln_implementation }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.lnImplementation });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.fiat_conversion }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.settings.fiatConversion });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.currency_unit }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.settings.currencyUnit });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.ln_server_url }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.settings.lnServerUrl });
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.logout_redirect_link + '\r\n' }); this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.appConfig.sso.logoutRedirectLink + '\r\n' });
} }
}; };

@ -103,9 +103,9 @@ export class ConfigService {
private updateLogByLevel = () => { private updateLogByLevel = () => {
let updateLogFlag = false; let updateLogFlag = false;
this.common.rtl_conf_file_path = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); this.common.appConfig.rtlConfFilePath = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
try { try {
const RTLConfFile = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; const RTLConfFile = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8')); const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.nodes.forEach((node) => { config.nodes.forEach((node) => {
if (node.Settings.hasOwnProperty('enableLogging')) { if (node.Settings.hasOwnProperty('enableLogging')) {
@ -125,16 +125,16 @@ export class ConfigService {
private validateNodeConfig = (config) => { private validateNodeConfig = (config) => {
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) { if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
this.common.rtl_pass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex'); this.common.appConfig.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
this.common.flg_allow_password_update = false; this.common.appConfig.allowPasswordUpdate = false;
} else if (config.multiPassHashed && config.multiPassHashed !== '') { } else if (config.multiPassHashed && config.multiPassHashed !== '') {
this.common.rtl_pass = config.multiPassHashed; this.common.appConfig.rtlPass = config.multiPassHashed;
} else if (config.multiPass && config.multiPass !== '') { } else if (config.multiPass && config.multiPass !== '') {
this.common.rtl_pass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex')); this.common.appConfig.rtlPass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex'));
} else { } else {
this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json'; this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json';
} }
this.common.rtl_secret2fa = config.secret2fa; this.common.appConfig.rtlSecret2fa = config.secret2fa;
} else { } else {
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') { if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
this.errMsg = this.errMsg + '\nRTL Password cannot be set with SSO. Please set SSO as 0 or remove password.'; this.errMsg = this.errMsg + '\nRTL Password cannot be set with SSO. Please set SSO as 0 or remove password.';
@ -142,20 +142,20 @@ export class ConfigService {
} }
this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000; this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000;
this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null; this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null;
this.common.db_directory_path = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..'); this.common.appConfig.dbDirectoryPath = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..');
if (config.nodes && config.nodes.length > 0) { if (config.nodes && config.nodes.length > 0) {
config.nodes.forEach((node, idx) => { config.nodes.forEach((node, idx) => {
this.common.nodes[idx] = {}; this.common.nodes[idx] = {};
this.common.nodes[idx].index = node.index; this.common.nodes[idx].index = node.index;
this.common.nodes[idx].ln_node = node.lnNode; this.common.nodes[idx].lnNode = node.lnNode;
this.common.nodes[idx].ln_implementation = (process?.env?.LN_IMPLEMENTATION) ? process?.env?.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND'; this.common.nodes[idx].lnImplementation = (process?.env?.lnImplementation) ? process?.env?.lnImplementation : node.lnImplementation ? node.lnImplementation : 'LND';
if (this.common.nodes[idx].ln_implementation === 'CLT') { this.common.nodes[idx].ln_implementation = 'CLN'; } if (this.common.nodes[idx].lnImplementation === 'CLT') { this.common.nodes[idx].lnImplementation = 'CLN'; }
switch (this.common.nodes[idx].ln_implementation) { switch (this.common.nodes[idx].lnImplementation) {
case 'CLN': case 'CLN':
if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') { if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') {
this.common.nodes[idx].rune_path = process?.env?.RUNE_PATH; this.common.nodes[idx].authentication.runePath = process?.env?.RUNE_PATH;
} else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') { } else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') {
this.common.nodes[idx].rune_path = node.Authentication.runePath; this.common.nodes[idx].authentication.runePath = node.Authentication.runePath;
} else { } else {
this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!';
} }
@ -163,118 +163,118 @@ export class ConfigService {
case 'ECL': case 'ECL':
if (process?.env?.LN_API_PASSWORD) { if (process?.env?.LN_API_PASSWORD) {
this.common.nodes[idx].ln_api_password = process?.env?.LN_API_PASSWORD; this.common.nodes[idx].authentication.lnApiPassword = process?.env?.LN_API_PASSWORD;
} else if (node.Authentication && node.Authentication.lnApiPassword) { } else if (node.Authentication && node.Authentication.lnApiPassword) {
this.common.nodes[idx].ln_api_password = node.Authentication.lnApiPassword; this.common.nodes[idx].authentication.lnApiPassword = node.Authentication.lnApiPassword;
} else { } else {
this.common.nodes[idx].ln_api_password = ''; this.common.nodes[idx].authentication.lnApiPassword = '';
} }
break; break;
default: default:
if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') { if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') {
this.common.nodes[idx].macaroon_path = process?.env?.MACAROON_PATH; this.common.nodes[idx].authentication.macaroonPath = process?.env?.MACAROON_PATH;
} else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') { } else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') {
this.common.nodes[idx].macaroon_path = node.Authentication.macaroonPath; this.common.nodes[idx].authentication.macaroonPath = node.Authentication.macaroonPath;
} else { } else {
this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!';
} }
break; break;
} }
if (process?.env?.CONFIG_PATH) { if (process?.env?.CONFIG_PATH) {
this.common.nodes[idx].config_path = process?.env?.CONFIG_PATH; this.common.nodes[idx].authentication.configPath = process?.env?.CONFIG_PATH;
} else if (node.Authentication && node.Authentication.configPath) { } else if (node.Authentication && node.Authentication.configPath) {
this.common.nodes[idx].config_path = node.Authentication.configPath; this.common.nodes[idx].authentication.configPath = node.Authentication.configPath;
} else { } else {
this.common.nodes[idx].config_path = ''; this.common.nodes[idx].authentication.configPath = '';
} }
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '' && this.common.nodes[idx].config_path !== '') { if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '' && this.common.nodes[idx].authentication.configPath !== '') {
try { try {
const exists = fs.existsSync(this.common.nodes[idx].config_path || ''); const exists = fs.existsSync(this.common.nodes[idx].authentication.configPath || '');
if (exists) { if (exists) {
try { try {
const configFile = fs.readFileSync((this.common.nodes[idx].config_path || ''), 'utf-8'); const configFile = fs.readFileSync((this.common.nodes[idx].authentication.configPath || ''), 'utf-8');
const iniParsed = ini.parse(configFile); const iniParsed = ini.parse(configFile);
this.common.nodes[idx].ln_api_password = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password; this.common.nodes[idx].authentication.lnApiPassword = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password;
} catch (err) { } catch (err) {
this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err; this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err;
} }
} else { } else {
this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].config_path; this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].authentication.configPath;
} }
} catch (err) { } catch (err) {
this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err; this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err;
} }
} }
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '') { if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '') {
this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!'; this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!';
} }
if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') { if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') {
this.common.nodes[idx].ln_server_url = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL; this.common.nodes[idx].settings.lnServerUrl = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL;
} else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') { } else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') {
this.common.nodes[idx].ln_server_url = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL; this.common.nodes[idx].settings.lnServerUrl = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL;
} else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') { } else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') {
this.common.nodes[idx].ln_server_url = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl; this.common.nodes[idx].settings.lnServerUrl = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl;
} else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') { } else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') {
this.common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl; this.common.nodes[idx].settings.lnServerUrl = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl;
} else { } else {
this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!'; this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!';
} }
this.common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT'; this.common.nodes[idx].settings.userPersona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT';
this.common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY'; this.common.nodes[idx].settings.themeMode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY';
this.common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE'; this.common.nodes[idx].settings.themeColor = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE';
this.common.nodes[idx].unannounced_channels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false; this.common.nodes[idx].settings.unannouncedChannels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false;
this.common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'; this.common.nodes[idx].settings.logLevel = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR';
this.common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false; this.common.nodes[idx].settings.fiatConversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false;
if (this.common.nodes[idx].fiat_conversion) { if (this.common.nodes[idx].settings.fiatConversion) {
this.common.nodes[idx].currency_unit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD'; this.common.nodes[idx].settings.currencyUnit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD';
} }
if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') { if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') {
this.common.nodes[idx].swap_server_url = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL; this.common.nodes[idx].settings.swapServerUrl = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL;
this.common.nodes[idx].swap_macaroon_path = process?.env?.SWAP_MACAROON_PATH; this.common.nodes[idx].authentication.swapMacaroonPath = process?.env?.SWAP_MACAROON_PATH;
} else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') { } else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') {
this.common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl; this.common.nodes[idx].settings.swapServerUrl = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl;
this.common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : ''; this.common.nodes[idx].authentication.swapMacaroonPath = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : '';
} else { } else {
this.common.nodes[idx].swap_server_url = ''; this.common.nodes[idx].settings.swapServerUrl = '';
this.common.nodes[idx].swap_macaroon_path = ''; this.common.nodes[idx].authentication.swapMacaroonPath = '';
} }
if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') { if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') {
this.common.nodes[idx].boltz_server_url = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL; this.common.nodes[idx].settings.boltzServerUrl = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL;
this.common.nodes[idx].boltz_macaroon_path = process?.env?.BOLTZ_MACAROON_PATH; this.common.nodes[idx].authentication.boltzMacaroonPath = process?.env?.BOLTZ_MACAROON_PATH;
} else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') { } else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') {
this.common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl; this.common.nodes[idx].settings.boltzServerUrl = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl;
this.common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : ''; this.common.nodes[idx].authentication.boltzMacaroonPath = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : '';
} else { } else {
this.common.nodes[idx].boltz_server_url = ''; this.common.nodes[idx].settings.boltzServerUrl = '';
this.common.nodes[idx].boltz_macaroon_path = ''; this.common.nodes[idx].authentication.boltzMacaroonPath = '';
} }
this.common.nodes[idx].enable_offers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false; this.common.nodes[idx].settings.enableOffers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false;
this.common.nodes[idx].enable_peerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false; this.common.nodes[idx].settings.enablePeerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false;
this.common.nodes[idx].bitcoind_config_path = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; this.common.nodes[idx].settings.bitcoindConfigPath = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
this.common.nodes[idx].channel_backup_path = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index; this.common.nodes[idx].settings.channelBackupPath = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.appConfig.rtlConfFilePath + sep + 'channels-backup' + sep + 'node-' + node.index;
try { try {
this.common.createDirectory(this.common.nodes[idx].channel_backup_path); this.common.createDirectory(this.common.nodes[idx].settings.channelBackupPath);
const exists = fs.existsSync(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); const exists = fs.existsSync(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
if (!exists) { if (!exists) {
try { try {
if (this.common.nodes[idx].ln_implementation === 'LND') { if (this.common.nodes[idx].lnImplementation === 'LND') {
this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]); this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]);
} else { } else {
const createStream = fs.createWriteStream(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak'); const createStream = fs.createWriteStream(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
createStream.end(); createStream.end();
} }
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err });
} }
} }
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err });
} }
this.common.nodes[idx].log_file = this.common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log'; this.common.nodes[idx].settings.logFile = this.common.appConfig.rtlConfFilePath + '/logs/RTL-Node-' + node.index + '.log';
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) });
const log_file = this.common.nodes[idx].log_file; const log_file = this.common.nodes[idx].settings.logFile;
if (fs.existsSync(log_file || '')) { if (fs.existsSync(log_file || '')) {
fs.writeFile((log_file || ''), '', () => { }); fs.writeFile((log_file || ''), '', () => { });
} else { } else {
@ -284,7 +284,7 @@ export class ConfigService {
const createStream = fs.createWriteStream(log_file || ''); const createStream = fs.createWriteStream(log_file || '');
createStream.end(); createStream.end();
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err });
} }
} }
}); });
@ -295,27 +295,27 @@ export class ConfigService {
private setSSOParams = (config) => { private setSSOParams = (config) => {
if (process?.env?.RTL_SSO) { if (process?.env?.RTL_SSO) {
this.common.rtl_sso = +process?.env?.RTL_SSO; this.common.appConfig.sso.rtlSso = +process?.env?.RTL_SSO;
} else if (config.SSO && config.SSO.rtlSSO) { } else if (config.SSO && config.SSO.rtlSSO) {
this.common.rtl_sso = config.SSO.rtlSSO; this.common.appConfig.sso.rtlSso = config.SSO.rtlSSO;
} }
if (process?.env?.RTL_COOKIE_PATH) { if (process?.env?.RTL_COOKIE_PATH) {
this.common.rtl_cookie_path = process?.env?.RTL_COOKIE_PATH; this.common.appConfig.sso.rtlCookiePath = process?.env?.RTL_COOKIE_PATH;
} else if (config.SSO && config.SSO.rtlCookiePath) { } else if (config.SSO && config.SSO.rtlCookiePath) {
this.common.rtl_cookie_path = config.SSO.rtlCookiePath; this.common.appConfig.sso.rtlCookiePath = config.SSO.rtlCookiePath;
} else { } else {
this.common.rtl_cookie_path = ''; this.common.appConfig.sso.rtlCookiePath = '';
} }
if (process?.env?.LOGOUT_REDIRECT_LINK) { if (process?.env?.LOGOUT_REDIRECT_LINK) {
this.common.logout_redirect_link = process?.env?.LOGOUT_REDIRECT_LINK; this.common.appConfig.sso.logoutRedirectLink = process?.env?.LOGOUT_REDIRECT_LINK;
} else if (config.SSO && config.SSO.logoutRedirectLink) { } else if (config.SSO && config.SSO.logoutRedirectLink) {
this.common.logout_redirect_link = config.SSO.logoutRedirectLink; this.common.appConfig.sso.logoutRedirectLink = config.SSO.logoutRedirectLink;
} }
if (+this.common.rtl_sso) { if (+this.common.appConfig.sso.rtlSso) {
if (!this.common.rtl_cookie_path || this.common.rtl_cookie_path.trim() === '') { if (!this.common.appConfig.sso.rtlCookiePath || this.common.appConfig.sso.rtlCookiePath.trim() === '') {
this.errMsg = 'Please set rtlCookiePath value for single sign on option!'; this.errMsg = 'Please set rtlCookiePath value for single sign on option!';
} else { } else {
this.common.readCookie(); this.common.readCookie();
@ -325,16 +325,16 @@ export class ConfigService {
private setSelectedNode = (config) => { private setSelectedNode = (config) => {
if (config.defaultNodeIndex) { if (config.defaultNodeIndex) {
this.common.initSelectedNode = this.common.findNode(config.defaultNodeIndex) || {}; this.common.selectedNode = this.common.findNode(config.defaultNodeIndex) || {};
} else { } else {
this.common.initSelectedNode = this.common.findNode(this.common.nodes[0].index) || {}; this.common.selectedNode = this.common.findNode(this.common.nodes[0].index) || {};
} }
}; };
public setServerConfiguration = () => { public setServerConfiguration = () => {
try { try {
this.common.rtl_conf_file_path = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..'); this.common.appConfig.rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
const confFileFullPath = this.common.rtl_conf_file_path + sep + 'RTL-Config.json'; const confFileFullPath = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
if (!fs.existsSync(confFileFullPath)) { if (!fs.existsSync(confFileFullPath)) {
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig())); fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig()));
} }
@ -343,7 +343,7 @@ export class ConfigService {
this.validateNodeConfig(config); this.validateNodeConfig(config);
this.setSelectedNode(config); this.setSelectedNode(config);
} catch (err: any) { } catch (err: any) {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err });
throw new Error(err); throw new Error(err);
} }
}; };

@ -8,7 +8,7 @@ class CORS {
public common: CommonService = Common; public common: CommonService = Common;
public mount(app: Application): Application { public mount(app: Application): Application {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' });
app.use((req, res, next) => { app.use((req, res, next) => {
res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath'); res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath');
@ -19,7 +19,7 @@ class CORS {
} }
next(); next();
}); });
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' });
return app; return app;
}; };

@ -10,11 +10,11 @@ class CSRF {
public common: CommonService = Common; public common: CommonService = Common;
public mount(app: Application): Application { public mount(app: Application): Application {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
if (process.env.NODE_ENV !== 'development') { if (process.env.NODE_ENV !== 'development') {
app.use((req, res, next) => this.csrfProtection(req, res, next)); app.use((req, res, next) => this.csrfProtection(req, res, next));
} }
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' });
return app; return app;
}; };

@ -3,20 +3,20 @@ import { join, sep } from 'path';
import { Common, CommonService } from '../utils/common.js'; import { Common, CommonService } from '../utils/common.js';
import { Logger, LoggerService } from '../utils/logger.js'; import { Logger, LoggerService } from '../utils/logger.js';
import { Collections, CollectionsEnum, validateDocument, LNDCollection, ECLCollection, CLNCollection, ECL_UPDATED_DB } from '../models/database.model.js'; import { Collections, CollectionsEnum, validateDocument, LNDCollection, ECLCollection, CLNCollection, ECL_UPDATED_DB } from '../models/database.model.js';
import { CommonSelectedNode } from '../models/config.model.js'; import { SelectedNode } from '../models/config.model.js';
export class DatabaseService { export class DatabaseService {
public common: CommonService = Common; public common: CommonService = Common;
public logger: LoggerService = Logger; public logger: LoggerService = Logger;
public dbDirectory = join(this.common.db_directory_path, 'database'); public dbDirectory = join(this.common.appConfig.dbDirectoryPath, 'database');
public nodeDatabase: { id?: { adapter: DatabaseAdapter, data: Collections } } = {}; public nodeDatabase: { id?: { adapter: DatabaseAdapter, data: Collections } } = {};
constructor() { } constructor() { }
migrateDatabase() { migrateDatabase() {
this.common.nodes?.map((node: any) => { this.common.nodes?.map((node: any) => {
if (node.ln_implementation === 'ECL') { if (node.lnImplementation === 'ECL') {
this.nodeDatabase[node.index] = { adapter: null, data: {} }; this.nodeDatabase[node.index] = { adapter: null, data: {} };
this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node); this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node);
this.fetchNodeData(node); this.fetchNodeData(node);
@ -82,8 +82,8 @@ export class DatabaseService {
} }
} }
fetchNodeData(selectedNode: CommonSelectedNode) { fetchNodeData(selectedNode: SelectedNode) {
switch (selectedNode.ln_implementation) { switch (selectedNode.lnImplementation) {
case 'CLN': case 'CLN':
for (const collectionName in CLNCollection) { for (const collectionName in CLNCollection) {
if (CLNCollection.hasOwnProperty(collectionName)) { if (CLNCollection.hasOwnProperty(collectionName)) {
@ -121,7 +121,7 @@ export class DatabaseService {
}); });
} }
insert(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, newCollection: any) { insert(selectedNode: SelectedNode, collectionName: CollectionsEnum, newCollection: any) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (!selectedNode || !selectedNode.index) { if (!selectedNode || !selectedNode.index) {
@ -136,7 +136,7 @@ export class DatabaseService {
}); });
} }
update(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, updatedDocument: any, documentFieldName: string, documentFieldValue: string) { update(selectedNode: SelectedNode, collectionName: CollectionsEnum, updatedDocument: any, documentFieldName: string, documentFieldValue: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (!selectedNode || !selectedNode.index) { if (!selectedNode || !selectedNode.index) {
@ -172,7 +172,7 @@ export class DatabaseService {
}); });
} }
find(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, documentFieldName?: string, documentFieldValue?: string) { find(selectedNode: SelectedNode, collectionName: CollectionsEnum, documentFieldName?: string, documentFieldValue?: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (!selectedNode || !selectedNode.index) { if (!selectedNode || !selectedNode.index) {
@ -189,7 +189,7 @@ export class DatabaseService {
}); });
} }
remove(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum, documentFieldName: string, documentFieldValue: string) { remove(selectedNode: SelectedNode, collectionName: CollectionsEnum, documentFieldName: string, documentFieldValue: string) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
if (!selectedNode || !selectedNode.index) { if (!selectedNode || !selectedNode.index) {
@ -209,7 +209,7 @@ export class DatabaseService {
}); });
} }
saveDatabase(selectedNode: CommonSelectedNode, collectionName: CollectionsEnum) { saveDatabase(selectedNode: SelectedNode, collectionName: CollectionsEnum) {
const nodeIndex = +selectedNode.index; const nodeIndex = +selectedNode.index;
try { try {
if (nodeIndex < 1) { if (nodeIndex < 1) {
@ -250,17 +250,17 @@ export class DatabaseAdapter {
private dbFilePath = ''; private dbFilePath = '';
private userSessions = []; private userSessions = [];
constructor(public dbDirectoryPath: string, public selNode: CommonSelectedNode = null, public id: string = '') { constructor(public dbDirectoryPath: string, public selNode: SelectedNode = null, public id: string = '') {
this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index; this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index;
// For backward compatibility Start // For backward compatibility Start
const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json'; const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json';
if (selNode.ln_implementation === 'CLN' && fs.existsSync(oldFilePath)) { this.renameOldDB(oldFilePath, selNode); } if (selNode.lnImplementation === 'CLN' && fs.existsSync(oldFilePath)) { this.renameOldDB(oldFilePath, selNode); }
// For backward compatibility End // For backward compatibility End
this.insertSession(id); this.insertSession(id);
} }
renameOldDB(oldFilePath: string, selNode: CommonSelectedNode = null) { renameOldDB(oldFilePath: string, selNode: SelectedNode = null) {
const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.ln_implementation + '-Offers.json'; const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.lnImplementation + '-Offers.json';
try { try {
this.common.createDirectory(this.dbFilePath); this.common.createDirectory(this.dbFilePath);
const oldOffers: any = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8')); const oldOffers: any = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8'));
@ -279,7 +279,7 @@ export class DatabaseAdapter {
} catch (err) { } catch (err) {
throw new Error(JSON.stringify(err)); throw new Error(JSON.stringify(err));
} }
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
try { try {
if (!fs.existsSync(collectionFilePath)) { if (!fs.existsSync(collectionFilePath)) {
fs.writeFileSync(collectionFilePath, '[]'); fs.writeFileSync(collectionFilePath, '[]');
@ -291,17 +291,17 @@ export class DatabaseAdapter {
const otherFiles = fs.readdirSync(this.dbFilePath); const otherFiles = fs.readdirSync(this.dbFilePath);
otherFiles.forEach((oFileName) => { otherFiles.forEach((oFileName) => {
let collectionValid = false; let collectionValid = false;
switch (this.selNode.ln_implementation) { switch (this.selNode.lnImplementation) {
case 'CLN': case 'CLN':
collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
case 'ECL': case 'ECL':
collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
default: default:
collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false); collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
break; break;
} }
if (oFileName.endsWith('.json') && !collectionValid) { if (oFileName.endsWith('.json') && !collectionValid) {
@ -327,7 +327,7 @@ export class DatabaseAdapter {
saveData(collectionName: string, collectionData: any) { saveData(collectionName: string, collectionData: any) {
try { try {
if (collectionData) { if (collectionData) {
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json'; const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
const tempFile = collectionFilePath + '.tmp'; const tempFile = collectionFilePath + '.tmp';
fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2)); fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2));
fs.renameSync(tempFile, collectionFilePath); fs.renameSync(tempFile, collectionFilePath);

@ -17,16 +17,16 @@ export class LoggerService {
msgStr = msgStr + '.\r\n'; msgStr = msgStr + '.\r\n';
} }
console.error(msgStr); console.error(msgStr);
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
break; break;
case 'WARN': case 'WARN':
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
if (!msgJSON.selectedNode || msgJSON.selectedNode.log_level === 'WARN' || msgJSON.selectedNode.log_level === 'INFO' || msgJSON.selectedNode.log_level === 'DEBUG') { if (!msgJSON.selectedNode || msgJSON.selectedNode.settings.logLevel === 'WARN' || msgJSON.selectedNode.settings.logLevel === 'INFO' || msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;
@ -34,17 +34,17 @@ export class LoggerService {
case 'INFO': case 'INFO':
if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') { if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') {
console.log(msgStr + '.\r\n'); console.log(msgStr + '.\r\n');
} else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'INFO') { } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'INFO') {
msgStr = msgStr + '.\r\n'; msgStr = msgStr + '.\r\n';
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;
@ -52,11 +52,11 @@ export class LoggerService {
case 'DEBUG': case 'DEBUG':
if (!msgJSON.selectedNode) { if (!msgJSON.selectedNode) {
console.log(msgStr + '.\r\n'); console.log(msgStr + '.\r\n');
} else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') { } else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
msgStr = prepMsgData(msgJSON, msgStr); msgStr = prepMsgData(msgJSON, msgStr);
console.log(msgStr); console.log(msgStr);
if (msgJSON.selectedNode.log_file) { if (msgJSON.selectedNode.settings.logFile) {
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { }); fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
} }
} }
break; break;

@ -6,7 +6,7 @@ import { Logger, LoggerService } from './logger.js';
import { Common, CommonService } from './common.js'; import { Common, CommonService } from './common.js';
import { verifyWSUser } from './authCheck.js'; import { verifyWSUser } from './authCheck.js';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { CommonSelectedNode } from '../models/config.model.js'; import { SelectedNode } from '../models/config.model.js';
export class RTLWebSocketServer { export class RTLWebSocketServer {
@ -32,7 +32,7 @@ export class RTLWebSocketServer {
}, 1000 * 60 * 60); // Terminate broken connections every hour }, 1000 * 60 * 60); // Terminate broken connections every hour
public mount = (httpServer) => { public mount = (httpServer) => {
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' }); this.logger.log({ selectedNode: this.common.selectedNode, 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) => {
if (request.headers['upgrade'] !== 'websocket') { if (request.headers['upgrade'] !== 'websocket') {
@ -48,7 +48,7 @@ export class RTLWebSocketServer {
}); });
this.webSocketServer.on('connection', this.mountEventsOnConnection); this.webSocketServer.on('connection', this.mountEventsOnConnection);
this.webSocketServer.on('close', () => clearInterval(this.pingInterval)); this.webSocketServer.on('close', () => clearInterval(this.pingInterval));
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' });
}; };
public upgradeCallback = (websocket, request) => { public upgradeCallback = (websocket, request) => {
@ -62,13 +62,13 @@ export class RTLWebSocketServer {
websocket.isAlive = true; websocket.isAlive = true;
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null; websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
websocket.clientNodeIndex = +protocols[1]; websocket.clientNodeIndex = +protocols[1];
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
websocket.on('error', this.sendErrorToAllLNClients); websocket.on('error', this.sendErrorToAllLNClients);
websocket.on('message', this.sendEventsToAllLNClients); websocket.on('message', this.sendEventsToAllLNClients);
websocket.on('pong', () => { websocket.isAlive = true; }); websocket.on('pong', () => { websocket.isAlive = true; });
websocket.on('close', (code, reason) => { websocket.on('close', (code, reason) => {
this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex); this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex);
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size }); this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
}); });
}; };
@ -87,7 +87,7 @@ export class RTLWebSocketServer {
this.connectToNodeClient(sessionId, currNodeIndex); this.connectToNodeClient(sessionId, currNodeIndex);
} else { } else {
const selectedNode = this.common.findNode(currNodeIndex); const selectedNode = this.common.findNode(currNodeIndex);
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' });
} }
}; };
@ -102,8 +102,8 @@ export class RTLWebSocketServer {
const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex); const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex);
this.clientDetails.splice(foundClientIdx, 1); this.clientDetails.splice(foundClientIdx, 1);
const prevSelectedNode = this.common.findNode(prevNodeIndex); const prevSelectedNode = this.common.findNode(prevNodeIndex);
if (prevSelectedNode && prevSelectedNode.ln_implementation) { if (prevSelectedNode && prevSelectedNode.lnImplementation) {
switch (prevSelectedNode.ln_implementation) { switch (prevSelectedNode.lnImplementation) {
case 'LND': case 'LND':
this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex); this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex);
break; break;
@ -132,8 +132,8 @@ export class RTLWebSocketServer {
const currSelectedNode = this.common.findNode(currNodeIndex); const currSelectedNode = this.common.findNode(currNodeIndex);
foundClient = { index: currNodeIndex, sessionIds: [sessionId] }; foundClient = { index: currNodeIndex, sessionIds: [sessionId] };
this.clientDetails.push(foundClient); this.clientDetails.push(foundClient);
if (currSelectedNode && currSelectedNode.ln_implementation) { if (currSelectedNode && currSelectedNode.lnImplementation) {
switch (currSelectedNode.ln_implementation) { switch (currSelectedNode.lnImplementation) {
case 'LND': case 'LND':
this.eventEmitterLND.emit('CONNECT', currNodeIndex); this.eventEmitterLND.emit('CONNECT', currNodeIndex);
break; break;
@ -150,29 +150,29 @@ export class RTLWebSocketServer {
} }
}; };
public sendErrorToAllLNClients = (serverError, selectedNode: CommonSelectedNode) => { public sendErrorToAllLNClients = (serverError, selectedNode: SelectedNode) => {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError });
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
client.send(serverError); client.send(serverError);
} }
}); });
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
} }
}; };
public sendEventsToAllLNClients = (newMessage, selectedNode: CommonSelectedNode) => { public sendEventsToAllLNClients = (newMessage, selectedNode: SelectedNode) => {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
client.send(newMessage); client.send(newMessage);
} }
}); });
} catch (err) { } catch (err) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) }); this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
} }
}; };

Loading…
Cancel
Save