CL Tables

CL Tables
pull/260/head
Shahana Farooqui 4 years ago
parent f22a20fe48
commit 41db338656

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -9,8 +9,8 @@
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
<link rel="manifest" href="assets/images/favicon/site.webmanifest"> <link rel="manifest" href="assets/images/favicon/site.webmanifest">
<link rel="stylesheet" href="styles.5986f047fc96bc7e6342.css"></head> <link rel="stylesheet" href="styles.50c2f6a606d60f850d7c.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.d75cd2c265dde80b73ba.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.ea762e60e8d2e18a62f0.js" defer></script></body> <script src="runtime.f855ea0cbc4f9069b03d.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.b4d9830f7088e62218ba.js" defer></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +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++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++)0!==o[t[a]]&&(n=!1);n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={0:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+""+({}[e]||e)+"."+{1:"77d491bf73b15683870f",6:"4c847e2e4a21ced9ec66",7:"631b04e7d1b0b93ef794"}[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()}([]);

@ -0,0 +1 @@
!function(e){function r(r){for(var n,a,i=r[0],f=r[1],c=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 f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,c||[]),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:"77d491bf73b15683870f",6:"5a3f5136d706d4191aba",7:"92fe25b3a99b58bf5108"}[e]+".js"}(e);var f=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(c);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;f.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",f.name="ChunkLoadError",f.type=n,f.request=u,t[1](f)}o[e]=void 0}};var c=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||[],f=i.push.bind(i);i.push=r,i=i.slice();for(var c=0;c<i.length;c++)r(i[c]);var l=f;t()}([]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -8,6 +8,12 @@ exports.listChannels = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/channel/listChannels'; options.url = common.getSelLNServerUrl() + '/channel/listChannels';
request(options).then(function (body) { request(options).then(function (body) {
logger.info({fileName: 'Channels', msg: 'List Channels: ' + JSON.stringify(body)}); logger.info({fileName: 'Channels', msg: 'List Channels: ' + JSON.stringify(body)});
body.map(channel => {
local = (channel.our_channel_reserve_satoshis) ? +channel.our_channel_reserve_satoshis : 0;
remote = (channel.their_channel_reserve_satoshis) ? +channel.their_channel_reserve_satoshis : 0;
total = local + remote;
channel.balancedness = (1 - Math.abs((local-remote)/total)).toFixed(3);
})
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(function (err) { .catch(function (err) {

@ -29,7 +29,9 @@ exports.listNode = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/network/listNode/' + req.params.id; options.url = common.getSelLNServerUrl() + '/network/listNode/' + req.params.id;
request(options).then(function (body) { request(options).then(function (body) {
logger.info({fileName: 'Network', msg: 'Node Lookup: ' + JSON.stringify(body)}); logger.info({fileName: 'Network', msg: 'Node Lookup: ' + JSON.stringify(body)});
body.last_timestamp_str = (body.last_timestamp) ? common.convertTimestampToDate(body.last_timestamp) : ''; body.forEach(node => {
node.last_timestamp_str = (node.last_timestamp) ? common.convertTimestampToDate(node.last_timestamp) : '';
});
res.status(200).json(body); res.status(200).json(body);
}) })
.catch((err) => { .catch((err) => {

@ -15,16 +15,16 @@
<div fxLayout="column" fxFlex.gt-sm="88" fxFlex="84" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar> <div fxLayout="column" fxFlex.gt-sm="88" fxFlex="84" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock"> <div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2"> <div *ngFor="let channel of allChannels" class="mt-2">
<span class="dashboard-capacity-header" matTooltip="{{channel.remote_alias || channel.remote_pubkey}}" matTooltipDisabled="{{(channel.remote_alias || channel.remote_pubkey).length < 26}}">{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</span> <span class="dashboard-capacity-header" matTooltip="{{channel.alias || channel.id}}" matTooltipDisabled="{{(channel.alias || channel.id).length < 26}}">{{(channel.alias || channel.id) | slice:0:24}}{{(channel.alias || channel.id).length > 25 ? '...' : ''}}</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100"> <div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Local:</strong>{{channel.local_balance || 0 | number}} Sats</mat-hint> <mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Local:</strong>{{channel.our_channel_reserve_satoshis || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="20" fxLayoutAlign="center center" class="font-size-90 color-primary"> <mat-hint fxFlex="20" fxLayoutAlign="center center" class="font-size-90 color-primary">
<fa-icon [icon]="faBalanceScale" class="color-primary mr-3px" matTooltip="Balance Score"></fa-icon> <fa-icon [icon]="faBalanceScale" class="color-primary mr-3px" matTooltip="Balance Score"></fa-icon>
({{channel.balancedness || 0 | number}}) ({{channel.balancedness || 0 | number}})
</mat-hint> </mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channel.remote_balance || 0 | number}} Sats</mat-hint> <mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channel.their_channel_reserve_satoshis || 0 | number}} Sats</mat-hint>
</div> </div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.local_balance && channel.local_balance > 0 ? ((+channel.local_balance/((+channel.local_balance)+(+channel.remote_balance)))*100) : 0}}"></mat-progress-bar> <mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.our_channel_reserve_satoshis && channel.our_channel_reserve_satoshis > 0 ? ((+channel.our_channel_reserve_satoshis/((+channel.our_channel_reserve_satoshis)+(+channel.their_channel_reserve_satoshis)))*100) : 0}}"></mat-progress-bar>
</div> </div>
</div> </div>
</div> </div>

@ -8,13 +8,13 @@
<div fxLayout="column" fxFlex.gt-sm="88" fxFlex="84" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar> <div fxLayout="column" fxFlex.gt-sm="88" fxFlex="84" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock"> <div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2"> <div *ngFor="let channel of allChannels" class="mt-2">
<span class="dashboard-capacity-header" matTooltip="{{channel.remote_alias || channel.remote_pubkey}}" matTooltipDisabled="{{(channel.remote_alias || channel.remote_pubkey).length < 26}}">{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</span> <span class="dashboard-capacity-header" matTooltip="{{channel.alias || channel.id}}" matTooltipDisabled="{{(channel.alias || channel.id).length < 26}}">{{(channel.alias || channel.id) | slice:0:24}}{{(channel.alias || channel.id).length > 25 ? '...' : ''}}</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100"> <div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.remote_balance || 0 | number}} Sats</mat-hint> <mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.their_channel_reserve_satoshis || 0 | number}} Sats</mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.local_balance || 0 | number}} Sats</mat-hint> <mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.our_channel_reserve_satoshis || 0 | number}} Sats</mat-hint>
</div> </div>
<mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.remote_balance || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar> <mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.their_channel_reserve_satoshis || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.local_balance || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar> <mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.our_channel_reserve_satoshis || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
</div> </div>
</div> </div>
</div> </div>

@ -22,10 +22,10 @@
<mat-card-content class="dashboard-card-content w-100" fxFlex="95"> <mat-card-content class="dashboard-card-content w-100" fxFlex="95">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100"> <div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [showColorFieldSeparately]="false" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info> <rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [showColorFieldSeparately]="false" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-cl-balances-info> <rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error'}"></rtl-cl-balances-info>
<rtl-cl-channel-capacity-info fxFlex="100" *ngSwitchCase="'capacity'" [sortBy]="sortField" [channelBalances]="channelBalances" [allChannels]="allChannelsCapacity" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-capacity-info> <rtl-cl-channel-capacity-info fxFlex="100" *ngSwitchCase="'capacity'" [sortBy]="sortField" [channelBalances]="channelBalances" [allChannels]="allChannelsCapacity" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-capacity-info>
<rtl-cl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [fees]="fees" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-cl-fee-info> <rtl-cl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [fees]="fees" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-cl-fee-info>
<rtl-cl-channel-status-info fxFlex="100" *ngSwitchCase="'status'" [channelsStatus]="channelsStatus" [ngClass]="{'error-border': flgLoading[5]==='error' || flgLoading[6]==='error'}"></rtl-cl-channel-status-info> <rtl-cl-channel-status-info fxFlex="100" *ngSwitchCase="'status'" [channelsStatus]="channelsStatus" [ngClass]="{'error-border': flgLoading[2]==='error'}"></rtl-cl-channel-status-info>
<h3 *ngSwitchDefault>Error! Unable to find information!</h3> <h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div> </div>
</mat-card-content> </mat-card-content>
@ -56,7 +56,7 @@
<mat-card-content class="dashboard-card-content w-100" fxFlex="{{card.id !== 'transactions' ? 95 : 100}}"> <mat-card-content class="dashboard-card-content w-100" fxFlex="{{card.id !== 'transactions' ? 95 : 100}}">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100"> <div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info> <rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-cl-balances-info> <rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error'}"></rtl-cl-balances-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allInboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info> <rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allInboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allOutboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info> <rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allOutboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info>
<span fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start" *ngSwitchCase="'transactions'"> <span fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start" *ngSwitchCase="'transactions'">

@ -62,46 +62,46 @@ export class CLHomeComponent implements OnInit, OnDestroy {
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.operatorCards = [ this.operatorCards = [
{ id: 'node', icon: this.faServer, title: 'Node Information', cols: 10, rows: 1 }, { id: 'node', icon: this.faServer, title: 'Node Information', cols: 10, rows: 1 },
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 10, rows: 1 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 10, rows: 1 },
{ id: 'fee', goTo: 'Routing', link: '/lnd/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 10, rows: 1 }, { id: 'fee', goTo: 'Routing', link: '/cl/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 10, rows: 1 },
{ id: 'status', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 10, rows: 1 }, { id: 'status', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 10, rows: 1 },
{ id: 'capacity', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 } { id: 'capacity', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }
]; ];
this.merchantCards = [ this.merchantCards = [
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 6, rows: 4 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 6, rows: 4 },
{ id: 'transactions', goTo: 'Transactions', link: '/lnd/transactions', title: '', cols: 6, rows: 4 }, { id: 'transactions', goTo: 'Transactions', link: '/cl/transactions', title: '', cols: 6, rows: 4 },
{ id: 'inboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 6, rows: 8 }, { id: 'inboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 6, rows: 8 },
{ id: 'outboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 6, rows: 8 } { id: 'outboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 6, rows: 8 }
]; ];
} else if(this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) {
this.operatorCards = [ this.operatorCards = [
{ id: 'node', icon: this.faServer, title: 'Node Information', cols: 5, rows: 1 }, { id: 'node', icon: this.faServer, title: 'Node Information', cols: 5, rows: 1 },
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 5, rows: 1 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 5, rows: 1 },
{ id: 'fee', goTo: 'Routing', link: '/lnd/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 5, rows: 1 }, { id: 'fee', goTo: 'Routing', link: '/cl/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 5, rows: 1 },
{ id: 'status', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 5, rows: 1 }, { id: 'status', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 5, rows: 1 },
{ id: 'capacity', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 } { id: 'capacity', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }
]; ];
this.merchantCards = [ this.merchantCards = [
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 4 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 4 },
{ id: 'transactions', goTo: 'Transactions', link: '/lnd/transactions', title: '', cols: 3, rows: 4 }, { id: 'transactions', goTo: 'Transactions', link: '/cl/transactions', title: '', cols: 3, rows: 4 },
{ id: 'inboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 3, rows: 8 }, { id: 'inboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 3, rows: 8 },
{ id: 'outboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 3, rows: 8 } { id: 'outboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 3, rows: 8 }
]; ];
} else { } else {
this.operatorCardHeight = ((window.screen.height - 200) / 2) + 'px'; this.operatorCardHeight = ((window.screen.height - 200) / 2) + 'px';
this.merchantCardHeight = ((window.screen.height - 210) / 10) + 'px'; this.merchantCardHeight = ((window.screen.height - 210) / 10) + 'px';
this.operatorCards = [ this.operatorCards = [
{ id: 'node', icon: this.faServer, title: 'Node Information', cols: 3, rows: 1 }, { id: 'node', icon: this.faServer, title: 'Node Information', cols: 3, rows: 1 },
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 1 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 1 },
{ id: 'capacity', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 4, rows: 2 }, { id: 'capacity', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 4, rows: 2 },
{ id: 'fee', goTo: 'Routing', link: '/lnd/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 3, rows: 1 }, { id: 'fee', goTo: 'Routing', link: '/cl/routing', icon: this.faBolt, title: 'Routing Fee Report', cols: 3, rows: 1 },
{ id: 'status', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 3, rows: 1 } { id: 'status', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faNetworkWired, title: 'Channels', cols: 3, rows: 1 }
]; ];
this.merchantCards = [ this.merchantCards = [
{ id: 'balance', goTo: 'On-Chain', link: '/lnd/onchain', icon: this.faChartPie, title: 'Balances', cols: 2, rows: 5 }, { id: 'balance', goTo: 'On-Chain', link: '/cl/onchain', icon: this.faChartPie, title: 'Balances', cols: 2, rows: 5 },
{ id: 'inboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 2, rows: 10 }, { id: 'inboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleDown, title: 'In-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'outboundLiq', goTo: 'Channels', link: '/lnd/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 2, rows: 10 }, { id: 'outboundLiq', goTo: 'Channels', link: '/cl/peerschannels', icon: this.faAngleDoubleUp, title: 'Out-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'transactions', goTo: 'Transactions', link: '/lnd/transactions', title: '', cols: 2, rows: 5 } { id: 'transactions', goTo: 'Transactions', link: '/cl/transactions', title: '', cols: 2, rows: 5 }
]; ];
} }
} }
@ -127,6 +127,9 @@ export class CLHomeComponent implements OnInit, OnDestroy {
if (effectsErr.action === 'FetchFeeRatesCL') { if (effectsErr.action === 'FetchFeeRatesCL') {
this.flgLoading[4] = 'error'; this.flgLoading[4] = 'error';
} }
if (effectsErr.action === 'FetchChannelsCL') {
this.flgLoading[5] = 'error';
}
}); });
this.selNode = rtlStore.nodeSettings; this.selNode = rtlStore.nodeSettings;
this.information = rtlStore.information; this.information = rtlStore.information;
@ -140,6 +143,10 @@ export class CLHomeComponent implements OnInit, OnDestroy {
} }
this.totalBalance = rtlStore.balance; this.totalBalance = rtlStore.balance;
this.balances.onchain = rtlStore.balance.confBalance;
this.balances.lightning = rtlStore.localRemoteBalance.localBalance;
this.balances.total = this.balances.lightning + this.balances.onchain;
this.balances = Object.assign({}, this.balances);
if (this.flgLoading[2] !== 'error') { if (this.flgLoading[2] !== 'error') {
this.flgLoading[2] = ('' !== this.totalBalance) ? false : true; this.flgLoading[2] = ('' !== this.totalBalance) ? false : true;
} }
@ -148,6 +155,9 @@ export class CLHomeComponent implements OnInit, OnDestroy {
let remote = (rtlStore.localRemoteBalance.remoteBalance) ? +rtlStore.localRemoteBalance.remoteBalance : 0; let remote = (rtlStore.localRemoteBalance.remoteBalance) ? +rtlStore.localRemoteBalance.remoteBalance : 0;
let total = local + remote; let total = local + remote;
this.channelBalances = { localBalance: local, remoteBalance: remote, balancedness: (1 - Math.abs((local-remote)/total)).toFixed(3) }; this.channelBalances = { localBalance: local, remoteBalance: remote, balancedness: (1 - Math.abs((local-remote)/total)).toFixed(3) };
if (this.flgLoading[3] !== 'error') {
this.flgLoading[3] = (rtlStore.localRemoteBalance.localBalance) ? false : true;
}
this.feeRatesPerKB = rtlStore.feeRatesPerKB; this.feeRatesPerKB = rtlStore.feeRatesPerKB;
this.feeRatesPerKW = rtlStore.feeRatesPerKW; this.feeRatesPerKW = rtlStore.feeRatesPerKW;
@ -155,18 +165,6 @@ export class CLHomeComponent implements OnInit, OnDestroy {
this.flgLoading[4] = (undefined !== this.feeRatesPerKB && undefined !== this.feeRatesPerKW) ? false : true; this.flgLoading[4] = (undefined !== this.feeRatesPerKB && undefined !== this.feeRatesPerKW) ? false : true;
} }
// this.balances.onchain = (+rtlStore.blockchainBalance.total_balance >= 0) ? +rtlStore.blockchainBalance.total_balance : 0;
// if (this.flgLoading[2] !== 'error') {
// this.flgLoading[2] = false;
// }
// this.balances.lightning = rtlStore.totalLocalBalance;
// if (this.flgLoading[5] !== 'error') {
// this.flgLoading[5] = false;
// }
// this.balances.total = this.balances.lightning + this.balances.onchain;
// this.balances = Object.assign({}, this.balances);
this.activeChannels = rtlStore.information.num_active_channels; this.activeChannels = rtlStore.information.num_active_channels;
this.inactiveChannels = rtlStore.information.num_inactive_channels; this.inactiveChannels = rtlStore.information.num_inactive_channels;
this.channelsStatus = { this.channelsStatus = {
@ -176,14 +174,17 @@ export class CLHomeComponent implements OnInit, OnDestroy {
}; };
this.totalInboundLiquidity = 0; this.totalInboundLiquidity = 0;
this.totalOutboundLiquidity = 0; this.totalOutboundLiquidity = 0;
this.allChannels = rtlStore.allChannels.filter(channel => channel.connected === true); this.allChannels = rtlStore.allChannels.filter(channel => channel.connected);
this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels, 'balancedness'))); this.allChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels, 'balancedness')));
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter(channel => +channel.their_channel_reserve_satoshis > 0), 'remote_balance'))); this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter(channel => +channel.their_channel_reserve_satoshis > 0), 'their_channel_reserve_satoshis')));
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter(channel => +channel.our_channel_reserve_satoshis > 0), 'local_balance'))); this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.allChannels.filter(channel => +channel.our_channel_reserve_satoshis > 0), 'our_channel_reserve_satoshis')));
this.allChannels.forEach(channel => { this.allChannels.forEach(channel => {
this.totalInboundLiquidity = this.totalInboundLiquidity + +channel.their_channel_reserve_satoshis; this.totalInboundLiquidity = this.totalInboundLiquidity + +channel.their_channel_reserve_satoshis;
this.totalOutboundLiquidity = this.totalOutboundLiquidity + +channel.our_channel_reserve_satoshis; this.totalOutboundLiquidity = this.totalOutboundLiquidity + +channel.our_channel_reserve_satoshis;
}); });
if (this.flgLoading[5] !== 'error') {
this.flgLoading[5] = (this.allChannels && this.allChannels.length) ? false : true;
}
if (this.balances.lightning >= 0 && this.balances.onchain >= 0 && this.fees.feeCollected >= 0) { if (this.balances.lightning >= 0 && this.balances.onchain >= 0 && this.fees.feeCollected >= 0) {
this.flgChildInfoUpdated = true; this.flgChildInfoUpdated = true;
} else { } else {

@ -15,9 +15,11 @@ export class CLNodeInfoComponent implements OnChanges {
constructor(private commonService: CommonService) { } constructor(private commonService: CommonService) { }
ngOnChanges() { ngOnChanges() {
if(this.information && this.information.network) { if(this.information && this.information.chains && this.information.chains.length > 0) {
this.chains = ['']; this.chains = [''];
this.chains.push(this.commonService.titleCase(this.information.network)); this.information.chains.forEach(chain => {
this.chains.push(this.commonService.titleCase(chain.chain) + ' ' + this.commonService.titleCase(chain.network));
});
} }
} }

@ -14,7 +14,7 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
<h4 class="font-bold-500">Active</h4> <h4 class="font-bold-500">Active</h4>
<span class="foreground-secondary-text">{{lookupResult[0].active}}</span> <span class="foreground-secondary-text">{{lookupResult[0].active ? 'True' : 'False'}}</span>
</div> </div>
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
@ -69,7 +69,7 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
<h4 class="font-bold-500">Public</h4> <h4 class="font-bold-500">Public</h4>
<span class="foreground-secondary-text">{{lookupResult[0].public}}</span> <span class="foreground-secondary-text">{{lookupResult[0].public ? 'Yes' : 'No'}}</span>
</div> </div>
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
@ -95,7 +95,7 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
<h4 class="font-bold-500">Active</h4> <h4 class="font-bold-500">Active</h4>
<span class="foreground-secondary-text">{{lookupResult[1].active}}</span> <span class="foreground-secondary-text">{{lookupResult[1].active ? 'True' : 'False'}}</span>
</div> </div>
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
@ -150,7 +150,7 @@
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">
<h4 class="font-bold-500">Public</h4> <h4 class="font-bold-500">Public</h4>
<span class="foreground-secondary-text">{{lookupResult[1].public}}</span> <span class="foreground-secondary-text">{{lookupResult[1].public ? 'Yes' : 'No'}}</span>
</div> </div>
<mat-divider [inset]="true"></mat-divider> <mat-divider [inset]="true"></mat-divider>
<div fxLayout="column" fxFlex="10" class="my-1"> <div fxLayout="column" fxFlex="10" class="my-1">

@ -27,7 +27,7 @@ export class CLLookupsComponent implements OnInit, OnDestroy {
public selectedFieldId = 0; public selectedFieldId = 0;
public lookupFields = [ public lookupFields = [
{ id: 0, name: 'Node', placeholder: 'Pubkey'}, { id: 0, name: 'Node', placeholder: 'Pubkey'},
{ id: 1, name: 'Channel', placeholder: 'Channel ID'} { id: 1, name: 'Channel', placeholder: 'Short Channel ID'}
]; ];
public flgLoading: Array<Boolean | 'error'> = [true]; public flgLoading: Array<Boolean | 'error'> = [true];
public faSearch = faSearch; public faSearch = faSearch;
@ -47,7 +47,16 @@ export class CLLookupsComponent implements OnInit, OnDestroy {
).subscribe((resLookup: RTLActions.SetLookupCL | RTLActions.EffectErrorCl) => { ).subscribe((resLookup: RTLActions.SetLookupCL | RTLActions.EffectErrorCl) => {
if(resLookup.type === RTLActions.SET_LOOKUP_CL) { if(resLookup.type === RTLActions.SET_LOOKUP_CL) {
this.flgLoading[0] = true; this.flgLoading[0] = true;
this.lookupValue = JSON.parse(JSON.stringify(resLookup.payload)); switch (this.selectedFieldId) {
case 0:
this.lookupValue = JSON.parse(JSON.stringify(resLookup.payload[0]));
break;
case 1:
this.lookupValue = JSON.parse(JSON.stringify(resLookup.payload));
break;
default:
break;
}
this.flgSetLookupValue = true; this.flgSetLookupValue = true;
this.logger.info(this.lookupValue); this.logger.info(this.lookupValue);
} }

@ -8,7 +8,7 @@
<div fxLayout="row"> <div fxLayout="row">
<div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1"> <div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1">
<h4 fxLayoutAlign="start" class="font-bold-500">Alias</h4> <h4 fxLayoutAlign="start" class="font-bold-500">Alias</h4>
<span class="foreground-secondary-text">{{lookupResult.alias}}<span class="ml-2" [ngStyle]="{'background-color': lookupResult.color}">{{lookupResult.color}}</span></span> <span class="foreground-secondary-text">{{lookupResult.alias}}<span class="ml-2" [ngStyle]="{'background-color': '#' + lookupResult.color}">#{{lookupResult.color}}</span></span>
<mat-divider class="my-1"></mat-divider> <mat-divider class="my-1"></mat-divider>
</div> </div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1"> <div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1">
@ -24,15 +24,15 @@
<mat-divider class="my-1"></mat-divider> <mat-divider class="my-1"></mat-divider>
</div> </div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1"> <div fxLayout="column" fxFlex="50" fxLayoutAlign="end start" class="my-1">
<h4 fxLayoutAlign="start" class="font-bold-500">Global_Features</h4> <h4 fxLayoutAlign="start" class="font-bold-500">Features</h4>
<span class="foreground-secondary-text">{{lookupResult.global_features}}</span> <span class="foreground-secondary-text">{{lookupResult.features}}</span>
<mat-divider class="my-1"></mat-divider> <mat-divider class="my-1"></mat-divider>
</div> </div>
</div> </div>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start" class="my-1"> <div fxLayout="column" fxFlex="100" fxLayoutAlign="start" class="my-1">
<h4 fxFlex="100" fxLayoutAlign="start" class="font-bold-500">Addresses</h4> <h4 fxFlex="100" fxLayoutAlign="start" class="font-bold-500">Addresses</h4>
<div perfectScrollbar class="table-container mt-2" fxFlex="100"> <div perfectScrollbar class="table-container mt-2" fxFlex="100">
<table mat-table [dataSource]="lookupResult.addresses" matSort class="overflow-auto"> <table mat-table [dataSource]="addresses" matSort class="overflow-auto">
<ng-container matColumnDef="type"> <ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header>Type</mat-header-cell> <mat-header-cell *matHeaderCellDef mat-sort-header>Type</mat-header-cell>
<mat-cell *matCellDef="let address"> <mat-cell *matCellDef="let address">

@ -1,4 +1,5 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, OnInit, Input, ViewChild } from '@angular/core';
import { MatTableDataSource, MatSort } from '@angular/material';
import { LookupNodeCL } from '../../../shared/models/clModels'; import { LookupNodeCL } from '../../../shared/models/clModels';
@ -8,11 +9,16 @@ import { LookupNodeCL } from '../../../shared/models/clModels';
styleUrls: ['./node-lookup.component.scss'] styleUrls: ['./node-lookup.component.scss']
}) })
export class CLNodeLookupComponent implements OnInit { export class CLNodeLookupComponent implements OnInit {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@Input() lookupResult: LookupNodeCL; @Input() lookupResult: LookupNodeCL;
public addresses: any;
public displayedColumns = ['type', 'address', 'port']; public displayedColumns = ['type', 'address', 'port'];
constructor() { } constructor() { }
ngOnInit() {} ngOnInit() {
this.addresses = new MatTableDataSource<any>([...this.lookupResult.addresses]);
this.addresses.sort = this.sort;
}
} }

@ -13,20 +13,22 @@
<mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option> <mat-option *ngFor="let amountUnit of amountUnits" [value]="amountUnit">{{amountUnit}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="10" fxLayoutAlign="start end"> <div fxFlex="60" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate"> <mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId"> <mat-select tabindex="6" placeholder="Fee Rate" [(value)]="transaction.feeRate">
{{feeRateType.feeRateType}} <mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
</mat-option> {{feeRateType.feeRateType}}
</mat-select> </mat-option>
</mat-form-field> </mat-select>
<mat-checkbox fxFlex="20" fxFlex.lt-lg="35" tabindex="7" [(ngModel)]="flgMinConf" name="flgMinConf">
<mat-form-field fxFlex="100">
<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-form-field> </mat-form-field>
</mat-checkbox> <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="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"> <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" (click)="resetData()">Clear Fields</button> <button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Fields</button>

@ -112,11 +112,13 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
onAmountUnitChange(event: any) { onAmountUnitChange(event: any) {
let self = this; let self = this;
let prevSelectedUnit = (this.selAmountUnit === this.amountUnits[2]) ? CurrencyUnitEnum.OTHER : this.selAmountUnit;
let currSelectedUnit = event.value === this.amountUnits[2] ? CurrencyUnitEnum.OTHER : event.value;
if(this.transaction.satoshis && this.selAmountUnit !== event.value) { if(this.transaction.satoshis && this.selAmountUnit !== event.value) {
this.commonService.convertCurrency(this.transaction.satoshis, CURRENCY_UNIT_FORMATS.Sats, this.amountUnits[2]) this.commonService.convertCurrency(this.transaction.satoshis, prevSelectedUnit, this.amountUnits[2])
.pipe(takeUntil(this.unSubs[4])) .pipe(takeUntil(this.unSubs[4]))
.subscribe(data => { .subscribe(data => {
self.transaction.satoshis = +self.decimalPipe.transform(data[CURRENCY_UNIT_FORMATS.Sats], self.currencyUnitFormats[CURRENCY_UNIT_FORMATS.Sats]).replace(/,/g, ''); self.transaction.satoshis = +self.decimalPipe.transform(data[currSelectedUnit], self.currencyUnitFormats[currSelectedUnit]).replace(/,/g, '');
}); });
} }
this.selAmountUnit = event.value; this.selAmountUnit = event.value;

@ -5,7 +5,7 @@
<mat-option (click)="addNewPeer()" [value]="'new'"> <mat-option (click)="addNewPeer()" [value]="'new'">
ADD PEER ADD PEER
</mat-option> </mat-option>
<mat-option *ngFor="let peer of peers" [value]="peer.pub_key"> <mat-option *ngFor="let peer of peers" [value]="peer.id">
{{peer.alias}} {{peer.alias}}
</mat-option> </mat-option>
</mat-select> </mat-select>
@ -27,22 +27,23 @@
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template> <ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
</button> </button>
</div> </div>
<div *ngIf="showAdvanced" fxFlex="100" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap"> <div *ngIf="showAdvanced" fxFlex="60" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<mat-form-field fxFlex="34" fxLayoutAlign="start end"> <mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate"> <mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate">
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId"> <mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
{{feeRateType.feeRateType}} {{feeRateType.feeRateType}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-checkbox fxFlex="34" tabindex="5" [(ngModel)]="flgMinConf" name="flgMinConf"> <div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
<mat-form-field fxFlex="100"> <mat-checkbox fxFlex="2" tabindex="5" color="primary" [(ngModel)]="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
<input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" <mat-form-field fxFlex="98">
name="blocks" step="1" min="0" tabindex="6" #blocks="ngModel" [required]="flgMinConf" <input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
[disabled]="!flgMinConf"> <mat-error *ngIf="flgMinConf && !minConfValue">Min Confirmation Blocks is required.</mat-error>
</mat-form-field> </mat-form-field>
</mat-checkbox> </div>
</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"> <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-stroked-button color="primary" tabindex="10" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onOpenChannel()" type="submit" tabindex="11">Open Channel</button> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onOpenChannel()" type="submit" tabindex="11">Open Channel</button>

@ -60,8 +60,8 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
this.logger.info(rtlStore); this.logger.info(rtlStore);
}); });
this.actions$.pipe(takeUntil(this.unSubs[1]), this.actions$.pipe(takeUntil(this.unSubs[1]),
filter((action) => action.type === RTLActions.SET_PEERS)) filter((action) => action.type === RTLActions.SET_PEERS_CL))
.subscribe((action: RTLActions.SetPeers) => { .subscribe((action: RTLActions.SetPeersCL) => {
if(this.newlyAddedPeer !== '') { if(this.newlyAddedPeer !== '') {
this.snackBar.open('Peer added successfully.'); this.snackBar.open('Peer added successfully.');
this.selectedPeer = this.newlyAddedPeer; this.selectedPeer = this.newlyAddedPeer;

@ -8,31 +8,40 @@
<div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100"> <div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="channels" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table [dataSource]="channels" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="remote_alias"> <ng-container matColumnDef="short_channel_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Peer </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Short Channel ID </th>
<td mat-cell *matCellDef="let channel"> <td mat-cell *matCellDef="let channel"> {{channel?.short_channel_id}}</td>
<div class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '22rem'}"> </ng-container>
<span *ngIf="channel.active" class="dot green" matTooltip="Active" matTooltipPosition="right"></span> <ng-container matColumnDef="alias">
<span *ngIf="!channel.active" class="dot yellow" matTooltip="Inactive" matTooltipPosition="right"></span> <th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
<span class="ellipsis-child">{{channel.remote_alias || channel.remote_pubkey}}</span> <td mat-cell *matCellDef="let channel">{{channel?.alias}}</td>
</div> </ng-container>
</td> <ng-container matColumnDef="connected">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Connected </th>
<td mat-cell *matCellDef="let channel"> {{(channel?.connected) ? 'Connected' : 'Disconnected'}} </td>
</ng-container>
<ng-container matColumnDef="private">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Private </th>
<td mat-cell *matCellDef="let channel"> {{(channel?.private ? 'Private' : 'Public')}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="local_balance"> <ng-container matColumnDef="state">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Local Balance </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> State </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.local_balance | number}} </span></td> <td mat-cell *matCellDef="let channel"> {{channel?.state}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="remote_balance"> <ng-container matColumnDef="msatoshi_to_us">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Remote Balance </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> mSatoshi To Us </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.remote_balance | number}} </span></td> <td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">
{{channel?.msatoshi_to_us | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="total_satoshis_sent"> <ng-container matColumnDef="msatoshi_total">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Sats Sent </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Total mSatoshis </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.total_satoshis_sent | number}} </span></td> <td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">
{{channel?.msatoshi_total | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="total_satoshis_received"> <ng-container matColumnDef="spendable_msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Sats Received </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Spendable Satoshi </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.total_satoshis_received | number}} </span></td> <td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">
{{channel?.spendable_msatoshi | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="balancedness"> <ng-container matColumnDef="balancedness">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="pl-3">Balance Score </th> <th mat-header-cell *matHeaderCellDef mat-sort-header class="pl-3">Balance Score </th>
@ -57,7 +66,7 @@
<mat-select placeholder="Actions" tabindex="2" class="mr-0"> <mat-select placeholder="Actions" tabindex="2" class="mr-0">
<mat-select-trigger></mat-select-trigger> <mat-select-trigger></mat-select-trigger>
<mat-option (click)="onChannelClick(channel, $event)">View Info</mat-option> <mat-option (click)="onChannelClick(channel, $event)">View Info</mat-option>
<mat-option (click)="onViewRemotePolicy(channel)">View Remote Fee </mat-option> <mat-option (click)="onViewRemotePolicy(channel)">View Remote Fee</mat-option>
<mat-option (click)="onChannelUpdate(channel)">Update Fee Policy</mat-option> <mat-option (click)="onChannelUpdate(channel)">Update Fee Policy</mat-option>
<mat-option (click)="onChannelClose(channel)">Close Channel</mat-option> <mat-option (click)="onChannelClose(channel)">Close Channel</mat-option>
</mat-select> </mat-select>
@ -70,7 +79,7 @@
<p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p> <p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p>
</td> </td>
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': numPeers>1 && channels.data && channels.data.length>0}"></tr> <tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': numPeers>0 && channels.data && channels.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> </table>

@ -1,4 +1,4 @@
.mat-column-remote_alias { .mat-column-alias {
flex: 0 0 20%; flex: 0 0 20%;
width: 20%; width: 20%;
& .ellipsis-parent { & .ellipsis-parent {
@ -8,13 +8,13 @@
.mat-column-balancedness { .mat-column-balancedness {
padding-left: 3rem; padding-left: 3rem;
flex: 0 0 25%; flex: 0 0 22%;
width: 25%; width: 22%;
} }
.mat-column-local_balance, .mat-column-remote_balance, .mat-column-total_satoshis_sent, .mat-column-total_satoshis_received { .mat-column-short_channel_id, .mat-column-state, .mat-column-msatoshi_total {
flex: 0 0 10%; flex: 0 0 15%;
width: 10%; width: 15%;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;

@ -46,16 +46,16 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = [ 'remote_alias', 'actions']; this.displayedColumns = ['short_channel_id', 'state', 'msatoshi_total', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['remote_alias', 'local_balance', 'remote_balance', 'actions']; this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['remote_alias', 'local_balance', 'remote_balance', 'actions']; this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'local_balance', 'remote_balance', 'balancedness', 'actions']; this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'balancedness', 'actions'];
} }
} }

@ -24,50 +24,55 @@
<div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container"> <div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="peers" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table [dataSource]="peers" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<td mat-cell *matCellDef="let peer">
<div> {{peer?.id | slice:0:10}}... </div>
</td>
</ng-container>
<ng-container matColumnDef="alias"> <ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
<td mat-cell *matCellDef="let peer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '5rem' : '10rem'}"> {{peer?.alias}} </td> <td mat-cell *matCellDef="let peer"> {{peer?.alias}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="pub_key"> <ng-container matColumnDef="connected">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Public Key </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Connected </th>
<td mat-cell *matCellDef="let peer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '5rem' : '20rem'}"> {{peer?.pub_key}} </td> <td mat-cell *matCellDef="let peer"> {{peer?.connected}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="sat_sent"> <ng-container matColumnDef="netaddr">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Network Address </th>
Sats Sent </th> <td mat-cell *matCellDef="let peer">
<td mat-cell *matCellDef="let peer"><span fxLayoutAlign="end center"> {{peer?.sat_sent | number}} </span></td> <span *ngFor="let addr of peer?.netaddr; last as isLast">{{ addr}}<span *ngIf="!isLast">,<br></span></span>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="sat_recv"> <ng-container matColumnDef="globalfeatures">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Global Features </th>
Sats Received </th> <td mat-cell *matCellDef="let peer"> {{peer?.globalfeatures}} </td>
<td mat-cell *matCellDef="let peer"><span fxLayoutAlign="end center"> {{peer?.sat_recv | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="ping_time"> <ng-container matColumnDef="localfeatures">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Ping </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Local Features </th>
<td mat-cell *matCellDef="let peer"><span fxLayoutAlign="end center"> {{peer?.ping_time | number}} </span> <td mat-cell *matCellDef="let peer"> {{peer?.localfeatures}} </td>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="px-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef class="px-3"><span fxLayoutAlign="end center">Actions</span></th>
<td mat-cell *matCellDef="let peer" fxLayoutAlign="end center" class="pl-3"> <td mat-cell *matCellDef="let peer" fxLayoutAlign="end center" class="pl-3">
<div fxFlex="100" class="bordered-box table-actions-select" fxLayoutAlign="center center"> <div fxFlex="100" class="bordered-box table-actions-select" fxLayoutAlign="center center">
<mat-select placeholder="Actions" tabindex="1" class="mr-0"> <mat-select placeholder="Actions" tabindex="1" class="mr-0">
<mat-select-trigger></mat-select-trigger> <mat-select-trigger></mat-select-trigger>
<mat-option (click)="onPeerClick(peer, $event)">View Info</mat-option> <mat-option (click)="onPeerClick(peer, $event)">View Info</mat-option>
<mat-option (click)="onOpenChannel(peer)">Open Channel</mat-option> <mat-option (click)="onOpenChannel(peer)">Open Channel</mat-option>
<mat-option (click)="onPeerDetach(peer)">Disconnect</mat-option> <mat-option (click)="onPeerDetach(peer)">Disconnect</mat-option>
</mat-select> </mat-select>
</div> </div>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="no_peer"> <ng-container matColumnDef="no_peer">
<td mat-footer-cell *matFooterCellDef colspan="4"> <td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="!peers.data || peers.data.length<1">No connected peers.</p> <p *ngIf="!peers.data || peers.data.length<1">No connected peers.</p>
</td> </td>
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': peers.data && peers.data.length>1}"></tr> <tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': peers.data && peers.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.pub_key === newlyAddedPeer && flgAnimate) ? 'added' : 'notAdded'"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.pub_key === newlyAddedPeer && flgAnimate) ? 'added' : 'notAdded'"></tr>
</table> </table>
</div> </div>
<mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator> <mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator>

@ -50,16 +50,16 @@ export class CLPeersComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = [ 'alias', 'actions']; this.displayedColumns = ['id', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = [ 'alias', 'sat_sent', 'sat_recv', 'actions']; this.displayedColumns = ['id', 'alias', 'connected', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['alias', 'sat_sent', 'sat_recv', 'ping_time', 'actions']; this.displayedColumns = ['id', 'alias', 'connected', 'netaddr', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['alias', 'pub_key', 'sat_sent', 'sat_recv', 'ping_time', 'actions']; this.displayedColumns = ['id', 'alias', 'connected', 'netaddr', 'globalfeatures', 'localfeatures', 'actions'];
} }
} }

@ -7,31 +7,45 @@
</div> </div>
<div perfectScrollbar fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container"> <div perfectScrollbar fxLayout="column" fxLayoutAlign="start center" fxFlex="100" class="table-container">
<table mat-table #table [dataSource]="forwardingHistoryEvents" fxFlex="100" matSort class="overflow-auto"> <table mat-table #table [dataSource]="forwardingHistoryEvents" fxFlex="100" matSort class="overflow-auto">
<ng-container matColumnDef="timestamp"> <ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Timestamp</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
<td mat-cell *matCellDef="let fhEvent">{{fhEvent.timestamp_str}}</td> <td mat-cell *matCellDef="let fhEvent">{{fhEvent?.status}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="chan_id_in"> <ng-container matColumnDef="received_time_str">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Inbound Channel ID</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Received Time</th>
<td mat-cell *matCellDef="let fhEvent">{{fhEvent.chan_id_in}}</td> <td mat-cell *matCellDef="let fhEvent">{{fhEvent?.received_time_str}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="chan_id_out"> <ng-container matColumnDef="resolved_time_str">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Outbound Channel ID</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Resolved Time</th>
<td mat-cell *matCellDef="let fhEvent">{{fhEvent.chan_id_out}}</td> <td mat-cell *matCellDef="let fhEvent">{{fhEvent?.resolved_time_str}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="amt_in"> <ng-container matColumnDef="in_channel">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Inbound Amount (Sats)</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>In Channel</th>
<td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent.amt_in | number}}</span></td> <td mat-cell *matCellDef="let fhEvent">{{fhEvent?.in_channel}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="amt_out"> <ng-container matColumnDef="out_channel">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Outbound Amount (Sats)</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Out Channel</th>
<td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent.amt_out | number}}</span></td> <td mat-cell *matCellDef="let fhEvent">{{fhEvent?.out_channel}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="fee_msat"> <ng-container matColumnDef="in_msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee (mSats)</th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">In mSatoshi</th>
<td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent.fee_msat | number}}</span></td> <td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent?.in_msatoshi | number}}</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="out_msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Out mSatoshi</th>
<td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent?.out_msatoshi | number}}</span></td>
</ng-container>
<ng-container matColumnDef="fee">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee mSat</th>
<td mat-cell *matCellDef="let fhEvent"><span fxLayoutAlign="end center">{{fhEvent?.fee | number}}</span></td>
</ng-container>
<ng-container matColumnDef="payment_hash">
<th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell class="pl-4" *matCellDef="let fhEvent">
<div>{{fhEvent?.payment_hash | slice:0:10}}...</div>
</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="px-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef class="px-3"><span fxLayoutAlign="end center">Actions</span></th>
<td mat-cell *matCellDef="let fhEvent" class="pl-3"> <td mat-cell *matCellDef="let fhEvent" class="pl-3">
<button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onForwardingEventClick(fhEvent,$event)">View Info</button> <button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onForwardingEventClick(fhEvent,$event)">View Info</button>

@ -34,13 +34,13 @@ export class CLForwardingHistoryComponent implements OnInit, OnChanges {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['timestamp', 'fee_msat', 'actions']; this.displayedColumns = ['status', 'in_msatoshi', 'out_msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['timestamp', 'amt_in', 'amt_out', 'fee_msat', 'actions']; this.displayedColumns = ['status', 'in_msatoshi', 'out_msatoshi', 'fee', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['timestamp', 'chan_id_in', 'chan_id_out', 'amt_in', 'amt_out', 'fee_msat', 'actions']; this.displayedColumns = ['status', 'received_time_str', 'resolved_time_str', 'in_channel', 'out_channel', 'in_msatoshi', 'out_msatoshi', 'fee', 'actions'];
} }
} }

@ -36,8 +36,8 @@ export class CLRoutingComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.onEventsFetch(); this.onEventsFetch();
this.actions$.pipe(takeUntil(this.unSubs[1]), filter((action) => action.type === RTLActions.RESET_LND_STORE)) this.actions$.pipe(takeUntil(this.unSubs[1]), filter((action) => action.type === RTLActions.RESET_CL_STORE))
.subscribe((resetLndStore: RTLActions.ResetLNDStore) => { .subscribe((resetClStore: RTLActions.ResetCLStore) => {
this.onEventsFetch(); this.onEventsFetch();
}); });
this.store.select('cl') this.store.select('cl')
@ -45,7 +45,7 @@ export class CLRoutingComponent implements OnInit, OnDestroy {
.subscribe((rtlStore) => { .subscribe((rtlStore) => {
this.errorMessage = ''; this.errorMessage = '';
rtlStore.effectErrorsCl.forEach(effectsErr => { rtlStore.effectErrorsCl.forEach(effectsErr => {
if (effectsErr.action === 'GetForwardingHistory') { if (effectsErr.action === 'GetForwardingHistoryCL') {
this.flgLoading[0] = 'error'; this.flgLoading[0] = 'error';
this.errorMessage = (typeof(effectsErr.message) === 'object') ? JSON.stringify(effectsErr.message) : effectsErr.message; this.errorMessage = (typeof(effectsErr.message) === 'object') ? JSON.stringify(effectsErr.message) : effectsErr.message;
} }
@ -72,10 +72,12 @@ export class CLRoutingComponent implements OnInit, OnDestroy {
if (undefined === this.startDate || this.startDate == null) { if (undefined === this.startDate || this.startDate == null) {
this.startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() - 30); this.startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() - 30);
} }
this.store.dispatch(new RTLActions.GetForwardingHistory({ this.store.dispatch(new RTLActions.GetForwardingHistoryCL(
end_time: Math.round(this.endDate.getTime() / 1000).toString(), // {
start_time: Math.round(this.startDate.getTime() / 1000).toString() // end_time: Math.round(this.endDate.getTime() / 1000).toString(),
})); // start_time: Math.round(this.startDate.getTime() / 1000).toString()
// }
));
} }
resetData() { resetData() {
@ -87,7 +89,7 @@ export class CLRoutingComponent implements OnInit, OnDestroy {
ngOnDestroy() { ngOnDestroy() {
this.resetData(); this.resetData();
this.store.dispatch(new RTLActions.SetForwardingHistory({})); this.store.dispatch(new RTLActions.SetForwardingHistoryCL({}));
this.unSubs.forEach(completeSub => { this.unSubs.forEach(completeSub => {
completeSub.next(); completeSub.next();
completeSub.complete(); completeSub.complete();

@ -10,7 +10,7 @@ import { Location } from '@angular/common';
import { environment, API_URL } from '../../../environments/environment'; import { environment, API_URL } from '../../../environments/environment';
import { LoggerService } from '../../shared/services/logger.service'; import { LoggerService } from '../../shared/services/logger.service';
import { SessionService } from '../../shared/services/session.service'; import { SessionService } from '../../shared/services/session.service';
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRatesCL, ListInvoicesCL, InvoiceCL } from '../../shared/models/clModels'; import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRatesCL, ListInvoicesCL, InvoiceCL, GetInfoChainCL } from '../../shared/models/clModels';
import * as fromRTLReducer from '../../store/rtl.reducers'; import * as fromRTLReducer from '../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../store/rtl.actions';
@ -42,6 +42,21 @@ export class CLEffects implements OnDestroy {
map((info) => { map((info) => {
this.logger.info(info); this.logger.info(info);
info.lnImplementation = 'C-Lightning'; info.lnImplementation = 'C-Lightning';
let chainObj = { chain: '', network: '' };
if (info.network === 'testnet') {
chainObj.chain = 'Bitcoin';
chainObj.network = 'Testnet';
} else if (info.network === 'bitcoin') {
chainObj.chain = 'Bitcoin';
chainObj.network = 'Mainnet';
} else if (info.network === 'litecoin') {
chainObj.chain = 'Litecoin';
chainObj.network = 'Mainnet';
} else if (info.network === 'litecoin-testnet') {
chainObj.chain = 'Litecoin';
chainObj.network = 'Testnet';
}
info.chains = [chainObj];
this.initializeRemainingData(info, action.payload.loadPage); this.initializeRemainingData(info, action.payload.loadPage);
return { return {
type: RTLActions.SET_INFO_CL, type: RTLActions.SET_INFO_CL,
@ -157,7 +172,7 @@ export class CLEffects implements OnDestroy {
getNewAddressCL = this.actions$.pipe( getNewAddressCL = this.actions$.pipe(
ofType(RTLActions.GET_NEW_ADDRESS_CL), ofType(RTLActions.GET_NEW_ADDRESS_CL),
mergeMap((action: RTLActions.GetNewAddressCL) => { mergeMap((action: RTLActions.GetNewAddressCL) => {
return this.httpClient.get(this.CHILD_API_URL + environment.ON_CHAIN_API + '?type=' + action.payload.addressTp) return this.httpClient.get(this.CHILD_API_URL + environment.ON_CHAIN_API + '?type=' + action.payload.addressCode)
.pipe(map((newAddress: any) => { .pipe(map((newAddress: any) => {
this.logger.info(newAddress); this.logger.info(newAddress);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
@ -690,25 +705,11 @@ export class CLEffects implements OnDestroy {
initializeRemainingData(info: any, landingPage: string) { initializeRemainingData(info: any, landingPage: string) {
this.sessionService.setItem('clUnlocked', 'true'); this.sessionService.setItem('clUnlocked', 'true');
let chainObj = { chain: '', network: '' };
if (info.network === 'testnet') {
chainObj.chain = 'Bitcoin';
chainObj.network = 'Testnet';
} else if (info.network === 'bitcoin') {
chainObj.chain = 'Bitcoin';
chainObj.network = 'Mainnet';
} else if (info.network === 'litecoin') {
chainObj.chain = 'Litecoin';
chainObj.network = 'Mainnet';
} else if (info.network === 'litecoin-testnet') {
chainObj.chain = 'Litecoin';
chainObj.network = 'Testnet';
}
const node_data = { const node_data = {
identity_pubkey: info.id, identity_pubkey: info.id,
alias: info.alias, alias: info.alias,
testnet: (info.network === 'testnet' || info.network === 'litecoin-testnet') ? true : false, testnet: (info.network === 'testnet' || info.network === 'litecoin-testnet') ? true : false,
chains: [chainObj], chains: info.chains,
version: info.version, version: info.version,
currency_unit: 'BTC', currency_unit: 'BTC',
smaller_currency_unit: 'Sats', smaller_currency_unit: 'Sats',
@ -716,6 +717,7 @@ export class CLEffects implements OnDestroy {
}; };
this.store.dispatch(new RTLActions.SetNodeData(node_data)); this.store.dispatch(new RTLActions.SetNodeData(node_data));
this.store.dispatch(new RTLActions.FetchFeesCL()); this.store.dispatch(new RTLActions.FetchFeesCL());
this.store.dispatch(new RTLActions.FetchChannelsCL());
this.store.dispatch(new RTLActions.FetchBalanceCL()); this.store.dispatch(new RTLActions.FetchBalanceCL());
this.store.dispatch(new RTLActions.FetchLocalRemoteBalanceCL()); this.store.dispatch(new RTLActions.FetchLocalRemoteBalanceCL());
this.store.dispatch(new RTLActions.FetchFeeRatesCL('perkw')); this.store.dispatch(new RTLActions.FetchFeeRatesCL('perkw'));

@ -1,32 +1,35 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap"> <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"> <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="100" fxLayoutAlign="end start"> <mat-form-field fxFlex="49" fxLayoutAlign="space-between stretch">
<input matInput [(ngModel)]="memo" placeholder="Memo" tabindex="1" name="memo"> <input matInput [(ngModel)]="label" placeholder="Label" tabindex="1" name="label">
</mat-form-field>
<mat-form-field fxFlex="49" fxLayoutAlign="space-between stretch">
<input matInput [(ngModel)]="description" placeholder="Description" tabindex="2" name="description">
</mat-form-field> </mat-form-field>
<mat-form-field [fxFlex]="showDetails ? '40' : '100'" fxLayoutAlign="start end"> <mat-form-field [fxFlex]="showDetails ? '40' : '100'" fxLayoutAlign="start end">
<input matInput [(ngModel)]="invoiceValue" (keyup)="onInvoiceValueChange()" placeholder="Amount" type="number" step="100" min="1" tabindex="2" name="invoiceValue"> <input matInput [(ngModel)]="invoiceValue" (keyup)="onInvoiceValueChange()" placeholder="Amount" type="number" step="100" min="1" tabindex="3" name="invoiceValue">
<span matSuffix> {{information?.smaller_currency_unit}} </span> <span matSuffix> {{information?.smaller_currency_unit}} </span>
<mat-hint>{{invoiceValueHint}}</mat-hint> <mat-hint>{{invoiceValueHint}}</mat-hint>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mr-2': screenSize === screenSizeEnum.LG}"> <mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mr-2': screenSize === screenSizeEnum.LG}">
<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="3" name="expiry"> <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> <span matSuffix> {{selTimeUnit | titlecase}} </span>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mr-2': screenSize === screenSizeEnum.LG}"> <mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails" [ngClass]="{'mr-2': screenSize === screenSizeEnum.LG}">
<mat-select [value]="selTimeUnit" tabindex="4" name="timeUnit" (selectionChange)="onTimeUnitChange($event)"> <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-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">{{timeUnit | titlecase}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<div fxFlex="23" tabindex="4" fxLayoutAlign="start center" *ngIf="showDetails"> <div fxFlex="23" 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> <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>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between start" *ngIf="showDetails" class="mt-2"> <div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between start" *ngIf="showDetails" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="5" type="reset" (click)="resetData()">Clear Field</button> <button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="6">Create Invoice</button> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="8">Create Invoice</button>
</div> </div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between stretch" *ngIf="!showDetails" class="mt-1"> <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="5" type="reset" (click)="resetData()">Clear Field</button> <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-raised-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="6">Create Invoice</button> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onAddInvoice(addInvoiceForm)" tabindex="10">Create Invoice</button>
</div> </div>
</form> </form>
<div fxLayout="column" fxLayoutAlign="start stretch" *ngIf="showDetails"> <div fxLayout="column" fxLayoutAlign="start stretch" *ngIf="showDetails">
@ -42,24 +45,40 @@
<div perfectScrollbar class="table-container"> <div perfectScrollbar class="table-container">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="invoices" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table [dataSource]="invoices" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="creation_date"> <ng-container matColumnDef="expires_at_str">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date Created </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Expiry Date </th>
<td mat-cell *matCellDef="let invoice"> <td mat-cell *matCellDef="let invoice">
<span *ngIf="invoice.settled" class="dot green" matTooltip="Settled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span> <span *ngIf="invoice.status === 'paid'" class="dot green" matTooltip="Settled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="!invoice.settled" class="dot yellow" matTooltip="Unsettled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span> <span *ngIf="invoice.status !== 'paid'" class="dot yellow" matTooltip="Unsettled" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{invoice.creation_date_str}}</td> {{invoice.expires_at_str}}
</td>
</ng-container>
<ng-container matColumnDef="paid_at_str">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Paid Date </th>
<td mat-cell *matCellDef="let invoice">{{invoice.paid_at_str}}</td>
</ng-container>
<ng-container matColumnDef="label">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Label </th>
<td mat-cell *matCellDef="let invoice">{{invoice.label}}</td>
</ng-container>
<ng-container matColumnDef="pay_index">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Pay Index </th>
<td mat-cell *matCellDef="let invoice"><span fxLayoutAlign="end center"> {{invoice?.pay_index | number}}
</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="memo"> <ng-container matColumnDef="msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Memo </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Amount </th>
<td mat-cell *matCellDef="let invoice">{{invoice.memo}}</td> <td mat-cell *matCellDef="let invoice"><span fxLayoutAlign="end center"> {{invoice.msatoshi | number}}
</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="value"> <ng-container matColumnDef="msatoshi_received">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Value (Sats) </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Received mSatoshi </th>
<td mat-cell *matCellDef="let invoice"><span fxLayoutAlign="end center"> {{invoice?.value | number}} </span></td> <td mat-cell *matCellDef="let invoice"><span fxLayoutAlign="end center">
{{invoice.msatoshi_received | number}} </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="settle_date"> <ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="pl-4"> Date Settled </th> <th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header> Description </th>
<td mat-cell *matCellDef="let invoice" class="pl-4">{{invoice.settle_date_str || '-'}}</td> <td mat-cell class="pl-4" *matCellDef="let invoice">{{invoice.description}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="pl-3 pr-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef class="pl-3 pr-3"><span fxLayoutAlign="end center">Actions</span></th>
@ -74,7 +93,7 @@
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_invoice']" [ngClass]="{'display-none': invoices.data && invoices.data.length>0}"></tr> <tr mat-footer-row *matFooterRowDef="['no_invoice']" [ngClass]="{'display-none': invoices.data && invoices.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.memo == newlyAddedInvoiceMemo && row.value == newlyAddedInvoiceValue && flgAnimate) ? 'added' : 'notAdded'" class="row-invoices"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.label == newlyAddedInvoiceMemo && row.value == newlyAddedInvoiceValue && flgAnimate) ? 'added' : 'notAdded'" class="row-invoices"></tr>
</table> </table>
<mat-paginator [length]="totalInvoices" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" (page)="onPageChange($event)" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator> <mat-paginator [length]="totalInvoices" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" (page)="onPageChange($event)" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator>
</div> </div>

@ -34,7 +34,8 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
public newlyAddedInvoiceMemo = ''; public newlyAddedInvoiceMemo = '';
public newlyAddedInvoiceValue = 0; public newlyAddedInvoiceValue = 0;
public flgAnimate = true; public flgAnimate = true;
public memo = ''; public label = '';
public description = '';
public expiry: number; public expiry: number;
public invoiceValue: number; public invoiceValue: number;
public invoiceValueHint = ''; public invoiceValueHint = '';
@ -62,16 +63,16 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['creation_date', 'actions']; this.displayedColumns = ['expires_at_str', 'msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['creation_date', 'value', 'actions']; this.displayedColumns = ['expires_at_str', 'label', 'msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['creation_date', 'memo', 'value', 'actions']; this.displayedColumns = ['expires_at_str', 'label', 'msatoshi', 'msatoshi_received', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['creation_date', 'memo', 'value', 'settle_date', 'actions']; this.displayedColumns = ['expires_at_str', 'paid_at_str', 'label', 'msatoshi', 'msatoshi_received', 'actions'];
} }
} }
@ -104,11 +105,11 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
expiryInSecs = this.commonService.convertTime(this.expiry, this.selTimeUnit, TimeUnitEnum.SECS); expiryInSecs = this.commonService.convertTime(this.expiry, this.selTimeUnit, TimeUnitEnum.SECS);
} }
this.flgAnimate = true; this.flgAnimate = true;
this.newlyAddedInvoiceMemo = this.memo; this.newlyAddedInvoiceMemo = this.label;
this.newlyAddedInvoiceValue = this.invoiceValue; this.newlyAddedInvoiceValue = this.invoiceValue;
this.store.dispatch(new RTLActions.OpenSpinner('Adding Invoice...')); this.store.dispatch(new RTLActions.OpenSpinner('Adding Invoice...'));
this.store.dispatch(new RTLActions.SaveNewInvoice({ this.store.dispatch(new RTLActions.SaveNewInvoiceCL({
memo: this.memo, invoiceValue: this.invoiceValue, private: this.private, expiry: expiryInSecs, pageSize: this.pageSize label: this.label, amount: this.invoiceValue, description: this.description, expiry: (this.expiry ? this.expiry : 3600), private: this.private
})); }));
this.resetData(); this.resetData();
} }
@ -117,7 +118,7 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
let reCreatedInvoice = { let reCreatedInvoice = {
payment_request: selInvoice.bolt11, payment_request: selInvoice.bolt11,
value: selInvoice.amount_msat, value: selInvoice.amount_msat,
memo: selInvoice.description, label: selInvoice.label,
settle_date_str: selInvoice.paid_at_str, settle_date_str: selInvoice.paid_at_str,
expiry: selInvoice.expires_at_str expiry: selInvoice.expires_at_str
}; };
@ -142,7 +143,8 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
} }
resetData() { resetData() {
this.memo = ''; this.label = '';
this.description = '';
this.invoiceValue = undefined; this.invoiceValue = undefined;
this.private = false; this.private = false;
this.expiry = undefined; this.expiry = undefined;
@ -165,7 +167,7 @@ export class CLLightningInvoicesComponent implements OnInit, OnDestroy {
reversed = true; reversed = true;
index_offset = 0; index_offset = 0;
} }
this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: event.pageSize, index_offset: index_offset, reversed: reversed})); this.store.dispatch(new RTLActions.FetchInvoicesCL({num_max_invoices: event.pageSize, index_offset: index_offset, reversed: reversed}));
} }
onInvoiceValueChange() { onInvoiceValueChange() {

@ -1,36 +1,10 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap"> <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"> <form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #sendPaymentForm="ngForm">
<mat-form-field [fxFlex]="showDetails ? '82' : '100'"> <mat-form-field fxFlex="100">
<input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" (keyup)="onPaymentRequestEntry()" required #paymentReq="ngModel"> <input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" (keyup)="onPaymentRequestEntry()" required #paymentReq="ngModel">
<mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint> <mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint>
<mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error> <mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error>
</mat-form-field> </mat-form-field>
<div *ngIf="showDetails" fxFlex="100" fxFlex.gt-sm="17" fxLayoutAlign="start center" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
<button fxFlex="100" mat-stroked-button color="primary" type="reset" (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="showDetails && showAdvanced" fxFlex="100" fxFlex.gt-sm="75" fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<mat-select tabindex="5" [(value)]="selFeeLimitType" Placeholder="Fee Limits">
<mat-option *ngFor="let feeLimitType of feeLimitTypes" [value]="feeLimitType">
{{feeLimitType.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="26">
<input matInput [(ngModel)]="feeLimit" [placeholder]="selFeeLimitType.placeholder" type="number" name="feeLimit" step="1" min="0" required tabindex="6" #feeLmt="ngModel" [disabled]="selFeeLimitType === feeLimitTypes[0]">
<mat-error *ngIf="selFeeLimitType !== feeLimitTypes[0] && !feeLimit">{{selFeeLimitType.placeholder}} is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex="40" fxLayoutAlign="start end">
<mat-select tabindex="7" [(value)]="selActiveChannel" placeholder="First Outgoing Channel">
<mat-option *ngFor="let activeChannel of activeChannels" [value]="activeChannel">
{{activeChannel.remote_alias || activeChannel.chan_id}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" *ngIf="showDetails" class="mt-2"> <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-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onSendPayment();" tabindex="3">Send Payment</button> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onSendPayment();" tabindex="3">Send Payment</button>
@ -53,25 +27,55 @@
<div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100"> <div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table fxFlex="100" [dataSource]="payments" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table fxFlex="100" [dataSource]="payments" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="creation_date"> <ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Creation Date</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let payment">{{payment?.creation_date_str}}</td> <td mat-cell *matCellDef="let payment">{{payment?.id}}</td>
</ng-container>
<ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bolt11</th>
<td mat-cell *matCellDef="let payment">{{payment?.bolt11 | slice:0:10}}...</td>
</ng-container>
<ng-container matColumnDef="created_at">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Created At</th>
<td mat-cell *matCellDef="let payment">{{payment?.created_at_str}}</td>
</ng-container>
<ng-container matColumnDef="destination">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment">{{payment?.destination | slice:0:10}}...</td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Status</th>
<td mat-cell *matCellDef="let payment">{{payment?.status}}</td>
</ng-container>
<ng-container matColumnDef="msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">mSatoshi</th>
<td mat-cell *matCellDef="let payment"><span
fxLayoutAlign="end center">{{payment?.msatoshi | number}}</span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_sent">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">mSatoshi Sent</th>
<td mat-cell *matCellDef="let payment"><span
fxLayoutAlign="end center">{{payment?.msatoshi_sent | number}}</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="payment_hash"> <ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th> <th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">{{payment?.payment_hash}}</td> <td mat-cell class="pl-4" *matCellDef="let payment">
<div>{{payment?.payment_hash | slice:0:10}}...</div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="fee"> <ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Pre Image</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.fee | number}}</span></td> <td mat-cell *matCellDef="let payment">
<div>{{payment?.payment_preimage | slice:0:10}}<span *ngIf="payment?.payment_preimage">...</span></div>
</td>
</ng-container> </ng-container>
<ng-container matColumnDef="value"> <ng-container matColumnDef="amount_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Value (Sats)</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Amount mSat</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.value | number}}</span></td> <td mat-cell *matCellDef="let payment">{{payment?.amount_msat}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="path"> <ng-container matColumnDef="amount_sent_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Path (Hops)</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Amount Sent mSat</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.path?.length || 0}}</span></td> <td mat-cell *matCellDef="let payment">{{payment?.amount_sent_msat}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="pl-4 pr-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef class="pl-4 pr-3"><span fxLayoutAlign="end center">Actions</span></th>

@ -44,12 +44,6 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
public paymentDecoded: PayRequestCL = {}; public paymentDecoded: PayRequestCL = {};
public paymentRequest = ''; public paymentRequest = '';
public paymentDecodedHint = ''; public paymentDecodedHint = '';
public showAdvanced = false;
public selActiveChannel: ChannelCL = {};
public activeChannels = {};
public feeLimit = null;
public selFeeLimitType = FEE_LIMIT_TYPES[0];
public feeLimitTypes = FEE_LIMIT_TYPES;
public flgSticky = false; public flgSticky = false;
public pageSize = PAGE_SIZE; public pageSize = PAGE_SIZE;
public pageSizeOptions = PAGE_SIZE_OPTIONS; public pageSizeOptions = PAGE_SIZE_OPTIONS;
@ -64,13 +58,13 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
this.displayedColumns = ['creation_date', 'actions']; this.displayedColumns = ['creation_date', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['creation_date', 'value', 'actions']; this.displayedColumns = ['created_at', 'msatoshi', 'msatoshi_sent', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['creation_date', 'fee', 'value', 'actions']; this.displayedColumns = ['created_at', 'status', 'msatoshi', 'msatoshi_sent', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'path', 'actions']; this.displayedColumns = ['created_at', 'status', 'payment_hash', 'msatoshi', 'msatoshi_sent', 'actions'];
} }
} }
@ -85,7 +79,6 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
}); });
this.information = rtlStore.information; this.information = rtlStore.information;
this.selNode = rtlStore.nodeSettings; this.selNode = rtlStore.nodeSettings;
this.activeChannels = rtlStore.allChannels.filter(channel => channel.connected);
this.paymentJSONArr = (null !== rtlStore.payments && rtlStore.payments.length > 0) ? rtlStore.payments : []; this.paymentJSONArr = (null !== rtlStore.payments && rtlStore.payments.length > 0) ? rtlStore.payments : [];
this.payments = (undefined === rtlStore.payments || null == rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource<PaymentCL>([...this.paymentJSONArr]); this.payments = (undefined === rtlStore.payments || null == rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource<PaymentCL>([...this.paymentJSONArr]);
this.payments.data = this.paymentJSONArr; this.payments.data = this.paymentJSONArr;
@ -208,21 +201,9 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
} }
} }
onShowAdvanced() {
this.showAdvanced = !this.showAdvanced;
if (!this.showAdvanced) {
this.selActiveChannel = null;
this.feeLimit = null;
this.selFeeLimitType = FEE_LIMIT_TYPES[0];
}
}
resetData() { resetData() {
this.paymentDecoded = {}; this.paymentDecoded = {};
this.paymentRequest = ''; this.paymentRequest = '';
this.selActiveChannel = null;
this.feeLimit = null;
this.selFeeLimitType = FEE_LIMIT_TYPES[0];
this.form.resetForm(); this.form.resetForm();
} }

@ -26,30 +26,34 @@
<div perfectScrollbar class="table-container mb-6"> <div perfectScrollbar class="table-container mb-6">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table [dataSource]="qrHops" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table [dataSource]="qrHops" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="hop_sequence"> <ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Hop </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<td mat-cell *matCellDef="let hop"> {{hop?.hop_sequence}} </td> <td mat-cell *matCellDef="let hop"> {{hop?.id}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="pubkey_alias"> <ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Peer </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
<td mat-cell *matCellDef="let hop" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '28rem'}"> {{hop?.pubkey_alias}} </td> <td mat-cell *matCellDef="let hop"> {{hop?.alias}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="chan_id"> <ng-container matColumnDef="channel">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Channel </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Channel </th>
<td mat-cell *matCellDef="let hop"> {{hop?.chan_id}} </td> <td mat-cell *matCellDef="let hop"> {{hop?.channel}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="chan_capacity"> <ng-container matColumnDef="direction">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Capacity (Sats) </th> <th mat-header-cell *matHeaderCellDef mat-sort-header> Direction </th>
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.chan_capacity | number}}</span></td> <td mat-cell *matCellDef="let hop"> {{hop?.direction}} </td>
</ng-container> </ng-container>
<ng-container matColumnDef="amt_to_forward_msat"> <ng-container matColumnDef="msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Amount To Fwd (Sats) </th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> mSatoshi </th>
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.amt_to_forward | number}} <td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.msatoshi | number}}
</span></td> </span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="fee_msat"> <ng-container matColumnDef="amount_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Fee (mSats) </th> <th mat-header-cell class="pl-4" *matHeaderCellDef mat-sort-header> Amount mSat </th>
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.fee_msat | number}} </span> <td mat-cell class="pl-4" *matCellDef="let hop"> {{hop?.amount_msat}} </td>
</ng-container>
<ng-container matColumnDef="delay">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Delay </th>
<td mat-cell *matCellDef="let hop"><span fxLayoutAlign="end center"> {{hop?.delay | number}} </span>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">

@ -36,16 +36,16 @@ export class CLQueryRoutesComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['pubkey_alias', 'actions']; this.displayedColumns = ['alias', 'msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'fee_msat', 'actions']; this.displayedColumns = ['alias', 'direction', 'msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat', 'actions']; this.displayedColumns = ['alias', 'direction', 'msatoshi', 'amount_msat', 'actions'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'chan_capacity', 'amt_to_forward_msat', 'fee_msat', 'actions']; this.displayedColumns = ['alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'actions'];
} }
} }

@ -70,7 +70,7 @@
<p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p> <p *ngIf="numPeers>0 && (!channels.data || channels.data.length<1)">No channels available.</p>
</td> </td>
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': numPeers>1 && channels.data && channels.data.length>0}"></tr> <tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': numPeers>0 && channels.data && channels.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> </table>

@ -65,7 +65,7 @@
<p *ngIf="!peers.data || peers.data.length<1">No connected peers.</p> <p *ngIf="!peers.data || peers.data.length<1">No connected peers.</p>
</td> </td>
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': peers.data && peers.data.length>1}"></tr> <tr mat-footer-row *matFooterRowDef="['no_peer']" [ngClass]="{'display-none': peers.data && peers.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.pub_key === newlyAddedPeer && flgAnimate) ? 'added' : 'notAdded'"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.pub_key === newlyAddedPeer && flgAnimate) ? 'added' : 'notAdded'"></tr>
</table> </table>

@ -34,7 +34,7 @@ export class OnChainGeneratedAddressComponent implements OnInit {
} }
onCopyAddress(payload: string) { onCopyAddress(payload: string) {
this.snackBar.open('Generated Address copied'); this.snackBar.open('Generated address copied.');
this.logger.info('Copied Text: ' + payload); this.logger.info('Copied Text: ' + payload);
} }
} }

@ -29,7 +29,7 @@ export class SettingsComponent implements OnInit, OnDestroy{
this.showLnConfig = false; this.showLnConfig = false;
this.showBitcoind = false; this.showBitcoind = false;
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.lnImplementationStr = this.selNode.lnImplementation.toUpperCase() === 'CLT' ? 'CLT Config' : 'LND Config'; this.lnImplementationStr = this.selNode.lnImplementation.toUpperCase() === 'CLT' ? 'C-Lightning Config' : 'LND Config';
if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.configPath && this.selNode.authentication.configPath !== '') { if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.configPath && this.selNode.authentication.configPath !== '') {
this.showLnConfig = true; this.showLnConfig = true;
} }

@ -21,6 +21,11 @@ export interface Address {
port?: number; port?: number;
} }
export interface GetInfoChainCL {
chain?: string;
network?: string;
}
export interface GetInfoCL { export interface GetInfoCL {
id?: string; id?: string;
alias?: string; alias?: string;
@ -34,6 +39,7 @@ export interface GetInfoCL {
version?: string; version?: string;
blockheight?: number; blockheight?: number;
network?: string; network?: string;
chains?: GetInfoChainCL[];
msatoshi_fees_collected?: number; msatoshi_fees_collected?: number;
fees_collected_msat?: string; fees_collected_msat?: string;
currency_unit?: string; currency_unit?: string;
@ -222,7 +228,7 @@ export interface LookupNodeCL {
last_timestamp?: number; last_timestamp?: number;
last_timestamp_str?: string; last_timestamp_str?: string;
globalfeatures?: string; globalfeatures?: string;
global_features?: string; features?: string;
addresses?: Address[]; addresses?: Address[];
} }

@ -23,7 +23,6 @@ export const MENU_DATA: MenuRootNode = {
{id: 3, parentId: 0, name: 'Lightning', iconType: 'FA', icon: faBolt, link: '/cl/peerschannels', userPersona: UserPersonaEnum.ALL, children: [ {id: 3, parentId: 0, name: 'Lightning', iconType: 'FA', icon: faBolt, link: '/cl/peerschannels', userPersona: UserPersonaEnum.ALL, children: [
{id: 31, parentId: 3, name: 'Peers/Channels', iconType: 'FA', icon: faUsers, link: '/cl/peerschannels', userPersona: UserPersonaEnum.ALL}, {id: 31, parentId: 3, name: 'Peers/Channels', iconType: 'FA', icon: faUsers, link: '/cl/peerschannels', userPersona: UserPersonaEnum.ALL},
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/cl/transactions', userPersona: UserPersonaEnum.ALL}, {id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/cl/transactions', userPersona: UserPersonaEnum.ALL},
{id: 33, parentId: 3, name: 'Backup', iconType: 'FA', icon: faDownload, link: '/cl/backup', userPersona: UserPersonaEnum.ALL},
{id: 34, parentId: 3, name: 'Routing', iconType: 'FA', icon: faMapSigns, link: '/cl/routing', userPersona: UserPersonaEnum.ALL}, {id: 34, parentId: 3, name: 'Routing', iconType: 'FA', icon: faMapSigns, link: '/cl/routing', userPersona: UserPersonaEnum.ALL},
{id: 35, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/cl/lookups', userPersona: UserPersonaEnum.ALL} {id: 35, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/cl/lookups', userPersona: UserPersonaEnum.ALL}
]}, ]},

@ -25,8 +25,8 @@ export const PAGE_SIZE = 10;
export const PAGE_SIZE_OPTIONS = [5, 10, 25, 100]; export const PAGE_SIZE_OPTIONS = [5, 10, 25, 100];
export const ADDRESS_TYPES = [ export const ADDRESS_TYPES = [
{ addressId: '0', addressTp: 'Bech32 (P2WKH)', addressDetails: 'Pay to witness key hash'}, { addressId: '0', addressCode: 'bech32', addressTp: 'Bech32 (P2WKH)', addressDetails: 'Pay to witness key hash'},
{ addressId: '1', addressTp: 'P2SH (NP2WKH)', addressDetails: 'Pay to nested witness key hash (default)'} { addressId: '1', addressCode: 'p2sh-segwit', addressTp: 'P2SH (NP2WKH)', addressDetails: 'Pay to nested witness key hash (default)'}
]; ];
export const TRANS_TYPES = [ export const TRANS_TYPES = [

@ -354,7 +354,6 @@
} }
.cc-data-block { .cc-data-block {
margin-right: 3.2rem;
& .cc-data-title { & .cc-data-title {
font-size: 80%; font-size: 80%;
font-weight: 500; font-weight: 500;
@ -362,6 +361,8 @@
& .cc-data-value { & .cc-data-value {
font-size: 120%; font-size: 120%;
color: $foreground-secondary-text; color: $foreground-secondary-text;
margin-right: 4rem;
min-width: 7rem;
} }
} }

@ -5,7 +5,7 @@ import { DialogConfig } from '../shared/models/alertData';
import { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild } from '../shared/models/RTLconfig'; import { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild } from '../shared/models/RTLconfig';
import { GetInfoCL, FeesCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL, ChannelCL, FeeRatesCL, ForwardingHistoryResCL, InvoiceCL, ListInvoicesCL, OnChainCL } from '../shared/models/clModels'; import { GetInfoCL, FeesCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL, ChannelCL, FeeRatesCL, ForwardingHistoryResCL, InvoiceCL, ListInvoicesCL, OnChainCL } from '../shared/models/clModels';
import { import {
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType, GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode,
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes, PendingChannelsGroup PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes, PendingChannelsGroup
} from '../shared/models/lndModels'; } from '../shared/models/lndModels';
@ -495,7 +495,7 @@ export class SetGraphNode implements Action {
export class GetNewAddress implements Action { export class GetNewAddress implements Action {
readonly type = GET_NEW_ADDRESS; readonly type = GET_NEW_ADDRESS;
constructor(public payload: AddressType) {} constructor(public payload: { addressId?: string, addressCode?: string, addressTp?: string, addressDetails?: string}) {}
} }
export class SetNewAddress implements Action { export class SetNewAddress implements Action {
@ -657,7 +657,7 @@ export class SetLocalRemoteBalanceCL implements Action {
export class GetNewAddressCL implements Action { export class GetNewAddressCL implements Action {
readonly type = GET_NEW_ADDRESS_CL; readonly type = GET_NEW_ADDRESS_CL;
constructor(public payload: AddressType) {} constructor(public payload: { addressId?: string, addressCode?: string, addressTp?: string, addressDetails?: string}) {}
} }
export class SetNewAddressCL implements Action { export class SetNewAddressCL implements Action {

Loading…
Cancel
Save