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>
<body>
<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>

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 channelsCLRoutes = require("./routes/c-lightning/channels");
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 payReqCLRoutes = require("./routes/c-lightning/payReq");
const peersCLRoutes = require("./routes/c-lightning/peers");
const switchCLRoutes = require("./routes/c-lightning/switch");
const transactionsCLRoutes = require("./routes/c-lightning/transactions");
const walletCLRoutes = require("./routes/c-lightning/wallet");
const networkCLRoutes = require("./routes/c-lightning/network");
app.use(cookieParser(common.secret_key));
app.use(bodyParser.json());
@ -81,13 +78,10 @@ app.use(apiCLRoot + "fees", feesCLRoutes);
app.use(apiCLRoot + "balance", balanceCLRoutes);
app.use(apiCLRoot + "channels", channelsCLRoutes);
app.use(apiCLRoot + "invoices", invoicesCLRoutes);
app.use(apiCLRoot + "newaddress", newAddressCLRoutes);
app.use(apiCLRoot + "onchain", onChainCLRoutes);
app.use(apiCLRoot + "payments", paymentsCLRoutes);
app.use(apiCLRoot + "payreq", payReqCLRoutes);
app.use(apiCLRoot + "peers", peersCLRoutes);
app.use(apiCLRoot + "switch", switchCLRoutes);
app.use(apiCLRoot + "transactions", transactionsCLRoutes);
app.use(apiCLRoot + "wallet", walletCLRoutes);
app.use(apiCLRoot + "network", networkCLRoutes);
app.use((req, res, next) => {
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 options = {};
exports.getPayments = (req, res, next) => {
exports.listPayments = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/payments';
options.url = common.getSelLNServerUrl() + '/pay/listPayments';
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: 'Payments', msg: 'Payment Decoded Received: ' + body_str});
if(undefined === body || search_idx > -1 || body.error) {
logger.info({fileName: 'Payments', msg: 'Payment List Received: ' + JSON.stringify(body.payments)});
if(undefined === body || body.error) {
res.status(500).json({
message: "Payments List Failed!",
error: (undefined === body || search_idx > -1) ? 'Error From Server!' : body.error
error: (undefined === body) ? 'Error From Server!' : body.error
});
} else {
if (undefined !== body.payments) {
if (undefined !== body && undefined !== body.payments) {
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);
}
@ -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");
router.get("/localremotebalance", authCheck, ChannelsController.getLocalRemoteBalance);
router.post("/", authCheck, ChannelsController.forwardingHistory);
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 router = express.Router();
const authCheck = require("../authCheck");
router.post("/", authCheck, SwitchController.forwardingHistory);
router.get("/", authCheck, OnChainController.getNewAddress);
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 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;

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

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

@ -1,4 +1,4 @@
<!-- <div fxLayout="column">
<div fxLayout="column">
<div class="padding-gap">
<mat-card>
<mat-card-header>
@ -7,18 +7,24 @@
</mat-card-subtitle>
</mat-card-header>
<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">
<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>
</div>
<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>
<ng-template #sendText><p>Send Payment</p></ng-template>
<ng-template #sendText>
<p>Send Payment</p>
</ng-template>
</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>
</form>
</mat-card-content>
@ -34,49 +40,65 @@
</div>
<div perfectScrollbar class="table-container mat-elevation-z8">
<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}">
<ng-container matColumnDef="creation_date">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Creation Date</th>
<td mat-cell *matCellDef="let payment">{{payment?.creation_date_str}}</td>
<table mat-table #table [dataSource]="payments" matSort
[ngClass]="{'mat-elevation-z8 overflow-auto error-border': flgLoading[0]==='error','mat-elevation-z8 overflow-auto': true}">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let payment">{{payment?.id}}</td>
</ng-container>
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">
<div>{{payment?.payment_hash | slice:0:10}}...</div>
</td>
<ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bolt11</th>
<td mat-cell *matCellDef="let payment">{{payment?.bolt11 | slice:0:10}}...</td>
</ng-container>
<ng-container matColumnDef="fee">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.fee | number}}</span></td>
<ng-container matColumnDef="created_at">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Created At</th>
<td mat-cell *matCellDef="let payment">{{payment?.created_at_str}}</td>
</ng-container>
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value | number}}</span></td>
<ng-container matColumnDef="destination">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment">{{payment?.destination | slice:0:10}}...</td>
</ng-container>
<ng-container matColumnDef="payment_preimage">
<th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header>Payment Pre Image</th>
<ng-container matColumnDef="status">
<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">
<div>{{payment?.payment_preimage | slice:0:10}}...</div>
<div>{{payment?.payment_hash | slice:0:10}}...</div>
</td>
</ng-container>
<ng-container matColumnDef="value_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value MSat</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value_msat | number}}</span></td>
<ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Pre Image</th>
<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 matColumnDef="value_sat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value Sat</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value_sat | number}}</span></td>
<ng-container matColumnDef="amount_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Amount mSat</th>
<td mat-cell *matCellDef="let payment">{{payment?.amount_msat}}</td>
</ng-container>
<ng-container matColumnDef="path">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Path</th>
<td mat-cell *matCellDef="let payment">{{payment?.path?.length || 0}} Hops</td>
<ng-container matColumnDef="amount_sent_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Amount Sent mSat</th>
<td mat-cell *matCellDef="let payment">{{payment?.amount_sent_msat}}</td>
</ng-container>
<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>
</div>
</mat-card-content>
</mat-card>
</div>
</div> -->
<h3>PAYMENTS SEND RECEIVE</h3>
</div>

@ -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 {
margin-left: -24px;
}

@ -34,79 +34,80 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
public paymentRequest = '';
public flgSticky = false;
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() {
// this.store.select('cl')
// .pipe(takeUntil(this.unsub[0]))
// .subscribe((rtlStore) => {
// rtlStore.effectErrorsCl.forEach(effectsErr => {
// if (effectsErr.action === 'FetchPayments') {
// 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<Payment>([...this.paymentJSONArr]);
// this.payments.data = this.paymentJSONArr;
// this.payments.sort = this.sort;
// this.payments.data.forEach(payment => {
// payment.creation_date_str = (payment.creation_date_str === '') ? '' : formatDate(payment.creation_date_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);
// });
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private clEffects: CLEffects) {
switch (true) {
case (window.innerWidth <= 415):
this.displayedColumns = ['created_at', 'status', 'msatoshi', 'msatoshi_sent'];
break;
case (window.innerWidth > 415 && window.innerWidth <= 730):
this.displayedColumns = ['bolt11', 'created_at', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash'];
break;
case (window.innerWidth > 730 && window.innerWidth <= 1024):
this.displayedColumns = ['bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash'];
break;
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
this.flgSticky = true;
this.displayedColumns = ['id', 'bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'];
break;
default:
this.flgSticky = true;
this.displayedColumns = ['id', 'bolt11', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'];
break;
}
}
// }
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() {
// this.flgAnimate = true;
@ -158,31 +159,27 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
// });
// }
// resetData() {
// this.form.reset();
// this.paymentDecoded = {};
// }
resetData() {
this.form.reset();
this.paymentDecoded = {};
}
// onPaymentClick(selRow: Payment, event: any) {
// const flgExpansionClicked = event.target.className.includes('mat-expansion-panel-header') || event.target.className.includes('mat-expansion-indicator');
// if (flgExpansionClicked) {
// return;
// }
// const selPayment = this.payments.data.filter(payment => {
// return payment.payment_hash === selRow.payment_hash;
// })[0];
// const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [
// 'creation_date_str', 'payment_hash', 'fee', 'value_msat', 'value_sat', 'value', 'payment_preimage', 'path'
// ] , 2));
// this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
// type: 'INFO',
// message: JSON.stringify(reorderedPayment)
// }}));
// }
onPaymentClick(selRow: PaymentCL, event: any) {
const selPayment = this.payments.data.filter(payment => {
return payment.payment_hash === selRow.payment_hash;
})[0];
const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [
'id', 'bolt11', 'created_at_str', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
type: 'INFO',
message: JSON.stringify(reorderedPayment)
}}));
}
// applyFilter(selFilter: string) {
// this.payments.filter = selFilter;
// }
applyFilter(selFilter: string) {
this.payments.filter = selFilter;
}
ngOnDestroy() {
this.unsub.forEach(completeSub => {

@ -7,7 +7,7 @@ import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators';
import { environment, API_URL } from '../../../environments/environment';
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 RTLActions from '../../store/rtl.actions';
@ -132,7 +132,7 @@ export class CLEffects implements OnDestroy {
getNewAddressCL = this.actions$.pipe(
ofType(RTLActions.GET_NEW_ADDRESS_CL),
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) => {
this.logger.info(newAddress);
this.store.dispatch(new RTLActions.CloseSpinner());
@ -142,7 +142,7 @@ export class CLEffects implements OnDestroy {
};
}),
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}) {
this.logger.error(err);
if(err.status === 401) {

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

@ -147,15 +147,18 @@ export interface HopCL {
}
export interface PaymentCL {
creation_date?: number;
creation_date_str?: string;
amount_msat?: 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;
path?: string[];
fee?: number;
value_msat?: number;
value_sat?: number;
value?: number;
payment_preimage?: string;
status?: string;
}
export interface PayRequestCL {
@ -183,4 +186,18 @@ export interface ForwardingEventCL {
chan_id_in?: string;
alias_in?: 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 { 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 { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild } from '../shared/models/RTLconfig';
import { GetInfoCL, FeesCL, AddressTypeCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL } from '../shared/models/clModels';
import {
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType,
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 DETACH_PEER_CL = 'DETACH_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 {
readonly type = VOID;
@ -605,6 +611,40 @@ export class RemovePeerCL implements Action {
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 =
ClearEffectErrorRoot | EffectErrorRoot | ClearEffectErrorLnd | EffectErrorLnd | ClearEffectErrorCl | EffectErrorCl |
VoidAction | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings |
@ -631,4 +671,6 @@ export type RTLActions =
FetchInfoCL | SetInfoCL | FetchFeesCL | SetFeesCL |
FetchBalanceCL | SetBalanceCL | FetchLocalRemoteBalanceCL | SetLocalRemoteBalanceCL |
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',
INVOICES_API: '/invoices',
SWITCH_API: '/switch',
ON_CHAIN_API: '/onchain',
VERSION: VERSION
};

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

Loading…
Cancel
Save