OnChain & Payments

OnChain & Payments
pull/209/head
Shahana Farooqui 5 years ago
parent e3668d2a37
commit fd18fc5dca

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -9,5 +9,5 @@
<link rel="stylesheet" href="styles.13a9674cdbdfd014a4cf.css"></head> <link rel="stylesheet" href="styles.13a9674cdbdfd014a4cf.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.57ae245e3c265cd0936f.js"></script><script src="polyfills-es5.763f4f23e8aee5ec234d.js" nomodule></script><script src="polyfills.e59b6f9dc696bd89cf7f.js"></script><script src="main.13ed415c7cb3709d892b.js"></script></body> <script src="runtime.80b102e4a415b9aef63b.js"></script><script src="polyfills-es5.763f4f23e8aee5ec234d.js" nomodule></script><script src="polyfills.e59b6f9dc696bd89cf7f.js"></script><script src="main.3ea4143bd4b1f1240f56.js"></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],p=0,s=[];p<a.length;p++)o[i=a[p]]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++)0!==o[t[a]]&&(n=!1);n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={0:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise(function(r,n){t=o[e]=[r,n]});r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+""+({}[e]||e)+"."+{1:"54859a9ed4dbe675e082",6:"10cd8607c932f8229120",7:"2becbc02aff346bd8d1e"}[e]+".js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout(function(){u({type:"timeout",target:a})},12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,(function(r){return e[r]}).bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="",i.oe=function(e){throw console.error(e),e};var a=window.webpackJsonp=window.webpackJsonp||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([]); !function(e){function r(r){for(var n,i,a=r[0],c=r[1],f=r[2],p=0,s=[];p<a.length;p++)o[i=a[p]]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++)0!==o[t[a]]&&(n=!1);n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={0:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise(function(r,n){t=o[e]=[r,n]});r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+""+({}[e]||e)+"."+{1:"54859a9ed4dbe675e082",6:"ce8707b220b01fc9d2e2",7:"0664e0a31cfe902f29cf"}[e]+".js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout(function(){u({type:"timeout",target:a})},12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,(function(r){return e[r]}).bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="",i.oe=function(e){throw console.error(e),e};var a=window.webpackJsonp=window.webpackJsonp||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var f=0;f<a.length;f++)r(a[f]);var l=c;t()}([]);

@ -31,13 +31,10 @@ const feesCLRoutes = require("./routes/c-lightning/fees");
const balanceCLRoutes = require("./routes/c-lightning/balance"); const balanceCLRoutes = require("./routes/c-lightning/balance");
const channelsCLRoutes = require("./routes/c-lightning/channels"); const channelsCLRoutes = require("./routes/c-lightning/channels");
const invoicesCLRoutes = require("./routes/c-lightning/invoices"); const invoicesCLRoutes = require("./routes/c-lightning/invoices");
const newAddressCLRoutes = require("./routes/c-lightning/newAddress"); const onChainCLRoutes = require("./routes/c-lightning/onchain");
const paymentsCLRoutes = require("./routes/c-lightning/payments"); const paymentsCLRoutes = require("./routes/c-lightning/payments");
const payReqCLRoutes = require("./routes/c-lightning/payReq");
const peersCLRoutes = require("./routes/c-lightning/peers"); const peersCLRoutes = require("./routes/c-lightning/peers");
const switchCLRoutes = require("./routes/c-lightning/switch"); const networkCLRoutes = require("./routes/c-lightning/network");
const transactionsCLRoutes = require("./routes/c-lightning/transactions");
const walletCLRoutes = require("./routes/c-lightning/wallet");
app.use(cookieParser(common.secret_key)); app.use(cookieParser(common.secret_key));
app.use(bodyParser.json()); app.use(bodyParser.json());
@ -81,13 +78,10 @@ app.use(apiCLRoot + "fees", feesCLRoutes);
app.use(apiCLRoot + "balance", balanceCLRoutes); app.use(apiCLRoot + "balance", balanceCLRoutes);
app.use(apiCLRoot + "channels", channelsCLRoutes); app.use(apiCLRoot + "channels", channelsCLRoutes);
app.use(apiCLRoot + "invoices", invoicesCLRoutes); app.use(apiCLRoot + "invoices", invoicesCLRoutes);
app.use(apiCLRoot + "newaddress", newAddressCLRoutes); app.use(apiCLRoot + "onchain", onChainCLRoutes);
app.use(apiCLRoot + "payments", paymentsCLRoutes); app.use(apiCLRoot + "payments", paymentsCLRoutes);
app.use(apiCLRoot + "payreq", payReqCLRoutes);
app.use(apiCLRoot + "peers", peersCLRoutes); app.use(apiCLRoot + "peers", peersCLRoutes);
app.use(apiCLRoot + "switch", switchCLRoutes); app.use(apiCLRoot + "network", networkCLRoutes);
app.use(apiCLRoot + "transactions", transactionsCLRoutes);
app.use(apiCLRoot + "wallet", walletCLRoutes);
app.use((req, res, next) => { app.use((req, res, next) => {
res.sendFile(path.join(__dirname, "angular", "index.html")); res.sendFile(path.join(__dirname, "angular", "index.html"));

@ -31,3 +31,50 @@ exports.getLocalRemoteBalance = (req, res, next) => {
}); });
}); });
}; };
exports.forwardingHistory = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/switch';
options.form = {};
if (undefined !== req.body.num_max_events) {
options.form.num_max_events = req.body.num_max_events;
}
if (undefined !== req.body.index_offset) {
options.form.index_offset = req.body.index_offset;
}
if (undefined !== req.body.end_time) {
options.form.end_time = req.body.end_time;
}
if (undefined !== req.body.start_time) {
options.form.start_time = req.body.start_time;
}
options.form = JSON.stringify(options.form);
logger.info({fileName: 'Switch', msg: 'Switch Post Options: ' + JSON.stringify(options)});
request.post(options).then((body) => {
logger.info({fileName: 'Switch', msg: 'Switch Post Response: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
logger.error({fileName: 'Switch', lineNum: 27, msg: 'Switch Post Erroe: ' + JSON.stringify((undefined === body) ? 'Error From Server!' : body.error)});
res.status(500).json({
message: "Switch post failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
if (undefined !== body.forwarding_events) {
body.forwarding_events.forEach(event => {
event.timestamp_str = (undefined === event.timestamp) ? '' : common.convertTimestampToDate(event.timestamp);
});
body.forwarding_events = common.sortDescByKey(body.forwarding_events, 'timestamp');
}
logger.info({fileName: 'Switch', msg: 'Forwarding History Received: ' + JSON.stringify(body)});
res.status(201).json(body);
}
})
.catch(function (err) {
logger.error({fileName: 'Switch', lineNum: 44, msg: 'Switch Post Error: ' + JSON.stringify(err)});
return res.status(500).json({
message: "Switch post failed!",
error: err.error
});
});
};

@ -0,0 +1,73 @@
var request = require('request-promise');
var common = require('../../common');
var logger = require('../logger');
var options = {};
exports.getRoute = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/network/getRoute/' + req.params.destPubkey + '/' + req.params.amount;
request(options).then((body) => {
logger.info({fileName: 'Network', msg: 'Query Routes Received: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
res.status(500).json({
message: "Fetching Query Routes Failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
}
res.status(200).json({routes: body});
})
.catch((err) => {
return res.status(500).json({
message: "Fetching Query Routes Failed!",
error: err.error
});
});
};
exports.listNode = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/peer/listPeers';
request(options).then(function (body) {
let peers = (undefined !== body) ? common.sortDescByKey(body, 'alias') : [];
logger.info({fileName: 'Peers', msg: 'Peers with Alias: ' + JSON.stringify(peers)});
res.status(200).json(peers);
})
.catch((err) => {
return res.status(500).json({
message: "Peers Fetch Failed!",
error: err.error
});
});
};
exports.listChannel = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/peer/listPeers';
request(options).then(function (body) {
let peers = (undefined !== body) ? common.sortDescByKey(body, 'alias') : [];
logger.info({fileName: 'Peers', msg: 'Peers with Alias: ' + JSON.stringify(peers)});
res.status(200).json(peers);
})
.catch((err) => {
return res.status(500).json({
message: "Peers Fetch Failed!",
error: err.error
});
});
};
exports.feeRates = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/peer/listPeers';
request(options).then(function (body) {
let peers = (undefined !== body) ? common.sortDescByKey(body, 'alias') : [];
logger.info({fileName: 'Peers', msg: 'Peers with Alias: ' + JSON.stringify(peers)});
res.status(200).json(peers);
})
.catch((err) => {
return res.status(500).json({
message: "Peers Fetch Failed!",
error: err.error
});
});
};

@ -1,30 +0,0 @@
var request = require('request-promise');
var common = require('../../common');
var logger = require('../logger');
var options = {};
exports.decodePayment = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/payreq/' + req.params.payRequest;
request(options).then((body) => {
const body_str = (undefined === body) ? '' : JSON.stringify(body);
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found');
logger.info({fileName: 'PayReq', msg: 'Payment Decodd Received: ' + body_str});
if(undefined === body || search_idx > -1 || body.error) {
res.status(500).json({
message: "Payment Request Decode Failed!",
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
body.btc_num_satoshis = (undefined === body.num_satoshis) ? 0 : common.convertToBTC(body.num_satoshis);
body.timestamp_str = (undefined === body.timestamp) ? '' : common.convertTimestampToDate(body.timestamp);
res.status(200).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Payment Request Decode Failed!",
error: err.error
});
});
};

@ -3,24 +3,22 @@ var common = require('../../common');
var logger = require('../logger'); var logger = require('../logger');
var options = {}; var options = {};
exports.getPayments = (req, res, next) => { exports.listPayments = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/payments'; options.url = common.getSelLNServerUrl() + '/pay/listPayments';
request(options).then((body) => { request(options).then((body) => {
const body_str = (undefined === body) ? '' : JSON.stringify(body); logger.info({fileName: 'Payments', msg: 'Payment List Received: ' + JSON.stringify(body.payments)});
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found'); if(undefined === body || body.error) {
logger.info({fileName: 'Payments', msg: 'Payment Decoded Received: ' + body_str});
if(undefined === body || search_idx > -1 || body.error) {
res.status(500).json({ res.status(500).json({
message: "Payments List Failed!", message: "Payments List Failed!",
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error error: (undefined === body) ? 'Error From Server!' : body.error
}); });
} else { } else {
if (undefined !== body.payments) { if (undefined !== body && undefined !== body.payments) {
body.payments.forEach(payment => { body.payments.forEach(payment => {
payment.creation_date_str = (undefined === payment.creation_date) ? '' : common.convertTimestampToDate(payment.creation_date); payment.created_at_str = (undefined === payment.created_at) ? '' : common.convertTimestampToDate(payment.created_at);
}); });
body.payments = common.sortDescByKey(body.payments, 'creation_date'); body.payments = common.sortDescByKey(body.payments, 'created_at');
} }
res.status(200).json(body.payments); res.status(200).json(body.payments);
} }
@ -32,3 +30,60 @@ exports.getPayments = (req, res, next) => {
}); });
}); });
}; };
exports.decodePayment = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/pay/decodePay/' + req.params.invoice;
request(options).then((body) => {
logger.info({fileName: 'Payments', msg: 'Payment Decode Received: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
res.status(500).json({
message: "Payment Request Decode Failed!",
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
// body.btc_num_satoshis = (undefined === body.num_satoshis) ? 0 : common.convertToBTC(body.num_satoshis);
// body.timestamp_str = (undefined === body.timestamp) ? '' : common.convertTimestampToDate(body.timestamp);
res.status(200).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Payment Request Decode Failed!",
error: err.error
});
});
};
exports.postPayment = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/pay';
options.body = req.body;
// options.body = {
// amount: req.body.amount,
// addr: req.body.address,
// sat_per_byte: req.body.fees,
// target_conf: req.body.blocks
// };
// if (req.body.sendAll) {
// options.form.send_all = req.body.sendAll;
// }
// options.form = JSON.stringify(options.form);
request.post(options).then((body) => {
logger.info({fileName: 'Payments', msg: 'Payment Post Response: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
res.status(500).json({
message: "Payment post failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
res.status(201).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Payment post failed!",
error: err.error
});
});
};

@ -1,50 +0,0 @@
var request = require('request-promise');
var common = require('../../common');
var logger = require('../logger');
var options = {};
exports.forwardingHistory = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/switch';
options.form = {};
if (undefined !== req.body.num_max_events) {
options.form.num_max_events = req.body.num_max_events;
}
if (undefined !== req.body.index_offset) {
options.form.index_offset = req.body.index_offset;
}
if (undefined !== req.body.end_time) {
options.form.end_time = req.body.end_time;
}
if (undefined !== req.body.start_time) {
options.form.start_time = req.body.start_time;
}
options.form = JSON.stringify(options.form);
logger.info({fileName: 'Switch', msg: 'Switch Post Options: ' + JSON.stringify(options)});
request.post(options).then((body) => {
logger.info({fileName: 'Switch', msg: 'Switch Post Response: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
logger.error({fileName: 'Switch', lineNum: 27, msg: 'Switch Post Erroe: ' + JSON.stringify((undefined === body) ? 'Error From Server!' : body.error)});
res.status(500).json({
message: "Switch post failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
if (undefined !== body.forwarding_events) {
body.forwarding_events.forEach(event => {
event.timestamp_str = (undefined === event.timestamp) ? '' : common.convertTimestampToDate(event.timestamp);
});
body.forwarding_events = common.sortDescByKey(body.forwarding_events, 'timestamp');
}
logger.info({fileName: 'Switch', msg: 'Forwarding History Received: ' + JSON.stringify(body)});
res.status(201).json(body);
}
})
.catch(function (err) {
logger.error({fileName: 'Switch', lineNum: 44, msg: 'Switch Post Error: ' + JSON.stringify(err)});
return res.status(500).json({
message: "Switch post failed!",
error: err.error
});
});
};

@ -1,66 +0,0 @@
var request = require('request-promise');
var common = require('../../common');
var logger = require('../logger');
var options = {};
exports.getTransactions = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/transactions';
request(options).then((body) => {
const body_str = (undefined === body) ? '' : JSON.stringify(body);
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found');
logger.info({fileName: 'Transactions', msg: 'Transaction Received: ' + body_str});
if(undefined === body || search_idx > -1 || body.error) {
res.status(500).json({
message: "Fetching Transactions Failed!",
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
if (undefined !== body.transactions) {
body.transactions.forEach(transaction => {
transaction.time_stamp_str = (undefined === transaction.time_stamp) ? '' : common.convertTimestampToDate(transaction.time_stamp);
});
body.transactions = common.sortDescByKey(body.transactions, 'time_stamp');
}
res.status(200).json(body.transactions);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Fetching Transactions Failed!",
error: err.error
});
});
};
exports.postTransactions = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/transactions';
options.form = {
amount: req.body.amount,
addr: req.body.address,
sat_per_byte: req.body.fees,
target_conf: req.body.blocks
};
if (req.body.sendAll) {
options.form.send_all = req.body.sendAll;
}
options.form = JSON.stringify(options.form);
request.post(options).then((body) => {
logger.info({fileName: 'Transactions', msg: 'Transaction Post Response: ' + JSON.stringify(body)});
if(undefined === body || body.error) {
res.status(500).json({
message: "Transactions post failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
res.status(201).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Transactions post failed!",
error: err.error
});
});
};

@ -1,93 +0,0 @@
var request = require('request-promise');
var common = require('../../common');
var atob = require('atob');
var logger = require('../logger');
var options = {};
exports.genSeed = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/genseed';
if (undefined !== req.params.passphrase) {
options.form = JSON.stringify({aezeed_passphrase: atob(req.params.passphrase)});
}
request(options).then((body) => {
if(undefined === body || body.error) {
res.status(500).json({
message: "Genseed failed!",
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
res.status(200).json(body);
}
})
.catch(function (err) {
return res.status(500).json({
message: "Genseed failed!",
error: err.error
});
});
}
exports.operateWallet = (req, res, next) => {
options = common.getOptions();
options.method = 'POST';
if (undefined === req.params.operation || req.params.operation === 'unlockwallet') {
options.url = common.getSelLNServerUrl() + '/unlockwallet';
options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64')
});
err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!';
} else {
options.url = common.getSelLNServerUrl() + '/initwallet';
if (undefined !== req.body.aezeed_passphrase && req.body.aezeed_passphrase !== '') {
options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic,
aezeed_passphrase: Buffer.from(atob(req.body.aezeed_passphrase)).toString('base64')
});
} else {
options.form = JSON.stringify({
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic
});
}
err_message = 'Initializing wallet failed!';
}
request(options).then((body) => {
logger.info({fileName: 'Wallet', msg: 'Wallet Response: ' + JSON.stringify(body)});
const body_str = (undefined === body) ? '' : JSON.stringify(body);
const search_idx = (undefined === body) ? -1 : body_str.search('Not Found');
if(undefined === body) {
res.status(500).json({
message: err_message,
error: (error) ? error : err_message
});
} else if(search_idx > -1) {
res.status(500).json({
message: err_message,
error: err_message
});
} else if(body.error) {
if((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) {
res.status(201).json('Successful');
} else {
res.status(500).json({
message: err_message,
error: body.error
});
}
} else {
res.status(201).json('Successful');
}
}).catch(error => {
logger.error({fileName: 'Wallet', lineNum: 83, msg: 'Wallet Response: ' + JSON.stringify(error.error)});
if((error.error.code === 1 && error.error.error === 'context canceled') || (error.error.code === 14 && error.error.error === 'transport is closing')) {
res.status(201).json('Successful');
} else {
res.status(500).json({
message: err_message,
error: error.message
});
}
});
};

@ -4,5 +4,6 @@ const router = express.Router();
const authCheck = require("../authCheck"); const authCheck = require("../authCheck");
router.get("/localremotebalance", authCheck, ChannelsController.getLocalRemoteBalance); router.get("/localremotebalance", authCheck, ChannelsController.getLocalRemoteBalance);
router.post("/", authCheck, ChannelsController.forwardingHistory);
module.exports = router; module.exports = router;

@ -0,0 +1,11 @@
const NetworkController = require("../../controllers/c-lightning/network");
const express = require("express");
const router = express.Router();
const authCheck = require("../authCheck");
router.get("/getRoute/:destPubkey/:amount", authCheck, NetworkController.getRoute);
router.get("/listNode", authCheck, NetworkController.listNode);
router.get("/listChannel", authCheck, NetworkController.listChannel);
router.get("/feeRates", authCheck, NetworkController.feeRates);
module.exports = router;

@ -1,8 +0,0 @@
const NewAddressController = require("../../controllers/c-lightning/newAddress");
const express = require("express");
const router = express.Router();
const authCheck = require("../authCheck");
router.get("/", authCheck, NewAddressController.getNewAddress);
module.exports = router;

@ -1,8 +1,8 @@
const SwitchController = require("../../controllers/c-lightning/switch"); const OnChainController = require("../../controllers/c-lightning/onchain");
const express = require("express"); const express = require("express");
const router = express.Router(); const router = express.Router();
const authCheck = require("../authCheck"); const authCheck = require("../authCheck");
router.post("/", authCheck, SwitchController.forwardingHistory); router.get("/", authCheck, OnChainController.getNewAddress);
module.exports = router; module.exports = router;

@ -1,8 +0,0 @@
const PayRequestController = require("../../controllers/c-lightning/payReq");
const express = require("express");
const router = express.Router();
const authCheck = require("../authCheck");
router.get("/:payRequest", authCheck, PayRequestController.decodePayment);
module.exports = router;

@ -3,6 +3,8 @@ const express = require("express");
const router = express.Router(); const router = express.Router();
const authCheck = require("../authCheck"); const authCheck = require("../authCheck");
router.get("/", authCheck, PaymentsController.getPayments); router.get("/", authCheck, PaymentsController.listPayments);
router.get("/:invoice", authCheck, PaymentsController.decodePayment);
router.post("/", authCheck, PaymentsController.postPayment);
module.exports = router; module.exports = router;

@ -1,9 +0,0 @@
const TransactionsController = require("../../controllers/c-lightning/transactions");
const express = require("express");
const router = express.Router();
const authCheck = require("../authCheck");
router.get("/", authCheck, TransactionsController.getTransactions);
router.post("/", authCheck, TransactionsController.postTransactions);
module.exports = router;

@ -1,9 +0,0 @@
const WalletController = require("../../controllers/c-lightning/wallet");
const express = require("express");
const router = express.Router();
const authCheck = require("../authCheck");
router.get("/genseed/:passphrase?", authCheck, WalletController.genSeed);
router.post("/:operation", authCheck, WalletController.operateWallet);
module.exports = router;

@ -1,80 +1,84 @@
<!-- <div fxLayout="column"> <div fxLayout="column">
<div class="padding-gap"> <div class="padding-gap">
<mat-card> <mat-card>
<mat-card-header> <mat-card-header>
<mat-card-subtitle> <mat-card-subtitle>
<h2>Query Routes</h2> <h2>Query Routes</h2>
</mat-card-subtitle> </mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap" <form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap"
(ngSubmit)="queryRoutesForm.form.valid && onQueryRoutes()" #queryRoutesForm="ngForm"> (ngSubmit)="queryRoutesForm.form.valid && onQueryRoutes()" #queryRoutesForm="ngForm">
<mat-form-field fxFlex="50" fxLayoutAlign="start end"> <mat-form-field fxFlex="50" fxLayoutAlign="start end">
<input matInput placeholder="Destination Pubkey" name="destinationPubkey" [(ngModel)]="destinationPubkey" <input matInput placeholder="Destination Pubkey" name="destinationPubkey" [(ngModel)]="destinationPubkey"
tabindex="1" required #destPubkey="ngModel"> tabindex="1" required #destPubkey="ngModel">
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="20" fxLayoutAlign="start end"> <mat-form-field fxFlex="20" fxLayoutAlign="start end">
<input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number" <input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number"
step="1000" min="0" required #destAmount="ngModel"> step="1000" min="0" required #destAmount="ngModel">
</mat-form-field> </mat-form-field>
<div fxFlex="15" fxLayoutAlign="start start"> <div fxFlex="15" fxLayoutAlign="start start">
<button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="primary" <button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="destPubkey.invalid || destAmount.invalid" type="submit" tabindex="3"> [disabled]="destPubkey.invalid || destAmount.invalid" type="submit" tabindex="3">
<p *ngIf="(destPubkey.invalid && (destPubkey.dirty || destPubkey.touched) || (destAmount.invalid && (destAmount.dirty || destAmount.touched))); else queryText">Invalid Pubkey/Amount <p
</p> *ngIf="(destPubkey.invalid && (destPubkey.dirty || destPubkey.touched) || (destAmount.invalid && (destAmount.dirty || destAmount.touched))); else queryText">
<ng-template #queryText> Invalid Pubkey/Amount
<p>Query</p> </p>
</ng-template> <ng-template #queryText>
</button> <p>Query</p>
</div> </ng-template>
<div fxFlex="15" fxLayoutAlign="start start"> </button>
<button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="4" type="reset" </div>
(click)="resetData()">Clear</button> <div fxFlex="15" fxLayoutAlign="start start">
</div> <button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="accent" tabindex="4" type="reset"
</form> (click)="resetData()">Clear</button>
</mat-card-content> </div>
</mat-card> </form>
</div> </mat-card-content>
<div class="padding-gap"> </mat-card>
<mat-card> </div>
<mat-card-content class="table-card-content"> <div class="padding-gap">
<div perfectScrollbar class="table-container mat-elevation-z8"> <mat-card>
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-card-content class="table-card-content">
<table mat-table #table [dataSource]="qrHops" matSort <div perfectScrollbar class="table-container mat-elevation-z8">
[ngClass]="{'mat-elevation-z8 overflow-x-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-x-auto': true}"> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<ng-container matColumnDef="hop_sequence"> <table mat-table #table [dataSource]="qRoutes" matSort
<th mat-header-cell *matHeaderCellDef mat-sort-header> Hop </th> [ngClass]="{'mat-elevation-z8 overflow-x-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-x-auto': true}">
<td mat-cell *matCellDef="let hop"> {{hop?.hop_sequence}} </td> <ng-container matColumnDef="id">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<ng-container matColumnDef="pubkey_alias"> <td mat-cell *matCellDef="let route"> {{route?.id}} </td>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Node </th> </ng-container>
<td mat-cell *matCellDef="let hop"> {{hop?.pubkey_alias}} </td> <ng-container matColumnDef="alias">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
<ng-container matColumnDef="chan_id"> <td mat-cell *matCellDef="let route"> {{route?.alias}} </td>
<th mat-header-cell *matHeaderCellDef mat-sort-header> Channel </th> </ng-container>
<td mat-cell *matCellDef="let hop"> {{hop?.chan_id}} </td> <ng-container matColumnDef="channel">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header> Channel </th>
<ng-container matColumnDef="chan_capacity"> <td mat-cell *matCellDef="let route"> {{route?.channel}} </td>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Capacity (sats) </th> </ng-container>
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.chan_capacity | number}} <ng-container matColumnDef="direction">
</span></td> <th mat-header-cell *matHeaderCellDef mat-sort-header> Direction </th>
</ng-container> <td mat-cell *matCellDef="let route"> {{route?.direction}} </td>
<ng-container matColumnDef="amt_to_forward_msat"> </ng-container>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Amount To Fwd (msats) </th> <ng-container matColumnDef="msatoshi">
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.amt_to_forward_msat | number}} <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> mSatoshi </th>
</span></td> <td mat-cell *matCellDef="let route"><span fxLayoutAlign="end center"> {{route?.msatoshi | number}}
</ng-container> </span></td>
<ng-container matColumnDef="fee_msat"> </ng-container>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Fee (msat) </th> <ng-container matColumnDef="amount_msat">
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.fee_msat | number}} </span> <th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header> Amount mSat </th>
</td> <td mat-cell class="pl-4" *matCellDef="let route"> {{route?.amount_msat}} </td>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <ng-container matColumnDef="delay">
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onHopClick(row, $event)"></tr> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Delay </th>
</table> <td mat-cell *matCellDef="let route"><span fxLayoutAlign="end center"> {{route?.delay | number}} </span>
</div> </td>
</mat-card-content> </ng-container>
</mat-card> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
</div> <tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="onRouteClick(row, $event)"></tr>
</div> --> </table>
<h3>PAYMENTS QUERY ROUTES</h3> </div>
</mat-card-content>
</mat-card>
</div>
</div>

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects'; import { Actions } from '@ngrx/effects';
import { MatTableDataSource, MatSort } from '@angular/material'; import { MatTableDataSource, MatSort } from '@angular/material';
import { HopCL } from '../../../shared/models/clModels'; import { RoutesCL } from '../../../shared/models/clModels';
import { LoggerService } from '../../../shared/services/logger.service'; import { LoggerService } from '../../../shared/services/logger.service';
import { CLEffects } from '../../store/cl.effects'; import { CLEffects } from '../../store/cl.effects';
@ -22,71 +22,71 @@ export class CLQueryRoutesComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: true }) sort: MatSort; @ViewChild(MatSort, { static: true }) sort: MatSort;
public destinationPubkey = ''; public destinationPubkey = '';
public amount = null; public amount = null;
public qrHops: any; public qRoutes: any;
public flgSticky = false; public flgSticky = false;
public displayedColumns = []; public displayedColumns = [];
public flgLoading: Array<Boolean | 'error'> = [false]; // 0: peers public flgLoading: Array<Boolean | 'error'> = [false]; // 0: peers
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
ngOnInit() {}
// constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private clEffects: CLEffects, private actions$: Actions) {
// switch (true) {
// case (window.innerWidth <= 415):
// this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'fee_msat'];
// break;
// case (window.innerWidth > 415 && window.innerWidth <= 730):
// this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'fee_msat'];
// break;
// case (window.innerWidth > 730 && window.innerWidth <= 1024):
// this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
// break;
// case (window.innerWidth > 1024 && window.innerWidth <= 1280):
// this.flgSticky = true;
// this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
// break;
// default:
// this.flgSticky = true;
// this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_id', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat'];
// break;
// }
// }
// ngOnInit() { constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private clEffects: CLEffects, private actions$: Actions) {
// this.clEffects.setQueryRoutes switch (true) {
// .pipe(takeUntil(this.unSubs[1])) case (window.innerWidth <= 415):
// .subscribe(queryRoute => { this.displayedColumns = ['alias', 'direction', 'msatoshi', 'delay'];
// this.qrHops = new MatTableDataSource([]); break;
// this.qrHops.data = []; case (window.innerWidth > 415 && window.innerWidth <= 730):
// if (undefined !== queryRoute.routes && undefined !== queryRoute.routes[0].hops) { this.displayedColumns = ['alias', 'channel', 'direction', 'msatoshi', 'delay'];
// this.flgLoading[0] = false; break;
// this.qrHops = new MatTableDataSource<HopCL>([...queryRoute.routes[0].hops]); case (window.innerWidth > 730 && window.innerWidth <= 1024):
// this.qrHops.data = queryRoute.routes[0].hops; this.displayedColumns = ['id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'];
// } else { break;
// this.flgLoading[0] = 'error'; case (window.innerWidth > 1024 && window.innerWidth <= 1280):
// } this.flgSticky = true;
// this.qrHops.sort = this.sort; this.displayedColumns = ['id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'];
// }); break;
// } default:
this.flgSticky = true;
this.displayedColumns = ['id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'];
break;
}
}
// onQueryRoutes() { ngOnInit() {
// this.flgLoading[0] = true; this.clEffects.setQueryRoutesCL
// this.store.dispatch(new RTLActions.GetQueryRoutes({destPubkey: this.destinationPubkey, amount: this.amount})); .pipe(takeUntil(this.unSubs[1]))
// } .subscribe(queryRoute => {
this.qRoutes = new MatTableDataSource([]);
this.qRoutes.data = [];
if (undefined !== queryRoute && undefined !== queryRoute.routes) {
this.flgLoading[0] = false;
this.qRoutes = new MatTableDataSource<RoutesCL>([...queryRoute.routes]);
this.qRoutes.data = queryRoute.routes;
} else {
this.flgLoading[0] = 'error';
}
this.qRoutes.sort = this.sort;
});
}
// resetData() { onQueryRoutes() {
// this.destinationPubkey = ''; this.flgLoading[0] = true;
// this.amount = null; this.store.dispatch(new RTLActions.GetQueryRoutesCL({destPubkey: this.destinationPubkey, amount: this.amount}));
// this.flgLoading[0] = false; }
// }
// onHopClick(selRow: HopCL, event: any) { resetData() {
// const selHop = this.qrHops.data.filter(hop => { this.destinationPubkey = '';
// return hop.hop_sequence === selRow.hop_sequence; this.amount = null;
// })[0]; this.flgLoading[0] = false;
// const reorderedHop = JSON.parse(JSON.stringify(selHop, [ }
// 'hop_sequence', 'pubkey_alias', 'pub_key', 'chan_id', 'chan_capacity', 'expiry', 'amt_to_forward', 'amt_to_forward_msat', 'fee_msat'
// ] , 2)); onRouteClick(selRow: RoutesCL, event: any) {
// this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: 'INFO', message: JSON.stringify(reorderedHop)}})); const selRoute = this.qRoutes.data.filter(route => {
// } return route.id === route.id;
})[0];
const reorderedRoute = JSON.parse(JSON.stringify(selRoute, [
'id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: 'INFO', message: JSON.stringify(reorderedRoute)}}));
}
ngOnDestroy() { ngOnDestroy() {
this.unSubs.forEach(completeSub => { this.unSubs.forEach(completeSub => {

@ -1,4 +1,4 @@
<!-- <div fxLayout="column"> <div fxLayout="column">
<div class="padding-gap"> <div class="padding-gap">
<mat-card> <mat-card>
<mat-card-header> <mat-card-header>
@ -7,18 +7,24 @@
</mat-card-subtitle> </mat-card-subtitle>
</mat-card-header> </mat-card-header>
<mat-card-content> <mat-card-content>
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap" #sendPaymentForm="ngForm"> <form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap"
#sendPaymentForm="ngForm">
<div fxFlex="69" fxLayoutAlign="space-between stretch"> <div fxFlex="69" fxLayoutAlign="space-between stretch">
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" required #paymentReq="ngModel"> <input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest"
tabindex="1" required #paymentReq="ngModel">
</mat-form-field> </mat-form-field>
</div> </div>
<div fxFlex="30" fxLayoutAlign="space-between stretch"> <div fxFlex="30" fxLayoutAlign="space-between stretch">
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="paymentReq.invalid" (click)="onSendPayment()" tabindex="2"> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="paymentReq.invalid" (click)="onSendPayment()" tabindex="2">
<p *ngIf="paymentReq.invalid && (paymentReq.dirty || paymentReq.touched); else sendText">Invalid Req</p> <p *ngIf="paymentReq.invalid && (paymentReq.dirty || paymentReq.touched); else sendText">Invalid Req</p>
<ng-template #sendText><p>Send Payment</p></ng-template> <ng-template #sendText>
<p>Send Payment</p>
</ng-template>
</button> </button>
<button fxFlex="48" mat-raised-button color="accent" type="reset" tabindex="3" type="reset" (click)="resetData()">Clear</button> <button fxFlex="48" mat-raised-button color="accent" type="reset" tabindex="3" type="reset"
(click)="resetData()">Clear</button>
</div> </div>
</form> </form>
</mat-card-content> </mat-card-content>
@ -34,49 +40,65 @@
</div> </div>
<div perfectScrollbar class="table-container mat-elevation-z8"> <div perfectScrollbar class="table-container mat-elevation-z8">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="payments" matSort [ngClass]="{'mat-elevation-z8 overflow-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-auto': true}"> <table mat-table #table [dataSource]="payments" matSort
<ng-container matColumnDef="creation_date"> [ngClass]="{'mat-elevation-z8 overflow-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-auto': true}">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Creation Date</th> <ng-container matColumnDef="id">
<td mat-cell *matCellDef="let payment">{{payment?.creation_date_str}}</td> <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let payment">{{payment?.id}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="payment_hash"> <ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Bolt11</th>
<td mat-cell *matCellDef="let payment"> <td mat-cell *matCellDef="let payment">{{payment?.bolt11 | slice:0:10}}...</td>
<div>{{payment?.payment_hash | slice:0:10}}...</div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="fee"> <ng-container matColumnDef="created_at">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Created At</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.fee | number}}</span></td> <td mat-cell *matCellDef="let payment">{{payment?.created_at_str}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="value"> <ng-container matColumnDef="destination">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value | number}}</span></td> <td mat-cell *matCellDef="let payment">{{payment?.destination | slice:0:10}}...</td>
</ng-container> </ng-container>
<ng-container matColumnDef="payment_preimage"> <ng-container matColumnDef="status">
<th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header>Payment Pre Image</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
<td mat-cell *matCellDef="let payment">{{payment?.status}}</td>
</ng-container>
<ng-container matColumnDef="msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">mSatoshi</th>
<td mat-cell *matCellDef="let payment"><span
fxLayoutAlign="end center">{{payment?.msatoshi | number}}</span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_sent">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">mSatoshi Sent</th>
<td mat-cell *matCellDef="let payment"><span
fxLayoutAlign="end center">{{payment?.msatoshi_sent | number}}</span></td>
</ng-container>
<ng-container matColumnDef="payment_hash">
<th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell class="pl-4" *matCellDef="let payment"> <td mat-cell class="pl-4" *matCellDef="let payment">
<div>{{payment?.payment_preimage | slice:0:10}}...</div> <div>{{payment?.payment_hash | slice:0:10}}...</div>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="value_msat"> <ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value MSat</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Pre Image</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value_msat | number}}</span></td> <td mat-cell *matCellDef="let payment">
<div>{{payment?.payment_preimage | slice:0:10}}<span *ngIf="payment?.payment_preimage">...</span></div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="value_sat"> <ng-container matColumnDef="amount_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value Sat</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Amount mSat</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value_sat | number}}</span></td> <td mat-cell *matCellDef="let payment">{{payment?.amount_msat}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="path"> <ng-container matColumnDef="amount_sent_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Path</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Amount Sent mSat</th>
<td mat-cell *matCellDef="let payment">{{payment?.path?.length || 0}} Hops</td> <td mat-cell *matCellDef="let payment">{{payment?.amount_sent_msat}}</td>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'" (click)="onPaymentClick(row, $event)"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"
[@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"
(click)="onPaymentClick(row, $event)"></tr>
</table> </table>
</div> </div>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
</div> </div>
</div> --> </div>
<h3>PAYMENTS SEND RECEIVE</h3>

@ -1,15 +1,3 @@
.mat-column-path {
padding-left: 10px;
}
.mat-expansion-panel-header {
padding: 0;
}
.mat-accordion .mat-expansion-panel {
padding: 0 10px;
}
.ml-minus-24px { .ml-minus-24px {
margin-left: -24px; margin-left: -24px;
} }

@ -34,79 +34,80 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
public paymentRequest = ''; public paymentRequest = '';
public flgSticky = false; public flgSticky = false;
private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()]; private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
ngOnInit() {}
// constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private clEffects: CLEffects) {
// switch (true) {
// case (window.innerWidth <= 415):
// this.displayedColumns = ['creation_date', 'fee', 'value'];
// break;
// case (window.innerWidth > 415 && window.innerWidth <= 730):
// this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage'];
// break;
// case (window.innerWidth > 730 && window.innerWidth <= 1024):
// this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'path'];
// break;
// case (window.innerWidth > 1024 && window.innerWidth <= 1280):
// this.flgSticky = true;
// this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'value_msat', 'value_sat', 'path'];
// break;
// default:
// this.flgSticky = true;
// this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'value_msat', 'value_sat', 'path'];
// break;
// }
// }
// ngOnInit() { constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private clEffects: CLEffects) {
// this.store.select('cl') switch (true) {
// .pipe(takeUntil(this.unsub[0])) case (window.innerWidth <= 415):
// .subscribe((rtlStore) => { this.displayedColumns = ['created_at', 'status', 'msatoshi', 'msatoshi_sent'];
// rtlStore.effectErrorsCl.forEach(effectsErr => { break;
// if (effectsErr.action === 'FetchPayments') { case (window.innerWidth > 415 && window.innerWidth <= 730):
// this.flgLoading[0] = 'error'; this.displayedColumns = ['bolt11', 'created_at', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash'];
// } break;
// }); case (window.innerWidth > 730 && window.innerWidth <= 1024):
// this.information = rtlStore.information; this.displayedColumns = ['bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash'];
// this.paymentJSONArr = (null !== rtlStore.payments && rtlStore.payments.length > 0) ? rtlStore.payments : []; break;
// this.payments = (undefined === rtlStore.payments || null == rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource<Payment>([...this.paymentJSONArr]); case (window.innerWidth > 1024 && window.innerWidth <= 1280):
// this.payments.data = this.paymentJSONArr; this.flgSticky = true;
// this.payments.sort = this.sort; this.displayedColumns = ['id', 'bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'];
// this.payments.data.forEach(payment => { break;
// payment.creation_date_str = (payment.creation_date_str === '') ? '' : formatDate(payment.creation_date_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); default:
// }); this.flgSticky = true;
// setTimeout(() => { this.flgAnimate = false; }, 3000); this.displayedColumns = ['id', 'bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'];
// if (this.flgLoading[0] !== 'error') { break;
// this.flgLoading[0] = (undefined !== this.paymentJSONArr) ? false : true; }
// } }
// this.logger.info(rtlStore);
// });
// } ngOnInit() {
this.store.dispatch(new RTLActions.FetchPaymentsCL());
this.store.select('cl')
.pipe(takeUntil(this.unsub[0]))
.subscribe((rtlStore) => {
rtlStore.effectErrorsCl.forEach(effectsErr => {
if (effectsErr.action === 'FetchPaymentsCL') {
this.flgLoading[0] = 'error';
}
});
this.information = rtlStore.information;
this.paymentJSONArr = (null !== rtlStore.payments && rtlStore.payments.length > 0) ? rtlStore.payments : [];
this.payments = (undefined === rtlStore.payments || null == rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource<PaymentCL>([...this.paymentJSONArr]);
this.payments.data = this.paymentJSONArr;
this.payments.sort = this.sort;
this.payments.data.forEach(payment => {
payment.created_at_str = (payment.created_at_str === '') ? '' : formatDate(payment.created_at_str, 'MMM/dd/yy HH:mm:ss', 'en-US');
});
setTimeout(() => { this.flgAnimate = false; }, 3000);
if (this.flgLoading[0] !== 'error') {
this.flgLoading[0] = (undefined !== this.paymentJSONArr) ? false : true;
}
this.logger.info(rtlStore);
});
// onSendPayment() { }
// if (undefined !== this.paymentDecoded.timestamp_str) {
// this.sendPayment();
// } else {
// this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...'));
// this.store.dispatch(new RTLActions.DecodePayment(this.paymentRequest));
// this.clEffects.setDecodedPayment
// .pipe(take(1))
// .subscribe(decodedPayment => {
// this.paymentDecoded = decodedPayment;
// if (undefined !== this.paymentDecoded.timestamp_str) {
// this.paymentDecoded.timestamp_str = (this.paymentDecoded.timestamp_str === '') ? '' :
// formatDate(this.paymentDecoded.timestamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US');
// if (undefined === this.paymentDecoded.num_satoshis) {
// this.paymentDecoded.num_satoshis = '0';
// }
// this.sendPayment();
// } else {
// this.resetData();
// }
// });
// }
// } onSendPayment() {
// if (undefined !== this.paymentDecoded.timestamp_str) {
// this.sendPayment();
// } else {
// this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...'));
// this.store.dispatch(new RTLActions.DecodePayment(this.paymentRequest));
// this.clEffects.setDecodedPayment
// .pipe(take(1))
// .subscribe(decodedPayment => {
// this.paymentDecoded = decodedPayment;
// if (undefined !== this.paymentDecoded.timestamp_str) {
// this.paymentDecoded.timestamp_str = (this.paymentDecoded.timestamp_str === '') ? '' :
// formatDate(this.paymentDecoded.timestamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US');
// if (undefined === this.paymentDecoded.num_satoshis) {
// this.paymentDecoded.num_satoshis = '0';
// }
// this.sendPayment();
// } else {
// this.resetData();
// }
// });
// }
}
// sendPayment() { // sendPayment() {
// this.flgAnimate = true; // this.flgAnimate = true;
@ -158,31 +159,27 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
// }); // });
// } // }
// resetData() { resetData() {
// this.form.reset(); this.form.reset();
// this.paymentDecoded = {}; this.paymentDecoded = {};
// } }
// onPaymentClick(selRow: Payment, event: any) { onPaymentClick(selRow: PaymentCL, event: any) {
// const flgExpansionClicked = event.target.className.includes('mat-expansion-panel-header') || event.target.className.includes('mat-expansion-indicator'); const selPayment = this.payments.data.filter(payment => {
// if (flgExpansionClicked) { return payment.payment_hash === selRow.payment_hash;
// return; })[0];
// } const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [
// const selPayment = this.payments.data.filter(payment => { 'id', 'bolt11', 'created_at_str', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'
// return payment.payment_hash === selRow.payment_hash; ] , 2));
// })[0]; this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
// const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [ type: 'INFO',
// 'creation_date_str', 'payment_hash', 'fee', 'value_msat', 'value_sat', 'value', 'payment_preimage', 'path' message: JSON.stringify(reorderedPayment)
// ] , 2)); }}));
// this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { }
// type: 'INFO',
// message: JSON.stringify(reorderedPayment)
// }}));
// }
// applyFilter(selFilter: string) { applyFilter(selFilter: string) {
// this.payments.filter = selFilter; this.payments.filter = selFilter;
// } }
ngOnDestroy() { ngOnDestroy() {
this.unsub.forEach(completeSub => { this.unsub.forEach(completeSub => {

@ -7,7 +7,7 @@ import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators';
import { environment, API_URL } from '../../../environments/environment'; import { environment, API_URL } from '../../../environments/environment';
import { LoggerService } from '../../shared/services/logger.service'; import { LoggerService } from '../../shared/services/logger.service';
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL } from '../../shared/models/clModels'; import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL } from '../../shared/models/clModels';
import * as fromRTLReducer from '../../store/rtl.reducers'; import * as fromRTLReducer from '../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../store/rtl.actions';
@ -132,7 +132,7 @@ export class CLEffects implements OnDestroy {
getNewAddressCL = this.actions$.pipe( getNewAddressCL = this.actions$.pipe(
ofType(RTLActions.GET_NEW_ADDRESS_CL), ofType(RTLActions.GET_NEW_ADDRESS_CL),
mergeMap((action: RTLActions.GetNewAddressCL) => { mergeMap((action: RTLActions.GetNewAddressCL) => {
return this.httpClient.get(this.CHILD_API_URL + environment.NEW_ADDRESS_API + '?type=' + action.payload.addressId) return this.httpClient.get(this.CHILD_API_URL + environment.ON_CHAIN_API + '?type=' + action.payload.addressId)
.pipe(map((newAddress: any) => { .pipe(map((newAddress: any) => {
this.logger.info(newAddress); this.logger.info(newAddress);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
@ -142,7 +142,7 @@ export class CLEffects implements OnDestroy {
}; };
}), }),
catchError((err: any) => { catchError((err: any) => {
return this.handleErrorWithAlert('ERROR', 'Generate New Address Failed', this.CHILD_API_URL + environment.NEW_ADDRESS_API + '?type=' + action.payload.addressId, err); return this.handleErrorWithAlert('ERROR', 'Generate New Address Failed', this.CHILD_API_URL + environment.ON_CHAIN_API + '?type=' + action.payload.addressId, err);
})); }));
}) })
); );
@ -221,6 +221,129 @@ export class CLEffects implements OnDestroy {
} }
)); ));
@Effect()
paymentsFetchCL = this.actions$.pipe(
ofType(RTLActions.FETCH_PAYMENTS_CL),
mergeMap((action: RTLActions.FetchPaymentsCL) => {
this.store.dispatch(new RTLActions.ClearEffectErrorCl('FetchPaymentsCL'));
return this.httpClient.get<PaymentCL[]>(this.CHILD_API_URL + environment.PAYMENTS_API);
}),
map((payments) => {
this.logger.info(payments);
return {
type: RTLActions.SET_PAYMENTS_CL,
payload: (undefined !== payments && null != payments) ? payments : []
};
}),
catchError((err: any) => {
return this.handleErrorWithoutAlert('FetchPaymentsCL', err);
}
));
@Effect()
decodePaymentCL = this.actions$.pipe(
ofType(RTLActions.DECODE_PAYMENT_CL),
mergeMap((action: RTLActions.DecodePaymentCL) => {
return this.httpClient.get(this.CHILD_API_URL + environment.PAYMENTS_API + '/' + action.payload)
.pipe(
map((decodedPayment) => {
this.logger.info(decodedPayment);
this.store.dispatch(new RTLActions.CloseSpinner());
return {
type: RTLActions.SET_DECODED_PAYMENT_CL,
payload: (undefined !== decodedPayment) ? decodedPayment : {}
};
}),
catchError((err: any) => {
return this.handleErrorWithAlert('ERROR', 'Decode Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API + '/' + action.payload, err);
})
);
})
);
@Effect({ dispatch: false })
setDecodedPaymentCL = this.actions$.pipe(
ofType(RTLActions.SET_DECODED_PAYMENT_CL),
map((action: RTLActions.SetDecodedPaymentCL) => {
this.logger.info(action.payload);
return action.payload;
})
);
@Effect()
sendPaymentCL = this.actions$.pipe(
ofType(RTLActions.SEND_PAYMENT_CL),
withLatestFrom(this.store.select('root')),
mergeMap(([action, store]: [RTLActions.SendPaymentCL, any]) => {
let queryHeaders = {};
if (action.payload[2]) {
queryHeaders = { paymentDecoded: action.payload[1] };
} else {
queryHeaders = { paymentReq: action.payload[0] };
}
return this.httpClient.post(this.CHILD_API_URL + environment.PAYMENTS_API, queryHeaders)
.pipe(
map((sendRes: any) => {
this.logger.info(sendRes);
if (sendRes.payment_error) {
return this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API, { status: sendRes.payment_error.status, error: sendRes.payment_error.error.message });
} else {
const confirmationMsg = { 'Destination': action.payload[1].destination, 'Timestamp': action.payload[1].timestamp_str, 'Expiry': action.payload[1].expiry };
confirmationMsg['Amount (' + ((undefined === store.information.smaller_currency_unit) ?
'Sats' : store.information.smaller_currency_unit) + ')'] = action.payload[1].num_satoshis;
const msg = {};
msg['Total Fee (' + ((undefined === store.information.smaller_currency_unit) ? 'Sats' : store.information.smaller_currency_unit) + ')'] =
(sendRes.payment_route.total_fees_msat / 1000);
Object.assign(msg, confirmationMsg);
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%',
data: { type: 'SUCCESS', titleMessage: 'Payment Sent Successfully!', message: JSON.stringify(msg) }
}));
// this.store.dispatch(new RTLActions.FetchChannelsCL({ routeParam: 'all' }));
this.store.dispatch(new RTLActions.FetchBalanceCL());
this.store.dispatch(new RTLActions.FetchPaymentsCL());
return {
type: RTLActions.SET_DECODED_PAYMENT_CL,
payload: {}
};
}
}),
catchError((err: any) => {
return this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API, err);
})
);
})
);
@Effect()
queryRoutesFetchCL = this.actions$.pipe(
ofType(RTLActions.GET_QUERY_ROUTES_CL),
mergeMap((action: RTLActions.GetQueryRoutesCL) => {
return this.httpClient.get(this.CHILD_API_URL + environment.NETWORK_API + '/getRoute/' + action.payload.destPubkey + '/' + action.payload.amount)
.pipe(
map((qrRes: any) => {
this.logger.info(qrRes);
return {
type: RTLActions.SET_QUERY_ROUTES_CL,
payload: qrRes
};
}),
catchError((err: any) => {
this.store.dispatch(new RTLActions.SetQueryRoutesCL({routes: []}));
return this.handleErrorWithAlert('ERROR', 'Get Query Routes Failed', this.CHILD_API_URL + environment.NETWORK_API + '/getRoute/' + action.payload.destPubkey + '/' + action.payload.amount, err);
})
);
}
));
@Effect({ dispatch: false })
setQueryRoutesCL = this.actions$.pipe(
ofType(RTLActions.SET_QUERY_ROUTES_CL),
map((action: RTLActions.SetQueryRoutesCL) => {
return action.payload;
})
);
handleErrorWithoutAlert(actionName: string, err: {status: number, error: any}) { handleErrorWithoutAlert(actionName: string, err: {status: number, error: any}) {
this.logger.error(err); this.logger.error(err);
if(err.status === 401) { if(err.status === 401) {

@ -1,5 +1,5 @@
import { SelNodeChild } from '../../shared/models/RTLconfig'; import { SelNodeChild } from '../../shared/models/RTLconfig';
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, AddressTypeCL, PeerCL } from '../../shared/models/clModels'; import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, AddressTypeCL, PeerCL, PaymentCL } from '../../shared/models/clModels';
import { ErrorPayload } from '../../shared/models/errorPayload'; import { ErrorPayload } from '../../shared/models/errorPayload';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../store/rtl.actions';
@ -11,6 +11,7 @@ export interface CLState {
balance: BalanceCL; balance: BalanceCL;
localRemoteBalance: LocalRemoteBalanceCL; localRemoteBalance: LocalRemoteBalanceCL;
peers: PeerCL[]; peers: PeerCL[];
payments: PaymentCL[];
addressTypes: AddressTypeCL[]; addressTypes: AddressTypeCL[];
} }
@ -22,9 +23,10 @@ export const initCLState: CLState = {
balance: {}, balance: {},
localRemoteBalance: {}, localRemoteBalance: {},
peers: [], peers: [],
payments: [],
addressTypes: [ addressTypes: [
{ addressId: '0', addressTp: 'bech32', addressDetails: 'bech32'}, { addressId: '0', addressTp: 'bech32', addressDetails: 'bech32' },
{ addressId: '1', addressTp: 'p2sh-segwit', addressDetails: 'p2sh-segwit (default)'} { addressId: '1', addressTp: 'p2sh-segwit', addressDetails: 'p2sh-segwit (default)' }
] ]
} }
@ -72,28 +74,33 @@ export function CLReducer(state = initCLState, action: RTLActions.RTLActions) {
...state, ...state,
localRemoteBalance: action.payload localRemoteBalance: action.payload
}; };
case RTLActions.SET_PEERS_CL: case RTLActions.SET_PEERS_CL:
return { return {
...state, ...state,
peers: action.payload peers: action.payload
}; };
case RTLActions.ADD_PEER_CL: case RTLActions.ADD_PEER_CL:
return { return {
...state, ...state,
peers: [...state.peers, action.payload] peers: [...state.peers, action.payload]
}; };
case RTLActions.REMOVE_PEER_CL: case RTLActions.REMOVE_PEER_CL:
const modifiedPeers = [...state.peers]; const modifiedPeers = [...state.peers];
const removePeerIdx = state.peers.findIndex(peer => { const removePeerIdx = state.peers.findIndex(peer => {
return peer.id === action.payload.id; return peer.id === action.payload.id;
}); });
if (removePeerIdx > -1) { if (removePeerIdx > -1) {
modifiedPeers.splice(removePeerIdx, 1); modifiedPeers.splice(removePeerIdx, 1);
} }
return { return {
...state, ...state,
peers: modifiedPeers peers: modifiedPeers
}; };
case RTLActions.SET_PAYMENTS_CL:
return {
...state,
payments: action.payload
};
default: default:
return state; return state;
} }

@ -147,15 +147,18 @@ export interface HopCL {
} }
export interface PaymentCL { export interface PaymentCL {
creation_date?: number; amount_msat?: string;
creation_date_str?: string; amount_sent_msat?: string;
bolt11?: string;
created_at?: number;
created_at_str?: string;
destination?: string;
id?: number;
msatoshi?: number;
msatoshi_sent?: number;
payment_hash?: string; payment_hash?: string;
path?: string[];
fee?: number;
value_msat?: number;
value_sat?: number;
value?: number;
payment_preimage?: string; payment_preimage?: string;
status?: string;
} }
export interface PayRequestCL { export interface PayRequestCL {
@ -183,4 +186,18 @@ export interface ForwardingEventCL {
chan_id_in?: string; chan_id_in?: string;
alias_in?: string; alias_in?: string;
fee?: string; fee?: string;
}
export interface QueryRoutesCL {
routes: RoutesCL[];
}
export interface RoutesCL {
id?: string;
channel?: string;
direction?: number;
msatoshi?: number;
amount_msat?: string;
delay?: number;
alias?: string;
} }

@ -1,10 +1,9 @@
import { MatDialogConfig } from '@angular/material'; import { MatDialogConfig } from '@angular/material';
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { GetInfoCL, FeesCL, AddressTypeCL, PeerCL } from '../shared/models/clModels';
import { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild } from '../shared/models/RTLconfig';
import { ErrorPayload } from '../shared/models/errorPayload'; import { ErrorPayload } from '../shared/models/errorPayload';
import { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild } from '../shared/models/RTLconfig';
import { GetInfoCL, FeesCL, AddressTypeCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL } from '../shared/models/clModels';
import { import {
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType, GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType,
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes
@ -115,6 +114,13 @@ export const SAVE_NEW_PEER_CL = 'SAVE_NEW_PEER_CL';
export const ADD_PEER_CL = 'ADD_PEER_CL'; export const ADD_PEER_CL = 'ADD_PEER_CL';
export const DETACH_PEER_CL = 'DETACH_PEER_CL'; export const DETACH_PEER_CL = 'DETACH_PEER_CL';
export const REMOVE_PEER_CL = 'REMOVE_PEER_CL'; export const REMOVE_PEER_CL = 'REMOVE_PEER_CL';
export const FETCH_PAYMENTS_CL = 'FETCH_PAYMENTS_CL';
export const SET_PAYMENTS_CL = 'SET_PAYMENTS_CL';
export const DECODE_PAYMENT_CL = 'DECODE_PAYMENT_CL';
export const SEND_PAYMENT_CL = 'SEND_PAYMENT_CL';
export const SET_DECODED_PAYMENT_CL = 'SET_DECODED_PAYMENT_CL';
export const GET_QUERY_ROUTES_CL = 'GET_QUERY_ROUTES_CL';
export const SET_QUERY_ROUTES_CL = 'SET_QUERY_ROUTES_CL';
export class VoidAction implements Action { export class VoidAction implements Action {
readonly type = VOID; readonly type = VOID;
@ -605,6 +611,40 @@ export class RemovePeerCL implements Action {
constructor(public payload: {id: string}) {} constructor(public payload: {id: string}) {}
} }
export class FetchPaymentsCL implements Action {
readonly type = FETCH_PAYMENTS_CL;
}
export class SetPaymentsCL implements Action {
readonly type = SET_PAYMENTS_CL;
constructor(public payload: PaymentCL[]) {}
}
export class DecodePaymentCL implements Action {
readonly type = DECODE_PAYMENT_CL;
constructor(public payload: string) {} // payload = routeParam
}
export class SetDecodedPaymentCL implements Action {
readonly type = SET_DECODED_PAYMENT_CL;
constructor(public payload: PayRequestCL) {}
}
export class SendPaymentCL implements Action {
readonly type = SEND_PAYMENT_CL;
constructor(public payload: [string, PayRequest, boolean]) {} // payload = [paymentReqStr, paymentDecoded, EmptyAmtInvoice]
}
export class GetQueryRoutesCL implements Action {
readonly type = GET_QUERY_ROUTES_CL;
constructor(public payload: {destPubkey: string, amount: number}) {}
}
export class SetQueryRoutesCL implements Action {
readonly type = SET_QUERY_ROUTES_CL;
constructor(public payload: QueryRoutesCL) {}
}
export type RTLActions = export type RTLActions =
ClearEffectErrorRoot | EffectErrorRoot | ClearEffectErrorLnd | EffectErrorLnd | ClearEffectErrorCl | EffectErrorCl | ClearEffectErrorRoot | EffectErrorRoot | ClearEffectErrorLnd | EffectErrorLnd | ClearEffectErrorCl | EffectErrorCl |
VoidAction | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings | VoidAction | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings |
@ -631,4 +671,6 @@ export type RTLActions =
FetchInfoCL | SetInfoCL | FetchFeesCL | SetFeesCL | FetchInfoCL | SetInfoCL | FetchFeesCL | SetFeesCL |
FetchBalanceCL | SetBalanceCL | FetchLocalRemoteBalanceCL | SetLocalRemoteBalanceCL | FetchBalanceCL | SetBalanceCL | FetchLocalRemoteBalanceCL | SetLocalRemoteBalanceCL |
GetNewAddressCL | SetNewAddressCL | GetNewAddressCL | SetNewAddressCL |
FetchPeersCL | SetPeersCL | AddPeerCL | DetachPeerCL | SaveNewPeerCL | RemovePeerCL; FetchPeersCL | SetPeersCL | AddPeerCL | DetachPeerCL | SaveNewPeerCL | RemovePeerCL |
FetchPaymentsCL | SetPaymentsCL | SendPaymentCL | DecodePaymentCL | SetDecodedPaymentCL |
GetQueryRoutesCL | SetQueryRoutesCL;

@ -21,5 +21,6 @@ export const environment = {
PAYMENTS_API: '/payments', PAYMENTS_API: '/payments',
INVOICES_API: '/invoices', INVOICES_API: '/invoices',
SWITCH_API: '/switch', SWITCH_API: '/switch',
ON_CHAIN_API: '/onchain',
VERSION: VERSION VERSION: VERSION
}; };

@ -21,5 +21,6 @@ export const environment = {
PAYMENTS_API: '/payments', PAYMENTS_API: '/payments',
INVOICES_API: '/invoices', INVOICES_API: '/invoices',
SWITCH_API: '/switch', SWITCH_API: '/switch',
ON_CHAIN_API: '/onchain',
VERSION: VERSION VERSION: VERSION
}; };

Loading…
Cancel
Save