mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2026-08-13 12:33:07 +02:00
Release 0.7.1 (#340)
* Peers And Channels Redesign (#294) * Send payment without confirmation * Removed vulnerabilities & added missing 2FAuth button * Invoice Redesign with invoice info modal opening * Firefox Payment Failure Issue #283 (#309) * On chain redesign (#315) * Bug fix #312 Bogus warning about unsecure connection (#316) * Peer Channels Redesign #290 (#317) * CLT transactions redesign #290 (#319) * CLT On-chain redesign #290 (#320) * Wallet error alert bug fix #298 & #299 (#321) * Configurable server host #303 (#322) * Receive tab on top #292 (#323) * Settings Layout Cleanup (#325) * Alias Autocomplete (#326) * Redirect to Dashboard after first RTL login * Bug fix Channel Uptime wrong #284 (#329) * Channel info redesigned Issue #328 (#331) * Fixed Transaction Info Scroll #324 (#333) * Remove macaroon info before logging #306 * Added Peer Alias for Closed And Pending Channels Tabs #275 & #285 (#336) * Show multiple URIs on show pubkey modal #337 (#338)
This commit is contained in:
parent
685372fc5b
commit
a980d9c3fa
190 changed files with 4405 additions and 2189 deletions
File diff suppressed because one or more lines are too long
|
|
@ -110,6 +110,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
|
||||
|
||||
@angular/material/autocomplete
|
||||
|
||||
@angular/material/button
|
||||
|
||||
@angular/material/card
|
||||
|
|
|
|||
1
angular/6.23ff3e765459f2da33da.js
Normal file
1
angular/6.23ff3e765459f2da33da.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
angular/7.417208cf5491f2b427d2.js
Normal file
1
angular/7.417208cf5491f2b427d2.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -12,8 +12,8 @@
|
|||
<link rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="stylesheet" href="styles.807ae95794a05be97fba.css"></head>
|
||||
<link rel="stylesheet" href="styles.da5d02955b06fbd16881.css"></head>
|
||||
<body>
|
||||
<rtl-app></rtl-app>
|
||||
<script src="runtime.2cfa778f51a601dbdb7e.js" defer></script><script src="polyfills-es5.2ae7ace69949ec0a3f00.js" nomodule defer></script><script src="polyfills.3302e98effc5e50a54c2.js" defer></script><script src="main.4b92e283188428242458.js" defer></script></body>
|
||||
<script src="runtime.9c469fe6b4e77e4e8274.js" defer></script><script src="polyfills-es5.2ae7ace69949ec0a3f00.js" nomodule defer></script><script src="polyfills.3302e98effc5e50a54c2.js" defer></script><script src="main.3cc0daec879a4055c999.js" defer></script></body>
|
||||
</html>
|
||||
|
|
|
|||
1
angular/main.3cc0daec879a4055c999.js
Normal file
1
angular/main.3cc0daec879a4055c999.js
Normal file
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,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=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,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(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,a),t.l=!0,t.exports}a.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,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"55621ac84bdf6c786e25",6:"3228fcaf0890e1d596e3",7:"6fecb498f36cf3efcace"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.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:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);
|
||||
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=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,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(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,a),t.l=!0,t.exports}a.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,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9f5a5551675b6e3c39b6",6:"23ff3e765459f2da33da",7:"417208cf5491f2b427d2"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.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:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);
|
||||
File diff suppressed because one or more lines are too long
1
angular/styles.da5d02955b06fbd16881.css
Normal file
1
angular/styles.da5d02955b06fbd16881.css
Normal file
File diff suppressed because one or more lines are too long
18
common.js
18
common.js
|
|
@ -8,6 +8,7 @@ common.rtl_pass = '';
|
|||
common.rtl_secret2fa = '';
|
||||
common.rtl_sso = 0;
|
||||
common.port = 3000;
|
||||
common.host = 'localhost';
|
||||
common.rtl_cookie_path = '';
|
||||
common.logout_redirect_link = '/login';
|
||||
common.cookie = '';
|
||||
|
|
@ -115,7 +116,22 @@ common.sortAscByKey = (array, key) => {
|
|||
common.sortDescByKey = (array, key) => {
|
||||
const temp = array.sort(function (a, b) {
|
||||
var x = +a[key]; var y = +b[key];
|
||||
return ((x > y) ? -1 : ((x < y) ? 1 : 0));
|
||||
return (x > y) ? -1 : ((x < y) ? 1 : 0);
|
||||
});
|
||||
return temp;
|
||||
}
|
||||
|
||||
common.sortAscByStrKey = (array, key) => {
|
||||
return array.sort(function (a, b) {
|
||||
var x = a[key] ? a[key].toUpperCase() : ''; var y = b[key] ? b[key].toUpperCase() : '';
|
||||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||||
});
|
||||
}
|
||||
|
||||
common.sortDescByStrKey = (array, key) => {
|
||||
const temp = array.sort(function (a, b) {
|
||||
var x = a[key] ? a[key].toUpperCase() : ''; var y = b[key] ? b[key].toUpperCase() : '';
|
||||
return (x > y) ? -1 : ((x < y) ? 1 : 0);
|
||||
});
|
||||
return temp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ connect.setDefaultConfig = () => {
|
|||
return {
|
||||
multiPass: "password",
|
||||
port: "3000",
|
||||
host: "localhost",
|
||||
defaultNodeIndex: 1,
|
||||
SSO: {
|
||||
rtlSSO: 0,
|
||||
|
|
@ -99,7 +100,7 @@ connect.replacePasswordWithHash = (multiPassHashed) => {
|
|||
}
|
||||
|
||||
connect.validateNodeConfig = (config) => {
|
||||
if((process.env.RTL_SSO === 0) || (typeof process.env.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
|
||||
if((process.env.RTL_SSO == 0) || (typeof process.env.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
|
||||
if (config.multiPassHashed !== '' && config.multiPassHashed) {
|
||||
common.rtl_pass = config.multiPassHashed;
|
||||
} else if (config.multiPass !== '' && config.multiPass) {
|
||||
|
|
@ -110,6 +111,7 @@ connect.validateNodeConfig = (config) => {
|
|||
common.rtl_secret2fa = config.secret2fa;
|
||||
}
|
||||
common.port = (process.env.PORT) ? connect.normalizePort(process.env.PORT) : (config.port) ? connect.normalizePort(config.port) : 3000;
|
||||
common.host = (process.env.HOST) ? process.env.HOST : (config.host) ? config.host : 'localhost';
|
||||
if (config.nodes && config.nodes.length > 0) {
|
||||
config.nodes.forEach((node, idx) => {
|
||||
common.nodes[idx] = {};
|
||||
|
|
@ -286,6 +288,7 @@ connect.logEnvVariables = () => {
|
|||
common.nodes.forEach((node, idx) => {
|
||||
if (!node.enable_logging) { return; }
|
||||
logger.info({fileName: 'Config Setup Variable', msg: 'PORT: ' + common.port, node});
|
||||
logger.info({fileName: 'Config Setup Variable', msg: 'HOST: ' + common.host, node});
|
||||
logger.info({fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + common.selectedNode.index});
|
||||
logger.info({fileName: 'Config Setup Variable', msg: 'SSO: ' + common.rtl_sso, node});
|
||||
logger.info({fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + common.logout_redirect_link + '\r\n', node});
|
||||
|
|
@ -344,6 +347,7 @@ connect.modifyJsonMultiNodeConfig = (confFileFullPath) => {
|
|||
if (!config.SSO) { config.SSO = {}; }
|
||||
var newConfig = {
|
||||
port: config.port ? config.port : 3000,
|
||||
host: config.host ? config.host : 'localhost',
|
||||
defaultNodeIndex: config.defaultNodeIndex ? config.defaultNodeIndex : 1,
|
||||
SSO: {
|
||||
rtlSSO: config.SSO.rtlSSO ? config.SSO.rtlSSO : 0,
|
||||
|
|
@ -414,6 +418,7 @@ connect.modifyIniSingleNodeConfig = (confFileFullPath) => {
|
|||
if (!config.Settings) { config.Settings = {}; }
|
||||
var newConfig = {
|
||||
port: config.Settings.port ? config.Settings.port : 3000,
|
||||
host: 'localhost',
|
||||
defaultNodeIndex: 1,
|
||||
SSO: {
|
||||
rtlSSO: config.SSO.rtlSSO ? config.SSO.rtlSSO : 0,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ exports.getRTLConfig = (req, res, next) => {
|
|||
fs.readFile(confFile, 'utf8', function(err, data) {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
logger.error({fileName: 'RTLConf', lineNum: 46, msg: 'Node config does not exist!'});
|
||||
logger.error({fileName: 'RTLConf', lineNum: 22, msg: 'Node config does not exist!'});
|
||||
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] });
|
||||
} else {
|
||||
logger.error({fileName: 'RTLConf', lineNum: 49, msg: 'Getting Node Config Failed!'});
|
||||
logger.error({fileName: 'RTLConf', lineNum: 25, msg: 'Getting Node Config Failed!'});
|
||||
res.status(500).json({
|
||||
message: "Reading Node Config Failed!",
|
||||
error: err
|
||||
|
|
@ -98,7 +98,7 @@ exports.updateUISettings = (req, res, next) => {
|
|||
res.status(201).json({message: 'Application Node Settings Updated Successfully'});
|
||||
}
|
||||
catch (err) {
|
||||
logger.error({fileName: 'Conf', lineNum: 102, msg: 'Updating Application Node Settings Failed!'});
|
||||
logger.error({fileName: 'Conf', lineNum: 101, msg: 'Updating Application Node Settings Failed!'});
|
||||
res.status(500).json({
|
||||
message: "Updating Application Node Settings Failed!",
|
||||
error: 'Updating Application Node Settings Failed!'
|
||||
|
|
@ -118,7 +118,7 @@ exports.update2FASettings = (req, res, next) => {
|
|||
res.status(201).json({message: message});
|
||||
}
|
||||
catch (err) {
|
||||
logger.error({fileName: 'Conf', lineNum: 102, msg: 'Updating 2FA Settings Failed!'});
|
||||
logger.error({fileName: 'Conf', lineNum: 121, msg: 'Updating 2FA Settings Failed!'});
|
||||
res.status(500).json({
|
||||
message: "Updating 2FA Settings Failed!",
|
||||
error: 'Updating 2FA Settings Failed!'
|
||||
|
|
@ -136,7 +136,7 @@ exports.updateDefaultNode = (req, res, next) => {
|
|||
res.status(201).json({message: 'Default Node Updated Successfully'});
|
||||
}
|
||||
catch (err) {
|
||||
logger.error({fileName: 'Conf', lineNum: 102, msg: 'Updating Default Node Failed!'});
|
||||
logger.error({fileName: 'Conf', lineNum: 139, msg: 'Updating Default Node Failed!'});
|
||||
res.status(500).json({
|
||||
message: "Updating Default Node Failed!",
|
||||
error: 'Updating Default Node Failed!'
|
||||
|
|
@ -168,7 +168,7 @@ exports.getConfig = (req, res, next) => {
|
|||
logger.info({fileName: 'RTLConf', msg: 'Node Type: ' + req.params.nodeType + ', File Path: ' + confFile});
|
||||
fs.readFile(confFile, 'utf8', function(err, data) {
|
||||
if (err) {
|
||||
logger.error({fileName: 'Conf', lineNum: 159, msg: 'Reading Conf Failed!'});
|
||||
logger.error({fileName: 'Conf', lineNum: 171, msg: 'Reading Conf Failed!'});
|
||||
res.status(500).json({
|
||||
message: "Reading Config File Failed!",
|
||||
error: err
|
||||
|
|
@ -207,7 +207,7 @@ exports.getCurrencyRates = (req, res, next) => {
|
|||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Conf', lineNum: 241, msg: 'Fetching Rates Failed! ' + JSON.stringify(err)});
|
||||
logger.error({fileName: 'Conf', lineNum: 210, msg: 'Fetching Rates Failed! ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Rates Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ exports.authenticateUser = (req, res, next) => {
|
|||
);
|
||||
res.status(200).json({ token: token });
|
||||
} else {
|
||||
logger.error({fileName: 'Authenticate', lineNum: 21, msg: 'Password Validation Failed!'});
|
||||
logger.error({fileName: 'Authenticate', lineNum: 20, msg: 'SSO Authentication Failed!'});
|
||||
res.status(401).json({
|
||||
message: "Login Failure!",
|
||||
error: "SSO Authentication Failed!"
|
||||
|
|
@ -33,10 +33,10 @@ exports.authenticateUser = (req, res, next) => {
|
|||
);
|
||||
res.status(200).json({ token: token });
|
||||
} else {
|
||||
logger.error({fileName: 'Authenticate', lineNum: 38, msg: 'Password Validation Failed!'});
|
||||
logger.error({fileName: 'Authenticate', lineNum: 36, msg: 'Invalid Password!'});
|
||||
res.status(401).json({
|
||||
message: "Authentication Failed!",
|
||||
error: "Password Validation Failed!"
|
||||
error: "Invalid Password!"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -44,9 +44,9 @@ exports.authenticateUser = (req, res, next) => {
|
|||
|
||||
exports.resetPassword = (req, res, next) => {
|
||||
if(+common.rtl_sso) {
|
||||
logger.error({fileName: 'Authenticate', lineNum: 46, msg: 'Password Reset Failed!'});
|
||||
res.status(402).json({
|
||||
message: "Password Reset Failure!",
|
||||
logger.error({fileName: 'Authenticate', lineNum: 47, msg: 'Password Reset Failed!'});
|
||||
res.status(401).json({
|
||||
message: "Password Reset Failed!",
|
||||
error: "Password cannot be reset for SSO authentication!"
|
||||
});
|
||||
} else {
|
||||
|
|
@ -60,8 +60,8 @@ exports.resetPassword = (req, res, next) => {
|
|||
);
|
||||
res.status(200).json({ token: token });
|
||||
} else {
|
||||
logger.error({fileName: 'Authenticate', lineNum: 62, msg: 'Password Reset Failed!'});
|
||||
res.status(402).json({
|
||||
logger.error({fileName: 'Authenticate', lineNum: 63, msg: 'Password Reset Failed!'});
|
||||
res.status(401).json({
|
||||
message: "Password Reset Failed!",
|
||||
error: "Old password is not correct!"
|
||||
});
|
||||
|
|
@ -80,4 +80,4 @@ exports.verifyToken = (req, res, next) => {
|
|||
error: "Token Verification Failed!"
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ exports.getBalance = (req, res, next) => {
|
|||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/getBalance';
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Balance', msg: ' Balance Received: ' + JSON.stringify(body)});
|
||||
logger.info({fileName: 'Balance', msg: 'Balance Received: ' + JSON.stringify(body)});
|
||||
if(!body.totalBalance) {
|
||||
body.totalBalance = 0;
|
||||
body.btc_totalBalance = 0;
|
||||
|
|
@ -26,10 +26,17 @@ exports.getBalance = (req, res, next) => {
|
|||
} else {
|
||||
body.btc_unconfBalance = common.convertToBTC(body.unconfBalance);
|
||||
}
|
||||
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Balance', lineNum: 38, msg: 'Balance Fetch Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching balance failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -16,8 +16,15 @@ exports.listChannels = (req, res, next) => {
|
|||
})
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 14, msg: 'List Channels: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 26, msg: 'List Channels: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Fetching List Channels Failed!',
|
||||
error: err.error
|
||||
|
|
@ -33,6 +40,7 @@ exports.openChannel = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Open Channel Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 42, msg: 'Open Channel Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Open Channel Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -41,8 +49,15 @@ exports.openChannel = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 39, msg: 'Open Channel Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 58, msg: 'Open Channel Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Open Channel Failed!',
|
||||
error: err.error
|
||||
|
|
@ -58,6 +73,7 @@ exports.setChannelFee = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Update Channel Policy: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 74, msg: 'Update Channel Policy Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Update Channel Policy Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -66,8 +82,15 @@ exports.setChannelFee = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 211, msg: 'Update Channel Policy: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 90, msg: 'Update Channel Policy: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Update Channel Policy Failed!',
|
||||
error: err.error
|
||||
|
|
@ -83,6 +106,7 @@ exports.closeChannel = (req, res, next) => {
|
|||
request.delete(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Close Channel Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 106, msg: 'Close Channel Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Close Channel Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -91,8 +115,15 @@ exports.closeChannel = (req, res, next) => {
|
|||
res.status(204).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 41, msg: 'Close Channel: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 122, msg: 'Close Channel Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Close Channel Failed!',
|
||||
error: err.error
|
||||
|
|
@ -117,11 +148,17 @@ exports.getLocalRemoteBalance = (req, res, next) => {
|
|||
} else {
|
||||
body.btc_remoteBalance = common.convertToBTC(body.remoteBalance);
|
||||
}
|
||||
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 14, msg: 'Local Remote Balance: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 156, msg: 'Local Remote Balance Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Fetching Local Remote Balance Failed!',
|
||||
error: err.error
|
||||
|
|
@ -135,7 +172,7 @@ exports.listForwards = (req, res, next) => {
|
|||
request.get(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Forwarding History Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 27, msg: 'Forwarding History Error: ' + JSON.stringify((!body) ? 'Error From Server!' : body.error)});
|
||||
logger.error({fileName: 'Channels', lineNum: 170, msg: 'Forwarding History Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Forwarding History Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -152,8 +189,15 @@ exports.listForwards = (req, res, next) => {
|
|||
res.status(200).json({ last_offset_index: 0, forwarding_events: body });
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 44, msg: 'Forwarding History Error: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 194, msg: 'Forwarding History Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Forwarding History Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.getFees = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Fees', msg: 'Fee Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Fees', lineNum: 12, msg: 'Get Fee Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching fee failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -23,7 +24,15 @@ exports.getFees = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Fees', lineNum: 34, msg: 'Get Fees Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching fee failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -8,48 +8,65 @@ exports.getInfo = (req, res, next) => {
|
|||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/getinfo';
|
||||
logger.info({fileName:'GetInfo', msg: 'Selected Node: ' + JSON.stringify(common.selectedNode.ln_node)});
|
||||
logger.info({fileName: 'GetInfo', msg: 'Calling getinfo from c-lightning server url: ' + options.url});
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'GetInfo', msg: JSON.stringify(body)});
|
||||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
res.status(500).json({
|
||||
message: "Fetching Info failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
body.currency_unit = 'BTC';
|
||||
body.smaller_currency_unit = 'Sats';
|
||||
body.lnImplementation = 'C-Lightning';
|
||||
let chainObj = { chain: '', network: '' };
|
||||
if (body.network === 'testnet') {
|
||||
chainObj.chain = 'Bitcoin';
|
||||
chainObj.network = 'Testnet';
|
||||
} else if (body.network === 'bitcoin') {
|
||||
chainObj.chain = 'Bitcoin';
|
||||
chainObj.network = 'Mainnet';
|
||||
} else if (body.network === 'litecoin') {
|
||||
chainObj.chain = 'Litecoin';
|
||||
chainObj.network = 'Mainnet';
|
||||
} else if (body.network === 'litecoin-testnet') {
|
||||
chainObj.chain = 'Litecoin';
|
||||
chainObj.network = 'Testnet';
|
||||
}
|
||||
body.chains = [chainObj];
|
||||
body.uris = [];
|
||||
if (body.address && body.address.length>0) {
|
||||
body.address.forEach(addr => {
|
||||
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
||||
});
|
||||
}
|
||||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
return res.status(500).json({
|
||||
message: "Fetching Info failed!",
|
||||
error: err.error
|
||||
logger.info({fileName: 'GetInfo', msg: 'Calling Info from C-Lightning server url: ' + options.url});
|
||||
if (!options.headers || !options.headers.macaroon) {
|
||||
logger.error({fileName: 'GetInfo', lineNum: 13, msg: 'C-Lightning Get info failed due to bad or missing macaroon!'});
|
||||
res.status(502).json({
|
||||
message: "Fetching Info Failed!",
|
||||
error: "Bad Macaroon"
|
||||
});
|
||||
});
|
||||
} else {
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'GetInfo', msg: JSON.stringify(body)});
|
||||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'GetInfo', lineNum: 24, msg: 'Get Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Info failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
body.currency_unit = 'BTC';
|
||||
body.smaller_currency_unit = 'Sats';
|
||||
body.lnImplementation = 'C-Lightning';
|
||||
let chainObj = { chain: '', network: '' };
|
||||
if (body.network === 'testnet') {
|
||||
chainObj.chain = 'Bitcoin';
|
||||
chainObj.network = 'Testnet';
|
||||
} else if (body.network === 'bitcoin') {
|
||||
chainObj.chain = 'Bitcoin';
|
||||
chainObj.network = 'Mainnet';
|
||||
} else if (body.network === 'litecoin') {
|
||||
chainObj.chain = 'Litecoin';
|
||||
chainObj.network = 'Mainnet';
|
||||
} else if (body.network === 'litecoin-testnet') {
|
||||
chainObj.chain = 'Litecoin';
|
||||
chainObj.network = 'Testnet';
|
||||
}
|
||||
body.chains = [chainObj];
|
||||
body.uris = [];
|
||||
if (body.address && body.address.length>0) {
|
||||
body.address.forEach(addr => {
|
||||
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
||||
});
|
||||
}
|
||||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'GetInfo', lineNum: 57, msg: 'Get Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Info failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ exports.deleteExpiredInvoice = (req, res, next) => {
|
|||
request.delete(options).then((body) => {
|
||||
logger.info({fileName: 'Invoice', msg: 'Invoices Deleted: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 13, msg: 'Invoice Delete Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Deleting Invoice Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -17,7 +18,15 @@ exports.deleteExpiredInvoice = (req, res, next) => {
|
|||
}
|
||||
res.status(204).json({status: 'Invoice Deleted Successfully'});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 28, msg: 'Invoice Delete Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Deleting Invoice Failed!",
|
||||
error: err.error
|
||||
|
|
@ -32,6 +41,7 @@ exports.listInvoices = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Invoice', msg: 'Invoices List Received: ' + body});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 43, msg: 'List Invoice Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Invoice Info failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -48,7 +58,15 @@ exports.listInvoices = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 67, msg: 'List Invoice Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Invoice Info failed!",
|
||||
error: err.error
|
||||
|
|
@ -63,6 +81,7 @@ exports.addInvoice = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Invoice', msg: 'Add Invoice Responce: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 82, msg: 'Add Invoice Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Add Invoice Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -71,7 +90,15 @@ exports.addInvoice = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 98, msg: 'Add Invoice Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Add Invoice Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ exports.signMessage = (req, res, next) => {
|
|||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Signed: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Messages', lineNum: 13, msg: 'Message Sign Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Sign message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -18,8 +19,15 @@ exports.signMessage = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Sign Message Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Messages', lineNum: 29, msg: 'Sign Message Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Sign Message Failed!',
|
||||
error: err.error
|
||||
|
|
@ -33,6 +41,7 @@ exports.verifyMessage = (req, res, next) => {
|
|||
request.get(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Verified: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Messages', lineNum: 43, msg: 'Verify Message Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Verify message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -41,8 +50,15 @@ exports.verifyMessage = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Message Verification Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Messages', lineNum: 59, msg: 'Message Verification Failed: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Verify Message Failed!',
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.getRoute = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Network', msg: 'Query Routes Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Network', lineNum: 12, msg: 'Query Routes Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -16,7 +17,15 @@ exports.getRoute = (req, res, next) => {
|
|||
}
|
||||
res.status(200).json({routes: body});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Network', lineNum: 27, msg: 'Query Routes Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: err.error
|
||||
|
|
@ -34,7 +43,15 @@ exports.listNode = (req, res, next) => {
|
|||
});
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Network', lineNum: 52, msg: 'Node Lookup Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Node Lookup Failed!",
|
||||
error: err.error
|
||||
|
|
@ -51,7 +68,15 @@ exports.listChannel = (req, res, next) => {
|
|||
body[1].last_update_str = (body.length > 1 && body[1].last_update) ? common.convertTimestampToDate(body[1].last_update) : '';
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Network', lineNum: 76, msg: 'Channel Lookup Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Channel Lookup Failed!",
|
||||
error: err.error
|
||||
|
|
@ -65,7 +90,15 @@ exports.feeRates = (req, res, next) => {
|
|||
request(options).then(function (body) {
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Network', lineNum: 97, msg: 'Fee Rates Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fee Rates Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -9,7 +9,15 @@ exports.getNewAddress = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'OnChain', lineNum: 19, msg: 'OnChain New Address Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching new address failed!",
|
||||
error: err.error
|
||||
|
|
@ -25,6 +33,7 @@ exports.onChainWithdraw = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'OnChain', msg: 'OnChain Withdraw Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'OnChain', lineNum: 35, msg: 'OnChain Withdraw Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'OnChain Withdraw Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -33,8 +42,15 @@ exports.onChainWithdraw = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'OnChain', lineNum: 211, msg: 'OnChain Withdraw Response: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'OnChain', lineNum: 51, msg: 'OnChain Withdraw Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'OnChain Withdraw Failed!',
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.listPayments = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Payments', msg: 'Payment List Received: ' + JSON.stringify(body.payments)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Payments', lineNum: 12, msg: 'Payments List Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Payments List Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -23,7 +24,15 @@ exports.listPayments = (req, res, next) => {
|
|||
res.status(200).json(body.payments);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Payments', lineNum: 34, msg: 'Payments List Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Payments List Failed!",
|
||||
error: err.error
|
||||
|
|
@ -37,6 +46,7 @@ exports.decodePayment = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Payments', msg: 'Payment Decode Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Payments', lineNum: 48, msg: 'Payment Decode Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Payment Request Decode Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -47,7 +57,15 @@ exports.decodePayment = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Payments', lineNum: 66, msg: 'Payment Decode Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Payment Request Decode Failed!",
|
||||
error: err.error
|
||||
|
|
@ -62,6 +80,7 @@ exports.postPayment = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Payments', msg: 'Payment Post Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Payments', lineNum: 81, msg: 'Payment Post Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Payment Post Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -70,7 +89,15 @@ exports.postPayment = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Payments', lineNum: 97, msg: 'Payments Post Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Payment Post Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -7,11 +7,19 @@ exports.getPeers = (req, res, next) => {
|
|||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/peer/listPeers';
|
||||
request(options).then(function (body) {
|
||||
let peers = ( body) ? common.sortDescByKey(body, 'alias') : [];
|
||||
let peers = ( body) ? common.sortDescByStrKey(body, 'alias') : [];
|
||||
logger.info({fileName: 'Peers', msg: 'Peers with Alias: ' + JSON.stringify(peers)});
|
||||
res.status(200).json(peers);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Peers', lineNum: 21, msg: 'Peers List Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Peers Fetch Failed!",
|
||||
error: err.error
|
||||
|
|
@ -25,6 +33,7 @@ exports.postPeer = (req, res, next) => {
|
|||
options.body = req.body;
|
||||
request.post(options, (error, response, body) => {
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Peers', lineNum: 35, msg: 'Connect Peer Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Adding peer failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -33,12 +42,20 @@ exports.postPeer = (req, res, next) => {
|
|||
logger.info({fileName: 'Peers', msg: 'Peer Added: ' + JSON.stringify(body)});
|
||||
options.url = common.getSelLNServerUrl() + '/peer/listPeers';
|
||||
request(options).then(function (body) {
|
||||
let peers = ( body) ? common.sortDescByKey(body, 'alias') : [];
|
||||
let peers = ( body) ? common.sortDescByStrKey(body, 'alias') : [];
|
||||
peers = common.newestOnTop(peers, 'id', req.body.id);
|
||||
logger.info({fileName: 'Peers', msg: 'Peer with Newest On Top: ' + JSON.stringify(peers)});
|
||||
logger.info({fileName: 'Peers', msg: 'Peer Added Successfully'});
|
||||
res.status(201).json(peers);
|
||||
}).catch((err) => {
|
||||
}).catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Peers', lineNum: 56, msg: 'Connect Peer Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Peer Add Failed!",
|
||||
error: err.error
|
||||
|
|
@ -54,6 +71,7 @@ exports.deletePeer = (req, res, next) => {
|
|||
request.delete(options).then((body) => {
|
||||
logger.info({fileName: 'Peers', msg: 'Detach Peer Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Peers', lineNum: 72, msg: 'Detach Peer Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Detach peer failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -63,10 +81,18 @@ exports.deletePeer = (req, res, next) => {
|
|||
res.status(204).json({});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
||||
delete err.options.headers.macaroon;
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
||||
delete err.response.request.headers.macaroon;
|
||||
}
|
||||
logger.error({fileName: 'Peers', lineNum: 89, msg: 'Detach Peer Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Detach Peer Failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ exports.getBalance = (req, res, next) => {
|
|||
options.qs = req.query;
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Balance', msg: 'Request params: ' + JSON.stringify(req.params) + 'Request Query: ' + JSON.stringify(req.query) + ' Balance Received: ' + JSON.stringify(body)});
|
||||
if( body) {
|
||||
if (body) {
|
||||
if (upperCase(req.params.source) === 'BLOCKCHAIN') {
|
||||
if (!body.total_balance) { body.total_balance = 0; }
|
||||
if (!body.confirmed_balance) { body.confirmed_balance = 0; }
|
||||
|
|
@ -28,7 +28,15 @@ exports.getBalance = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Balance', lineNum: 38, msg: 'Fetch Balance Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching balance failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -5,13 +5,17 @@ var options = {};
|
|||
|
||||
getAliasForChannel = (channel) => {
|
||||
return new Promise(function(resolve, reject) {
|
||||
options.url = common.getSelLNServerUrl() + '/graph/node/' + channel.remote_pubkey;
|
||||
let pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : '';
|
||||
options.url = common.getSelLNServerUrl() + '/graph/node/' + pubkey;
|
||||
request(options).then(function(aliasBody) {
|
||||
logger.info({fileName: 'Channels', msg: 'Alias: ' + JSON.stringify(aliasBody.node.alias)});
|
||||
channel.remote_alias = aliasBody.node.alias;
|
||||
resolve(aliasBody.node.alias);
|
||||
})
|
||||
.catch(err => resolve(''));
|
||||
.catch(err => {
|
||||
channel.remote_alias = pubkey.slice(0, 10) + '...' + pubkey.slice(-10);
|
||||
resolve(pubkey);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -38,8 +42,16 @@ exports.getAllChannels = (req, res, next) => {
|
|||
body.channels = common.sortDescByKey(body.channels, 'balancedness');
|
||||
logger.info({fileName: 'Channels', msg: 'All Channels with Alias: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
}).catch(err => {
|
||||
logger.error({fileName: 'Channels', lineNum: 49, msg: 'Get All Channel Alias: ' + JSON.stringify(err)});
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 48, msg: 'Get All Channel Alias Error: ' + JSON.stringify(err)});
|
||||
res.status(500).json({
|
||||
message: 'Fetching Channels Alias Failed!',
|
||||
error: err.error
|
||||
|
|
@ -50,8 +62,15 @@ exports.getAllChannels = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 54, msg: 'Get All Channel: ' + JSON.stringify(err.error)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 66, msg: 'Get All Channels Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Fetching All Channels Failed!',
|
||||
error: err.error
|
||||
|
|
@ -64,18 +83,53 @@ exports.getPendingChannels = (req, res, next) => {
|
|||
options.url = common.getSelLNServerUrl() + '/channels/pending';
|
||||
options.qs = req.query;
|
||||
request(options).then(function (body) {
|
||||
let channels = [];
|
||||
if (!body.total_limbo_balance) {
|
||||
body.total_limbo_balance = 0;
|
||||
body.btc_total_limbo_balance = 0;
|
||||
} else {
|
||||
body.btc_total_limbo_balance = common.convertToBTC(body.total_limbo_balance);
|
||||
}
|
||||
logger.info({fileName: 'Channels', msg: 'Pending Channels: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
const promises = [];
|
||||
if(body.pending_open_channels && body.pending_open_channels.length > 0) {
|
||||
body.pending_open_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
|
||||
}
|
||||
if(body.pending_closing_channels && body.pending_closing_channels.length > 0) {
|
||||
body.pending_closing_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
|
||||
}
|
||||
if(body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) {
|
||||
body.pending_force_closing_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
|
||||
}
|
||||
if(body.waiting_close_channels && body.waiting_close_channels.length > 0) {
|
||||
body.waiting_close_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
|
||||
}
|
||||
Promise.all(promises).then(function(values) {
|
||||
logger.info({fileName: 'Channels', msg: 'Pending Channels: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 106, msg: 'Get Pending Channel Alias Error: ' + JSON.stringify(err)});
|
||||
res.status(500).json({
|
||||
message: 'Fetching Pending Channels Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 78, msg: 'Get Pending Channel: ' + JSON.stringify(err.error)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 97, msg: 'Get Pending Channel Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Fetching Pending Channels Failed!',
|
||||
error: err.error
|
||||
|
|
@ -88,18 +142,46 @@ exports.getClosedChannels = (req, res, next) => {
|
|||
options.url = common.getSelLNServerUrl() + '/channels/closed';
|
||||
options.qs = req.query;
|
||||
request(options).then(function (body) {
|
||||
let channels = [];
|
||||
if (body.channels && body.channels.length > 0) {
|
||||
body.channels.forEach(channel => {
|
||||
channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type;
|
||||
Promise.all(
|
||||
body.channels.map(channel => {
|
||||
channel.close_type = (!channel.close_type) ? 'COOPERATIVE_CLOSE' : channel.close_type;
|
||||
return getAliasForChannel(channel);
|
||||
})
|
||||
)
|
||||
.then(function(values) {
|
||||
body.channels = common.sortDescByKey(body.channels, 'close_height');
|
||||
logger.info({fileName: 'Channels', msg: 'Closed Channels: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 48, msg: 'Get All Channel Alias Error: ' + JSON.stringify(err)});
|
||||
res.status(500).json({
|
||||
message: 'Fetching Channels Alias Failed!',
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
body.channels = common.sortDescByKey(body.channels, 'close_height');
|
||||
}
|
||||
logger.info({fileName: 'Channels', msg: 'Closed Channels: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
} else {
|
||||
body.channels = [];
|
||||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 102, msg: 'Get Closed Channel: ' + JSON.stringify(err.error)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 126, msg: 'Get Closed Channel Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Fetching Closed Channels Failed!',
|
||||
error: err.error
|
||||
|
|
@ -125,6 +207,7 @@ exports.postChannel = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Channel Open Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 152, msg: 'Open New Channel Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Open Channel Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -133,8 +216,15 @@ exports.postChannel = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 103, msg: 'Open Channel: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 168, msg: 'Open New Channel Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Open Channel Failed!',
|
||||
error: err.error
|
||||
|
|
@ -166,11 +256,13 @@ exports.postTransactions = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Send Payment Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 200, msg: 'Send Payment Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Send Payment Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else if (body.payment_error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 206, msg: 'Send Payment Error: ' + JSON.stringify(body.payment_error)});
|
||||
res.status(500).json({
|
||||
message: 'Send Payment Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.payment_error
|
||||
|
|
@ -179,8 +271,15 @@ exports.postTransactions = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 143, msg: 'Send Payment: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 222, msg: 'Send Payment Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Send Payment Failed!',
|
||||
error: err.error
|
||||
|
|
@ -199,6 +298,7 @@ exports.closeChannel = (req, res, next) => {
|
|||
request.delete(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Close Channel Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 241, msg: 'Close Channel Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Close Channel Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -207,8 +307,15 @@ exports.closeChannel = (req, res, next) => {
|
|||
res.status(204).json({message: 'Channel Closed!'});
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 169, msg: 'Close Channel: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 257, msg: 'Close Channel Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Close Channel Failed!',
|
||||
error: err.error
|
||||
|
|
@ -241,6 +348,7 @@ exports.postChanPolicy = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Channels', msg: 'Update Channel Policy: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Channels', lineNum: 290, msg: 'Update Channel Policy Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: 'Update Channel Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -249,8 +357,15 @@ exports.postChanPolicy = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels', lineNum: 211, msg: 'Update Channel Policy: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Channels', lineNum: 306, msg: 'Update Channel Policy Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Update Channel Failed!',
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function getFilesList(callback) {
|
|||
}
|
||||
});
|
||||
}
|
||||
response = {all_restore_exists: all_restore_exists, files: files_list};
|
||||
response = {all_restore_exists: all_restore_exists, files: files_list};
|
||||
callback(response);
|
||||
});
|
||||
}
|
||||
|
|
@ -33,12 +33,10 @@ exports.getBackup = (req, res, next) => {
|
|||
if (req.params.channelPoint === 'ALL') {
|
||||
channel_backup_file = common.selectedNode.channel_backup_path + common.path_separator + 'channel-all.bak';
|
||||
message = 'All Channels Backup Successful.';
|
||||
// message = 'All Channels Backup Successful at: ' + channel_backup_file + ' !';
|
||||
options.url = common.getSelLNServerUrl() + '/channels/backup';
|
||||
} else {
|
||||
channel_backup_file = common.selectedNode.channel_backup_path + common.path_separator + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak';
|
||||
message = 'Channel Backup Successful.';
|
||||
// message = 'Channel Backup Successful at: ' + channel_backup_file + ' !';
|
||||
let channelpoint = req.params.channelPoint.replace(':', '/');
|
||||
options.url = common.getSelLNServerUrl() + '/channels/backup/' + channelpoint;
|
||||
let exists = fs.existsSync(channel_backup_file);
|
||||
|
|
@ -49,23 +47,46 @@ exports.getBackup = (req, res, next) => {
|
|||
var createStream = fs.createWriteStream(channel_backup_file);
|
||||
createStream.end();
|
||||
}
|
||||
catch (err) {
|
||||
catch (errRes) {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'ChannelsBackup', lineNum: 57, msg: 'Channels Backup Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({ message: 'Channels Backup Failed!', error: err });
|
||||
}
|
||||
}
|
||||
}
|
||||
request(options).then(function (body) {
|
||||
logger.info({fileName: 'Channels Backup', msg: 'Channel Backup: ' + JSON.stringify(body)});
|
||||
fs.writeFile(channel_backup_file, JSON.stringify(body), function(err) {
|
||||
if (err) {
|
||||
logger.info({fileName: 'ChannelsBackup', msg: 'Channel Backup: ' + JSON.stringify(body)});
|
||||
fs.writeFile(channel_backup_file, JSON.stringify(body), function(errRes) {
|
||||
if (errRes) {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'ChannelsBackup', lineNum: 72, msg: 'Channels Backup Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({ message: 'Channels Backup Failed!', error: err.error });
|
||||
} else {
|
||||
res.status(200).json({ message: message });
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels Backup', lineNum: 44, msg: 'Channel Backup: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'ChannelsBackup', lineNum: 86, msg: 'Channel Backup Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Channels Backup Failed!',
|
||||
error: err.error
|
||||
|
|
@ -98,7 +119,6 @@ exports.postBackupVerify = (req, res, next) => {
|
|||
}
|
||||
} else {
|
||||
message = 'Channel Verify Successful.';
|
||||
// message = 'Channel ' + req.params.channelPoint + ' Verify Successful!';
|
||||
channel_verify_file = common.selectedNode.channel_backup_path + common.path_separator + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak';
|
||||
let exists = fs.existsSync(channel_verify_file);
|
||||
if (exists) {
|
||||
|
|
@ -111,11 +131,18 @@ exports.postBackupVerify = (req, res, next) => {
|
|||
}
|
||||
if (verify_backup !== '') {
|
||||
request.post(options).then(function (body) {
|
||||
logger.info({fileName: 'Channels Backup Verify', msg: 'Channel Backup Verify: ' + JSON.stringify(body)});
|
||||
logger.info({fileName: 'BackupVerify', msg: 'Channel Backup Verify: ' + JSON.stringify(body)});
|
||||
res.status(201).json({ message: message });
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels Backup Verify', lineNum: 93, msg: 'Channel Backup Verify: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'BackupVerify', lineNum: 141, msg: 'Channel Backup Verify Error: ' + JSON.stringify(err)});
|
||||
return res.status(404).json({
|
||||
message: 'Channel backup to Verify failed!',
|
||||
error: err.error
|
||||
|
|
@ -148,7 +175,6 @@ exports.postRestore = (req, res, next) => {
|
|||
}
|
||||
} else {
|
||||
message = 'Channel Restore Successful.';
|
||||
// message = 'Channel ' + req.params.channelPoint + ' Restore Successful!';
|
||||
channel_restore_file = common.selectedNode.channel_backup_path + common.path_separator + 'restore' + common.path_separator + 'channel-' + req.params.channelPoint.replace(':', '-') + '.bak';
|
||||
let exists = fs.existsSync(channel_restore_file);
|
||||
if (exists) {
|
||||
|
|
@ -161,10 +187,11 @@ exports.postRestore = (req, res, next) => {
|
|||
}
|
||||
if (restore_backup !== '') {
|
||||
request.post(options).then(function (body) {
|
||||
logger.info({fileName: 'Channels Backup Restore', msg: 'Channel Backup Restore: ' + JSON.stringify(body)});
|
||||
logger.info({fileName: 'ChannelRestore', msg: 'Channel Backup Restore: ' + JSON.stringify(body)});
|
||||
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
|
||||
getFilesList(getFilesListRes => {
|
||||
if (getFilesListRes.error) {
|
||||
logger.error({fileName: 'ChannelRestore', lineNum: 190, msg: 'Channel Restore Error: ' + JSON.stringify(getFilesListRes.error)});
|
||||
return res.status(500).json({ message: 'Channel restore failed!', list: getFilesListRes });
|
||||
} else {
|
||||
return res.status(201).json({ message: message, list: getFilesListRes });
|
||||
|
|
@ -172,8 +199,15 @@ exports.postRestore = (req, res, next) => {
|
|||
});
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Channels Backup Restore', lineNum: 143, msg: 'Channel Backup Restore: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'ChannelRestore', lineNum: 205, msg: 'Channel Restore Error: ' + JSON.stringify(err)});
|
||||
return res.status(404).json({
|
||||
message: 'Channel restore failed!',
|
||||
error: err.error.error
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ exports.getFees = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Fees', msg: 'Fee Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Fees', lineNum: 13, msg: 'Get Fee Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching fee failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -45,12 +46,22 @@ exports.getFees = (req, res, next) => {
|
|||
body.weekly_tx_count = weekly_tx_count && weekly_tx_count.length ? weekly_tx_count.length : 0;
|
||||
body.monthly_tx_count = history.forwarding_events && history.forwarding_events.length ? history.forwarding_events.length : 0;
|
||||
body.forwarding_events_history = history;
|
||||
if (history.error) { logger.error({fileName: 'Fees', lineNum: 48, msg: 'Fetch Forwarding Events Error: ' + JSON.stringify(err)}); }
|
||||
if (history.error) {
|
||||
logger.error({fileName: 'Fees', lineNum: 50, msg: 'Fetch Forwarding Events Error: ' + JSON.stringify(history.error)});
|
||||
}
|
||||
res.status(200).json(body);
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Fees', lineNum: 63, msg: 'Fetch Forwarding Events Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching fee failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.getInfo = (req, res, next) => {
|
|||
options = common.getOptions();
|
||||
options.url = common.getSelLNServerUrl() + '/getinfo';
|
||||
logger.info({fileName:'GetInfo', msg: 'Selected Node: ' + JSON.stringify(common.selectedNode.ln_node)});
|
||||
logger.info({fileName: 'GetInfo', msg: 'Calling Info from LND server url: ' + options.url});
|
||||
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
|
||||
logger.error({fileName: 'GetInfo', lineNum: 17, msg: 'LND Get info failed due to bad or missing macaroon!'});
|
||||
res.status(502).json({
|
||||
|
|
@ -17,12 +18,12 @@ exports.getInfo = (req, res, next) => {
|
|||
});
|
||||
} else {
|
||||
common.nodes.map(node => { if (node.lnImplementation === 'LND') { connect.getAllNodeAllChannelBackup(node); }});
|
||||
logger.info({fileName: 'GetInfo', msg: 'Calling getinfo from lnd server url: ' + options.url});
|
||||
request(options).then((body) => {
|
||||
logger.info({fileName: 'GetInfo', msg: JSON.stringify(body)});
|
||||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'GetInfo', lineNum: 26, msg: 'Get Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Info Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -31,7 +32,15 @@ exports.getInfo = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'GetInfo', lineNum: 42, msg: 'Get Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Info Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ exports.getDescribeGraph = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'Graph', msg: 'Describe Graph Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 27, msg: 'Describe Graph Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Describe Graph Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -32,7 +33,15 @@ exports.getDescribeGraph = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 43, msg: 'Describe Graph Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Describe Graph Failed!",
|
||||
error: err.error
|
||||
|
|
@ -48,6 +57,7 @@ exports.getGraphInfo = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'Graph', msg: 'Network Info Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 59, msg: 'Network Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching network Info failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -61,7 +71,15 @@ exports.getGraphInfo = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 80, msg: 'Fetch Network Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching network Info failed!",
|
||||
error: err.error
|
||||
|
|
@ -75,17 +93,26 @@ exports.getGraphNode = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Graph', msg: 'Node Info Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 94, msg: 'Fetch Node Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching node Info failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
}
|
||||
if ( body) {
|
||||
if (body) {
|
||||
body.node.last_update_str = (!body.node.last_update) ? '' : common.convertTimestampToDate(body.node.last_update);
|
||||
}
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 112, msg: 'Fetch Node Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching node Info failed!",
|
||||
error: err.error
|
||||
|
|
@ -99,17 +126,26 @@ exports.getGraphEdge = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Graph', msg: 'Edge Info Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 126, msg: 'Fetch Edge Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
}
|
||||
if ( body) {
|
||||
if (body) {
|
||||
body.last_update_str = (!body.last_update) ? '' : common.convertTimestampToDate(body.last_update);
|
||||
}
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 144, msg: 'Fetch Edge Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
error: err.error
|
||||
|
|
@ -127,12 +163,13 @@ exports.getQueryRoutes = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Graph', msg: 'Query Routes Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 162, msg: 'Fetch Query Routes Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
}
|
||||
if ( body.routes && body.routes.length > 0) {
|
||||
if (body.routes && body.routes.length > 0) {
|
||||
body.routes.forEach(route => {
|
||||
if ( route.hops) {
|
||||
Promise.all(
|
||||
|
|
@ -144,7 +181,16 @@ exports.getQueryRoutes = (req, res, next) => {
|
|||
.then(function(values) {
|
||||
logger.info({fileName: 'Graph', msg: 'Hops with Alias: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
}).catch(err => {
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 187, msg: 'Fetch Query Routes Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: err.error
|
||||
|
|
@ -154,7 +200,15 @@ exports.getQueryRoutes = (req, res, next) => {
|
|||
});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 204, msg: 'Fetch Query Routes Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Query Routes Failed!",
|
||||
error: err.error
|
||||
|
|
@ -168,15 +222,15 @@ exports.getRemoteFeePolicy = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Graph', msg: 'Edge Info Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Graph', lineNum: 218, msg: 'Fetch Edge Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
});
|
||||
}
|
||||
if ( body) {
|
||||
if (body) {
|
||||
body.last_update_str = (!body.last_update) ? '' : common.convertTimestampToDate(body.last_update);
|
||||
}
|
||||
|
||||
remoteNodeFee = {};
|
||||
if(body.node1_pub === req.params.localPubkey){
|
||||
remoteNodeFee = {
|
||||
|
|
@ -184,21 +238,27 @@ exports.getRemoteFeePolicy = (req, res, next) => {
|
|||
fee_base_msat: body.node2_policy.fee_base_msat,
|
||||
fee_rate_milli_msat: body.node2_policy.fee_rate_milli_msat
|
||||
};
|
||||
}
|
||||
else if(body.node2_pub === req.params.localPubkey) {
|
||||
} else if(body.node2_pub === req.params.localPubkey) {
|
||||
remoteNodeFee = {
|
||||
time_lock_delta: body.node1_policy.time_lock_delta,
|
||||
fee_base_msat: body.node1_policy.fee_base_msat,
|
||||
fee_rate_milli_msat: body.node1_policy.fee_rate_milli_msat
|
||||
};
|
||||
}
|
||||
|
||||
res.status(200).json(remoteNodeFee);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Graph', lineNum: 250, msg: 'Fetch Edge Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Edge Info Failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.getGraphInfo = (req, res, next) => {
|
|||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'GraphInfo', lineNum: 12, msg: 'Fetch Network Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching network Info failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -20,5 +21,19 @@ exports.getGraphInfo = (req, res, next) => {
|
|||
body.btc_max_channel_size = (!body.max_channel_size) ? 0 : common.convertToBTC(body.max_channel_size);
|
||||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'GraphInfo', lineNum: 32, msg: 'Fetch Network Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Network Info Failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ exports.getInvoice = (req, res, next) => {
|
|||
request(options).then((body) => {
|
||||
logger.info({fileName: 'Invoice', msg: 'Invoice Info Received: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 12, msg: 'Invoice Info Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Invoice Info Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -16,7 +17,15 @@ exports.getInvoice = (req, res, next) => {
|
|||
}
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 27, msg: 'Fetch Invoice Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Invoice Info Failed!",
|
||||
error: err.error
|
||||
|
|
@ -33,6 +42,7 @@ exports.listInvoices = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'Invoice', msg: 'Invoices List Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 44, msg: 'List Invoices Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Invoice Info failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -51,9 +61,17 @@ exports.listInvoices = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 70, msg: 'List Invoice Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Invoice Info failed!",
|
||||
message: "Fetching Invoices failed!",
|
||||
error: err.error
|
||||
});
|
||||
});
|
||||
|
|
@ -76,6 +94,7 @@ exports.addInvoice = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Invoice', msg: 'Add Invoice Responce: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Invoice', lineNum: 95, msg: 'Add Invoice Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Add Invoice Failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -84,7 +103,15 @@ exports.addInvoice = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Invoice', lineNum: 111, msg: 'Add Invoice Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Add Invoice Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
var fs = require('fs');
|
||||
|
||||
exports.getLNDSettings = (req, res, next) => {
|
||||
fs.readFile(req.headers.filepath, function(err, data) {
|
||||
if (err) {
|
||||
fs.readFile(req.headers.filepath, function(errRes, data) {
|
||||
if (errRes) {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'LNDConfSetting', lineNum: 12, msg: 'Reading Config File Error: ' + JSON.stringify(err)});
|
||||
res.status(500).json({
|
||||
message: "Reading Config File Failed!",
|
||||
error: err
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ exports.loopOut = (req, res, next) => {
|
|||
request.post(options).then(function (body) {
|
||||
logger.info({fileName: 'Loop', msg: 'Loop Out: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Loop', lineNum: 28, msg: 'Loop Out Error: ' + JSON.stringify(body.error)});
|
||||
res.status(500).json({
|
||||
message: 'Loop Out Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error.message
|
||||
|
|
@ -33,11 +34,18 @@ exports.loopOut = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Loop Out', lineNum: 33, msg: 'Loop Out Failed: ' + JSON.stringify(err.error)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 44, msg: 'Loop Out Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Out Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -50,10 +58,18 @@ exports.loopOutTerms = (req, res, next) => {
|
|||
logger.info({fileName: 'Loop', msg: 'Loop Out Terms: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 67, msg: 'Loop Out Terms Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Out Terms Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -70,10 +86,18 @@ exports.loopOutQuote = (req, res, next) => {
|
|||
body.swap_payment_dest = body.swap_payment_dest ? Buffer.from(body.swap_payment_dest, 'base64').toString('hex') : '';
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 94, msg: 'Loop Out Quote Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Out Quote Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -101,17 +125,33 @@ exports.loopOutTermsAndQuotes = (req, res, next) => {
|
|||
logger.info({fileName: 'Loop', msg: 'Loop Out Quotes 2: ' + JSON.stringify(values[1])});
|
||||
res.status(200).json(values);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 132, msg: 'Loop Out Quotes Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Out Quotes Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 146, msg: 'Loop Out Terms Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Out Terms Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -124,25 +164,31 @@ exports.loopIn = (req, res, next) => {
|
|||
amt: req.body.amount,
|
||||
max_swap_fee: req.body.swapFee,
|
||||
max_miner_fee: req.body.minerFee
|
||||
// last_hop: req.body.lastHop,
|
||||
// external_htlc: req.body.externalHtlc
|
||||
});
|
||||
request.post(options).then(function (body) {
|
||||
logger.info({fileName: 'Loop', msg: 'Loop In: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Loop', lineNum: 166, msg: 'Loop In Error: ' + JSON.stringify(body.error)});
|
||||
res.status(500).json({
|
||||
message: 'Loop In Failed!',
|
||||
error: (!body) ? 'Error From Server!' : body.error.message
|
||||
error: (body.error && body.error.message) ? body.error.message : 'Error From Server!'
|
||||
});
|
||||
} else {
|
||||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Loop In', lineNum: 134, msg: 'Loop In Failed: ' + JSON.stringify(err.error)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 182, msg: 'Loop In Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop In Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -155,10 +201,18 @@ exports.loopInTerms = (req, res, next) => {
|
|||
logger.info({fileName: 'Loop', msg: 'Loop In Terms: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 205, msg: 'Loop In Terms Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop In Terms Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -175,10 +229,18 @@ exports.loopInQuote = (req, res, next) => {
|
|||
body.swap_payment_dest = body.swap_payment_dest ? Buffer.from(body.swap_payment_dest, 'base64').toString('hex') : '';
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 232, msg: 'Loop In Quote Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop In Quote Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -206,17 +268,33 @@ exports.loopInTermsAndQuotes = (req, res, next) => {
|
|||
logger.info({fileName: 'Loop', msg: 'Loop In Quotes 2: ' + JSON.stringify(values[1])});
|
||||
res.status(200).json(values);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 270, msg: 'Loop In Quotes Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop In Quotes Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 284, msg: 'Loop In Terms Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop In Terms Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -238,10 +316,18 @@ exports.swaps = (req, res, next) => {
|
|||
}
|
||||
res.status(200).json(body.swaps);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 316, msg: 'List Swaps Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Swaps Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -257,11 +343,18 @@ exports.swap = (req, res, next) => {
|
|||
body.last_update_time_str = (!body.last_update_time) ? '' : common.convertTimestampToDate(Math.round(body.last_update_time/1000000000));
|
||||
res.status(200).json(body);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Loop', lineNum: 342, msg: 'Swap Info Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Loop Swap Failed!",
|
||||
error: err.error.error ? err.error.error : err.error
|
||||
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ exports.signMessage = (req, res, next) => {
|
|||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Signed: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Messages', lineNum: 15, msg: 'Sign Message Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Sign message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -20,8 +21,15 @@ exports.signMessage = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Sign Message Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Messages', lineNum: 31, msg: 'Sign Message Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Sign Message Failed!',
|
||||
error: err.error
|
||||
|
|
@ -39,6 +47,7 @@ exports.verifyMessage = (req, res, next) => {
|
|||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Messages', msg: 'Message Verified: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Messages', lineNum: 49, msg: 'Verify Message Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Verify message failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -47,8 +56,15 @@ exports.verifyMessage = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
logger.error({fileName: 'Messages', lineNum: 24, msg: 'Message Verification Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Messages', lineNum: 65, msg: 'Message Verification Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: 'Verify Message Failed!',
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -11,15 +11,24 @@ exports.getNewAddress = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'NewAddress', msg: 'New Address Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'NewAddress', lineNum: 14, msg: 'New Address Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching new address failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
res.status(200).json(body);
|
||||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'NewAddress', lineNum: 30, msg: 'New Address Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching new address failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ exports.decodePayment = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'PayReq', msg: 'Payment Decode Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'PayReq', lineNum: 14, msg: 'Payment Decode Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Payment Request Decode Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -21,7 +22,15 @@ exports.decodePayment = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'PayReq', lineNum: 32, msg: 'Payment Decode Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Payment Request Decode Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ exports.getPayments = (req, res, next) => {
|
|||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'Payments', msg: 'Payment Decoded Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'Payments', lineNum: 14, msg: 'List Payments Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Payments List Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
|
|
@ -25,7 +26,15 @@ exports.getPayments = (req, res, next) => {
|
|||
res.status(200).json(body.payments);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Payments', lineNum: 36, msg: 'List Payments Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Payments List Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -12,7 +12,10 @@ getAliasForPeers = (peer) => {
|
|||
peer.alias = aliasBody.node.alias;
|
||||
resolve(aliasBody.node.alias);
|
||||
})
|
||||
.catch(err => resolve(''));
|
||||
.catch(err => {
|
||||
peer.alias = peer.pub_key.slice(0, 10) + '...' + peer.pub_key.slice(-10);
|
||||
resolve(peer.pub_key);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -29,14 +32,21 @@ exports.getPeers = (req, res, next) => {
|
|||
.then(function(values) {
|
||||
logger.info({fileName: 'Peers', msg: 'Peers with Alias before Sort: ' + JSON.stringify(body)});
|
||||
if (body.peers) {
|
||||
body.peers = common.sortDescByKey(body.peers, 'alias');
|
||||
body.peers = common.sortDescByStrKey(body.peers, 'alias');
|
||||
}
|
||||
logger.info({fileName: 'Peers', msg: 'Peers with Alias after Sort: ' + JSON.stringify(body)});
|
||||
res.status(200).json(body.peers);
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error({fileName: 'Peers', lineNum: 39, msg: 'Peers List Failed: ' + JSON.stringify(err)});
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Peers', lineNum: 39, msg: 'List Peers Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Peers List Failed!",
|
||||
error: err.error
|
||||
|
|
@ -54,6 +64,7 @@ exports.postPeer = (req, res, next) => {
|
|||
request.post(options, (error, response, body) => {
|
||||
logger.info({fileName: 'Peers', msg: 'Peer Added: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Peers', lineNum: 63, msg: 'Add Peer Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Adding peer failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -67,8 +78,8 @@ exports.postPeer = (req, res, next) => {
|
|||
return getAliasForPeers(peer);
|
||||
}))
|
||||
.then(function(values) {
|
||||
if ( body.peers) {
|
||||
body.peers = common.sortDescByKey(body.peers, 'alias');
|
||||
if (body.peers) {
|
||||
body.peers = common.sortDescByStrKey(body.peers, 'alias');
|
||||
logger.info({fileName: 'Peers', msg: 'Peer with Alias: ' + JSON.stringify(body)});
|
||||
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);
|
||||
logger.info({fileName: 'Peers', msg: 'Peer with Newest On Top: ' + JSON.stringify(body)});
|
||||
|
|
@ -76,7 +87,15 @@ exports.postPeer = (req, res, next) => {
|
|||
logger.info({fileName: 'Peers', msg: 'Peer Added Successfully'});
|
||||
res.status(201).json(body.peers);
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Peer', lineNum: 93, msg: 'Add Peer Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Peer Add Failed!",
|
||||
error: err.error
|
||||
|
|
@ -93,6 +112,7 @@ exports.deletePeer = (req, res, next) => {
|
|||
request.delete(options).then((body) => {
|
||||
logger.info({fileName: 'Peers', msg: 'Detach Peer Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Peers', lineNum: 110, msg: 'Detach Peer Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Detach peer failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -102,7 +122,15 @@ exports.deletePeer = (req, res, next) => {
|
|||
res.status(204).json({});
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Peers', lineNum: 127, msg: 'Detach Peer Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Detach Peer Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -44,8 +44,16 @@ exports.getAllForwardingEvents = (start, end, offset, callback) => {
|
|||
} else {
|
||||
this.getAllForwardingEvents(start, end, offset + num_max_events, callback);
|
||||
}
|
||||
}).catch(err => {
|
||||
logger.error({fileName: 'Switch', lineNum: 32, msg: 'Get All Forwarding Events Failed: ' + JSON.stringify(err)});
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Switch', lineNum: 54, msg: 'Get All Forwarding Events Error: ' + JSON.stringify(err)});
|
||||
callback({
|
||||
message: "Forwarding Events Failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -10,13 +10,14 @@ exports.getTransactions = (req, res, next) => {
|
|||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
logger.info({fileName: 'Transactions', msg: 'Transaction Received: ' + body_str});
|
||||
if(!body || search_idx > -1 || body.error) {
|
||||
if (!body || search_idx > -1 || body.error) {
|
||||
logger.error({fileName: 'Transactions', lineNum: 14, msg: 'List Transactions Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Fetching Transactions Failed!",
|
||||
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
|
||||
});
|
||||
} else {
|
||||
if ( body.transactions && body.transactions.length > 0) {
|
||||
if (body.transactions && body.transactions.length > 0) {
|
||||
body.transactions.forEach(transaction => {
|
||||
transaction.time_stamp_str = (!transaction.time_stamp) ? '' : common.convertTimestampToDate(transaction.time_stamp);
|
||||
});
|
||||
|
|
@ -25,7 +26,15 @@ exports.getTransactions = (req, res, next) => {
|
|||
res.status(200).json(body.transactions);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Transactions', lineNum: 36, msg: 'List Transactions Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Fetching Transactions Failed!",
|
||||
error: err.error
|
||||
|
|
@ -49,6 +58,7 @@ exports.postTransactions = (req, res, next) => {
|
|||
request.post(options).then((body) => {
|
||||
logger.info({fileName: 'Transactions', msg: 'Transaction Post Response: ' + JSON.stringify(body)});
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Transactions', lineNum: 60, msg: 'Post Transaction Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Transactions post failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -57,7 +67,15 @@ exports.postTransactions = (req, res, next) => {
|
|||
res.status(201).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Transactions', lineNum: 76, msg: 'Transaction Post Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Transactions post failed!",
|
||||
error: err.error
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ exports.genSeed = (req, res, next) => {
|
|||
}
|
||||
request(options).then((body) => {
|
||||
if(!body || body.error) {
|
||||
logger.error({fileName: 'Wallet', lineNum: 16, msg: 'Gen Seed Error: ' + ((!body || !body.error) ? 'Error From Server!' : JSON.stringify(body.error))});
|
||||
res.status(500).json({
|
||||
message: "Genseed failed!",
|
||||
error: (!body) ? 'Error From Server!' : body.error
|
||||
|
|
@ -21,7 +22,15 @@ exports.genSeed = (req, res, next) => {
|
|||
res.status(200).json(body);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Wallet', lineNum: 32, msg: 'Gen Seed Error: ' + JSON.stringify(err)});
|
||||
return res.status(500).json({
|
||||
message: "Genseed failed!",
|
||||
error: err.error
|
||||
|
|
@ -59,11 +68,13 @@ exports.operateWallet = (req, res, next) => {
|
|||
const body_str = (!body) ? '' : JSON.stringify(body);
|
||||
const search_idx = (!body) ? -1 : body_str.search('Not Found');
|
||||
if(!body) {
|
||||
logger.error({fileName: 'Wallet', lineNum: 70, msg: 'Wallet Error: ' + ((error) ? JSON.stringify(error) : err_message)});
|
||||
res.status(500).json({
|
||||
message: err_message,
|
||||
error: (error) ? error : err_message
|
||||
});
|
||||
} else if(search_idx > -1) {
|
||||
logger.error({fileName: 'Wallet', lineNum: 76, msg: 'Wallet Error: ' + err_message});
|
||||
res.status(500).json({
|
||||
message: err_message,
|
||||
error: err_message
|
||||
|
|
@ -72,6 +83,7 @@ exports.operateWallet = (req, res, next) => {
|
|||
if((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) {
|
||||
res.status(201).json('Successful');
|
||||
} else {
|
||||
logger.error({fileName: 'Wallet', lineNum: 85, msg: 'Wallet Error: ' + JSON.stringify(body.error)});
|
||||
res.status(500).json({
|
||||
message: err_message,
|
||||
error: body.error
|
||||
|
|
@ -80,20 +92,28 @@ exports.operateWallet = (req, res, next) => {
|
|||
} 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')) {
|
||||
})
|
||||
.catch(errRes => {
|
||||
let err = JSON.parse(JSON.stringify(errRes));
|
||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
|
||||
delete err.response.request.headers['Grpc-Metadata-macaroon'];
|
||||
}
|
||||
logger.error({fileName: 'Wallet', lineNum: 101, msg: 'Wallet Error: ' + JSON.stringify(err)});
|
||||
if((err.error.code === 1 && err.error.error === 'context canceled') || (err.error.code === 14 && err.error.error === 'transport is closing')) {
|
||||
res.status(201).json('Successful');
|
||||
} else {
|
||||
res.status(500).json({
|
||||
message: err_message,
|
||||
error: error.error.message ? error.error.message : error.message
|
||||
error: err.error.message ? err.error.message : err.message ? err.message : err_message
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
exports.updateSelNodeOptions = (req, res, next) => {
|
||||
let response = common.updateSelectedNodeOptions();
|
||||
res.status(response.status).json({updateMessage: response.message});
|
||||
let response = common.updateSelectedNodeOptions();
|
||||
res.status(response.status).json({updateMessage: response.message});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ parameters have `default` values for initial setup and can be updated after RTL
|
|||
{
|
||||
"multiPass": "<The password in plain text, default 'password', Required>",
|
||||
"port": "<port number for the rtl node server, default '3000', Required>",
|
||||
"host": "<host for the rtl node server, default 'localhost', Optional>",
|
||||
"defaultNodeIndex": <Default index to load when rtl server starts, default 1, Optional>,
|
||||
"SSO": {
|
||||
"rtlSSO": <parameter to turn SSO off/on. Allowed values - 1 (single sign on via an external cookie), 0 (stand alone RTL authentication), default 0, Required>,
|
||||
|
|
@ -41,6 +42,7 @@ parameters have `default` values for initial setup and can be updated after RTL
|
|||
;The environment variable can also be used for all of the above configurations except the UI settings.
|
||||
;If the environment variables are set, it will take precedence over the parameters in the RTL-Config.json file.
|
||||
PORT (port number for the rtl node server, default 3000, Required)
|
||||
HOST (host for the rtl node server, default localhost, Optional)
|
||||
LN_IMPLEMENTATION (LND, CLT. Default 'LND', Required)
|
||||
LN_SERVER_URL (LND server URL for REST APIs, default https://localhost:8080/v1) OR LN_SERVER_URL (LN server URL for LNP REST APIs) (Required)
|
||||
SWAP_SERVER_URL (Swap server URL for REST APIs, default http://localhost:8081/v1) (Optional)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ If your running RTL and LND on different devices on your local LAN, certain conf
|
|||
{
|
||||
"multiPass": "<password in plain text, Default 'password'>",
|
||||
"port": "3000",
|
||||
"host": "localhost",
|
||||
"defaultNodeIndex": 1,
|
||||
"SSO": {
|
||||
"rtlSSO": 0,
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rtl",
|
||||
"version": "0.7.0-beta",
|
||||
"version": "0.7.1-beta",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "rtl",
|
||||
"version": "0.7.0-beta",
|
||||
"version": "0.7.1-beta",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
|
|
|
|||
4
rtl.js
4
rtl.js
|
|
@ -31,11 +31,11 @@ const onListening = () => {
|
|||
const addr = server.address();
|
||||
const bind = typeof addr === "string" ? "pipe " + addr : "port " + common.port;
|
||||
debug("Listening on " + bind);
|
||||
console.log('Server is up and running, please open the UI at http://localhost:' + common.port);
|
||||
console.log('Server is up and running, please open the UI at http://' + common.host + ':' + common.port);
|
||||
};
|
||||
|
||||
const server = http.createServer(app);
|
||||
|
||||
server.on("error", onError);
|
||||
server.on("listening", onListening);
|
||||
server.listen(common.port);
|
||||
server.listen(common.port, common.host);
|
||||
|
|
|
|||
|
|
@ -102,8 +102,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.userIdle.onTimeout().pipe(takeUntil(this.unSubs[3])).subscribe(() => {
|
||||
if (this.sessionService.getItem('token')) {
|
||||
this.logger.warn('Time limit exceeded for session inactivity.');
|
||||
this.store.dispatch(new RTLActions.CloseAlert());
|
||||
this.store.dispatch(new RTLActions.CloseConfirmation(false));
|
||||
this.store.dispatch(new RTLActions.CloseAllDialogs());
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
type: AlertTypeEnum.WARNING,
|
||||
alertTitle: 'Logging out',
|
||||
|
|
|
|||
|
|
@ -30,11 +30,21 @@ import { LNDEffects } from './lnd/store/lnd.effects';
|
|||
import { CLEffects } from './clightning/store/cl.effects';
|
||||
import { LayoutModule } from '@angular/cdk/layout';
|
||||
import { CLOpenChannelComponent } from './clightning/peers-channels/channels/open-channel-modal/open-channel.component';
|
||||
import { CLChannelInformationComponent } from './clightning/peers-channels/channels/channel-information-modal/channel-information.component';
|
||||
import { CLInvoiceInformationComponent } from './clightning/transactions/invoice-information-modal/invoice-information.component';
|
||||
import { CLConnectPeerComponent } from './clightning/peers-channels/connect-peer/connect-peer.component';
|
||||
import { CLLightningSendPaymentsComponent } from './clightning/transactions/send-payment-modal/send-payment.component';
|
||||
import { CLCreateInvoiceComponent } from './clightning/transactions/create-invoice-modal/create-invoice.component';
|
||||
import { CLOnChainSendComponent } from './clightning/on-chain/on-chain-send-modal/on-chain-send.component';
|
||||
import { InvoiceInformationComponent } from './lnd/transactions/invoice-information-modal/invoice-information.component';
|
||||
import { ChannelRebalanceComponent } from './lnd/peers-channels/channels/channel-rebalance-modal/channel-rebalance.component';
|
||||
import { CloseChannelComponent } from './lnd/peers-channels/channels/close-channel-modal/close-channel.component';
|
||||
import { OpenChannelComponent } from './lnd/peers-channels/channels/open-channel-modal/open-channel.component';
|
||||
import { ChannelInformationComponent } from './lnd/peers-channels/channels/channel-information-modal/channel-information.component';
|
||||
import { OnChainSendComponent } from './lnd/on-chain/on-chain-send-modal/on-chain-send.component';
|
||||
import { LightningSendPaymentsComponent } from './lnd/transactions/send-payment-modal/send-payment.component';
|
||||
import { CreateInvoiceComponent } from './lnd/transactions/create-invoice-modal/create-invoice.component';
|
||||
import { ConnectPeerComponent } from './lnd/peers-channels/connect-peer/connect-peer.component';
|
||||
import { ShowPubkeyComponent } from './shared/components/data-modal/show-pubkey/show-pubkey.component';
|
||||
import { OnChainGeneratedAddressComponent } from './shared/components/data-modal/on-chain-generated-address/on-chain-generated-address.component';
|
||||
import { SpinnerDialogComponent } from './shared/components/data-modal/spinner-dialog/spinner-dialog.component';
|
||||
|
|
@ -65,7 +75,15 @@ import { LoginTokenComponent } from './shared/components/data-modal/login-2fa-to
|
|||
ChannelRebalanceComponent,
|
||||
OnChainGeneratedAddressComponent,
|
||||
CLOpenChannelComponent,
|
||||
CLConnectPeerComponent,
|
||||
CLLightningSendPaymentsComponent,
|
||||
CLCreateInvoiceComponent,
|
||||
CLOnChainSendComponent,
|
||||
CLChannelInformationComponent,
|
||||
OpenChannelComponent,
|
||||
ChannelInformationComponent,
|
||||
LightningSendPaymentsComponent,
|
||||
ConnectPeerComponent,
|
||||
ShowPubkeyComponent,
|
||||
SpinnerDialogComponent,
|
||||
AlertMessageComponent,
|
||||
|
|
@ -74,7 +92,9 @@ import { LoginTokenComponent } from './shared/components/data-modal/login-2fa-to
|
|||
CloseChannelComponent,
|
||||
LoopModalComponent,
|
||||
TwoFactorAuthComponent,
|
||||
LoginTokenComponent
|
||||
LoginTokenComponent,
|
||||
CreateInvoiceComponent,
|
||||
OnChainSendComponent
|
||||
],
|
||||
entryComponents: [
|
||||
CLInvoiceInformationComponent,
|
||||
|
|
@ -82,7 +102,15 @@ import { LoginTokenComponent } from './shared/components/data-modal/login-2fa-to
|
|||
ChannelRebalanceComponent,
|
||||
OnChainGeneratedAddressComponent,
|
||||
CLOpenChannelComponent,
|
||||
CLConnectPeerComponent,
|
||||
CLLightningSendPaymentsComponent,
|
||||
CLCreateInvoiceComponent,
|
||||
CLOnChainSendComponent,
|
||||
CLChannelInformationComponent,
|
||||
OpenChannelComponent,
|
||||
ChannelInformationComponent,
|
||||
LightningSendPaymentsComponent,
|
||||
ConnectPeerComponent,
|
||||
ShowPubkeyComponent,
|
||||
SpinnerDialogComponent,
|
||||
AlertMessageComponent,
|
||||
|
|
@ -91,7 +119,9 @@ import { LoginTokenComponent } from './shared/components/data-modal/login-2fa-to
|
|||
CloseChannelComponent,
|
||||
LoopModalComponent,
|
||||
TwoFactorAuthComponent,
|
||||
LoginTokenComponent
|
||||
LoginTokenComponent,
|
||||
CreateInvoiceComponent,
|
||||
OnChainSendComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: LoggerService, useClass: ConsoleLoggerService },
|
||||
|
|
|
|||
|
|
@ -10,11 +10,9 @@ import { CLPeersChannelsComponent } from './peers-channels/peers-channels.compon
|
|||
import { CLChannelsTablesComponent } from './peers-channels/channels/channels-tables/channels-tables.component';
|
||||
import { CLPeersComponent } from './peers-channels/peers/peers.component';
|
||||
import { CLLightningInvoicesComponent } from './transactions/invoices/lightning-invoices.component';
|
||||
import { CLOnChainSendComponent } from './on-chain/on-chain-send/on-chain-send.component';
|
||||
import { CLOnChainReceiveComponent } from './on-chain/on-chain-receive/on-chain-receive.component';
|
||||
import { CLOnChainComponent } from './on-chain/on-chain.component';
|
||||
import { CLLightningPaymentsComponent } from './transactions/payments/lightning-payments.component';
|
||||
import { CLChannelManageComponent } from './peers-channels/channels/channel-manage/channel-manage.component';
|
||||
import { CLTransactionsComponent } from './transactions/transactions.component';
|
||||
import { CLLookupsComponent } from './lookups/lookups.component';
|
||||
import { CLRoutingComponent } from './routing/routing.component';
|
||||
|
|
@ -52,7 +50,6 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
|
|||
CLPeersChannelsComponent,
|
||||
CLLightningInvoicesComponent,
|
||||
CLLightningPaymentsComponent,
|
||||
CLChannelManageComponent,
|
||||
CLTransactionsComponent,
|
||||
CLLookupsComponent,
|
||||
CLRoutingComponent,
|
||||
|
|
@ -61,7 +58,6 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
|
|||
CLChannelLookupComponent,
|
||||
CLNodeLookupComponent,
|
||||
CLQueryRoutesComponent,
|
||||
CLOnChainSendComponent,
|
||||
CLOnChainReceiveComponent,
|
||||
CLOnChainComponent,
|
||||
CLChannelsTablesComponent,
|
||||
|
|
|
|||
|
|
@ -32,6 +32,6 @@
|
|||
<ng-template #noChannelBlock>
|
||||
<div fxLayout="row" fxFlex="10" fxLayoutAlign="space-between center" class="w-100 mt-1">
|
||||
No channels available.
|
||||
<button fxFlex="33" fxLayoutAlign="center center" mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
|
||||
<button mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
|
|||
|
|
@ -22,6 +22,6 @@
|
|||
<ng-template #noChannelBlock>
|
||||
<div fxLayout="row" fxFlex="10" fxLayoutAlign="space-between center" class="w-100 mt-1">
|
||||
No channels available.
|
||||
<button *ngIf="direction === 'Out'" fxFlex="33" fxLayoutAlign="center center" mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
|
||||
<button *ngIf="direction === 'Out'" mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
<input matInput name="lookupKey" [placeholder]="lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'" (change)="clearLookupValue()" [(ngModel)]="lookupKey" tabindex="2" required #key>
|
||||
<mat-error *ngIf="!lookupKey">{{lookupFields[selectedFieldId]?.placeholder}} is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="button" (click)="resetData()">Clear</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" tabindex="4" type="submit" (click)="onLookup()">Lookup</button>
|
||||
<div fxLayout="row" class="mt-2">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="3" type="button" (click)="resetData()">Clear</button>
|
||||
<button mat-flat-button color="primary" tabindex="4" type="submit" (click)="onLookup()">Lookup</button>
|
||||
</div>
|
||||
</form>
|
||||
<div fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" *ngIf="flgSetLookupValue" class="w-100 mt-2">
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="mt-2" fxFlex="48" fxFlex.gt-md="25">
|
||||
<button fxFlex="100" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onGenerateAddress()" tabindex="2" class="top-minus-15px">Generate Address</button>
|
||||
<div class="mt-2">
|
||||
<button mat-flat-button color="primary" (click)="onGenerateAddress()" tabindex="2" class="top-minus-15px">Generate Address</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<div fxLayout="row">
|
||||
<div fxFlex="100" class="padding-gap-large">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
|
||||
<div fxFlex="95" fxLayoutAlign="start start">
|
||||
<span class="page-title">Send Payment</span>
|
||||
</div>
|
||||
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" [mat-dialog-close]="false" default mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="mt-5px">
|
||||
<form fxLayout="row wrap" fxFlex="100" fxLayoutAlign="space-between start" class="padding-gap overflow-x-hidden" (submit)="onSendFunds()" (reset)="resetData()" #form="ngForm">
|
||||
<mat-form-field fxFlex="55">
|
||||
<input matInput autoFocus [(ngModel)]="transaction.address" placeholder="Bitcoin Address" tabindex="1" name="address" required #address="ngModel">
|
||||
<mat-error *ngIf="!transaction.address">Bitcoin address is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="30">
|
||||
<input matInput [(ngModel)]="transaction.satoshis" placeholder="Amount" name="amount" type="number" step="100" min="0" tabindex="2" required #amount="ngModel">
|
||||
<span matSuffix> {{selAmountUnit}} </span>
|
||||
<mat-error *ngIf="!transaction.satoshis">Amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10" fxLayoutAlign="start end">
|
||||
<mat-select [value]="selAmountUnit" tabindex="3" required name="amountUnit" (selectionChange)="onAmountUnitChange($event)">
|
||||
<mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="60" fxLayoutAlign="space-between stretch" fxLayout="row wrap">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate" [disabled]="flgMinConf">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="7" color="primary" [(ngModel)]="flgMinConf" (change)="transaction.feeRate=null" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput [(ngModel)]="transaction.minconf" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
|
||||
<mat-error *ngIf="flgMinConf && !transaction.minconf">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch"></div>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="sendFundError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span *ngIf="sendFundError !== ''">{{sendFundError}}</span>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="end center">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="7" type="reset">Clear Fields</button>
|
||||
<button mat-flat-button color="primary" type="submit" tabindex="8">Send Funds</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { MatDialogRef } from '@angular/material';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { SelNodeChild, GetInfoRoot } from '../../../shared/models/RTLconfig';
|
||||
import { GetInfoCL, BalanceCL, OnChainCL } from '../../../shared/models/clModels';
|
||||
|
|
@ -11,10 +14,8 @@ import { RTLConfiguration } from '../../../shared/models/RTLconfig';
|
|||
import { CommonService } from '../../../shared/services/common.service';
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
|
||||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
import { MessageDataField } from '../../../shared/models/alertData';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-on-chain-send',
|
||||
|
|
@ -22,7 +23,8 @@ import { MessageDataField } from '../../../shared/models/alertData';
|
|||
styleUrls: ['./on-chain-send.component.scss']
|
||||
})
|
||||
export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('form', { static: false }) form: any;
|
||||
@ViewChild('form', { static: false }) form: any;
|
||||
public faExclamationTriangle = faExclamationTriangle;
|
||||
public selNode: SelNodeChild = {};
|
||||
public appConfig: RTLConfiguration;
|
||||
public nodeData: GetInfoRoot;
|
||||
|
|
@ -35,6 +37,7 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
|||
public transaction: OnChainCL = {};
|
||||
public feeRateTypes = FEE_RATE_TYPES;
|
||||
public flgMinConf = false;
|
||||
public sendFundError = '';
|
||||
public fiatConversion = false;
|
||||
public amountUnits = CURRENCY_UNITS;
|
||||
public selAmountUnit = CURRENCY_UNITS[0];
|
||||
|
|
@ -43,7 +46,7 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
|||
public currencyUnitFormats = CURRENCY_UNIT_FORMATS;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private commonService: CommonService, private decimalPipe: DecimalPipe) {}
|
||||
constructor(public dialogRef: MatDialogRef<CLOnChainSendComponent>, private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private commonService: CommonService, private decimalPipe: DecimalPipe, private actions$: Actions) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('root')
|
||||
|
|
@ -55,51 +58,35 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
|||
this.nodeData = rootStore.nodeData;
|
||||
this.logger.info(rootStore);
|
||||
});
|
||||
this.actions$.pipe(takeUntil(this.unSubs[1]),
|
||||
filter(action => action.type === RTLActions.EFFECT_ERROR_CL || action.type === RTLActions.SET_CHANNEL_TRANSACTION_RES_CL))
|
||||
.subscribe((action: RTLActions.EffectErrorCl | RTLActions.SetChannelTransactionResCL) => {
|
||||
if (action.type === RTLActions.SET_CHANNEL_TRANSACTION_RES_CL) {
|
||||
this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully!'));
|
||||
this.dialogRef.close();
|
||||
}
|
||||
if (action.type === RTLActions.EFFECT_ERROR_CL && action.payload.action === 'SetChannelTransactionCL') {
|
||||
this.sendFundError = action.payload.message;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
onSendFunds() {
|
||||
if(this.invalidValues) { return true; }
|
||||
this.sendFundError = '';
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...'));
|
||||
if(this.transaction.satoshis && this.selAmountUnit !== CurrencyUnitEnum.SATS) {
|
||||
this.commonService.convertCurrency(this.transaction.satoshis, this.selAmountUnit === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : this.selAmountUnit, this.amountUnits[2], this.fiatConversion)
|
||||
.pipe(takeUntil(this.unSubs[1]))
|
||||
.pipe(takeUntil(this.unSubs[2]))
|
||||
.subscribe(data => {
|
||||
this.transaction.satoshis = parseInt(data[CurrencyUnitEnum.SATS]);
|
||||
this.selAmountUnit = CurrencyUnitEnum.SATS;
|
||||
this.confirmSend();
|
||||
this.store.dispatch(new RTLActions.SetChannelTransactionCL(this.transaction));
|
||||
});
|
||||
} else {
|
||||
this.confirmSend();
|
||||
this.store.dispatch(new RTLActions.SetChannelTransactionCL(this.transaction));
|
||||
}
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(takeUntil(this.unSubs[2]))
|
||||
.subscribe(pwdConfirmRes => {
|
||||
if (pwdConfirmRes) {
|
||||
this.dispatchToSendFunds();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
confirmSend() {
|
||||
const confirmationMsg: Array<Array<MessageDataField>> = [
|
||||
[{key: 'address', value: this.transaction.address, title: 'BTC Address', width: 100}],
|
||||
[{key: 'satoshi', value: this.transaction.satoshis, title: 'Amount (Sats)', width: 100}],
|
||||
[{key: 'feeRate', value: this.transaction.feeRate, title: 'Fee Rate', width: 100}],
|
||||
[{key: 'minconf', value: this.transaction.minconf, title: 'Min Confirmation Blocks', width: 100}]
|
||||
];
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
|
||||
type: AlertTypeEnum.CONFIRM,
|
||||
alertTitle: 'Confirm Payment',
|
||||
message: confirmationMsg,
|
||||
noBtnText: 'Cancel',
|
||||
yesBtnText: 'Send'
|
||||
}}));
|
||||
}
|
||||
|
||||
dispatchToSendFunds() {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...'));
|
||||
this.store.dispatch(new RTLActions.SetChannelTransactionCL(this.transaction));
|
||||
this.transaction = {};
|
||||
this.form.resetForm();
|
||||
}
|
||||
|
||||
get invalidValues(): boolean {
|
||||
|
|
@ -109,6 +96,7 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
resetData() {
|
||||
this.sendFundError = '';
|
||||
this.transaction = {};
|
||||
this.flgMinConf = false;
|
||||
}
|
||||
|
|
@ -119,7 +107,7 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
|
|||
let currSelectedUnit = event.value === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : event.value;
|
||||
if(this.transaction.satoshis && this.selAmountUnit !== event.value) {
|
||||
this.commonService.convertCurrency(this.transaction.satoshis, prevSelectedUnit, this.amountUnits[2], this.fiatConversion)
|
||||
.pipe(takeUntil(this.unSubs[4]))
|
||||
.pipe(takeUntil(this.unSubs[3]))
|
||||
.subscribe(data => {
|
||||
self.transaction.satoshis = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit]).replace(/,/g, '');
|
||||
});
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
<form fxLayout="column" fxFlex="98" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" fxLayoutAlign.gt-sm="space-between start" class="padding-gap overflow-x-hidden" (submit)="onSendFunds()" (reset)="resetData()" #form="ngForm">
|
||||
<mat-form-field fxFlex.gt-sm="55">
|
||||
<input matInput [(ngModel)]="transaction.address" placeholder="Bitcoin Address" tabindex="1" name="address" required #address="ngModel">
|
||||
<mat-error *ngIf="!transaction.address">Bitcoin address is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex.gt-sm="30">
|
||||
<input matInput [(ngModel)]="transaction.satoshis" placeholder="Amount" name="amount" type="number" step="100" min="0" tabindex="2" required #amount="ngModel">
|
||||
<span matSuffix> {{selAmountUnit}} </span>
|
||||
<mat-error *ngIf="!transaction.satoshis">Amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex.gt-sm="10" fxLayoutAlign="start end">
|
||||
<mat-select [value]="selAmountUnit" tabindex="3" required name="amountUnit" (selectionChange)="onAmountUnitChange($event)">
|
||||
<mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="60" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="7" color="primary" [(ngModel)]="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput [(ngModel)]="transaction.minconf" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
|
||||
<mat-error *ngIf="flgMinConf && !transaction.minconf">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" fxLayoutAlign.gt-sm="space-between start"></div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset">Clear Fields</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="8">Send Funds</button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -17,12 +17,16 @@
|
|||
<mat-card>
|
||||
<mat-card-content fxLayout="column">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Send">
|
||||
<rtl-cl-on-chain-send></rtl-cl-on-chain-send>
|
||||
</mat-tab>
|
||||
<mat-tab label="Receive">
|
||||
<rtl-cl-on-chain-receive></rtl-cl-on-chain-receive>
|
||||
</mat-tab>
|
||||
<mat-tab label="Send">
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<div fxLayout="row">
|
||||
<button mat-flat-button color="primary" type="button" tabindex="1" (click)="openSendFundsModal()">Send Funds</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import { Store } from '@ngrx/store';
|
|||
import { faExchangeAlt, faChartPie } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { SelNodeChild } from '../../shared/models/RTLconfig';
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
import { CLOnChainSendComponent } from './on-chain-send-modal/on-chain-send.component';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-on-chain',
|
||||
|
|
@ -30,6 +32,12 @@ export class CLOnChainComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
openSendFundsModal() {
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
component: CLOnChainSendComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
<div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign="space-between stretch">
|
||||
<div fxFlex="100" class="padding-gap-large pl-3">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header mb-1">
|
||||
<div fxFlex="95" fxLayoutAlign="start start">
|
||||
<fa-icon [icon]="faReceipt" class="page-title-img mr-1"></fa-icon>
|
||||
<span class="page-title">Channel Information</span>
|
||||
</div>
|
||||
<button tabindex="3" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content [ngClass]="{'xs-scroll-y': screenSize === screenSizeEnum.XS}">
|
||||
<div fxLayout="column">
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Short Channel ID</h4>
|
||||
<span class="foreground-secondary-text">{{channel.short_channel_id}}</span>
|
||||
</div>
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Peer Alias</h4>
|
||||
<span class="foreground-secondary-text">{{channel.alias}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="100">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Channel ID</h4>
|
||||
<span class="foreground-secondary-text">{{channel.channel_id}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="100">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Peer Public Key</h4>
|
||||
<span class="foreground-secondary-text">{{channel.id}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">mSatoshi to Us</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.msatoshi_to_us | number}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Spendable (mSats)</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.spendable_msatoshi | number}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Total (mSats)</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.msatoshi_total | number}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">State</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.state}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Our Reserve (Sats)</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.our_channel_reserve_satoshis | number}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Their Reserve (Sats)</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.their_channel_reserve_satoshis | number}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.connected ? 'Yes' : 'No'}}</span>
|
||||
</div>
|
||||
<div fxFlex="25">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Private</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{channel.private ? 'Yes' : 'No'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="showAdvanced">
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="100">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Funding Transaction Id</h4>
|
||||
<span class="foreground-secondary-text">{{channel.funding_txid}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-1"></mat-divider>
|
||||
</div>
|
||||
<div [ngClass]="{'mt-2': !showAdvanced, 'mt-1': showAdvanced}" fxLayout="row" fxLayoutAlign="end center" fxFlex="100">
|
||||
<button mat-stroked-button color="primary" type="reset" (click)="onShowAdvanced()" tabindex="1" class="mr-1">
|
||||
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
|
||||
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
|
||||
</button>
|
||||
<button *ngIf="showCopy" autoFocus mat-flat-button color="primary" tabindex="2" type="submit" rtlClipboard [payload]="channel.short_channel_id" (copied)="onCopyChanID($event)">Copy Short Channel ID</button>
|
||||
<button *ngIf="!showCopy" autoFocus mat-flat-button color="primary" tabindex="2" type="button" (click)="onClose()">OK</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CLChannelInformationComponent } from './channel-information.component';
|
||||
|
||||
describe('CLChannelInformationComponent', () => {
|
||||
let component: CLChannelInformationComponent;
|
||||
let fixture: ComponentFixture<CLChannelInformationComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CLChannelInformationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CLChannelInformationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
import { faReceipt } from '@fortawesome/free-solid-svg-icons';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { LoggerService } from '../../../../shared/services/logger.service';
|
||||
import { CommonService } from '../../../../shared/services/common.service';
|
||||
import { CLChannelInformation } from '../../../../shared/models/alertData';
|
||||
import { ChannelCL } from '../../../../shared/models/clModels';
|
||||
import { ScreenSizeEnum } from '../../../../shared/services/consts-enums-functions';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-channel-information',
|
||||
templateUrl: './channel-information.component.html',
|
||||
styleUrls: ['./channel-information.component.scss']
|
||||
})
|
||||
export class CLChannelInformationComponent implements OnInit {
|
||||
public faReceipt = faReceipt;
|
||||
public showAdvanced = false;
|
||||
public showCopy = true;
|
||||
public showCopyField = null;
|
||||
public channel: ChannelCL;
|
||||
public screenSize = '';
|
||||
public screenSizeEnum = ScreenSizeEnum;
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<CLChannelInformationComponent>, @Inject(MAT_DIALOG_DATA) public data: CLChannelInformation, private logger: LoggerService, private commonService: CommonService, private snackBar: MatSnackBar) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.channel = this.data.channel;
|
||||
this.showCopy = this.data.showCopy;
|
||||
this.screenSize = this.commonService.getScreenSize();
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
onShowAdvanced() {
|
||||
this.showAdvanced = !this.showAdvanced;
|
||||
}
|
||||
|
||||
onCopyChanID(payload: string) {
|
||||
this.snackBar.open('Short channel ID ' + payload + ' copied.');
|
||||
this.logger.info('Copied Text: ' + payload);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
|
||||
<mat-form-field fxFlex="40" fxFlex.gt-sm="30" fxLayoutAlign="start end">
|
||||
<mat-select [(ngModel)]="selectedPeer" placeholder="Alias" name="peer_alias" tabindex="1" required name="selPeer" #selPeer="ngModel">
|
||||
<mat-option (click)="addNewPeer()" [value]="'new'">
|
||||
ADD PEER
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let peer of peers" [value]="peer.id">
|
||||
{{peer.alias}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<mat-error *ngIf="!selectedPeer">Alias is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="25" fxFlex.gt-sm="30" fxLayoutAlign="start end">
|
||||
<input matInput [(ngModel)]="fundingAmount" placeholder="Amount" type="number" step="1000" min="1" tabindex="2" required name="amount" #amount="ngModel" max="{{totalBalance}}">
|
||||
<mat-hint>(Wallet Bal: {{totalBalance}}, Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0)}})</mat-hint>
|
||||
<span matSuffix> {{information?.smaller_currency_unit | titlecase}} </span>
|
||||
<mat-error *ngIf="!fundingAmount">Amount is required.</mat-error>
|
||||
<mat-error *ngIf="amount.errors?.max">Amount must be less than or equal to {{totalBalance}}.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="15" fxFlex.gt-sm="20" fxLayoutAlign="start center" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
|
||||
<mat-slide-toggle tabindex="3" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
|
||||
</div>
|
||||
<div fxFlex="100" fxFlex.gt-sm="17" fxLayoutAlign="start center" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
|
||||
<button fxFlex="48" fxFlex.gt-sm="100" fxLayoutAlign="center center" mat-stroked-button color="primary" type="button" (click)="onShowAdvanced()" tabindex="4">
|
||||
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
|
||||
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="showAdvanced" fxFlex="60" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="5" color="primary" [(ngModel)]="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
|
||||
<mat-error *ngIf="flgMinConf && !minConfValue">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="showAdvanced" fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" fxLayoutAlign.gt-sm="space-between start"></div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="10" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onOpenChannel()" type="submit" tabindex="11">Open Channel</button>
|
||||
</div>
|
||||
</form>
|
||||
<rtl-cl-channels-tables fxLayout="row" fxFlex="100"></rtl-cl-channels-tables>
|
||||
</div>
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
.mat-column-close, .mat-column-update, .mat-column-active, .mat-column-private {
|
||||
flex: 0 0 6%;
|
||||
min-width: 60px;
|
||||
}
|
||||
|
||||
.mat-column-private {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.mat-cell.mat-column-close, .mat-column-update {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mat-column-chan_id {
|
||||
flex: 0 0 16%;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.mat-checkbox-inner-container:focus, .mat-checkbox-input:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.size-40 {
|
||||
font-size: 40px;
|
||||
margin-left: -30%;
|
||||
}
|
||||
|
||||
.mat-button-text {
|
||||
font-size: 24px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.flex-ellipsis {
|
||||
padding-right: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
table {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.chkbox-options:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.flip {
|
||||
position: relative;
|
||||
backface-visibility: hidden;
|
||||
animation: spin 1.5s cubic-bezier(.175, .885, .32, 1.275) 2;
|
||||
transform-style: preserve-3d;
|
||||
transform: rotateX(0deg);
|
||||
}
|
||||
|
||||
@-moz-keyframes spin {
|
||||
from { -moz-transform: rotateX(0deg); }
|
||||
to { -moz-transform: rotateX(360deg); }
|
||||
}
|
||||
@-webkit-keyframes spin {
|
||||
from { -webkit-transform: rotateX(0deg); }
|
||||
to { -webkit-transform: rotateX(360deg); }
|
||||
}
|
||||
@keyframes spin {
|
||||
from { transform:rotateX(0deg); }
|
||||
to { transform:rotateX(360deg); }
|
||||
}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { take, takeUntil, filter } from 'rxjs/operators';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { MatSort, MatSnackBar } from '@angular/material';
|
||||
import { PeerCL, GetInfoCL } from '../../../../shared/models/clModels';
|
||||
import { ScreenSizeEnum, AlertTypeEnum, DataTypeEnum, FEE_RATE_TYPES } from '../../../../shared/services/consts-enums-functions';
|
||||
import { LoggerService } from '../../../../shared/services/logger.service';
|
||||
import { CommonService } from '../../../../shared/services/common.service';
|
||||
|
||||
import { RTLEffects } from '../../../../store/rtl.effects';
|
||||
import { CLEffects } from '../../../store/cl.effects';
|
||||
import * as RTLActions from '../../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-channel-manage',
|
||||
templateUrl: './channel-manage.component.html',
|
||||
styleUrls: ['./channel-manage.component.scss']
|
||||
})
|
||||
export class CLChannelManageComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
@ViewChild('form', {static: true}) form: any;
|
||||
public totalBalance = 0;
|
||||
public selectedPeer = '';
|
||||
public fundingAmount: number;
|
||||
public peers: PeerCL[] = [];
|
||||
public information: GetInfoCL = {};
|
||||
public myChanPolicy: any = {};
|
||||
public isPrivate = false;
|
||||
public feeRateTypes = FEE_RATE_TYPES;
|
||||
public showAdvanced = false;
|
||||
public peerAddress = '';
|
||||
public newlyAddedPeer = '';
|
||||
public selFeeRate = null;
|
||||
public flgMinConf = false;
|
||||
public minConfValue = null;
|
||||
public moreOptions = false;
|
||||
public screenSizeEnum = ScreenSizeEnum;
|
||||
public screenSize = '';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private lndEffects: CLEffects, private commonService: CommonService, private actions$: Actions, private snackBar: MatSnackBar) {
|
||||
this.screenSize = this.commonService.getScreenSize();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.select('cl')
|
||||
.pipe(takeUntil(this.unSubs[0]))
|
||||
.subscribe((rtlStore) => {
|
||||
this.information = rtlStore.information;
|
||||
this.peers = rtlStore.peers;
|
||||
this.peers.forEach(peer => {
|
||||
if (!peer.alias || peer.alias === '') {
|
||||
peer.alias = peer.id.substring(0, 15) + '...';
|
||||
}
|
||||
});
|
||||
this.totalBalance = rtlStore.balance.totalBalance;
|
||||
this.logger.info(rtlStore);
|
||||
});
|
||||
this.actions$.pipe(takeUntil(this.unSubs[1]),
|
||||
filter((action) => action.type === RTLActions.SET_PEERS_CL || action.type === RTLActions.FETCH_CHANNELS_CL))
|
||||
.subscribe((action: RTLActions.SetPeersCL | RTLActions.FetchChannelsCL) => {
|
||||
if(action.type === RTLActions.SET_PEERS_CL) {
|
||||
if(this.newlyAddedPeer !== '') {
|
||||
this.snackBar.open('Peer added successfully. Proceed to open the channel.');
|
||||
this.selectedPeer = this.newlyAddedPeer;
|
||||
this.newlyAddedPeer = '';
|
||||
}
|
||||
}
|
||||
if(action.type === RTLActions.FETCH_CHANNELS_CL) {
|
||||
this.form.resetForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onOpenChannel() {
|
||||
if (!this.selectedPeer || this.selectedPeer === '' || !this.fundingAmount || (this.totalBalance - ((this.fundingAmount) ? this.fundingAmount : 0) < 0)) { return true; }
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewChannelCL({
|
||||
peerId: this.selectedPeer, satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null
|
||||
}));
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.selectedPeer = '';
|
||||
this.fundingAmount = 0;
|
||||
this.moreOptions = false;
|
||||
this.flgMinConf = false;
|
||||
this.isPrivate = false;
|
||||
this.selFeeRate = null;
|
||||
this.minConfValue = null;
|
||||
this.showAdvanced = false;
|
||||
this.form.resetForm();
|
||||
}
|
||||
|
||||
onShowAdvanced() {
|
||||
this.showAdvanced = !this.showAdvanced;
|
||||
if (!this.showAdvanced) {
|
||||
this.flgMinConf = false;
|
||||
this.selFeeRate = null;
|
||||
this.minConfValue = null;
|
||||
}
|
||||
}
|
||||
|
||||
addNewPeer() {
|
||||
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
|
||||
type: AlertTypeEnum.CONFIRM,
|
||||
alertTitle: 'Add peer',
|
||||
message: '',
|
||||
noBtnText: 'Do it Later',
|
||||
yesBtnText: 'Add Peer',
|
||||
flgShowInput: true,
|
||||
titleMessage: 'Enter Lightning Address',
|
||||
getInputs: [
|
||||
{placeholder: 'Lightning Address (pubkey OR pubkey@ip:port)', inputType: DataTypeEnum.STRING, inputValue: '', width: 100}
|
||||
]
|
||||
}}));
|
||||
this.rtlEffects.closeConfirm
|
||||
.pipe(take(1))
|
||||
.subscribe(confirmRes => {
|
||||
if (confirmRes) {
|
||||
this.peerAddress = confirmRes[0].inputValue;
|
||||
const deviderIndex = this.peerAddress.search('@');
|
||||
this.newlyAddedPeer = (deviderIndex<0) ? 'none' : this.peerAddress.substring(0, deviderIndex);
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress, showOpenChannelModal: false}));
|
||||
} else {
|
||||
this.selectedPeer = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
</ng-container>
|
||||
<ng-container matColumnDef="no_peer">
|
||||
<td mat-footer-cell *matFooterCellDef colspan="4">
|
||||
<p *ngIf="numPeers<1">No peers connected. Add a peer in order to open a channel.</p>
|
||||
<p *ngIf="numPeers<1 && (!channels.data || channels.data.length<1)">No peers connected. Add a peer in order to open a channel.</p>
|
||||
<p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTyp
|
|||
import { LoggerService } from '../../../../../shared/services/logger.service';
|
||||
import { CommonService } from '../../../../../shared/services/common.service';
|
||||
|
||||
import { CLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';
|
||||
import { CLEffects } from '../../../../store/cl.effects';
|
||||
import { RTLEffects } from '../../../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../../../store/rtl.actions';
|
||||
|
|
@ -206,29 +207,12 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
onChannelClick(selChannel: ChannelCL, event: any) {
|
||||
const reorderedChannel = [
|
||||
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 34, type: DataTypeEnum.STRING},
|
||||
{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 66, type: DataTypeEnum.STRING}],
|
||||
[{key: 'connected', value: selChannel.connected, title: 'Connected', width: 34, type: DataTypeEnum.BOOLEAN},
|
||||
{key: 'private', value: selChannel.private, title: 'Private', width: 33, type: DataTypeEnum.BOOLEAN},
|
||||
{key: 'state', value: selChannel.state, title: 'State', width: 33, type: DataTypeEnum.STRING}],
|
||||
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve (Sats)', width: 34, type: DataTypeEnum.NUMBER},
|
||||
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve (Sats)', width: 33, type: DataTypeEnum.NUMBER},
|
||||
{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 33, type: DataTypeEnum.NUMBER}],
|
||||
[{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable (mSats)', width: 34, type: DataTypeEnum.NUMBER},
|
||||
{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total (mSats)', width: 66, type: DataTypeEnum.NUMBER}]
|
||||
];
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
type: AlertTypeEnum.INFORMATION,
|
||||
alertTitle: 'Channel Information',
|
||||
showCopyName: 'Short Channel ID',
|
||||
showCopyField: selChannel.short_channel_id,
|
||||
message: reorderedChannel
|
||||
}}));
|
||||
}
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
channel: selChannel,
|
||||
showCopy: true,
|
||||
component: CLChannelInformationComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
loadChannelsTable(mychannels) {
|
||||
mychannels.sort(function(a, b) {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
</ng-container>
|
||||
<ng-container matColumnDef="no_peer">
|
||||
<td mat-footer-cell *matFooterCellDef colspan="4">
|
||||
<p *ngIf="numPeers<1">No peers connected. Add a peer in order to open a channel.</p>
|
||||
<p *ngIf="numPeers<1 && (!channels.data || channels.data.length<1)">No peers connected. Add a peer in order to open a channel.</p>
|
||||
<p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTyp
|
|||
import { LoggerService } from '../../../../../shared/services/logger.service';
|
||||
import { CommonService } from '../../../../../shared/services/common.service';
|
||||
|
||||
import { CLChannelInformationComponent } from '../../channel-information-modal/channel-information.component';
|
||||
import { CLEffects } from '../../../../store/cl.effects';
|
||||
import { RTLEffects } from '../../../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../../../store/rtl.actions';
|
||||
|
|
@ -87,27 +88,10 @@ export class CLChannelPendingTableComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
onChannelClick(selChannel: ChannelCL, event: any) {
|
||||
const reorderedChannel = [
|
||||
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 100, type: DataTypeEnum.STRING}],
|
||||
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 34, type: DataTypeEnum.STRING},
|
||||
{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 66, type: DataTypeEnum.STRING}],
|
||||
[{key: 'connected', value: selChannel.connected, title: 'Connected', width: 34, type: DataTypeEnum.BOOLEAN},
|
||||
{key: 'private', value: selChannel.private, title: 'Private', width: 33, type: DataTypeEnum.BOOLEAN},
|
||||
{key: 'state', value: selChannel.state, title: 'State', width: 33, type: DataTypeEnum.STRING}],
|
||||
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve (Sats)', width: 34, type: DataTypeEnum.NUMBER},
|
||||
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve (Sats)', width: 33, type: DataTypeEnum.NUMBER},
|
||||
{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 33, type: DataTypeEnum.NUMBER}],
|
||||
[{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable (mSats)', width: 34, type: DataTypeEnum.NUMBER},
|
||||
{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total (mSats)', width: 66, type: DataTypeEnum.NUMBER}]
|
||||
];
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
type: AlertTypeEnum.INFORMATION,
|
||||
alertTitle: 'Channel Information',
|
||||
showCopyName: 'Channel ID',
|
||||
showCopyField: selChannel.channel_id,
|
||||
message: reorderedChannel
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
channel: selChannel,
|
||||
showCopy: true,
|
||||
component: CLChannelInformationComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,85 +7,98 @@
|
|||
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="mt-5px">
|
||||
<form fxLayout="column" (ngSubmit)="openChannelForm.form.valid && onOpenChannel()" #openChannelForm="ngForm">
|
||||
<mat-expansion-panel class="flat-expansion-panel">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<span>{{newlyAdded ? '' : 'Open channel with'}} </span><strong class="font-weight-900">{{peer.alias || peer.id}}</strong> {{newlyAdded ? 'added as a peer.' : '.'}}
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div fxLayout="column">
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="100">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Pubkey</h4>
|
||||
<span class="foreground-secondary-text">{{peer.id}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="w-100 my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Address</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{peer.netaddr}}</span>
|
||||
</div>
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{peer.connected ? 'True' : 'False'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
<div fxLayout="column" class="bordered-box mt-2 open-inputs-box">
|
||||
<div fxLayout="row" fxFlex="100">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
|
||||
<div fxFlex="100" fxLayoutAlign="start start">
|
||||
<span class="page-title">Open Channel</span>
|
||||
</div>
|
||||
</mat-card-header>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100">
|
||||
Available balance: {{totalBalance | number}} {{information.smaller_currency_unit}}
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center" class="mt-1">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<input matInput [(ngModel)]="fundingAmount" placeholder="Amount" type="number" step="1000" min="1" tabindex="2" required name="amount" #amount="ngModel" max="{{totalBalance}}">
|
||||
<mat-hint>(Wallet Bal: {{totalBalance}}, Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0)}})</mat-hint>
|
||||
<span matSuffix> {{information?.smaller_currency_unit | titlecase}} </span>
|
||||
<mat-error *ngIf="!fundingAmount">Amount is required.</mat-error>
|
||||
<mat-error *ngIf="amount.errors?.max">Amount must be less than or equal to {{totalBalance}}.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayoutAlign="start center">
|
||||
<mat-slide-toggle tabindex="3" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="5" color="primary" [(ngModel)]="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
|
||||
<mat-error *ngIf="flgMinConf && !minConfValue">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<form fxLayout="column" (submit)="onOpenChannel()" (reset)="resetData()" #form="ngForm">
|
||||
<div fxLayout="column">
|
||||
<mat-form-field fxFlex="100" *ngIf="!peer && peers && peers.length > 0">
|
||||
<input type="text" placeholder="Peer Alias" aria-label="Peers" matInput [formControl]="selectedPeer" (change)="onSelectedPeerChanged()" [matAutocomplete]="auto" tabindex="1" required>
|
||||
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" (optionSelected)="onSelectedPeerChanged()">
|
||||
<mat-option *ngFor="let peer of filteredPeers | async" [value]="peer">{{peer.alias ? peer.alias : peer.id ? peer.id : ''}}</mat-option>
|
||||
</mat-autocomplete>
|
||||
<mat-error *ngIf="selectedPeer.errors?.required">Peer alias is required.</mat-error>
|
||||
<mat-error *ngIf="selectedPeer.errors?.notfound">Peer not found in the list.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<ng-container *ngTemplateOutlet="peerDetailsExpansionBlock"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="openChannelBlock"></ng-container>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="channelConnectionError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span *ngIf="channelConnectionError !== ''">{{channelConnectionError}}</span>
|
||||
</div>
|
||||
<div class="mt-2" fxLayout="row" fxLayoutAlign="end center">
|
||||
<div *ngIf="newlyAdded" fxLayoutAlign="space-between center" fxFlex="60">
|
||||
<button fxFlex="33" fxLayoutAlign="center center" mat-stroked-button color="warn" (click)="onClose()" tabindex="7">Do It Later</button>
|
||||
<button fxFlex="32" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="8" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button autoFocus fxFlex="33" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="9">Open Channel</button>
|
||||
</div>
|
||||
<div *ngIf="!newlyAdded" fxLayout="row" fxLayoutAlign="space-between stretch" fxFlex="30" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button autoFocus fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="8">Open Channel</button>
|
||||
</div>
|
||||
<button mat-stroked-button color="primary" class="mr-1" tabindex="7" type="reset">Clear Fields</button>
|
||||
<button autoFocus mat-flat-button color="primary" type="submit" tabindex="9">Open Channel</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template #peerDetailsExpansionBlock>
|
||||
<mat-expansion-panel class="flat-expansion-panel my-1" *ngIf="peer" expanded="false">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<span>Peer: </span><strong class="font-weight-900">{{peer?.alias || peer?.id}}</strong>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div fxLayout="column">
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="100">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Pubkey</h4>
|
||||
<span class="foreground-secondary-text">{{peer.id}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="w-100 my-1"></mat-divider>
|
||||
<div fxLayout="row">
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Address</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{peer?.netaddr}}</span>
|
||||
</div>
|
||||
<div fxFlex="50">
|
||||
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
|
||||
<span class="overflow-wrap foreground-secondary-text">{{peer.connected ? 'True' : 'False'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</ng-template>
|
||||
<ng-template #openChannelBlock>
|
||||
<form fxLayout="column" #form="ngForm">
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex="70" fxLayoutAlign="start end">
|
||||
<input matInput [(ngModel)]="fundingAmount" placeholder="Amount" type="number" step="1000" min="1" max="{{totalBalance}}" tabindex="1" required name="amount" #amount="ngModel">
|
||||
<mat-hint>Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0) | number}}</mat-hint>
|
||||
<span matSuffix> {{information?.smaller_currency_unit}} </span>
|
||||
<mat-error *ngIf="amount.errors?.required">Amount is required.</mat-error>
|
||||
<mat-error *ngIf="amount.errors?.max">Amount must be less than or equal to {{totalBalance}}.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="25" fxLayoutAlign="start center">
|
||||
<mat-slide-toggle tabindex="2" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
<mat-expansion-panel class="flat-expansion-panel mt-2" expanded="false" (closed)="onAdvancedPanelToggle(true)" (opened)="onAdvancedPanelToggle(false)">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<span>{{advancedTitle}}</span>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch">
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate" [disabled]="flgMinConf">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="5" color="primary" [(ngModel)]="flgMinConf" (change)="selFeeRate=null;" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
|
||||
<mat-error *ngIf="flgMinConf && !minConfValue">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</form>
|
||||
</ng-template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import { Component, OnInit, Inject } from '@angular/core';
|
||||
import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
import { Subject, Observable, of } from 'rxjs';
|
||||
import { takeUntil, filter, startWith, map } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { PeerCL, GetInfoCL } from '../../../../shared/models/clModels';
|
||||
import { CLOpenChannelAlert } from '../../../../shared/models/alertData';
|
||||
|
|
@ -14,29 +19,78 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
|
|||
templateUrl: './open-channel.component.html',
|
||||
styleUrls: ['./open-channel.component.scss']
|
||||
})
|
||||
export class CLOpenChannelComponent implements OnInit {
|
||||
export class CLOpenChannelComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('form', { static: false }) form: any;
|
||||
public selectedPeer = new FormControl();
|
||||
public faExclamationTriangle = faExclamationTriangle;
|
||||
public alertTitle: string;
|
||||
public peer: PeerCL;
|
||||
public peers: PeerCL[];
|
||||
public sortedPeers: PeerCL[];
|
||||
public filteredPeers: Observable<PeerCL[]>;
|
||||
public channelConnectionError = '';
|
||||
public advancedTitle = 'Advanced Options';
|
||||
public information: GetInfoCL;
|
||||
public totalBalance = 0;
|
||||
public fundingAmount: number;
|
||||
public myChanPolicy: any = {};
|
||||
public selectedPubkey = '';
|
||||
public isPrivate = false;
|
||||
public feeRateTypes = FEE_RATE_TYPES;
|
||||
public totalBalance = 0;
|
||||
public newlyAdded = false;
|
||||
public selFeeRate = '';
|
||||
public flgMinConf = false;
|
||||
public minConfValue = null;
|
||||
public moreOptions = false;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>) {}
|
||||
constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.peer = this.data.message.peer;
|
||||
this.information = this.data.message.information;
|
||||
this.totalBalance = this.data.message.balance;
|
||||
this.newlyAdded = this.data.newlyAdded;
|
||||
this.alertTitle = this.data.alertTitle;
|
||||
this.peer = this.data.message.peer ? this.data.message.peer : null;
|
||||
this.peers = this.data.message.peers && this.data.message.peers.length ? this.data.message.peers : [];
|
||||
this.actions$.pipe(takeUntil(this.unSubs[0]),
|
||||
filter(action => action.type === RTLActions.EFFECT_ERROR_CL || action.type === RTLActions.FETCH_CHANNELS_CL))
|
||||
.subscribe((action: RTLActions.EffectErrorCl | RTLActions.FetchChannelsCL) => {
|
||||
if (action.type === RTLActions.EFFECT_ERROR_CL && action.payload.action === 'SaveNewChannelCL') {
|
||||
this.channelConnectionError = action.payload.message;
|
||||
}
|
||||
if (action.type === RTLActions.FETCH_CHANNELS_CL) {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
});
|
||||
let x = '', y = '';
|
||||
this.sortedPeers = this.peers.sort((p1, p2) => {
|
||||
x = p1.alias ? p1.alias.toLowerCase() : p1.id ? p1.id.toLowerCase() : '';
|
||||
y = p2.alias ? p2.alias.toLowerCase() : p1.id.toLowerCase();
|
||||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||||
});
|
||||
this.filteredPeers = this.selectedPeer.valueChanges.pipe(takeUntil(this.unSubs[1]), startWith(''),
|
||||
map(peer => typeof peer === 'string' ? peer : peer.alias ? peer.alias : peer.id),
|
||||
map(alias => alias ? this.filterPeers(alias) : this.sortedPeers.slice())
|
||||
);
|
||||
}
|
||||
|
||||
private filterPeers(newlySelectedPeer: string): PeerCL[] {
|
||||
return this.sortedPeers.filter(peer => peer.alias.toLowerCase().indexOf(newlySelectedPeer ? newlySelectedPeer.toLowerCase() : '') === 0);
|
||||
}
|
||||
|
||||
displayFn(peer: PeerCL): string {
|
||||
return (peer && peer.alias) ? peer.alias : (peer && peer.id) ? peer.id : '';
|
||||
}
|
||||
|
||||
onSelectedPeerChanged() {
|
||||
this.channelConnectionError = '';
|
||||
this.selectedPubkey = (this.selectedPeer.value && this.selectedPeer.value.id) ? this.selectedPeer.value.id : undefined;
|
||||
if (typeof this.selectedPeer.value === 'string') {
|
||||
let selPeer = this.peers.filter(peer => peer.alias.length === this.selectedPeer.value.length && peer.alias.toLowerCase().indexOf(this.selectedPeer.value ? this.selectedPeer.value.toLowerCase() : '') === 0);
|
||||
if (selPeer.length === 1 && selPeer[0].id) { this.selectedPubkey = selPeer[0].id; }
|
||||
}
|
||||
if (this.selectedPeer.value && !this.selectedPubkey) {
|
||||
this.selectedPeer.setErrors({notfound: true});
|
||||
} else {
|
||||
this.selectedPeer.setErrors(null);
|
||||
}
|
||||
}
|
||||
|
||||
onClose() {
|
||||
|
|
@ -44,21 +98,37 @@ export class CLOpenChannelComponent implements OnInit {
|
|||
}
|
||||
|
||||
resetData() {
|
||||
this.fundingAmount = 0;
|
||||
this.moreOptions = false;
|
||||
this.flgMinConf = false;
|
||||
this.isPrivate = false;
|
||||
this.selFeeRate = '';
|
||||
this.minConfValue = null;
|
||||
this.selectedPeer.setValue('');
|
||||
this.fundingAmount = null;
|
||||
this.isPrivate = false;
|
||||
this.channelConnectionError = '';
|
||||
this.advancedTitle = 'Advanced Options';
|
||||
this.form.resetForm();
|
||||
}
|
||||
|
||||
onAdvancedPanelToggle(isClosed: boolean) {
|
||||
if (isClosed) {
|
||||
this.advancedTitle = (!this.flgMinConf && !this.selFeeRate) ? 'Advanced Options' : 'Advanced Options | ' + (this.flgMinConf ? 'Min Confirmation Blocks: ' : 'Fee Rate: ') + (this.flgMinConf ? this.minConfValue : (this.selFeeRate ? this.feeRateTypes.find(feeRateType => feeRateType.feeRateId === this.selFeeRate).feeRateType : ''));
|
||||
} else {
|
||||
this.advancedTitle = 'Advanced Options';
|
||||
}
|
||||
}
|
||||
|
||||
onOpenChannel() {
|
||||
if (!this.fundingAmount || (this.totalBalance - ((this.fundingAmount) ? this.fundingAmount : 0) < 0)) { return true; }
|
||||
if ((!this.peer && !this.selectedPubkey) || (!this.fundingAmount || ((this.totalBalance - this.fundingAmount) < 0) || (this.flgMinConf && !this.minConfValue))) { return true; }
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewChannelCL({
|
||||
peerId: this.peer.id, satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null
|
||||
peerId: ((!this.peer || !this.peer.id) ? this.selectedPubkey : this.peer.id), satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null
|
||||
}));
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
<div fxLayout="row">
|
||||
<div fxFlex="100" class="padding-gap-large">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
|
||||
<div fxFlex="95" fxLayoutAlign="start start">
|
||||
<span class="page-title">Connect to a new peer</span>
|
||||
</div>
|
||||
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="mt-5px">
|
||||
<div fxLayout="column">
|
||||
<mat-vertical-stepper [linear]="true" #stepper (selectionChange)="stepSelectionChanged($event)">
|
||||
<mat-step [stepControl]="peerFormGroup" [editable]="flgEditable">
|
||||
<form [formGroup]="peerFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="my-1">
|
||||
<ng-template matStepLabel>{{peerFormLabel}}</ng-template>
|
||||
<mat-form-field fxFlex="100">
|
||||
<input autoFocus matInput placeholder="Lightning Address (pubkey OR pubkey@ip:port)" formControlName="peerAddress" tabindex="1" required>
|
||||
<mat-error *ngIf="peerFormGroup.controls.peerAddress.errors?.required">Address is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="peerConnectionError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span>{{peerConnectionError}}</span>
|
||||
</div>
|
||||
<div class="mt-2" fxLayout="row" fxLayoutAlign="start center" fxFlex="100">
|
||||
<button mat-stroked-button color="primary" tabindex="3" type="button" (click)="onConnectPeer()">{{peerConnectionError !== '' ? 'Retry' : 'Add Peer'}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step [stepControl]="channelFormGroup" [editable]="flgEditable">
|
||||
<form [formGroup]="channelFormGroup" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="start" fxLayoutAlign.gt-sm="space-between" class="mb-1">
|
||||
<ng-template matStepLabel disabled="true">{{channelFormLabel}}</ng-template>
|
||||
<div fxLayout="column" fxLayout.gt-sm="row wrap" fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
|
||||
<mat-form-field fxFlex="60" fxLayoutAlign="start end">
|
||||
<input matInput autoFocus formControlName="fundingAmount" placeholder="Amount" type="number" step="1000" tabindex="1" required>
|
||||
<mat-hint>Remaining Bal: {{totalBalance - ((channelFormGroup.controls.fundingAmount.value) ? channelFormGroup.controls.fundingAmount.value : 0)}}</mat-hint>
|
||||
<span matSuffix> Sats </span>
|
||||
<mat-error *ngIf="channelFormGroup.controls.fundingAmount.errors?.required">Amount is required.</mat-error>
|
||||
<mat-error *ngIf="channelFormGroup.controls.fundingAmount.errors?.min">Amount must be a positive number.</mat-error>
|
||||
<mat-error *ngIf="channelFormGroup.controls.fundingAmount.errors?.max">Amount must be less than or equal to {{totalBalance}}.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="35" fxLayoutAlign="start center">
|
||||
<mat-slide-toggle tabindex="2" color="primary" formControlName="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
|
||||
</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center" class="mt-1">
|
||||
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
|
||||
<mat-select tabindex="4" placeholder="Fee Rate" formControlName="selFeeRate">
|
||||
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
|
||||
{{feeRateType.feeRateType}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
|
||||
<mat-checkbox fxFlex="2" tabindex="5" color="primary" formControlName="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
|
||||
<mat-form-field fxFlex="98">
|
||||
<input matInput formControlName="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" [required]="channelFormGroup.controls.flgMinConf.value">
|
||||
<mat-error *ngIf="channelFormGroup.controls.flgMinConf.value && !channelFormGroup.controls.minConfValue.value">Min Confirmation Blocks is required.</mat-error>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="channelConnectionError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span>{{channelConnectionError}}</span>
|
||||
</div>
|
||||
<div class="mt-2" fxLayout="row" fxLayoutAlign="start center" fxFlex="100">
|
||||
<button mat-stroked-button color="primary" tabindex="8" type="button" (click)="onOpenChannel()">{{channelConnectionError !== '' ? 'Retry' : 'Open Channel'}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
</mat-vertical-stepper>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="end center">
|
||||
<button mat-stroked-button color="primary" tabindex="12" type="button" [mat-dialog-close]="false" default>{{newlyAddedPeer?.id ? 'Do It Later' : 'Close'}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ChannelManageComponent } from './channel-manage.component';
|
||||
import { CLConnectPeerComponent } from './connect-peer.component';
|
||||
|
||||
describe('ChannelManageComponent', () => {
|
||||
let component: ChannelManageComponent;
|
||||
let fixture: ComponentFixture<ChannelManageComponent>;
|
||||
describe('CLConnectPeerComponent', () => {
|
||||
let component: CLConnectPeerComponent;
|
||||
let fixture: ComponentFixture<CLConnectPeerComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ChannelManageComponent ]
|
||||
declarations: [ CLConnectPeerComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ChannelManageComponent);
|
||||
fixture = TestBed.createComponent(CLConnectPeerComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
import { Component, OnInit, OnDestroy, ViewChild, Inject } from '@angular/core';
|
||||
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil, filter } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatVerticalStepper } from '@angular/material';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { LoggerService } from '../../../shared/services/logger.service';
|
||||
import { PeerCL } from '../../../shared/models/clModels';
|
||||
import { CLOpenChannelAlert } from '../../../shared/models/alertData';
|
||||
import { FEE_RATE_TYPES } from '../../../shared/services/consts-enums-functions';
|
||||
|
||||
import { CLEffects } from '../../store/cl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-connect-peer',
|
||||
templateUrl: './connect-peer.component.html',
|
||||
styleUrls: ['./connect-peer.component.scss']
|
||||
})
|
||||
export class CLConnectPeerComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('peersForm', {static: true}) form: any;
|
||||
@ViewChild('stepper', { static: false }) stepper: MatVerticalStepper;
|
||||
public faExclamationTriangle = faExclamationTriangle;
|
||||
public peerAddress = '';
|
||||
public totalBalance = 0;
|
||||
public feeRateTypes = FEE_RATE_TYPES;
|
||||
public flgChannelOpened = false;
|
||||
public channelOpenStatus = null;
|
||||
public newlyAddedPeer: PeerCL = null;
|
||||
public flgEditable = true;
|
||||
public peerConnectionError = '';
|
||||
public channelConnectionError = '';
|
||||
public peerFormLabel = 'Peer Details';
|
||||
public channelFormLabel = 'Open Channel (Optional)';
|
||||
peerFormGroup: FormGroup;
|
||||
channelFormGroup: FormGroup;
|
||||
statusFormGroup: FormGroup;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<CLConnectPeerComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>, private clEffects: CLEffects, private formBuilder: FormBuilder, private actions$: Actions, private logger: LoggerService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.totalBalance = this.data.message.balance;
|
||||
this.peerFormGroup = this.formBuilder.group({
|
||||
hiddenAddress: ['', [Validators.required]],
|
||||
peerAddress: ['', [Validators.required]]
|
||||
});
|
||||
this.channelFormGroup = this.formBuilder.group({
|
||||
fundingAmount: ['', [Validators.required, Validators.min(1), Validators.max(this.totalBalance)]],
|
||||
isPrivate: [false],
|
||||
selFeeRate: [null],
|
||||
flgMinConf: [false],
|
||||
minConfValue: [null],
|
||||
hiddenAmount: ['', [Validators.required]]
|
||||
});
|
||||
this.statusFormGroup = this.formBuilder.group({});
|
||||
this.channelFormGroup.controls.flgMinConf.valueChanges.pipe(takeUntil(this.unSubs[0])).subscribe(flg => {
|
||||
if (flg) {
|
||||
this.channelFormGroup.controls.selFeeRate.setValue(null);
|
||||
this.channelFormGroup.controls.selFeeRate.disable();
|
||||
this.channelFormGroup.controls.minConfValue.enable();
|
||||
this.channelFormGroup.controls.minConfValue.setValidators([Validators.required]);
|
||||
} else {
|
||||
this.channelFormGroup.controls.selFeeRate.enable();
|
||||
this.channelFormGroup.controls.minConfValue.disable();
|
||||
this.channelFormGroup.controls.minConfValue.setValidators(null);
|
||||
}
|
||||
});
|
||||
this.actions$.pipe(takeUntil(this.unSubs[1]),
|
||||
filter((action) => action.type === RTLActions.NEWLY_ADDED_PEER_CL || action.type === RTLActions.FETCH_CHANNELS_CL || action.type === RTLActions.EFFECT_ERROR_CL))
|
||||
.subscribe((action: (RTLActions.NewlyAddedPeerCL | RTLActions.FetchChannelsCL | RTLActions.EffectErrorCl)) => {
|
||||
if (action.type === RTLActions.NEWLY_ADDED_PEER_CL) {
|
||||
this.logger.info(action.payload);
|
||||
this.flgEditable = false;
|
||||
this.newlyAddedPeer = action.payload.peer;
|
||||
this.peerFormGroup.controls.hiddenAddress.setValue(this.peerFormGroup.controls.peerAddress.value);
|
||||
this.stepper.next();
|
||||
}
|
||||
if (action.type === RTLActions.FETCH_CHANNELS_CL) {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
if (action.type === RTLActions.EFFECT_ERROR_CL) {
|
||||
if (action.payload.action === 'SaveNewPeerCL') {
|
||||
this.peerConnectionError = action.payload.message;
|
||||
} else if (action.payload.action === 'SaveNewChannelCL') {
|
||||
this.channelConnectionError = action.payload.message;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onConnectPeer() {
|
||||
if(!this.peerFormGroup.controls.peerAddress.value) { return true; }
|
||||
this.peerConnectionError = '';
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerFormGroup.controls.peerAddress.value}));
|
||||
}
|
||||
|
||||
onOpenChannel() {
|
||||
if (!this.channelFormGroup.controls.fundingAmount.value || ((this.totalBalance - this.channelFormGroup.controls.fundingAmount.value) < 0) || (this.channelFormGroup.controls.flgMinConf.value && !this.channelFormGroup.controls.minConfValue.value)) { return true; }
|
||||
this.channelConnectionError = '';
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewChannelCL({
|
||||
peerId: this.newlyAddedPeer.id, satoshis: this.channelFormGroup.controls.fundingAmount.value, announce: !this.channelFormGroup.controls.isPrivate.value, feeRate: this.channelFormGroup.controls.selFeeRate.value, minconf: this.channelFormGroup.controls.flgMinConf.value ? this.channelFormGroup.controls.minConfValue.value : null
|
||||
}));
|
||||
}
|
||||
|
||||
onClose() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
stepSelectionChanged(event: any) {
|
||||
switch (event.selectedIndex) {
|
||||
case 0:
|
||||
this.peerFormLabel = 'Peer Details';
|
||||
this.channelFormLabel = 'Open Channel (Optional)';
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (this.peerFormGroup.controls.peerAddress.value) {
|
||||
this.peerFormLabel = 'Peer Added: ' + (this.newlyAddedPeer.alias ? this.newlyAddedPeer.alias : this.newlyAddedPeer.id);
|
||||
} else {
|
||||
this.peerFormLabel = 'Peer Details';
|
||||
}
|
||||
this.channelFormLabel = 'Open Channel (Optional)';
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (this.peerFormGroup.controls.peerAddress.value) {
|
||||
this.peerFormLabel = 'Peer Added: ' + (this.newlyAddedPeer.alias ? this.newlyAddedPeer.alias : this.newlyAddedPeer.id);
|
||||
} else {
|
||||
this.peerFormLabel = 'Peer Details';
|
||||
}
|
||||
if (this.channelFormGroup.controls.fundingAmount.value) {
|
||||
this.channelFormLabel = 'Opening Channel for ' + this.channelFormGroup.controls.fundingAmount.value + ' Sats';
|
||||
} else {
|
||||
this.channelFormLabel = 'Open Channel (Optional)';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
this.peerFormLabel = 'Peer Details';
|
||||
this.channelFormLabel = 'Open Channel (Optional)';
|
||||
break;
|
||||
}
|
||||
if (event.selectedIndex < event.previouslySelectedIndex) {
|
||||
if (event.selectedIndex === 0) {
|
||||
this.peerFormGroup.controls.hiddenAddress.setValue('');
|
||||
} else if (event.selectedIndex === 1) {
|
||||
this.channelFormGroup.controls.hiddenAmount.setValue('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,7 +21,12 @@
|
|||
<ng-template mat-tab-label>
|
||||
<span matBadge="{{activeChannels}}" matBadgeOverlap="false" class="tab-badge">Channels</span>
|
||||
</ng-template>
|
||||
<rtl-cl-channel-manage></rtl-cl-channel-manage>
|
||||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<div fxLayout="row">
|
||||
<button mat-flat-button color="primary" (click)="onOpenChannel()" type="submit" tabindex="1">Open Channel</button>
|
||||
</div>
|
||||
<rtl-cl-channels-tables fxLayout="row" fxFlex="100"></rtl-cl-channels-tables>
|
||||
</div>
|
||||
</mat-tab>
|
||||
<mat-tab>
|
||||
<ng-template mat-tab-label>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import { Store } from '@ngrx/store';
|
|||
import { Actions } from '@ngrx/effects';
|
||||
import { faUsers, faChartPie } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { GetInfoCL, PeerCL } from '../../shared/models/clModels';
|
||||
import { CLOpenChannelComponent } from './channels/open-channel-modal/open-channel.component';
|
||||
import { SelNodeChild } from '../../shared/models/RTLconfig';
|
||||
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
|
|
@ -15,6 +19,9 @@ import * as fromRTLReducer from '../../store/rtl.reducers';
|
|||
})
|
||||
export class CLPeersChannelsComponent implements OnInit, OnDestroy {
|
||||
public selNode: SelNodeChild = {};
|
||||
public information: GetInfoCL = {};
|
||||
public peers: PeerCL[] = [];
|
||||
public totalBalance = 0;
|
||||
public activePeers = 0;
|
||||
public activeChannels = 0;
|
||||
public faUsers = faUsers;
|
||||
|
|
@ -29,12 +36,28 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
|
|||
.pipe(takeUntil(this.unSubs[1]))
|
||||
.subscribe((rtlStore) => {
|
||||
this.selNode = rtlStore.nodeSettings;
|
||||
this.information = rtlStore.information;
|
||||
this.peers = rtlStore.peers;
|
||||
this.activePeers = (rtlStore.peers && rtlStore.peers.length) ? rtlStore.peers.length : 0;
|
||||
this.activeChannels = rtlStore.information.num_active_channels;
|
||||
this.totalBalance = rtlStore.balance.totalBalance;
|
||||
this.balances = [{title: 'Total Balance', dataValue: rtlStore.balance.totalBalance || 0}, {title: 'Confirmed', dataValue: rtlStore.balance.confBalance}, {title: 'Unconfirmed', dataValue: rtlStore.balance.unconfBalance}];
|
||||
});
|
||||
}
|
||||
|
||||
onOpenChannel() {
|
||||
const peerToAddChannelMessage = {
|
||||
peers: this.peers,
|
||||
information: this.information,
|
||||
balance: this.totalBalance
|
||||
};
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
alertTitle: 'Open Channel',
|
||||
message: peerToAddChannelMessage,
|
||||
component: CLOpenChannelComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
|
|
|
|||
|
|
@ -1,13 +1,6 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #peersForm="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<input matInput placeholder="Lightning Address (pubkey OR pubkey@ip:port)" name="peerAddress" [(ngModel)]="peerAddress" tabindex="1" required #peerAdd="ngModel">
|
||||
<mat-error *ngIf="!peerAddress">Lightning address is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="3" (click)="onConnectPeer()">Add Peer</button>
|
||||
</div>
|
||||
<button mat-flat-button color="primary" type="submit" tabindex="1" (click)="onConnectPeer()">Add Peer</button>
|
||||
</form>
|
||||
<div fxLayout="column">
|
||||
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="padding-gap-x page-sub-title-container mt-2">
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { CLEffects } from '../../store/cl.effects';
|
|||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
import { CLConnectPeerComponent } from '../connect-peer/connect-peer.component';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-peers',
|
||||
|
|
@ -30,7 +31,6 @@ import * as fromRTLReducer from '../../../store/rtl.reducers';
|
|||
export class CLPeersComponent implements OnInit, OnDestroy {
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
|
||||
@ViewChild('peersForm', {static: true}) form: any;
|
||||
public faUsers = faUsers;
|
||||
public newlyAddedPeer = '';
|
||||
public flgAnimate = true;
|
||||
|
|
@ -96,18 +96,9 @@ export class CLPeersComponent implements OnInit, OnDestroy {
|
|||
).subscribe((setPeers: RTLActions.SetPeersCL) => {
|
||||
this.peerAddress = undefined;
|
||||
this.flgAnimate = true;
|
||||
this.form.resetForm();
|
||||
});
|
||||
}
|
||||
|
||||
onConnectPeer() {
|
||||
if(!this.peerAddress) { return true; }
|
||||
this.flgAnimate = true;
|
||||
this.newlyAddedPeer = this.peerAddress;
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress, showOpenChannelModal: true}));
|
||||
}
|
||||
|
||||
onPeerClick(selPeer: PeerCL, event: any) {
|
||||
const reorderedPeer = [
|
||||
[{key: 'id', value: selPeer.id, title: 'Public Key', width: 100}],
|
||||
|
|
@ -126,9 +117,11 @@ export class CLPeersComponent implements OnInit, OnDestroy {
|
|||
}}));
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.peerAddress = '';
|
||||
this.form.resetForm();
|
||||
onConnectPeer() {
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
message: { peer: null, information: this.information, balance: this.availableBalance },
|
||||
component: CLConnectPeerComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
onOpenChannel(peerToAddChannel: PeerCL) {
|
||||
|
|
|
|||
|
|
@ -6,27 +6,6 @@
|
|||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start start" class="padding-gap-x">
|
||||
<mat-card fxLayout="row" fxFlex="100" fxLayoutAlign="start start">
|
||||
<mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start start">
|
||||
<!-- <mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="card-content-gap mt-1"> -->
|
||||
<!-- <form fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="w-100 mb-1" (ngSubmit)="onEventsFetch()" #routingForm="ngForm">
|
||||
<div fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<mat-form-field fxFlex="49" fxLayoutAlign="start">
|
||||
<input matInput [matDatepicker]="startDatepicker" placeholder="Start Date" [max]="yesterday"
|
||||
name="startDate" [(ngModel)]="startDate" tabindex="1" #strtDate="ngModel">
|
||||
<mat-datepicker-toggle matSuffix [for]="startDatepicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #startDatepicker [startAt]="startDate"></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="49" fxLayoutAlign="start">
|
||||
<input matInput [matDatepicker]="endDatepicker" [max]="today" placeholder="End Date" name="endDate"
|
||||
[(ngModel)]="endDate" tabindex="2" #enDate="ngModel">
|
||||
<mat-datepicker-toggle matSuffix [for]="endDatepicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #endDatepicker [startAt]="endDate"></mat-datepicker>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="4">Fetch Events</button>
|
||||
</div>
|
||||
</form> -->
|
||||
<div *ngIf="filteredData" fxLayout="row" fxFlex="100" [ngClass]="{'error-border w-100 routing-tabs-block': flgLoading[0]==='error', 'w-100 routing-tabs-block': true}">
|
||||
<mat-tab-group fxLayout="column" fxFlex="100">
|
||||
<mat-tab label="Forwarding History">
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@
|
|||
<textarea autoFocus matInput [(ngModel)]="message" rows="1" placeholder="Message to sign" required tabindex="1" (keyup)="onMessageChange()" name="message"></textarea>
|
||||
<mat-error *ngIf="!message">Message is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="my-1">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()" type="reset">Clear Field</button>
|
||||
<button fxFlex="48" mat-flat-button color="primary" (click)="onSign()" tabindex="3" type="submit">Sign</button>
|
||||
<div fxLayout="row" class="my-1">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button mat-flat-button color="primary" (click)="onSign()" tabindex="3" type="submit">Sign</button>
|
||||
</div>
|
||||
<mat-divider [inset]="true" class="my-2"></mat-divider>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center"><p>Generated Signature</p></div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center" class="bordered-box read-only h-4 padding-gap">{{signature}}</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="4" rtlClipboard [payload]="signature" (copied)="onCopyField($event)" type="button">Copy Signature</button>
|
||||
<div fxLayout="row" class="mt-2">
|
||||
<button mat-stroked-button color="primary" tabindex="4" rtlClipboard [payload]="signature" (copied)="onCopyField($event)" type="button">Copy Signature</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ export class CLSignComponent implements OnInit, OnDestroy {
|
|||
onSign() {
|
||||
if (!this.message || this.message === '') { return true; }
|
||||
this.dataService.signMessage(this.message).pipe(takeUntil(this.unSubs[0])).subscribe(res => {
|
||||
console.warn(res);
|
||||
this.signedMessage = this.message;
|
||||
this.signature = res.zbase;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
<mat-error *ngIf="!signature">Signature is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<p *ngIf="showVerifyStatus && !verifyRes.verified" fxFlex="100" class="color-warn" fxLayoutAlign="start center"><mat-icon class="mr-1 icon-small">close</mat-icon>Verification failed, please double check message and signature</p>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="my-1">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()" type="reset">Clear Fields</button>
|
||||
<button fxFlex="48" mat-flat-button color="primary" (click)="onVerify()" tabindex="4" type="submit">Verify</button>
|
||||
<div fxLayout="row" class="my-1">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear Fields</button>
|
||||
<button mat-flat-button color="primary" (click)="onVerify()" tabindex="4" type="submit">Verify</button>
|
||||
</div>
|
||||
<div *ngIf="showVerifyStatus && verifyRes.verified" fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
|
||||
<mat-divider [inset]="true" class="my-2"></mat-divider>
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
<div *ngIf="verifyRes.verified" fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="bordered-box read-only h-4 padding-gap">
|
||||
<p>{{verifyRes?.pubkey}}</p>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2" *ngIf="verifyRes.verified">
|
||||
<button fxFlex="48" mat-stroked-button color="primary" tabindex="5" rtlClipboard [payload]="verifyRes?.pubkey" (copied)="onCopyField($event)" type="button">Copy Pubkey</button>
|
||||
<div fxLayout="row" class="mt-2" *ngIf="verifyRes.verified">
|
||||
<button mat-stroked-button color="primary" tabindex="5" rtlClipboard [payload]="verifyRes?.pubkey" (copied)="onCopyField($event)" type="button">Copy Pubkey</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { CommonService } from '../../shared/services/common.service';
|
|||
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component';
|
||||
import { CLInvoiceInformationComponent } from '../transactions/invoice-information-modal/invoice-information.component';
|
||||
import { CLOpenChannelComponent } from '../peers-channels/channels/open-channel-modal/open-channel.component';
|
||||
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRatesCL, ListInvoicesCL, InvoiceCL } from '../../shared/models/clModels';
|
||||
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRatesCL, ListInvoicesCL, InvoiceCL, PeerCL } from '../../shared/models/clModels';
|
||||
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
|
||||
import * as fromRTLReducer from '../../store/rtl.reducers';
|
||||
import * as RTLActions from '../../store/rtl.actions';
|
||||
|
|
@ -53,24 +53,10 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err) => {
|
||||
let code = err.status ? err.status : '';
|
||||
let message = err.error.message ? err.error.message + ' ' : '';
|
||||
if (err.error && err.error.error) {
|
||||
if (err.error.error.code) {
|
||||
code = err.error.error.code;
|
||||
} else if (err.error.error.message && err.error.error.message.code) {
|
||||
code = err.error.error.message.code;
|
||||
}
|
||||
if (typeof err.error.error === 'string') {
|
||||
message = message + err.error.error;
|
||||
} else if (err.error.error.error) {
|
||||
message = message + err.error.error.error;
|
||||
} else if (err.error.error.errno) {
|
||||
message = message + err.error.error.errno;
|
||||
}
|
||||
}
|
||||
const code = (err.error && err.error.error && err.error.error.message && err.error.error.message.code) ? err.error.error.message.code : (err.error && err.error.error && err.error.error.code) ? err.error.error.code : err.status ? err.status : '';
|
||||
const message = ((err.error && err.error.message) ? err.error.message + ' ' : '') + ((err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error : (err.error && err.error.error && err.error.error.errno && typeof err.error.error.errno === 'string') ? err.error.error.errno : (err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error : (err.error && typeof err.error === 'string') ? err.error : 'Unknown Error');
|
||||
this.router.navigate(['/error'], { state: { errorCode: code, errorMessage: message }});
|
||||
this.handleErrorWithoutAlert('FetchInfoCL', err);
|
||||
this.handleErrorWithoutAlert('FetchInfoCL', 'Fetching Node Info Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -92,7 +78,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchFeesCL', err);
|
||||
this.handleErrorWithoutAlert('FetchFeesCL', 'Fetching Fees Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -112,7 +98,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchFeeRatesCL', err);
|
||||
this.handleErrorWithoutAlert('FetchFeeRatesCL', 'Fetching Fee Rates Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -132,7 +118,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchBalanceCL', err);
|
||||
this.handleErrorWithoutAlert('FetchBalanceCL', 'Fetching Balances Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -152,7 +138,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchLocalRemoteBalanceCL', err);
|
||||
this.handleErrorWithoutAlert('FetchLocalRemoteBalanceCL', 'Fetching Balances Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -201,7 +187,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchPeersCL', err);
|
||||
this.handleErrorWithoutAlert('FetchPeersCL', 'Fetching Peers Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -213,36 +199,20 @@ export class CLEffects implements OnDestroy {
|
|||
ofType(RTLActions.SAVE_NEW_PEER_CL),
|
||||
withLatestFrom(this.store.select('cl')),
|
||||
mergeMap(([action, clData]: [RTLActions.SaveNewPeerCL, fromCLReducers.CLState]) => {
|
||||
this.store.dispatch(new RTLActions.ClearEffectErrorCl('SaveNewPeerCL'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.PEERS_API, { id: action.payload.id })
|
||||
.pipe(
|
||||
map((postRes: any) => {
|
||||
map((postRes: PeerCL[]) => {
|
||||
this.logger.info(postRes);
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.SetPeersCL((postRes && postRes.length > 0) ? postRes : []));
|
||||
if(action.payload.showOpenChannelModal) {
|
||||
const peerToAddChannelMessage = {
|
||||
peer: postRes[0],
|
||||
information: clData.information,
|
||||
balance: clData.balance.totalBalance || 0
|
||||
};
|
||||
return {
|
||||
type: RTLActions.OPEN_ALERT,
|
||||
payload: { data: {
|
||||
type: AlertTypeEnum.INFORMATION,
|
||||
alertTitle: 'Peer Connected',
|
||||
message: peerToAddChannelMessage,
|
||||
newlyAdded: true,
|
||||
component: CLOpenChannelComponent
|
||||
}}
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
type: RTLActions.VOID
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: RTLActions.NEWLY_ADDED_PEER_CL,
|
||||
payload: {peer: postRes.find(peer => action.payload.id.indexOf(peer.id) === 0)}
|
||||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithAlert('ERROR', 'Add Peer Failed', this.CHILD_API_URL + environment.PEERS_API, err);
|
||||
this.handleErrorWithoutAlert('SaveNewPeerCL', 'Peer Connection Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -287,7 +257,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
},
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchChannelsCL', err);
|
||||
this.handleErrorWithoutAlert('FetchChannelsCL', 'Fetching Channels Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
));
|
||||
|
|
@ -298,6 +268,7 @@ export class CLEffects implements OnDestroy {
|
|||
openNewChannelCL = this.actions$.pipe(
|
||||
ofType(RTLActions.SAVE_NEW_CHANNEL_CL),
|
||||
mergeMap((action: RTLActions.SaveNewChannelCL) => {
|
||||
this.store.dispatch(new RTLActions.ClearEffectErrorCl('SaveNewChannelCL'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.CHANNELS_API, {
|
||||
id: action.payload.peerId, satoshis: action.payload.satoshis, feeRate: action.payload.feeRate, announce: action.payload.announce, minconf: (action.payload.minconf) ? action.payload.minconf : null
|
||||
})
|
||||
|
|
@ -312,7 +283,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithAlert('ERROR', 'Open Channel Failed', this.CHILD_API_URL + environment.CHANNELS_API, err);
|
||||
this.handleErrorWithoutAlert('SaveNewChannelCL', 'Opening Channel Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -386,7 +357,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchPaymentsCL', err);
|
||||
this.handleErrorWithoutAlert('FetchPaymentsCL', 'Fetching Payments Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -395,7 +366,8 @@ export class CLEffects implements OnDestroy {
|
|||
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)
|
||||
this.store.dispatch(new RTLActions.ClearEffectErrorCl('DecodePaymentCL'));
|
||||
return this.httpClient.get(this.CHILD_API_URL + environment.PAYMENTS_API + '/' + action.payload.routeParam)
|
||||
.pipe(
|
||||
map((decodedPayment) => {
|
||||
this.logger.info(decodedPayment);
|
||||
|
|
@ -406,7 +378,11 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithAlert('ERROR', 'Decode Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API + '/' + action.payload, err);
|
||||
if (action.payload.fromDialog) {
|
||||
this.handleErrorWithoutAlert('DecodePaymentCL', 'Decode Payment Failed.', err);
|
||||
} else {
|
||||
this.handleErrorWithAlert('ERROR', 'Decode Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API + '/' + action.payload, err);
|
||||
}
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -427,26 +403,41 @@ export class CLEffects implements OnDestroy {
|
|||
ofType(RTLActions.SEND_PAYMENT_CL),
|
||||
withLatestFrom(this.store.select('root')),
|
||||
mergeMap(([action, store]: [RTLActions.SendPaymentCL, any]) => {
|
||||
this.store.dispatch(new RTLActions.ClearEffectErrorCl('SendPaymentCL'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.PAYMENTS_API, action.payload)
|
||||
.pipe(
|
||||
map((sendRes: any) => {
|
||||
this.logger.info(sendRes);
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
if (sendRes.error) {
|
||||
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API, { status: sendRes.status, error: sendRes.error.message });
|
||||
this.logger.error('Error: ' + sendRes.payment_error);
|
||||
const myErr = {status: sendRes.payment_error.status, error: sendRes.payment_error.error && sendRes.payment_error.error.error && typeof(sendRes.payment_error.error.error) === 'object' ? sendRes.payment_error.error.error : {error: sendRes.payment_error.error && sendRes.payment_error.error.error ? sendRes.payment_error.error.error : 'Unknown Error'}};
|
||||
if (action.payload.fromDialog) {
|
||||
this.handleErrorWithoutAlert('SendPaymentCL', 'Send Payment Failed.', myErr);
|
||||
} else {
|
||||
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions', myErr);
|
||||
}
|
||||
return of({type: RTLActions.VOID});
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.OpenSnackBar('Payment Sent Successfully!'));
|
||||
this.store.dispatch(new RTLActions.FetchChannelsCL());
|
||||
this.store.dispatch(new RTLActions.FetchBalanceCL());
|
||||
this.store.dispatch(new RTLActions.FetchPaymentsCL());
|
||||
this.store.dispatch(new RTLActions.SetDecodedPaymentCL({}));
|
||||
return {
|
||||
type: RTLActions.SET_DECODED_PAYMENT_CL,
|
||||
payload: {}
|
||||
type: RTLActions.SEND_PAYMENT_STATUS_CL,
|
||||
payload: sendRes
|
||||
};
|
||||
}
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API, err.error ? err.error : err);
|
||||
this.logger.error('Error: ' + JSON.stringify(err));
|
||||
const myErr = {status: err.status, error: err.error && err.error.error && typeof(err.error.error) === 'object' ? err.error.error : {error: err.error && err.error.error ? err.error.error : 'Unknown Error'}};
|
||||
if (action.payload.fromDialog) {
|
||||
this.handleErrorWithoutAlert('SendPaymentCL', 'Send Payment Failed.', myErr);
|
||||
} else {
|
||||
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions', myErr);
|
||||
}
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -624,6 +615,7 @@ export class CLEffects implements OnDestroy {
|
|||
saveNewInvoiceCL = this.actions$.pipe(
|
||||
ofType(RTLActions.SAVE_NEW_INVOICE_CL),
|
||||
mergeMap((action: RTLActions.SaveNewInvoiceCL) => {
|
||||
this.store.dispatch(new RTLActions.ClearEffectErrorCl('SaveNewInvoiceCL'));
|
||||
return this.httpClient.post(this.CHILD_API_URL + environment.INVOICES_API, {
|
||||
label: action.payload.label, amount: action.payload.amount, description: action.payload.description, expiry: action.payload.expiry, private: action.payload.private
|
||||
})
|
||||
|
|
@ -648,7 +640,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithAlert('ERROR', 'Add Invoice Failed', this.CHILD_API_URL + environment.INVOICES_API, err);
|
||||
this.handleErrorWithoutAlert('SaveNewInvoiceCL', 'Add Invoice Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
})
|
||||
);
|
||||
|
|
@ -673,7 +665,7 @@ export class CLEffects implements OnDestroy {
|
|||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.handleErrorWithoutAlert('FetchInvoicesCL', err);
|
||||
this.handleErrorWithoutAlert('FetchInvoicesCL', 'Fetching Invoices Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}
|
||||
));
|
||||
|
|
@ -690,12 +682,13 @@ export class CLEffects implements OnDestroy {
|
|||
this.logger.info(postRes);
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.FetchBalanceCL());
|
||||
this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully.'));
|
||||
return { type: RTLActions.VOID };
|
||||
return {
|
||||
type: RTLActions.SET_CHANNEL_TRANSACTION_RES_CL,
|
||||
payload: postRes
|
||||
};
|
||||
}),
|
||||
catchError((err: any) => {
|
||||
this.store.dispatch(new RTLActions.EffectErrorCl({ action: 'SetChannelTransactionCL', code: err.status, message: err.error.error }));
|
||||
this.handleErrorWithAlert('ERROR', 'Sending Fund Failed', this.CHILD_API_URL + environment.ON_CHAIN_API, err);
|
||||
this.handleErrorWithoutAlert('SetChannelTransactionCL', 'Sending Fund Failed.', err);
|
||||
return of({type: RTLActions.VOID});
|
||||
}));
|
||||
})
|
||||
|
|
@ -734,13 +727,16 @@ export class CLEffects implements OnDestroy {
|
|||
this.router.navigate([newRoute]);
|
||||
}
|
||||
|
||||
handleErrorWithoutAlert(actionName: string, err: { status: number, error: any }) {
|
||||
handleErrorWithoutAlert(actionName: string, genericErrorMessage: string, err: { status: number, error: any }) {
|
||||
this.logger.error('ERROR IN: ' + actionName + '\n' + JSON.stringify(err));
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.CloseAllDialogs());
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
this.store.dispatch(new RTLActions.OpenSnackBar('Authentication Failed. Redirecting to Login.'));
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.EffectErrorCl({ action: actionName, code: err.status.toString(), message: err.error.error }));
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.EffectErrorCl({ action: actionName, code: err.status.toString(), message: (err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message : (err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message : (err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message : (err.error.message && typeof err.error.message === 'string') ? err.error.message : typeof err.error === 'string' ? err.error : genericErrorMessage }));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -748,14 +744,16 @@ export class CLEffects implements OnDestroy {
|
|||
this.logger.error(err);
|
||||
if (err.status === 401) {
|
||||
this.logger.info('Redirecting to Login');
|
||||
this.store.dispatch(new RTLActions.CloseAllDialogs());
|
||||
this.store.dispatch(new RTLActions.Logout());
|
||||
this.store.dispatch(new RTLActions.OpenSnackBar('Authentication Failed. Redirecting to Login.'));
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
||||
this.store.dispatch(new RTLActions.OpenAlert({
|
||||
data: {
|
||||
type: alerType,
|
||||
alertTitle: alertTitle,
|
||||
message: { code: err.status, message: err.error.error, URL: errURL },
|
||||
message: { code: err.status, message: (err.error.error && err.error.error.error && err.error.error.error.error && err.error.error.error.error.message && typeof err.error.error.error.error.message === 'string') ? err.error.error.error.error.message : (err.error.error && err.error.error.error && err.error.error.error.message && typeof err.error.error.error.message === 'string') ? err.error.error.error.message : (err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message : (err.error.message && typeof err.error.message === 'string') ? err.error.message : typeof err.error === 'string' ? err.error : 'Unknown Error', URL: errURL },
|
||||
component: ErrorMessageComponent
|
||||
}
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<div fxLayout="row">
|
||||
<div fxFlex="100" class="padding-gap-large">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
|
||||
<div fxFlex="95" fxLayoutAlign="start start">
|
||||
<span class="page-title">Create Invoice</span>
|
||||
</div>
|
||||
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" [mat-dialog-close]="false" default mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="mt-5px">
|
||||
<form fxLayout="row wrap" fxLayoutAlign="start space-between" fxFlex="100" #addInvoiceForm="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<input matInput autoFocus [(ngModel)]="description" placeholder="Description" tabindex="2" name="description">
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxLayoutAlign="space-between start" fxFlex="100">
|
||||
<mat-form-field fxFlex="40">
|
||||
<input matInput [(ngModel)]="invoiceValue" (keyup)="onInvoiceValueChange()" placeholder="Amount" type="number" step="100" min="1" tabindex="3" name="invoiceValue" required>
|
||||
<span matSuffix> {{information?.smaller_currency_unit}} </span>
|
||||
<mat-hint>{{invoiceValueHint}}</mat-hint>
|
||||
<mat-error *ngIf="!invoiceValue">Amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="30">
|
||||
<input matInput [(ngModel)]="expiry" placeholder="Expiry" type="number" step="{{selTimeUnit === timeUnitEnum.SECS ? 300 : selTimeUnit === timeUnitEnum.MINS ? 10 : selTimeUnit === timeUnitEnum.HOURS ? 2 : 1}}" min="1" tabindex="4" name="expiry">
|
||||
<span matSuffix> {{selTimeUnit | titlecase}} </span>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="26">
|
||||
<mat-select [value]="selTimeUnit" tabindex="5" name="timeUnit" (selectionChange)="onTimeUnitChange($event)">
|
||||
<mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">{{timeUnit | titlecase}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div fxFlex="50" fxLayoutAlign="start center" class="mt-2">
|
||||
<mat-slide-toggle tabindex="6" color="primary" [(ngModel)]="private" matTooltip="Include routing hints for private channels" [matTooltipPosition]="'above'" name="private">Private Routing Hints</mat-slide-toggle>
|
||||
</div>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="invoiceError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span *ngIf="invoiceError !== ''">{{invoiceError}}</span>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" class="mt-2" fxLayoutAlign="end center">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button mat-flat-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="8">Create Invoice</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.mat-column-actions {
|
||||
min-height: 4.8rem;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
import { Component, OnInit, OnDestroy, Inject } from '@angular/core';
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { Subject } from 'rxjs';
|
||||
import { filter, takeUntil } from 'rxjs/operators';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Actions } from '@ngrx/effects';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
|
||||
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
import { InvoiceInformation } from '../../../shared/models/alertData';
|
||||
import { TimeUnitEnum, CurrencyUnitEnum, TIME_UNITS, CURRENCY_UNIT_FORMATS, PAGE_SIZE } from '../../../shared/services/consts-enums-functions';
|
||||
import { SelNodeChild } from '../../../shared/models/RTLconfig';
|
||||
import { GetInfoCL } from '../../../shared/models/clModels';
|
||||
import { CommonService } from '../../../shared/services/common.service';
|
||||
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-create-invoices',
|
||||
templateUrl: './create-invoice.component.html',
|
||||
styleUrls: ['./create-invoice.component.scss']
|
||||
})
|
||||
export class CLCreateInvoiceComponent implements OnInit, OnDestroy {
|
||||
public faExclamationTriangle = faExclamationTriangle;
|
||||
public selNode: SelNodeChild = {};
|
||||
public description = '';
|
||||
public expiry: number;
|
||||
public invoiceValue: number;
|
||||
public invoiceValueHint = '';
|
||||
public invoicePaymentReq = '';
|
||||
public invoices: any;
|
||||
public information: GetInfoCL = {};
|
||||
public private = false;
|
||||
public expiryStep = 100;
|
||||
public pageSize = PAGE_SIZE;
|
||||
public timeUnitEnum = TimeUnitEnum;
|
||||
public timeUnits = TIME_UNITS;
|
||||
public selTimeUnit = TimeUnitEnum.SECS;
|
||||
public invoiceError = '';
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(public dialogRef: MatDialogRef<CLCreateInvoiceComponent>, @Inject(MAT_DIALOG_DATA) public data: InvoiceInformation, private store: Store<fromRTLReducer.RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private actions$: Actions) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.pageSize = this.data.pageSize;
|
||||
this.store.select('cl')
|
||||
.pipe(takeUntil(this.unSubs[0]))
|
||||
.subscribe((rtlStore) => {
|
||||
this.selNode = rtlStore.nodeSettings;
|
||||
this.information = rtlStore.information;
|
||||
});
|
||||
this.actions$.pipe(takeUntil(this.unSubs[1]),
|
||||
filter(action => action.type === RTLActions.EFFECT_ERROR_CL || action.type === RTLActions.FETCH_INVOICES_CL))
|
||||
.subscribe((action: RTLActions.EffectErrorCl | RTLActions.FetchInvoicesCL) => {
|
||||
if (action.type === RTLActions.FETCH_INVOICES_CL) {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
if (action.type === RTLActions.EFFECT_ERROR_CL && action.payload.action === 'SaveNewInvoiceCL') {
|
||||
this.invoiceError = action.payload.message;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onAddInvoice(form: any) {
|
||||
this.invoiceError = '';
|
||||
if(!this.invoiceValue) { return true; }
|
||||
let expiryInSecs = (this.expiry ? this.expiry : 3600);
|
||||
if (this.selTimeUnit !== TimeUnitEnum.SECS) {
|
||||
expiryInSecs = this.commonService.convertTime(this.expiry, this.selTimeUnit, TimeUnitEnum.SECS);
|
||||
}
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Adding Invoice...'));
|
||||
this.store.dispatch(new RTLActions.SaveNewInvoiceCL({
|
||||
label: ('ulbl' + Math.random().toString(36).slice(2) + Date.now()), amount: this.invoiceValue*1000, description: this.description, expiry: expiryInSecs, private: this.private
|
||||
}));
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.description = '';
|
||||
this.invoiceValue = undefined;
|
||||
this.private = false;
|
||||
this.expiry = undefined;
|
||||
this.invoiceValueHint = '';
|
||||
this.selTimeUnit = TimeUnitEnum.SECS;
|
||||
this.invoiceError = '';
|
||||
}
|
||||
|
||||
onInvoiceValueChange() {
|
||||
if(this.selNode.fiatConversion && this.invoiceValue > 99) {
|
||||
this.invoiceValueHint = '';
|
||||
this.commonService.convertCurrency(this.invoiceValue, CurrencyUnitEnum.SATS, this.selNode.currencyUnits[2], this.selNode.fiatConversion)
|
||||
.pipe(takeUntil(this.unSubs[2]))
|
||||
.subscribe(data => {
|
||||
this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onTimeUnitChange(event: any) {
|
||||
if(this.expiry && this.selTimeUnit !== event.value) {
|
||||
this.expiry = this.commonService.convertTime(this.expiry, this.selTimeUnit, event.value);
|
||||
}
|
||||
this.selTimeUnit = event.value;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.unSubs.forEach(completeSub => {
|
||||
completeSub.next();
|
||||
completeSub.complete();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -77,12 +77,12 @@
|
|||
</div>
|
||||
<mat-divider class="w-100 my-1"></mat-divider>
|
||||
</div>
|
||||
<div [ngClass]="{'mt-2': !showAdvanced, 'mt-1': showAdvanced}" fxLayout="row" fxLayoutAlign="end center" fxFlex="100">
|
||||
<button fxFlex="50" fxFlex.gt-sm="25" fxLayoutAlign="center center" mat-stroked-button color="primary" type="reset" (click)="onShowAdvanced()" tabindex="1" class="mr-2">
|
||||
<div [ngClass]="{'mt-2': !showAdvanced, 'mt-1': showAdvanced}" fxLayout="row" fxLayoutAlign="end center">
|
||||
<button class="mr-1" mat-stroked-button color="primary" type="reset" (click)="onShowAdvanced()" tabindex="1">
|
||||
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
|
||||
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
|
||||
</button>
|
||||
<button autoFocus fxFlex="50" fxFlex.gt-sm="33" fxLayoutAlign="center center" mat-flat-button color="primary" tabindex="2" type="submit" rtlClipboard [payload]="invoice.bolt11" (copied)="onCopyPayment($event)">Copy Invoice</button>
|
||||
<button autoFocus mat-flat-button color="primary" tabindex="2" type="submit" rtlClipboard [payload]="invoice.bolt11" (copied)="onCopyPayment($event)">Copy Invoice</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,23 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<form [fxLayout]="showDetails ? 'column' : 'row wrap'" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" fxFlex="100" #addInvoiceForm="ngForm">
|
||||
<mat-form-field [fxFlex]="showDetails ? '45' : '100'" fxLayoutAlign="space-between stretch">
|
||||
<form *ngIf="!showDetails" fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100" #addInvoiceForm="ngForm">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="space-between stretch">
|
||||
<input matInput [(ngModel)]="description" placeholder="Description" tabindex="2" name="description">
|
||||
</mat-form-field>
|
||||
<mat-form-field [fxFlex]="showDetails ? '18' : '100'" fxLayoutAlign="start end">
|
||||
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
|
||||
<input matInput [(ngModel)]="invoiceValue" (keyup)="onInvoiceValueChange()" placeholder="Amount" type="number" step="100" min="1" tabindex="3" name="invoiceValue" required>
|
||||
<span matSuffix> {{information?.smaller_currency_unit}} </span>
|
||||
<mat-hint>{{invoiceValueHint}}</mat-hint>
|
||||
<mat-error *ngIf="!invoiceValue">Amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
|
||||
<input matInput [(ngModel)]="expiry" placeholder="Expiry" type="number" step="{{selTimeUnit === timeUnitEnum.SECS ? 300 : selTimeUnit === timeUnitEnum.MINS ? 10 : selTimeUnit === timeUnitEnum.HOURS ? 2 : 1}}" min="1" tabindex="4" name="expiry">
|
||||
<span matSuffix> {{selTimeUnit | titlecase}} </span>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="6" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
|
||||
<mat-select [value]="selTimeUnit" tabindex="5" name="timeUnit" (selectionChange)="onTimeUnitChange($event)">
|
||||
<mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">{{timeUnit | titlecase}}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div fxFlex="16" tabindex="6" fxLayoutAlign="start center" *ngIf="showDetails">
|
||||
<mat-slide-toggle color="primary" [(ngModel)]="private" matTooltip="Include routing hints for private channels" [matTooltipPosition]="'above'" name="private">Private Routing Hints</mat-slide-toggle>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="space-between start" *ngIf="showDetails" class="mt-2">
|
||||
<button fxFlex="31" fxLayoutAlign="center center" mat-stroked-button color="warn" tabindex="11" type="button" (click)="onDeleteExpiredInvoices()">Delete Expired</button>
|
||||
<button fxFlex="31" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="31" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="8">Create Invoice</button>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between stretch" *ngIf="!showDetails" class="mt-1">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="9" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="10">Create Invoice</button>
|
||||
<div fxLayout="row" class="mt-1">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="9" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button mat-flat-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="10">Create Invoice</button>
|
||||
</div>
|
||||
</form>
|
||||
<div fxLayout="row" *ngIf="showDetails">
|
||||
<button class="mr-1" mat-stroked-button color="warn" tabindex="7" type="button" (click)="onDeleteExpiredInvoices()">Delete Expired</button>
|
||||
<button mat-flat-button color="primary" (click)="openCreateInvoiceModal()" tabindex="8">Create Invoice</button>
|
||||
</div>
|
||||
<div fxLayout="column" fxLayoutAlign="start stretch" [ngClass]="{'display-none': !showDetails}">
|
||||
<div fxLayout="column" fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="start center" fxLayoutAlign="start stretch" class="padding-gap-x page-sub-title-container mt-2">
|
||||
<div fxFlex="70">
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation'
|
|||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
import { CLCreateInvoiceComponent } from '../create-invoice-modal/create-invoice.component';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-lightning-invoices',
|
||||
|
|
@ -105,6 +106,13 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
|
|||
|
||||
}
|
||||
|
||||
openCreateInvoiceModal() {
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
pageSize: this.pageSize,
|
||||
component: CLCreateInvoiceComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
onAddInvoice(form: any) {
|
||||
if(!this.invoiceValue) { return true; }
|
||||
let expiryInSecs = (this.expiry ? this.expiry : 3600);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
|
||||
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #sendPaymentForm="ngForm">
|
||||
<mat-form-field fxFlex="100">
|
||||
<input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" (keyup)="onPaymentRequestEntry()" required #paymentReq="ngModel">
|
||||
<mat-form-field fxFlex="100" *ngIf="!showDetails">
|
||||
<textarea matInput placeholder="Payment Request" name="paymentRequest" tabindex="1" [ngModel]="paymentRequest" (ngModelChange)="onPaymentRequestEntry($event)" required (matTextareaAutosize)="true" #paymentReq="ngModel"></textarea>
|
||||
<mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint>
|
||||
<mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" *ngIf="showDetails" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onSendPayment();" tabindex="3">Send Payment</button>
|
||||
<div fxLayout="row" *ngIf="!showDetails" class="mt-1">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button mat-flat-button color="primary" (click)="onSendPayment()" tabindex="3">Send Payment</button>
|
||||
</div>
|
||||
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between stretch" *ngIf="!showDetails" class="mt-1">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" (click)="onSendPayment();" tabindex="3">Send Payment</button>
|
||||
<div fxLayout="row" *ngIf="showDetails" class="mt-2">
|
||||
<button mat-flat-button color="primary" (click)="openSendPaymentModal()" tabindex="3">Send Payment</button>
|
||||
</div>
|
||||
</form>
|
||||
<div fxLayout="column" fxLayoutAlign="start stretch" [ngClass]="{'display-none': !showDetails}">
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@ import { LoggerService } from '../../../shared/services/logger.service';
|
|||
import { CommonService } from '../../../shared/services/common.service';
|
||||
|
||||
import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation';
|
||||
import { CLLightningSendPaymentsComponent } from '../send-payment-modal/send-payment.component';
|
||||
import { SelNodeChild } from '../../../shared/models/RTLconfig';
|
||||
import { CLEffects } from '../../store/cl.effects';
|
||||
import { RTLEffects } from '../../../store/rtl.effects';
|
||||
import * as RTLActions from '../../../store/rtl.actions';
|
||||
import * as fromRTLReducer from '../../../store/rtl.reducers';
|
||||
import { SelNodeChild } from '../../../shared/models/RTLconfig';
|
||||
|
||||
@Component({
|
||||
selector: 'rtl-cl-lightning-payments',
|
||||
|
|
@ -51,7 +52,7 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
|
|||
public screenSizeEnum = ScreenSizeEnum;
|
||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||
|
||||
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private lndEffects: CLEffects, private decimalPipe: DecimalPipe, private titleCasePipe: TitleCasePipe) {
|
||||
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private clEffects: CLEffects, private decimalPipe: DecimalPipe, private titleCasePipe: TitleCasePipe) {
|
||||
this.screenSize = this.commonService.getScreenSize();
|
||||
if(this.screenSize === ScreenSizeEnum.XS) {
|
||||
this.flgSticky = false;
|
||||
|
|
@ -100,8 +101,8 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
|
|||
this.sendPayment();
|
||||
} else {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...'));
|
||||
this.store.dispatch(new RTLActions.DecodePaymentCL(this.paymentRequest));
|
||||
this.lndEffects.setDecodedPaymentCL
|
||||
this.store.dispatch(new RTLActions.DecodePaymentCL({routeParam: this.paymentRequest, fromDialog: false}));
|
||||
this.clEffects.setDecodedPaymentCL
|
||||
.pipe(take(1))
|
||||
.subscribe(decodedPayment => {
|
||||
this.paymentDecoded = decodedPayment;
|
||||
|
|
@ -149,7 +150,7 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
|
|||
if (confirmRes) {
|
||||
this.paymentDecoded.msatoshi = confirmRes[0].inputValue;
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...'));
|
||||
this.store.dispatch(new RTLActions.SendPaymentCL({invoice: this.paymentRequest, amount: confirmRes[0].inputValue*1000}));
|
||||
this.store.dispatch(new RTLActions.SendPaymentCL({invoice: this.paymentRequest, amount: confirmRes[0].inputValue*1000, fromDialog: false}));
|
||||
this.resetData();
|
||||
}
|
||||
});
|
||||
|
|
@ -175,19 +176,20 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
|
|||
.subscribe(confirmRes => {
|
||||
if (confirmRes) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...'));
|
||||
this.store.dispatch(new RTLActions.SendPaymentCL({invoice: this.paymentRequest}));
|
||||
this.store.dispatch(new RTLActions.SendPaymentCL({invoice: this.paymentRequest, fromDialog: false}));
|
||||
this.resetData();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onPaymentRequestEntry() {
|
||||
onPaymentRequestEntry(event: any) {
|
||||
this.paymentRequest = event;
|
||||
this.paymentDecodedHint = '';
|
||||
if(this.paymentRequest.length > 100) {
|
||||
if(this.paymentRequest && this.paymentRequest.length > 100) {
|
||||
this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...'));
|
||||
this.store.dispatch(new RTLActions.DecodePaymentCL(this.paymentRequest));
|
||||
this.lndEffects.setDecodedPaymentCL.subscribe(decodedPayment => {
|
||||
this.store.dispatch(new RTLActions.DecodePaymentCL({routeParam: this.paymentRequest, fromDialog: false}));
|
||||
this.clEffects.setDecodedPaymentCL.subscribe(decodedPayment => {
|
||||
this.paymentDecoded = decodedPayment;
|
||||
if(this.paymentDecoded.msatoshi) {
|
||||
this.commonService.convertCurrency(+this.paymentDecoded.msatoshi, CurrencyUnitEnum.SATS, this.selNode.currencyUnits[2], this.selNode.fiatConversion)
|
||||
|
|
@ -206,6 +208,12 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
openSendPaymentModal() {
|
||||
this.store.dispatch(new RTLActions.OpenAlert({ data: {
|
||||
component: CLLightningSendPaymentsComponent
|
||||
}}));
|
||||
}
|
||||
|
||||
resetData() {
|
||||
this.paymentDecoded = {};
|
||||
this.paymentRequest = '';
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
<input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number" step="1000" min="0" required #destAmount="ngModel">
|
||||
<mat-error *ngIf="!amount">Amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear</button>
|
||||
<button fxFlex="48" fxLayoutAlign="center center" mat-flat-button color="primary" type="submit" tabindex="4">Query Route</button>
|
||||
<div fxLayout="row" class="mt-2">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear</button>
|
||||
<button mat-flat-button color="primary" type="submit" tabindex="4">Query Route</button>
|
||||
</div>
|
||||
</form>
|
||||
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2 mb-1">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
<div fxLayout="row">
|
||||
<div fxFlex="100" class="padding-gap-large">
|
||||
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
|
||||
<div fxFlex="95" fxLayoutAlign="start start">
|
||||
<span class="page-title">Send Payment</span>
|
||||
</div>
|
||||
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" [mat-dialog-close]="false" default mat-button>X</button>
|
||||
</mat-card-header>
|
||||
<mat-card-content class="mt-5px">
|
||||
<form fxLayoutAlign="space-between stretch" fxLayout="column" #sendPaymentForm="ngForm">
|
||||
<mat-form-field fxFlex="100">
|
||||
<textarea autoFocus matInput placeholder="Payment Request" name="paymentRequest" tabindex="1" [ngModel]="paymentRequest" (ngModelChange)="onPaymentRequestEntry($event)" (matTextareaAutosize)="true" required #paymentReq="ngModel"></textarea>
|
||||
<mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint>
|
||||
<mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error>
|
||||
<mat-error *ngIf="paymentReq.errors?.decodeError">{{paymentDecodedHint}}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="100" *ngIf="zeroAmtInvoice">
|
||||
<input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="paymentAmount" (change)="onAmountChange($event)" tabindex="2" required #paymentAmt="ngModel">
|
||||
<mat-hint>It is a zero amount invoice, enter amount to be paid.</mat-hint>
|
||||
<mat-error *ngIf="!paymentAmount">Payment amount is required.</mat-error>
|
||||
</mat-form-field>
|
||||
<div fxFlex="100" class="alert alert-danger mt-1" *ngIf="paymentError !== ''">
|
||||
<fa-icon [icon]="faExclamationTriangle" class="mr-1 alert-icon"></fa-icon>
|
||||
<span *ngIf="paymentError !== ''">{{paymentError}}</span>
|
||||
</div>
|
||||
<div class="mt-2" fxLayout="row" fxLayoutAlign="end center">
|
||||
<button class="mr-1" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Fields</button>
|
||||
<button mat-flat-button color="primary" (click)="onSendPayment();" tabindex="3">Send Payment</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
.mat-column-actions {
|
||||
min-height: 4.8rem;
|
||||
}
|
||||
|
||||
.mat-column-payment_hash {
|
||||
flex: 1 1 20%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue