Incomplete lazy load

Incomplete lazy load
pull/209/head
Shahana Farooqui 5 years ago
parent e93231c590
commit d318ad7c82

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -3,10 +3,11 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>RTL</title> <title>RTL</title>
<base href="/rtl/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <base href="/rtl/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="assets/images/favicon.ico"> <link rel="icon" type="image/x-icon" href="assets/images/favicon.ico">
<link rel="stylesheet" href="styles.95c3afc83be2d91ee834.css"></head> <link rel="stylesheet" href="styles.95c3afc83be2d91ee834.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime-es2015.daac63f861585ab7a235.js" type="module"></script><script src="polyfills-es2015.2a0da12c7706d5c3e2aa.js" type="module"></script><script src="runtime-es5.5a48a1a46f5d6db38cc2.js" nomodule></script><script src="polyfills-es5.84431ea76d33490d0941.js" nomodule></script><script src="main-es2015.31d82cbabd2de8337eaa.js" type="module"></script><script src="main-es5.2e2e9dbae4980e7e928a.js" nomodule></script></body> <script src="runtime-es2015.6c92075aefa095411d25.js" type="module"></script><script src="polyfills-es2015.af35579f5b57e97fcdea.js" type="module"></script><script src="runtime-es5.18bd9dad956fbe3e232b.js" nomodule></script><script src="polyfills-es5.64372fcf007b6e0e7247.js" nomodule></script><script src="main-es2015.803decf729a522acb617.js" type="module"></script><script src="main-es5.69224cfebb64abd32219.js" nomodule></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +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++)o[a=i[p]]&&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)+"-es2015."+{1:"6aacfc3b356893189a11",5:"728790da8d674f1a9a03",6:"12f89c6eac1f84929add"}[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()}([]);

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

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

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

@ -27,27 +27,29 @@ common.setOptions = () => {
if(undefined !== common.nodes[0].options && undefined !== common.nodes[0].options.headers) { return; } if(undefined !== common.nodes[0].options && undefined !== common.nodes[0].options.headers) { return; }
try { try {
common.nodes.forEach(node => { common.nodes.forEach(node => {
console.log(node);
node.options = { node.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex'),
},
form: '' form: ''
}; };
if(node.ln_implementation !== 'CLightning') {
node.options.headers = {'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex')};
}
}); });
// Options cannot be set before selected node initializes. Updating selected node's options separatly // Options cannot be set before selected node initializes. Updating selected node's options separatly
common.selectedNode.options = { common.selectedNode.options = {
url: '', url: '',
rejectUnauthorized: false, rejectUnauthorized: false,
json: true, json: true,
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(common.selectedNode.macaroon_path + '/admin.macaroon').toString('hex'),
},
form: '' form: ''
}; };
if(common.selectedNode.ln_implementation !== 'CLightning') {
common.selectedNode.options.headers = {'Grpc-Metadata-macaroon': fs.readFileSync(common.selectedNode.macaroon_path + '/admin.macaroon').toString('hex')};
}
} catch(err) { } catch(err) {
console.error('Common Set Options Error:' + JSON.stringify(err));
common.nodes.forEach(node => { common.nodes.forEach(node => {
node.options = { node.options = {
url: '', url: '',

@ -262,12 +262,16 @@ connect.validateMultiNodeConfig = (config) => {
config.nodes.forEach((node, idx) => { config.nodes.forEach((node, idx) => {
common.nodes[idx] = {}; common.nodes[idx] = {};
if(node.Authentication.macaroonPath === '' || undefined === node.Authentication.macaroonPath) { if(node.lnImplementation === 'CLightning') {
errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Multi-Node-Conf.json!'; common.nodes[idx].macaroon_path = '';
} else { } else {
common.nodes[idx].macaroon_path = node.Authentication.macaroonPath; if(node.Authentication.macaroonPath === '' || undefined === node.Authentication.macaroonPath) {
errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Multi-Node-Conf.json!';
} else {
common.nodes[idx].macaroon_path = node.Authentication.macaroonPath;
}
} }
if((node.Settings.lndServerUrl === '' || undefined === node.Settings.lndServerUrl)) { if((node.Settings.lndServerUrl === '' || undefined === node.Settings.lndServerUrl)) {
errMsg = errMsg + '\nPlease set LND server URL for node index ' + node.index + ' in RTL-Multi-Node-Conf.json!'; errMsg = errMsg + '\nPlease set LND server URL for node index ' + node.index + ' in RTL-Multi-Node-Conf.json!';
} else { } else {
@ -277,7 +281,7 @@ connect.validateMultiNodeConfig = (config) => {
common.nodes[idx].index = node.index; common.nodes[idx].index = node.index;
common.nodes[idx].ln_node = node.lnNode; common.nodes[idx].ln_node = node.lnNode;
common.nodes[idx].ln_implementation = node.lnImplementation; common.nodes[idx].ln_implementation = node.lnImplementation;
common.nodes[idx].lnd_config_path = (undefined !== node.Authentication.lndConfigPath) ? node.Authentication.lndConfigPath : ''; common.nodes[idx].lnd_config_path = (undefined !== node.Authentication && undefined !== node.Authentication.lndConfigPath) ? node.Authentication.lndConfigPath : '';
common.nodes[idx].bitcoind_config_path = (undefined !== node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : ''; common.nodes[idx].bitcoind_config_path = (undefined !== node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
common.nodes[idx].enable_logging = (undefined !== node.Settings.enableLogging) ? node.Settings.enableLogging : false; common.nodes[idx].enable_logging = (undefined !== node.Settings.enableLogging) ? node.Settings.enableLogging : false;
common.nodes[idx].channel_backup_path = (undefined !== node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : common.rtl_conf_file_path + common.path_separator + 'backup' + common.path_separator + 'node-' + node.index; common.nodes[idx].channel_backup_path = (undefined !== node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : common.rtl_conf_file_path + common.path_separator + 'backup' + common.path_separator + 'node-' + node.index;

@ -60,7 +60,7 @@ exports.getRTLConfig = (req, res, next) => {
multiNodeConfig.nodes.forEach((node, i) => { multiNodeConfig.nodes.forEach((node, i) => {
const authentication = {}; const authentication = {};
authentication.nodeAuthType = 'CUSTOM'; authentication.nodeAuthType = 'CUSTOM';
if(node.Authentication.lndConfigPath) { if(node.Authentication && node.Authentication.lndConfigPath) {
authentication.lndConfigPath = node.Authentication.lndConfigPath; authentication.lndConfigPath = node.Authentication.lndConfigPath;
} }
if(node.Settings.bitcoindConfigPath) { if(node.Settings.bitcoindConfigPath) {

@ -5,9 +5,10 @@
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve --base-href /rtl/ --open --aot", "start": "ng serve --base-href /rtl/ --open --aot",
"prebuild": "node ./prebuild",
"build": "ng analytics off && ng build --prod --base-href /rtl/ --aot", "build": "ng analytics off && ng build --prod --base-href /rtl/ --aot",
"serve": "ng serve", "serve": "ng serve",
"prebuild": "node ./prebuild", "server": "nodemon ./rtl.js",
"test": "ng test", "test": "ng test",
"lint": "ng lint", "lint": "ng lint",
"e2e": "ng e2e" "e2e": "ng e2e"

@ -18,10 +18,10 @@
<rtl-top-menu></rtl-top-menu> <rtl-top-menu></rtl-top-menu>
</div> </div>
</mat-toolbar> </mat-toolbar>
<div fxLayout="row" fxLayoutAlign="center center" class="bg-primary flex-wrap pubkey-info-top" rtlClipboard [payload]="information?.identity_pubkey" (copied)="copiedText($event)"> <div fxLayout="row" fxLayoutAlign="center center" class="bg-primary flex-wrap pubkey-info-top" rtlClipboard [payload]="selNodeInfo?.identity_pubkey" (copied)="copiedText($event)">
<mat-icon [ngClass]="{'icon-smaller': smallScreen}">vpn_key</mat-icon> <mat-icon [ngClass]="{'icon-smaller': smallScreen}">vpn_key</mat-icon>
<div [ngClass]="{'word-break font-9px': smallScreen, 'word-break': !smallScreen}">&nbsp;{{information?.identity_pubkey}} <div [ngClass]="{'word-break font-9px': smallScreen, 'word-break': !smallScreen}">&nbsp;{{selNodeInfo?.identity_pubkey}}
<mat-spinner [diameter]="20" *ngIf="flgLoading[0]" class="inline-spinner foreground"></mat-spinner> <mat-spinner [diameter]="20" *ngIf="!selNodeInfo?.identity_pubkey" class="inline-spinner foreground"></mat-spinner>
<mat-icon [ngClass]="{'icon-smaller cursor-pointer copy-icon-smaller': smallScreen, 'icon-small cursor-pointer copy-icon': !smallScreen}">file_copy</mat-icon><span [hidden]="!flgCopied">Copied</span> <mat-icon [ngClass]="{'icon-smaller cursor-pointer copy-icon-smaller': smallScreen, 'icon-small cursor-pointer copy-icon': !smallScreen}">file_copy</mat-icon><span [hidden]="!flgCopied">Copied</span>
</div> </div>
</div> </div>

@ -8,11 +8,8 @@ import { UserIdleService } from 'angular-user-idle';
import * as sha256 from 'sha256'; import * as sha256 from 'sha256';
import { LoggerService } from './shared/services/logger.service'; import { LoggerService } from './shared/services/logger.service';
import { RTLConfiguration, Settings, Node } from './shared/models/RTLconfig'; import { RTLConfiguration, Settings, Node, SelNodeInfo } from './shared/models/RTLconfig';
import { GetInfo } from './shared/models/lndModels';
import * as LNDActions from './lnd/store/lnd.actions';
import * as fromLNDReducer from './lnd/store/lnd.reducers';
import * as RTLActions from './store/rtl.actions'; import * as RTLActions from './store/rtl.actions';
import * as fromRTLReducer from './store/rtl.reducers'; import * as fromRTLReducer from './store/rtl.reducers';
@ -26,7 +23,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('settingSidenav', { static: true }) settingSidenav: any; @ViewChild('settingSidenav', { static: true }) settingSidenav: any;
public selNode: Node; public selNode: Node;
public settings: Settings; public settings: Settings;
public information: GetInfo = {}; public selNodeInfo: SelNodeInfo;
public flgLoading: Array<Boolean | 'error'> = [true]; // 0: Info public flgLoading: Array<Boolean | 'error'> = [true]; // 0: Info
public flgCopied = false; public flgCopied = false;
public appConfig: RTLConfiguration; public appConfig: RTLConfiguration;
@ -34,22 +31,15 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
public smallScreen = false; public smallScreen = false;
unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()]; unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private lndStore: Store<fromLNDReducer.LNDState>, private actions$: Actions, constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private actions$: Actions, private userIdle: UserIdleService, private router: Router) {}
private userIdle: UserIdleService, private router: Router) {}
ngOnInit() { ngOnInit() {
this.store.dispatch(new RTLActions.FetchRTLConfig()); this.store.dispatch(new RTLActions.FetchRTLConfig());
this.accessKey = this.readAccessKey(); this.accessKey = this.readAccessKey();
this.lndStore.select('lnd')
.pipe(takeUntil(this.unsubs[3]))
.subscribe(lndStore => {
this.information = lndStore ? lndStore.information : {};
this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
this.logger.info(lndStore);
});
this.store.select('rtlRoot') this.store.select('rtlRoot')
.pipe(takeUntil(this.unsubs[0])) .pipe(takeUntil(this.unsubs[0]))
.subscribe(rtlStore => { .subscribe(rtlStore => {
this.selNodeInfo = rtlStore.selNodeInfo;
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings; this.settings = this.selNode.settings;
this.appConfig = rtlStore.appConfig; this.appConfig = rtlStore.appConfig;
@ -62,18 +52,12 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
this.smallScreen = true; this.smallScreen = true;
} }
this.logger.info(this.settings); this.logger.info(this.settings);
if (!sessionStorage.getItem('token')) {
this.flgLoading[0] = false;
}
}); });
if (sessionStorage.getItem('token')) {
this.lndStore.dispatch(new LNDActions.FetchInfo());
}
this.actions$ this.actions$
.pipe( .pipe(
takeUntil(this.unsubs[1]), takeUntil(this.unsubs[1]),
filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_RTL_CONFIG) filter(action => action.type === RTLActions.SET_RTL_CONFIG)
).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => { ).subscribe((actionPayload: RTLActions.SetRTLConfig) => {
if (actionPayload.type === RTLActions.SET_RTL_CONFIG) { if (actionPayload.type === RTLActions.SET_RTL_CONFIG) {
if (!sessionStorage.getItem('token')) { if (!sessionStorage.getItem('token')) {
if (+actionPayload.payload.sso.rtlSSO) { if (+actionPayload.payload.sso.rtlSSO) {
@ -89,17 +73,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed
setTimeout(() => { this.settingSidenav.toggle(); }, 100); setTimeout(() => { this.settingSidenav.toggle(); }, 100);
} }
} else if (actionPayload.type === RTLActions.INIT_APP_DATA) {
this.lndStore.dispatch(new LNDActions.FetchInfo());
}
});
this.actions$
.pipe(
takeUntil(this.unsubs[1]),
filter((action) => action.type === LNDActions.SET_INFO)
).subscribe((infoData: LNDActions.SetInfo) => {
if (undefined !== infoData.payload.identity_pubkey) {
this.initializeRemainingData();
} }
}); });
this.userIdle.startWatching(); this.userIdle.startWatching();
@ -122,17 +95,6 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
return url.substring(url.lastIndexOf('access-key=') + 11).trim(); return url.substring(url.lastIndexOf('access-key=') + 11).trim();
} }
initializeRemainingData() {
this.lndStore.dispatch(new LNDActions.FetchPeers());
this.lndStore.dispatch(new LNDActions.FetchBalance('channels'));
this.lndStore.dispatch(new LNDActions.FetchFees());
this.lndStore.dispatch(new LNDActions.FetchNetwork());
this.lndStore.dispatch(new LNDActions.FetchChannels({routeParam: 'all'}));
this.lndStore.dispatch(new LNDActions.FetchChannels({routeParam: 'pending'}));
this.lndStore.dispatch(new LNDActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
this.lndStore.dispatch(new LNDActions.FetchPayments());
}
ngAfterViewInit() { ngAfterViewInit() {
if (!this.settings.flgSidenavPinned) { if (!this.settings.flgSidenavPinned) {
this.sideNavigation.close(); this.sideNavigation.close();

@ -1,8 +1,22 @@
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core'; import { ModuleWithProviders } from '@angular/core';
import { ServerConfigComponent } from './shared/components/server-config/server-config.component';
import { HelpComponent } from './shared/components/help/help.component';
import { SigninComponent } from './shared/components/signin/signin.component';
import { NotFoundComponent } from './shared/components/not-found/not-found.component';
import { SsoFailedComponent } from './shared/components/sso-failed/sso-failed.component';
import { AuthGuard } from './shared/services/auth.guard';
export const routes: Routes = [ export const routes: Routes = [
{ path: '', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LndModule)}, { path: '', redirectTo: '/lnd', pathMatch: 'full' },
{ path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LndModule)},
{ path: 'cl', loadChildren: () => import('./c-lightning/cl.module').then(childModule => childModule.ClModule)},
{ path: 'sconfig', component: ServerConfigComponent, canActivate: [AuthGuard] },
{ path: 'login', component: SigninComponent },
{ path: 'help', component: HelpComponent },
{ path: 'ssoerror', component: SsoFailedComponent },
{ path: '**', component: NotFoundComponent }
]; ];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes); export const routing: ModuleWithProviders = RouterModule.forRoot(routes);

@ -0,0 +1 @@
<router-outlet></router-outlet>

@ -0,0 +1,4 @@
.inline-spinner {
display: inline-flex !important;
top: 0px !important;
}

@ -0,0 +1,54 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import * as CLActions from './store/cl.actions';
import * as RTLActions from '../store/rtl.actions';
import * as fromRTLReducer from '../store/rtl.reducers';
@Component({
selector: 'rtl-cl-root-app',
templateUrl: './cl-root.component.html',
styleUrls: ['./cl-root.component.scss']
})
export class ClRootComponent implements OnInit, OnDestroy {
unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.State>, private actions$: Actions, private router: Router, private activatedRoute: ActivatedRoute) {}
ngOnInit() {
console.warn('CL ROOT');
this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
this.actions$.pipe(takeUntil(this.unsubs[0]), filter((action) => action.type === RTLActions.INIT_APP_DATA))
.subscribe((actionPayload: RTLActions.InitAppData) => {
this.store.dispatch(new CLActions.FetchCLInfo());
});
this.actions$.pipe(takeUntil(this.unsubs[1]), filter((action) => action.type === CLActions.SET_CL_INFO))
.subscribe((infoData: CLActions.SetCLInfo) => {
if (undefined !== infoData.payload.identity_pubkey) {
this.initializeRemainingData();
}
});
}
initializeRemainingData() {
// this.store.dispatch(new CLActions.FetchPeers());
// this.store.dispatch(new CLActions.FetchBalance('channels'));
// this.store.dispatch(new CLActions.FetchFees());
// this.store.dispatch(new CLActions.FetchNetwork());
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'all'}));
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'pending'}));
// this.store.dispatch(new CLActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
// this.store.dispatch(new CLActions.FetchPayments());
}
ngOnDestroy() {
this.unsubs.forEach(unsub => {
unsub.next();
unsub.complete();
});
}
}

@ -0,0 +1,34 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgxChartsModule } from '@swimlane/ngx-charts';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
import { environment } from '../../environments/environment';
import { SharedModule } from '../shared/shared.module';
import { CLReducer } from './store/cl.reducers';
import { CLEffects } from './store/cl.effects';
import { clRouting } from './cl.routing';
import { ClRootComponent } from './cl-root.component';
import { HomeComponent } from './home/home.component';
@NgModule({
imports: [
CommonModule,
SharedModule,
clRouting,
NgxChartsModule,
EffectsModule.forFeature([CLEffects]),
StoreModule.forFeature('cl', CLReducer),
!environment.production ? StoreDevtoolsModule.instrument() : []
],
declarations: [
ClRootComponent,
HomeComponent
],
providers: [],
bootstrap: [ClRootComponent]
})
export class ClModule {}

@ -0,0 +1,15 @@
import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core';
import { AuthGuard } from '../shared/services/auth.guard';
import { ClRootComponent } from './cl-root.component';
import { HomeComponent } from './home/home.component';
export const clRoutes: Routes = [
{ path: '', redirectTo: '.', pathMatch: 'full', canActivate: [AuthGuard]},
{ path: '.', component: ClRootComponent, canActivate: [AuthGuard] },
{ path: './home', component: HomeComponent, canActivate: [AuthGuard] }
];
export const clRouting: ModuleWithProviders = RouterModule.forChild(clRoutes);

@ -0,0 +1,2 @@
<h4>CL Home</h4>
<p>{{information | json}}</p>

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HomeComponent } from './home.component';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HomeComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,39 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { LoggerService } from '../../shared/services/logger.service';
import { GetInfo } from '../../shared/models/clModels';
import * as fromCLReducer from '../store/cl.reducers';
@Component({
selector: 'rtl-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit, OnDestroy {
public information: GetInfo = {};
private unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private logger: LoggerService, private clStore: Store<fromCLReducer.CLState>) {}
ngOnInit() {
console.warn('CL HOME');
this.clStore.select('cl')
.pipe(takeUntil(this.unsubs[1]))
.subscribe(clStore => {
this.information = clStore.information;
this.logger.info(clStore);
});
}
ngOnDestroy() {
this.unsubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

@ -0,0 +1,22 @@
import { Action } from '@ngrx/store';
import { GetInfo } from '../../shared/models/clModels';
export const RESET_CL_STORE = 'RESET_CL_STORE';
export const FETCH_CL_INFO = 'FETCH_CL_INFO';
export const SET_CL_INFO = 'SET_CL_INFO';
export class ResetCLStore implements Action {
readonly type = RESET_CL_STORE;
}
export class FetchCLInfo implements Action {
readonly type = FETCH_CL_INFO;
}
export class SetCLInfo implements Action {
readonly type = SET_CL_INFO;
constructor(public payload: GetInfo) {}
}
export type CLActions =
ResetCLStore | FetchCLInfo | SetCLInfo;

@ -0,0 +1,83 @@
import { Injectable, OnDestroy } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { of, Subject } from 'rxjs';
import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators';
import { MatDialog } from '@angular/material';
import { environment } from '../../../environments/environment';
import { LoggerService } from '../../shared/services/logger.service';
import { GetInfo } from '../../shared/models/clModels';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import * as CLActions from './cl.actions';
import * as fromCLReducer from './cl.reducers';
@Injectable()
export class CLEffects implements OnDestroy {
dialogRef: any;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(
private actions$: Actions,
private httpClient: HttpClient,
private store: Store<fromCLReducer.CLState>,
private logger: LoggerService,
public dialog: MatDialog,
private router: Router) { }
@Effect()
infoFetch = this.actions$.pipe(
ofType(CLActions.FETCH_CL_INFO),
withLatestFrom(this.store.select('rtlRoot')),
mergeMap(([action, store]: [CLActions.FetchCLInfo, fromRTLReducer.State]) => {
this.store.dispatch(new RTLActions.ClearEffectError('FetchInfo'));
return this.httpClient.get<GetInfo>(environment.GETINFO_API)
.pipe(
map((info) => {
this.logger.info(info);
if (undefined === info.identity_pubkey) {
this.store.dispatch(new RTLActions.SetSelNodeInfo({}));
sessionStorage.removeItem('clUnlocked');
return {
type: CLActions.SET_CL_INFO,
payload: {}
};
} else {
this.store.dispatch(new RTLActions.SetSelNodeInfo(info));
sessionStorage.setItem('clUnlocked', 'true');
return {
type: CLActions.SET_CL_INFO,
payload: (undefined !== info) ? info : {}
};
}
}),
catchError((err) => {
this.logger.error(err);
this.store.dispatch(new RTLActions.EffectError({ action: 'FetchInfo', code: err.status, message: err.error.error }));
if (+store.appConfig.sso.rtlSSO) {
this.router.navigate(['/ssoerror']);
} else {
if (err.status === 401) {
this.logger.info('Redirecting to Signin');
this.router.navigate([store.appConfig.sso.logoutRedirectLink]);
return of();
}
}
})
);
}
));
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

@ -0,0 +1,47 @@
import * as CLActions from './cl.actions';
import { GetInfo, GetInfoChain } from '../../shared/models/clModels';
import * as fromApp from '../../store/rtl.reducers';
export interface FeatureState extends fromApp.State {
cl: CLState;
}
export interface CLState {
information: GetInfo;
}
export const CLInitialState: CLState = {
information: {}
};
export function CLReducer(state = CLInitialState, action: CLActions.CLActions) {
switch (action.type) {
case CLActions.RESET_CL_STORE:
return {
...CLInitialState
};
case CLActions.SET_CL_INFO:
if (undefined !== action.payload.chains) {
if (typeof action.payload.chains[0] === 'string') {
action.payload.smaller_currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
action.payload.currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
} else if (typeof action.payload.chains[0] === 'object' && action.payload.chains[0].hasOwnProperty('chain')) {
const getInfoChain = <GetInfoChain>action.payload.chains[0];
action.payload.smaller_currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
action.payload.currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
}
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
} else {
action.payload.smaller_currency_unit = 'Sats';
action.payload.currency_unit = 'BTC';
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
}
return {
...state,
information: action.payload
};
default:
return state;
}
}

@ -1,48 +1 @@
<div fxLayout="column" id="rtl-container" class="rtl-container" [ngClass]="settings.theme" [class.horizontal]="settings.menu === 'Horizontal'" [class.compact]="settings.menuType === 'Compact'" [class.mini]="settings.menuType === 'Mini'"> <router-outlet></router-outlet>
<mat-sidenav-container>
<mat-sidenav perfectScrollbar *ngIf="settings.menu === 'Vertical'" [opened]="settings.flgSidenavOpened" [mode]="(settings.flgSidenavPinned) ? 'side' : 'over'"
#sideNavigation class="sidenav mat-elevation-z6 overflow-auto">
<rtl-side-navigation (ChildNavClicked)="onNavigationClicked($event)"></rtl-side-navigation>
</mat-sidenav>
<mat-sidenav-content perfectScrollbar class="overflow-auto">
<mat-toolbar fxLayout="row" fxLayoutAlign="space-between center" color="primary" class="padding-gap-x">
<div fxLayoutAlign="center center">
<button *ngIf="settings.menu === 'Vertical'" mat-icon-button (click)="sideNavToggle()">
<mat-icon>menu</mat-icon>
</button>
</div>
<div>
<h2>Ride The Lightning <span class="font-60-percent">(Beta)</span></h2>
</div>
<div fxLayoutAlign="space-between center">
<rtl-top-menu></rtl-top-menu>
</div>
</mat-toolbar>
<div fxLayout="row" fxLayoutAlign="center center" class="bg-primary flex-wrap pubkey-info-top" rtlClipboard [payload]="information?.identity_pubkey" (copied)="copiedText($event)">
<mat-icon [ngClass]="{'icon-smaller': smallScreen}">vpn_key</mat-icon>
<div [ngClass]="{'word-break font-9px': smallScreen, 'word-break': !smallScreen}">&nbsp;{{information?.identity_pubkey}}
<mat-spinner [diameter]="20" *ngIf="flgLoading[0]" class="inline-spinner foreground"></mat-spinner>
<mat-icon [ngClass]="{'icon-smaller cursor-pointer copy-icon-smaller': smallScreen, 'icon-small cursor-pointer copy-icon': !smallScreen}">file_copy</mat-icon><span [hidden]="!flgCopied">Copied</span>
</div>
</div>
<mat-toolbar color="primary" *ngIf="settings.menu === 'Horizontal'" class="padding-gap-x horizontal-nav">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="center center" class="h-100">
<rtl-horizontal-navigation></rtl-horizontal-navigation>
</div>
</mat-toolbar>
<div [ngClass]="{'mt-minus-1': smallScreen, 'inner-sidenav-content': true}">
<router-outlet></router-outlet>
</div>
<div fxLayout="row" fxLayoutAlign="center center" class="bg-primary settings-icon" (click)="settingSidenav.toggle()">
<mat-icon class="animate-settings">settings</mat-icon>
</div>
</mat-sidenav-content>
<mat-sidenav #settingSidenav position="end" class="settings mat-elevation-z6" mode="side">
<rtl-settings-nav (done)="settingSidenav.toggle()"></rtl-settings-nav>
</mat-sidenav>
</mat-sidenav-container>
<div class="rtl-spinner" *ngIf="undefined === settings.theme">
<mat-spinner color="accent"></mat-spinner>
<h4>Loading RTL...</h4>
</div>
</div>

@ -1,18 +1,11 @@
import { Component, OnInit, AfterViewInit, OnDestroy, ViewChild, HostListener } from '@angular/core'; import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router'; import { Router, ActivatedRoute } from '@angular/router';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators'; import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { UserIdleService } from 'angular-user-idle';
import * as sha256 from 'sha256';
import { LoggerService } from '../shared/services/logger.service';
import { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig';
import { GetInfo } from '../shared/models/lndModels';
import * as fromLNDReducer from './store/lnd.reducers';
import * as LNDActions from './store/lnd.actions'; import * as LNDActions from './store/lnd.actions';
import * as RTLActions from '../store/rtl.actions';
import * as fromRTLReducer from '../store/rtl.reducers'; import * as fromRTLReducer from '../store/rtl.reducers';
@Component({ @Component({
@ -20,100 +13,22 @@ import * as fromRTLReducer from '../store/rtl.reducers';
templateUrl: './lnd-root.component.html', templateUrl: './lnd-root.component.html',
styleUrls: ['./lnd-root.component.scss'] styleUrls: ['./lnd-root.component.scss']
}) })
export class LndRootComponent implements OnInit, AfterViewInit, OnDestroy { export class LndRootComponent implements OnInit, OnDestroy {
@ViewChild('sideNavigation', { static: true }) sideNavigation: any; unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
@ViewChild('settingSidenav', { static: true }) settingSidenav: any;
public selNode: Node;
public settings: Settings;
public information: GetInfo = {};
public flgLoading: Array<Boolean | 'error'> = [true]; // 0: Info
public flgCopied = false;
public appConfig: RTLConfiguration;
public accessKey = '';
public smallScreen = false;
unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private actions$: Actions, constructor(private store: Store<fromRTLReducer.State>, private lndStore: Store<fromLNDReducer.LNDState>, private router: Router, private activatedRoute: ActivatedRoute) {}
private userIdle: UserIdleService, private router: Router) {}
ngOnInit() { ngOnInit() {
this.store.dispatch(new RTLActions.FetchRTLConfig()); console.warn('LND ROOT');
this.accessKey = this.readAccessKey(); this.store.dispatch(new LNDActions.FetchInfo());
this.store.select('rtlRoot') this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
this.lndStore.select('lnd')
.pipe(takeUntil(this.unsubs[0])) .pipe(takeUntil(this.unsubs[0]))
.subscribe(rtlStore => { .subscribe(lndStore => {
this.selNode = rtlStore.selNode; if (undefined !== lndStore.information.identity_pubkey) {
this.settings = this.selNode.settings;
this.appConfig = rtlStore.appConfig;
this.information = rtlStore.information;
this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
if (window.innerWidth <= 768) {
this.settings.menu = 'Vertical';
this.settings.flgSidenavOpened = false;
this.settings.flgSidenavPinned = false;
}
if (window.innerWidth <= 414) {
this.smallScreen = true;
}
this.logger.info(this.settings);
if (!sessionStorage.getItem('token')) {
this.flgLoading[0] = false;
}
});
if (sessionStorage.getItem('token')) {
this.store.dispatch(new LNDActions.FetchInfo());
}
this.actions$
.pipe(
takeUntil(this.unsubs[1]),
filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_RTL_CONFIG)
).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => {
if (actionPayload.type === RTLActions.SET_RTL_CONFIG) {
if (!sessionStorage.getItem('token')) {
if (+actionPayload.payload.sso.rtlSSO) {
this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey)));
} else {
this.router.navigate([this.appConfig.sso.logoutRedirectLink]);
}
}
if (
this.settings.menu === 'Horizontal' ||
this.settings.menuType === 'Compact' ||
this.settings.menuType === 'Mini') {
this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed
setTimeout(() => { this.settingSidenav.toggle(); }, 100);
}
} else if (actionPayload.type === RTLActions.INIT_APP_DATA) {
this.store.dispatch(new LNDActions.FetchInfo());
}
});
this.actions$
.pipe(
takeUntil(this.unsubs[1]),
filter((action) => action.type === LNDActions.SET_INFO)
).subscribe((infoData: LNDActions.SetInfo) => {
if (undefined !== infoData.payload.identity_pubkey) {
this.initializeRemainingData(); this.initializeRemainingData();
} }
}); });
this.userIdle.startWatching();
this.userIdle.onTimerStart().subscribe(count => {});
this.userIdle.onTimeout().subscribe(() => {
if (sessionStorage.getItem('token')) {
this.logger.warn('Time limit exceeded for session inactivity! Logging out!');
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
type: 'WARN',
titleMessage: 'Time limit exceeded for session inactivity! Logging out!'
}}));
this.store.dispatch(new RTLActions.Signout());
this.userIdle.resetTimer();
}
});
}
private readAccessKey() {
const url = window.location.href;
return url.substring(url.lastIndexOf('access-key=') + 11).trim();
} }
initializeRemainingData() { initializeRemainingData() {
@ -127,42 +42,6 @@ export class LndRootComponent implements OnInit, AfterViewInit, OnDestroy {
this.store.dispatch(new LNDActions.FetchPayments()); this.store.dispatch(new LNDActions.FetchPayments());
} }
ngAfterViewInit() {
if (!this.settings.flgSidenavPinned) {
this.sideNavigation.close();
this.settingSidenav.toggle();
}
if (window.innerWidth <= 768) {
this.sideNavigation.close();
this.settingSidenav.toggle();
}
}
@HostListener('window:resize')
public onWindowResize(): void {
if (window.innerWidth <= 768) {
this.settings.menu = 'Vertical';
this.settings.flgSidenavOpened = false;
this.settings.flgSidenavPinned = false;
}
}
sideNavToggle() {
this.sideNavigation.toggle();
}
onNavigationClicked(event: any) {
if (window.innerWidth <= 414) {
this.sideNavigation.close();
}
}
copiedText(payload) {
this.flgCopied = true;
setTimeout(() => {this.flgCopied = false; }, 5000);
this.logger.info('Copied Text: ' + payload);
}
ngOnDestroy() { ngOnDestroy() {
this.unsubs.forEach(unsub => { this.unsubs.forEach(unsub => {
unsub.next(); unsub.next();

@ -16,13 +16,10 @@ import { HomeComponent } from './home/home.component';
import { PeersComponent } from './peers/peers.component'; import { PeersComponent } from './peers/peers.component';
import { SendReceiveTransComponent } from './transactions/send-receive/send-receive-trans.component'; import { SendReceiveTransComponent } from './transactions/send-receive/send-receive-trans.component';
import { InvoicesComponent } from './invoices/invoices.component'; import { InvoicesComponent } from './invoices/invoices.component';
import { ServerConfigComponent } from './server-config/server-config.component';
import { HelpComponent } from './help/help.component';
import { UnlockLNDComponent } from './unlock-lnd/unlock-lnd.component'; import { UnlockLNDComponent } from './unlock-lnd/unlock-lnd.component';
import { PaymentsComponent } from './payments/send-receive/payments.component'; import { PaymentsComponent } from './payments/send-receive/payments.component';
import { ChannelManageComponent } from './channels/channel-manage/channel-manage.component'; import { ChannelManageComponent } from './channels/channel-manage/channel-manage.component';
import { ChannelPendingComponent } from './channels/channel-pending/channel-pending.component'; import { ChannelPendingComponent } from './channels/channel-pending/channel-pending.component';
import { SigninComponent } from './signin/signin.component';
import { ChannelClosedComponent } from './channels/channel-closed/channel-closed.component'; import { ChannelClosedComponent } from './channels/channel-closed/channel-closed.component';
import { ListTransactionsComponent } from './transactions/list-transactions/list-transactions.component'; import { ListTransactionsComponent } from './transactions/list-transactions/list-transactions.component';
import { LookupsComponent } from './lookups/lookups.component'; import { LookupsComponent } from './lookups/lookups.component';
@ -49,13 +46,10 @@ import { QueryRoutesComponent } from './payments/query-routes/query-routes.compo
PeersComponent, PeersComponent,
SendReceiveTransComponent, SendReceiveTransComponent,
InvoicesComponent, InvoicesComponent,
ServerConfigComponent,
HelpComponent,
UnlockLNDComponent, UnlockLNDComponent,
PaymentsComponent, PaymentsComponent,
ChannelManageComponent, ChannelManageComponent,
ChannelPendingComponent, ChannelPendingComponent,
SigninComponent,
ChannelClosedComponent, ChannelClosedComponent,
ListTransactionsComponent, ListTransactionsComponent,
LookupsComponent, LookupsComponent,

@ -1,10 +1,9 @@
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core'; import { ModuleWithProviders } from '@angular/core';
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
import { SsoFailedComponent } from '../shared/components/sso-failed/sso-failed.component';
import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard'; import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard';
import { LndRootComponent } from './lnd-root.component';
import { HomeComponent } from './home/home.component'; import { HomeComponent } from './home/home.component';
import { UnlockLNDComponent } from './unlock-lnd/unlock-lnd.component'; import { UnlockLNDComponent } from './unlock-lnd/unlock-lnd.component';
import { ChannelClosedComponent } from './channels/channel-closed/channel-closed.component'; import { ChannelClosedComponent } from './channels/channel-closed/channel-closed.component';
@ -15,37 +14,30 @@ import { SendReceiveTransComponent } from './transactions/send-receive/send-rece
import { ListTransactionsComponent } from './transactions/list-transactions/list-transactions.component'; import { ListTransactionsComponent } from './transactions/list-transactions/list-transactions.component';
import { PaymentsComponent } from './payments/send-receive/payments.component'; import { PaymentsComponent } from './payments/send-receive/payments.component';
import { QueryRoutesComponent } from './payments/query-routes/query-routes.component'; import { QueryRoutesComponent } from './payments/query-routes/query-routes.component';
import { ServerConfigComponent } from './server-config/server-config.component';
import { HelpComponent } from './help/help.component';
import { InvoicesComponent } from './invoices/invoices.component'; import { InvoicesComponent } from './invoices/invoices.component';
import { LookupsComponent } from './lookups/lookups.component'; import { LookupsComponent } from './lookups/lookups.component';
import { SigninComponent } from './signin/signin.component';
import { ForwardingHistoryComponent } from './switch/forwarding-history.component'; import { ForwardingHistoryComponent } from './switch/forwarding-history.component';
import { RoutingPeersComponent } from './routing-peers/routing-peers.component'; import { RoutingPeersComponent } from './routing-peers/routing-peers.component';
import { ChannelBackupComponent } from './channels/channel-backup/channel-backup.component'; import { ChannelBackupComponent } from './channels/channel-backup/channel-backup.component';
export const lndRoutes: Routes = [ export const lndRoutes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: '', redirectTo: '.', pathMatch: 'full', canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'unlocklnd', component: UnlockLNDComponent, canActivate: [AuthGuard] }, { path: '.', component: LndRootComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './unlocklnd', component: UnlockLNDComponent, canActivate: [AuthGuard] },
{ path: 'peers', component: PeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './home', component: HomeComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'chnlclosed', component: ChannelClosedComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './peers', component: PeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'chnlmanage', component: ChannelManageComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './chnlclosed', component: ChannelClosedComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'chnlpending', component: ChannelPendingComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './chnlmanage', component: ChannelManageComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'chnlbackup', component: ChannelBackupComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './chnlpending', component: ChannelPendingComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'transsendreceive', component: SendReceiveTransComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './chnlbackup', component: ChannelBackupComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'translist', component: ListTransactionsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './transsendreceive', component: SendReceiveTransComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'paymentsend', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './translist', component: ListTransactionsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'queryroutes', component: QueryRoutesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './paymentsend', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'invoices', component: InvoicesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './queryroutes', component: QueryRoutesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'switch', component: ForwardingHistoryComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './invoices', component: InvoicesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'routingpeers', component: RoutingPeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './switch', component: ForwardingHistoryComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'lookups', component: LookupsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, { path: './routingpeers', component: RoutingPeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] },
{ path: 'sconfig', component: ServerConfigComponent, canActivate: [AuthGuard] }, { path: './lookups', component: LookupsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }
{ path: 'login', component: SigninComponent },
{ path: 'help', component: HelpComponent },
{ path: 'ssoerror', component: SsoFailedComponent },
{ path: '**', component: NotFoundComponent }
]; ];
export const lndRouting: ModuleWithProviders = RouterModule.forChild(lndRoutes); export const lndRouting: ModuleWithProviders = RouterModule.forChild(lndRoutes);

@ -4,6 +4,7 @@ import {
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes
} from '../../shared/models/lndModels'; } from '../../shared/models/lndModels';
export const RESET_LND_STORE = 'RESET_LND_STORE';
export const FETCH_INFO = 'FETCH_INFO'; export const FETCH_INFO = 'FETCH_INFO';
export const SET_INFO = 'SET_INFO'; export const SET_INFO = 'SET_INFO';
export const FETCH_PEERS = 'FETCH_PEERS'; export const FETCH_PEERS = 'FETCH_PEERS';
@ -63,6 +64,10 @@ export const SET_FORWARDING_HISTORY = 'SET_FORWARDING_HISTORY';
export const GET_QUERY_ROUTES = 'GET_QUERY_ROUTES'; export const GET_QUERY_ROUTES = 'GET_QUERY_ROUTES';
export const SET_QUERY_ROUTES = 'SET_QUERY_ROUTES'; export const SET_QUERY_ROUTES = 'SET_QUERY_ROUTES';
export class ResetLNDStore implements Action {
readonly type = RESET_LND_STORE;
}
export class FetchInfo implements Action { export class FetchInfo implements Action {
readonly type = FETCH_INFO; readonly type = FETCH_INFO;
} }
@ -348,7 +353,7 @@ export class SetQueryRoutes implements Action {
} }
export type LNDActions = export type LNDActions =
FetchInfo | SetInfo | FetchPeers | SetPeers | AddPeer | ResetLNDStore | FetchInfo | SetInfo | FetchPeers | SetPeers | AddPeer |
DetachPeer | SaveNewPeer | RemovePeer | AddInvoice | SaveNewInvoice | DetachPeer | SaveNewPeer | RemovePeer | AddInvoice | SaveNewInvoice |
GetForwardingHistory | SetForwardingHistory | FetchFees | SetFees | GetForwardingHistory | SetForwardingHistory | FetchFees | SetFees |
FetchBalance | SetBalance | FetchNetwork | SetNetwork | FetchBalance | SetBalance | FetchNetwork | SetNetwork |

@ -43,12 +43,14 @@ export class LNDEffects implements OnDestroy {
if (undefined === info.identity_pubkey) { if (undefined === info.identity_pubkey) {
sessionStorage.removeItem('lndUnlocked'); sessionStorage.removeItem('lndUnlocked');
this.logger.info('Redirecting to Unlock'); this.logger.info('Redirecting to Unlock');
this.store.dispatch(new RTLActions.SetSelNodeInfo({}));
this.router.navigate(['/unlocklnd']); this.router.navigate(['/unlocklnd']);
return { return {
type: LNDActions.SET_INFO, type: LNDActions.SET_INFO,
payload: {} payload: {}
}; };
} else { } else {
this.store.dispatch(new RTLActions.SetSelNodeInfo(info));
sessionStorage.setItem('lndUnlocked', 'true'); sessionStorage.setItem('lndUnlocked', 'true');
return { return {
type: LNDActions.SET_INFO, type: LNDActions.SET_INFO,

@ -60,6 +60,10 @@ export const LNDInitialState: LNDState = {
export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDActions) { export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDActions) {
switch (action.type) { switch (action.type) {
case LNDActions.RESET_LND_STORE:
return {
...LNDInitialState
};
case LNDActions.SET_INFO: case LNDActions.SET_INFO:
if (undefined !== action.payload.chains) { if (undefined !== action.payload.chains) {
if (typeof action.payload.chains[0] === 'string') { if (typeof action.payload.chains[0] === 'string') {

@ -9,9 +9,9 @@
</mat-toolbar> </mat-toolbar>
<div fxLayout="row" fxLayoutAlign="start center" class="lnd-info pl-2" *ngIf="settings.menuType !== 'Mini'"> <div fxLayout="row" fxLayoutAlign="start center" class="lnd-info pl-2" *ngIf="settings.menuType !== 'Mini'">
<div fxLayout="column"> <div fxLayout="column">
<p class="name">Alias: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{information?.alias}}</p> <p class="name">Alias: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{selNodeInfo?.alias}}</p>
<p>Chain: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{informationChain.chain | titlecase}}<span> [{{informationChain.network | titlecase}}]</span></p> <p>Chain: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{selNodeInfoChain.chain | titlecase}}<span> [{{selNodeInfoChain.network | titlecase}}]</span></p>
<p class="name">LND Version: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{information?.version}}</p> <p class="name">LND Version: <mat-spinner [diameter]="20" *ngIf="flgLoading" class="inline-spinner"></mat-spinner>{{selNodeInfo?.version}}</p>
</div> </div>
</div> </div>

@ -9,9 +9,8 @@ import { environment } from '../../../../../environments/environment';
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree';
import { Node, Settings } from '../../../models/RTLconfig'; import { Node, Settings, SelNodeInfo, SelNodeInfoChain } from '../../../models/RTLconfig';
import { LoggerService } from '../../../services/logger.service'; import { LoggerService } from '../../../services/logger.service';
import { GetInfo, GetInfoChain } from '../../../models/lndModels';
import { MenuNode, FlatMenuNode, MENU_DATA } from '../../../models/navMenu'; import { MenuNode, FlatMenuNode, MENU_DATA } from '../../../models/navMenu';
import * as fromLNDReducer from '../../../../lnd/store/lnd.reducers'; import * as fromLNDReducer from '../../../../lnd/store/lnd.reducers';
@ -29,8 +28,8 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
public selNode: Node; public selNode: Node;
public settings: Settings; public settings: Settings;
public version = ''; public version = '';
public information: GetInfo = {}; public selNodeInfo: SelNodeInfo = {};
public informationChain: GetInfoChain = {}; public selNodeInfoChain: SelNodeInfoChain = {};
public flgLoading = true; public flgLoading = true;
public logoutNode = [{id: 100, parentId: 0, name: 'Logout', icon: 'eject'}]; public logoutNode = [{id: 100, parentId: 0, name: 'Logout', icon: 'eject'}];
public showLogout = false; public showLogout = false;
@ -65,32 +64,32 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
this.lndStore.select('lnd') this.lndStore.select('lnd')
.pipe(takeUntil(this.unSubs[3])) .pipe(takeUntil(this.unSubs[3]))
.subscribe(lndStore => { .subscribe(lndStore => {
this.information = lndStore ? lndStore.information : {};
this.numPendingChannels = lndStore ? lndStore.numberOfPendingChannels : -1; this.numPendingChannels = lndStore ? lndStore.numberOfPendingChannels : -1;
if (undefined !== this.information.identity_pubkey) {
if (undefined !== this.information.chains && typeof this.information.chains[0] === 'string') {
this.informationChain.chain = this.information.chains[0].toString();
this.informationChain.network = (this.information.testnet) ? 'Testnet' : 'Mainnet';
} else if (typeof this.information.chains[0] === 'object' && this.information.chains[0].hasOwnProperty('chain')) {
const getInfoChain = <GetInfoChain>this.information.chains[0];
this.informationChain.chain = getInfoChain.chain;
this.informationChain.network = getInfoChain.network;
}
} else {
this.informationChain.chain = '';
this.informationChain.network = '';
}
this.flgLoading = (undefined !== this.information.identity_pubkey) ? false : true;
this.logger.info(lndStore); this.logger.info(lndStore);
}); });
this.store.select('rtlRoot') this.store.select('rtlRoot')
.pipe(takeUntil(this.unSubs[0])) .pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore: fromRTLReducer.State) => { .subscribe((rtlStore: fromRTLReducer.State) => {
this.selNodeInfo = rtlStore.selNodeInfo;
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings; this.settings = this.selNode.settings;
this.showLogout = (sessionStorage.getItem('token')) ? true : false; this.showLogout = (sessionStorage.getItem('token')) ? true : false;
if (undefined !== this.selNodeInfo.identity_pubkey) {
if (undefined !== this.selNodeInfo.chains && typeof this.selNodeInfo.chains[0] === 'string') {
this.selNodeInfoChain.chain = this.selNodeInfo.chains[0].toString();
this.selNodeInfoChain.network = (this.selNodeInfo.testnet) ? 'Testnet' : 'Mainnet';
} else if (typeof this.selNodeInfo.chains[0] === 'object' && this.selNodeInfo.chains[0].hasOwnProperty('chain')) {
const getInfoChain = <SelNodeInfoChain>this.selNodeInfo.chains[0];
this.selNodeInfoChain.chain = getInfoChain.chain;
this.selNodeInfoChain.network = getInfoChain.network;
}
} else {
this.selNodeInfoChain.chain = '';
this.selNodeInfoChain.network = '';
}
this.flgLoading = (undefined !== this.selNodeInfo.identity_pubkey) ? false : true;
if (!sessionStorage.getItem('token')) { if (!sessionStorage.getItem('token')) {
this.flgLoading = false; this.flgLoading = false;
} }

@ -9,7 +9,6 @@
<mat-card-content fxLayout="row" fxLayoutAlign="center center"> <mat-card-content fxLayout="row" fxLayoutAlign="center center">
<mat-card fxLayout="column" fxLayoutAlign="center center" class="mat-elevation-z12 w-100"> <mat-card fxLayout="column" fxLayoutAlign="center center" class="mat-elevation-z12 w-100">
<div class="box-text">This page does not exist!</div> <div class="box-text">This page does not exist!</div>
<button mat-raised-button color="primary" class="mat-elevation-z12 padding-gap-x" type="button" (click)="goHome()">HOME</button>
</mat-card> </mat-card>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>

@ -1,16 +1,7 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({ @Component({
selector: 'rtl-not-found', selector: 'rtl-not-found',
templateUrl: './not-found.component.html' templateUrl: './not-found.component.html'
}) })
export class NotFoundComponent { export class NotFoundComponent {}
constructor(public router: Router) {}
goHome(): void {
this.router.navigate(['/']);
}
}

@ -3,13 +3,13 @@ import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Node } from '../../shared/models/RTLconfig'; import { Node } from '../../models/RTLconfig';
import { LNDEffects } from '../store/lnd.effects'; import { LNDEffects } from '../../../lnd/store/lnd.effects';
import * as LNDActions from '../store/lnd.actions'; import * as LNDActions from '../../../lnd/store/lnd.actions';
import { RTLEffects } from '../../store/rtl.effects'; import { RTLEffects } from '../../../store/rtl.effects';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers'; import * as fromRTLReducer from '../../../store/rtl.reducers';
@Component({ @Component({
selector: 'rtl-server-config', selector: 'rtl-server-config',

@ -4,10 +4,10 @@ import { takeUntil } from 'rxjs/operators';
import * as sha256 from 'sha256'; import * as sha256 from 'sha256';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Node } from '../../shared/models/RTLconfig'; import { Node } from '../../models/RTLconfig';
import { LoggerService } from '../../shared/services/logger.service'; import { LoggerService } from '../../services/logger.service';
import * as fromRTLReducer from '../../store/rtl.reducers'; import * as fromRTLReducer from '../../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../../store/rtl.actions';
@Component({ @Component({
selector: 'rtl-signin', selector: 'rtl-signin',

@ -45,3 +45,16 @@ export class RTLConfiguration {
public nodes: Node[] public nodes: Node[]
) { } ) { }
} }
export interface SelNodeInfo {
identity_pubkey?: string;
alias?: string;
testnet?: boolean;
chains?: SelNodeInfoChain[] | string[];
version?: string;
}
export interface SelNodeInfoChain {
chain?: string;
network?: string;
}

@ -0,0 +1,43 @@
// export interface GetInfoAddress {
// type?: string;
// address?: string;
// port?: number;
// }
// export interface GetInfo {
// id?: string;
// alias?: string;
// color?: string;
// num_peers?: number;
// num_pending_channels?: number;
// num_active_channels?: number;
// num_inactive_channels?: number;
// address?: GetInfoAddress[];
// binding?: GetInfoAddress[];
// version?: string;
// blockheight?: number;
// network?: string;
// msatoshi_fees_collected?: number;
// fees_collected_msat?: string;
// }
export interface GetInfoChain {
chain?: string;
network?: string;
}
export interface GetInfo {
identity_pubkey?: string;
alias?: string;
num_pending_channels?: number;
num_active_channels?: number;
num_inactive_channels?: number;
num_peers?: number;
block_height?: number;
synced_to_chain?: boolean;
testnet?: boolean;
chains?: GetInfoChain[];
version?: string;
currency_unit?: string;
smaller_currency_unit?: string;
}

@ -17,6 +17,9 @@ import { HorizontalNavigationComponent } from './components/navigation/horizonta
import { AlertMessageComponent } from './components/alert-message/alert-message.component'; import { AlertMessageComponent } from './components/alert-message/alert-message.component';
import { ConfirmationMessageComponent } from './components/confirmation-message/confirmation-message.component'; import { ConfirmationMessageComponent } from './components/confirmation-message/confirmation-message.component';
import { SpinnerDialogComponent } from './components/spinner-dialog/spinner-dialog.component'; import { SpinnerDialogComponent } from './components/spinner-dialog/spinner-dialog.component';
import { ServerConfigComponent } from './components/server-config/server-config.component';
import { HelpComponent } from './components/help/help.component';
import { SigninComponent } from './components/signin/signin.component';
import { NotFoundComponent } from './components/not-found/not-found.component'; import { NotFoundComponent } from './components/not-found/not-found.component';
import { SettingsNavComponent } from './components/settings-nav/settings-nav.component'; import { SettingsNavComponent } from './components/settings-nav/settings-nav.component';
import { ClipboardDirective } from './directive/clipboard.directive'; import { ClipboardDirective } from './directive/clipboard.directive';
@ -94,6 +97,9 @@ import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe';
ConfirmationMessageComponent, ConfirmationMessageComponent,
SpinnerDialogComponent, SpinnerDialogComponent,
NotFoundComponent, NotFoundComponent,
ServerConfigComponent,
HelpComponent,
SigninComponent,
SettingsNavComponent, SettingsNavComponent,
ClipboardDirective, ClipboardDirective,
QRCodeModule, QRCodeModule,
@ -107,6 +113,9 @@ import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe';
ConfirmationMessageComponent, ConfirmationMessageComponent,
SpinnerDialogComponent, SpinnerDialogComponent,
NotFoundComponent, NotFoundComponent,
ServerConfigComponent,
HelpComponent,
SigninComponent,
SettingsNavComponent, SettingsNavComponent,
ClipboardDirective, ClipboardDirective,
SsoFailedComponent, SsoFailedComponent,

@ -1,5 +1,5 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig'; import { RTLConfiguration, Settings, Node, SelNodeInfo } from '../shared/models/RTLconfig';
import { ErrorPayload } from '../shared/models/errorPayload'; import { ErrorPayload } from '../shared/models/errorPayload';
import { MatDialogConfig } from '@angular/material'; import { MatDialogConfig } from '@angular/material';
@ -18,6 +18,7 @@ export const FETCH_RTL_CONFIG = 'FETCH_RTL_CONFIG';
export const SET_RTL_CONFIG = 'SET_RTL_CONFIG'; export const SET_RTL_CONFIG = 'SET_RTL_CONFIG';
export const SAVE_SETTINGS = 'SAVE_SETTINGS'; export const SAVE_SETTINGS = 'SAVE_SETTINGS';
export const SET_SELECTED_NODE = 'SET_SELECTED_NODE'; export const SET_SELECTED_NODE = 'SET_SELECTED_NODE';
export const SET_SELECTED_NODE_INFO = 'SET_SELECTED_NODE_INFO';
export const IS_AUTHORIZED = 'IS_AUTHORIZED'; export const IS_AUTHORIZED = 'IS_AUTHORIZED';
export const IS_AUTHORIZED_RES = 'IS_AUTHORIZED_RES'; export const IS_AUTHORIZED_RES = 'IS_AUTHORIZED_RES';
export const SIGNIN = 'SIGNIN'; export const SIGNIN = 'SIGNIN';
@ -86,6 +87,11 @@ export class SetSelelectedNode implements Action {
constructor(public payload: Node) {} constructor(public payload: Node) {}
} }
export class SetSelNodeInfo implements Action {
readonly type = SET_SELECTED_NODE_INFO;
constructor(public payload: SelNodeInfo) {}
}
export class IsAuthorized implements Action { export class IsAuthorized implements Action {
readonly type = IS_AUTHORIZED; readonly type = IS_AUTHORIZED;
constructor(public payload: string) {} // payload = password constructor(public payload: string) {} // payload = password
@ -114,5 +120,5 @@ export type RTLActions =
ClearEffectError | EffectError | OpenSpinner | CloseSpinner | ClearEffectError | EffectError | OpenSpinner | CloseSpinner |
FetchRTLConfig | SetRTLConfig | SaveSettings | FetchRTLConfig | SetRTLConfig | SaveSettings |
OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation |
ResetStore | SetSelelectedNode | ResetStore | SetSelelectedNode | SetSelNodeInfo |
IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData; IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData;

@ -15,6 +15,7 @@ import { SpinnerDialogComponent } from '../shared/components/spinner-dialog/spin
import { AlertMessageComponent } from '../shared/components/alert-message/alert-message.component'; import { AlertMessageComponent } from '../shared/components/alert-message/alert-message.component';
import { ConfirmationMessageComponent } from '../shared/components/confirmation-message/confirmation-message.component'; import { ConfirmationMessageComponent } from '../shared/components/confirmation-message/confirmation-message.component';
import * as CLActions from '../c-lightning/store/cl.actions';
import * as LNDActions from '../lnd/store/lnd.actions'; import * as LNDActions from '../lnd/store/lnd.actions';
import * as RTLActions from './rtl.actions'; import * as RTLActions from './rtl.actions';
import * as fromRTLReducer from './rtl.reducers'; import * as fromRTLReducer from './rtl.reducers';
@ -207,7 +208,17 @@ export class RTLEffects implements OnDestroy {
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
if (sessionStorage.getItem('token')) { if (sessionStorage.getItem('token')) {
this.store.dispatch(new RTLActions.ResetStore(action.payload)); this.store.dispatch(new RTLActions.ResetStore(action.payload));
return { type: LNDActions.FETCH_INFO }; if (action.payload.lnImplementation === 'CLightning') {
this.router.navigate(['./cl']);
this.store.dispatch(new CLActions.ResetCLStore());
this.store.dispatch(new LNDActions.ResetLNDStore());
return { type: CLActions.FETCH_CL_INFO };
} else {
this.router.navigate(['./lnd']);
this.store.dispatch(new CLActions.ResetCLStore());
this.store.dispatch(new LNDActions.ResetLNDStore());
return { type: LNDActions.FETCH_INFO };
}
} else { } else {
return { return {
type: RTLActions.OPEN_ALERT, type: RTLActions.OPEN_ALERT,

@ -1,16 +1,12 @@
import * as RTLActions from './rtl.actions'; import * as RTLActions from './rtl.actions';
import { ErrorPayload } from '../shared/models/errorPayload'; import { ErrorPayload } from '../shared/models/errorPayload';
import { RTLConfiguration, Node } from '../shared/models/RTLconfig'; import { RTLConfiguration, Node, SelNodeInfo } from '../shared/models/RTLconfig';
import { LNDReducer, LNDState, LNDInitialState } from '../lnd/store/lnd.reducers';
import { ActionReducerMap } from '@ngrx/store';
import * as fromLNDReducer from '../lnd/store/lnd.reducers';
export interface State { export interface State {
effectErrors: ErrorPayload[]; effectErrors: ErrorPayload[];
selNode: Node; selNode: Node;
appConfig: RTLConfiguration; appConfig: RTLConfiguration;
lnd: fromLNDReducer.LNDState; selNodeInfo: SelNodeInfo;
} }
const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false }; const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false };
@ -24,7 +20,7 @@ const initialState: State = {
sso: { rtlSSO: 0, logoutRedirectLink: '/login' }, sso: { rtlSSO: 0, logoutRedirectLink: '/login' },
nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}] nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}]
}, },
lnd: fromLNDReducer.LNDInitialState selNodeInfo: {}
}; };
export function RTLRootReducer(state = initialState, action: RTLActions.RTLActions) { export function RTLRootReducer(state = initialState, action: RTLActions.RTLActions) {
@ -63,6 +59,11 @@ export function RTLRootReducer(state = initialState, action: RTLActions.RTLActio
selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex), selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex),
appConfig: action.payload appConfig: action.payload
}; };
case RTLActions.SET_SELECTED_NODE_INFO:
return {
...state,
selNodeInfo: action.payload
};
default: default:
return state; return state;
} }

Loading…
Cancel
Save