2021-12-29 18:08:41 -05:00
|
|
|
import request from 'request-promise';
|
|
|
|
import { Logger } from '../../utils/logger.js';
|
|
|
|
import { Common } from '../../utils/common.js';
|
|
|
|
let options = null;
|
|
|
|
const logger = Logger;
|
|
|
|
const common = Common;
|
|
|
|
let pendingInvoices = [];
|
|
|
|
export const getReceivedPaymentInfo = (lnServerUrl, invoice) => {
|
|
|
|
let idx = -1;
|
|
|
|
invoice.expiresAt = (!invoice.expiry) ? null : (+invoice.timestamp + +invoice.expiry);
|
|
|
|
if (invoice.amount) {
|
|
|
|
invoice.amount = Math.round(invoice.amount / 1000);
|
|
|
|
}
|
|
|
|
idx = pendingInvoices.findIndex((pendingInvoice) => invoice.serialized === pendingInvoice.serialized);
|
|
|
|
if (idx < 0) {
|
|
|
|
options.url = lnServerUrl + '/getreceivedinfo';
|
|
|
|
options.form = { paymentHash: invoice.paymentHash };
|
|
|
|
return request(options).then((response) => {
|
|
|
|
invoice.status = response.status.type;
|
|
|
|
if (response.status && response.status.type === 'received') {
|
|
|
|
invoice.amountSettled = response.status.amount ? Math.round(response.status.amount / 1000) : 0;
|
2023-04-25 22:04:29 -07:00
|
|
|
invoice.receivedAt = response.status.receivedAt.unix ? response.status.receivedAt.unix : 0;
|
2021-12-29 18:08:41 -05:00
|
|
|
}
|
|
|
|
return invoice;
|
|
|
|
}).catch((err) => {
|
|
|
|
invoice.status = 'unknown';
|
|
|
|
return invoice;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pendingInvoices.splice(idx, 1);
|
|
|
|
invoice.status = 'unpaid';
|
|
|
|
return invoice;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
export const getInvoice = (req, res, next) => {
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' });
|
|
|
|
options = common.getOptions(req);
|
|
|
|
if (options.error) {
|
|
|
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice';
|
2021-12-29 18:08:41 -05:00
|
|
|
options.form = { paymentHash: req.params.paymentHash };
|
|
|
|
request.post(options).then((body) => {
|
2022-01-16 15:55:50 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
|
2021-12-29 18:08:41 -05:00
|
|
|
const current_time = (Math.round(new Date(Date.now()).getTime() / 1000));
|
|
|
|
body.amount = body.amount ? body.amount / 1000 : 0;
|
|
|
|
body.expiresAt = body.expiresAt ? body.expiresAt : (body.timestamp + body.expiry);
|
|
|
|
body.status = body.status ? body.status : (+body.expiresAt < current_time ? 'expired' : 'unknown');
|
|
|
|
res.status(200).json(body);
|
|
|
|
}).catch((errRes) => {
|
|
|
|
const err = common.handleError(errRes, 'Invoices', 'Get Invoice Error', req.session.selectedNode);
|
|
|
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
|
|
|
});
|
|
|
|
};
|
2024-06-10 12:40:37 -07:00
|
|
|
export const listPendingInvoicesRequestCall = (selectedNode, count, skip) => {
|
2023-04-25 22:04:29 -07:00
|
|
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
|
2024-06-10 12:40:37 -07:00
|
|
|
options = selectedNode.authentication.options;
|
|
|
|
options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
2023-04-25 22:04:29 -07:00
|
|
|
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
|
2024-06-10 12:40:37 -07:00
|
|
|
// Limit the number of invoices till provided count
|
|
|
|
if (count) {
|
|
|
|
options.form.count = count;
|
|
|
|
}
|
|
|
|
if (skip) {
|
|
|
|
options.form.skip = skip;
|
|
|
|
}
|
2023-04-25 22:04:29 -07:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
request.post(options).then((pendingInvoicesResponse) => {
|
|
|
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
|
|
|
|
resolve(pendingInvoicesResponse);
|
|
|
|
}).catch((errRes) => {
|
|
|
|
reject(common.handleError(errRes, 'Invoices', 'List Pending Invoices Error', selectedNode));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2021-12-29 18:08:41 -05:00
|
|
|
export const listInvoices = (req, res, next) => {
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting List Invoices..' });
|
|
|
|
options = common.getOptions(req);
|
|
|
|
if (options.error) {
|
|
|
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
|
|
|
}
|
2022-12-15 14:06:56 -08:00
|
|
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
2021-12-29 18:08:41 -05:00
|
|
|
const options1 = JSON.parse(JSON.stringify(options));
|
2024-06-10 12:40:37 -07:00
|
|
|
options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
|
2022-12-15 14:06:56 -08:00
|
|
|
options1.form = { from: 0, to: tillToday };
|
2024-06-10 12:40:37 -07:00
|
|
|
if (req.query.count) {
|
|
|
|
options1.form.count = req.query.count;
|
|
|
|
}
|
|
|
|
if (req.query.skip) {
|
|
|
|
options1.form.skip = req.query.skip;
|
|
|
|
}
|
2021-12-29 18:08:41 -05:00
|
|
|
const options2 = JSON.parse(JSON.stringify(options));
|
2024-06-10 12:40:37 -07:00
|
|
|
options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
2022-12-15 14:06:56 -08:00
|
|
|
options2.form = { from: 0, to: tillToday };
|
2021-12-29 18:08:41 -05:00
|
|
|
if (common.read_dummy_data) {
|
2024-06-10 12:40:37 -07:00
|
|
|
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then(([invoices, pendingInvoicesRes]) => {
|
|
|
|
pendingInvoices = pendingInvoicesRes;
|
|
|
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
2022-10-20 14:51:06 -07:00
|
|
|
then((values) => res.status(200).json(invoices));
|
2021-12-29 18:08:41 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Promise.all([request(options1), request(options2)]).
|
2024-06-10 12:40:37 -07:00
|
|
|
then(([invoices, pendingInvoicesRes]) => {
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: invoices });
|
|
|
|
// pendingInvoices will be used to get the status (paid/unpaid) of the invoice via getReceivedPaymentInfo
|
|
|
|
pendingInvoices = pendingInvoicesRes;
|
2021-12-29 18:08:41 -05:00
|
|
|
if (invoices && invoices.length > 0) {
|
2024-06-10 12:40:37 -07:00
|
|
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
2021-12-29 18:08:41 -05:00
|
|
|
then((values) => {
|
2022-01-16 15:55:50 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });
|
2021-12-29 18:08:41 -05:00
|
|
|
return res.status(200).json(invoices);
|
|
|
|
}).
|
|
|
|
catch((errRes) => {
|
|
|
|
const err = common.handleError(errRes, 'Invoices', 'List Invoices Error', req.session.selectedNode);
|
|
|
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Empty List Invoice Received' });
|
|
|
|
return res.status(200).json([]);
|
|
|
|
}
|
|
|
|
}).
|
|
|
|
catch((errRes) => {
|
|
|
|
const err = common.handleError(errRes, 'Invoices', 'List Invoices Error', req.session.selectedNode);
|
|
|
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
2023-04-25 22:04:29 -07:00
|
|
|
export const createInvoiceRequestCall = (selectedNode, description, amount) => {
|
|
|
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
2024-06-10 12:40:37 -07:00
|
|
|
options = selectedNode.authentication.options;
|
|
|
|
options.url = selectedNode.settings.lnServerUrl + '/createinvoice';
|
2023-04-25 22:04:29 -07:00
|
|
|
options.form = { description: description, amountMsat: amount };
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
request.post(options).then((invResponse) => {
|
|
|
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: invResponse });
|
|
|
|
if (invResponse.amount) {
|
|
|
|
invResponse.amount = Math.round(invResponse.amount / 1000);
|
|
|
|
}
|
|
|
|
resolve(invResponse);
|
|
|
|
}).catch((errRes) => {
|
|
|
|
reject(common.handleError(errRes, 'Invoices', 'Create Invoice Error', selectedNode));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2021-12-29 18:08:41 -05:00
|
|
|
export const createInvoice = (req, res, next) => {
|
2024-06-10 12:40:37 -07:00
|
|
|
const { description, amountMsat } = req.body;
|
2021-12-29 18:08:41 -05:00
|
|
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
|
|
|
options = common.getOptions(req);
|
|
|
|
if (options.error) {
|
|
|
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
|
|
|
}
|
2024-06-10 12:40:37 -07:00
|
|
|
createInvoiceRequestCall(req.session.selectedNode, description, amountMsat).then((invRes) => {
|
2023-04-25 22:04:29 -07:00
|
|
|
res.status(201).json(invRes);
|
2023-05-02 17:34:41 -07:00
|
|
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
2021-12-29 18:08:41 -05:00
|
|
|
};
|