CL Peers & Channels

CL Peers & Channels
pull/260/head
Shahana Farooqui 4 years ago
parent 1e5a8179ab
commit 46044c5510

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

@ -12,5 +12,5 @@
<link rel="stylesheet" href="styles.87b171242d5c32215e74.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.6f62e75da92af0a26161.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.500c2732a03d69d31b76.js" defer></script></body>
<script src="runtime.2062541fefdba5cf619b.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.6ea2ca78e7451366c45e.js" defer></script></body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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

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

@ -1,5 +1,5 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
<mat-form-field fxFlex="40" fxFlex.gt-sm="30" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selectedPeer" placeholder="Alias" name="peer_alias" tabindex="1" required name="selPeer" #selPeer="ngModel">
<mat-option (click)="addNewPeer()" [value]="'new'">
@ -22,7 +22,7 @@
<mat-slide-toggle tabindex="3" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
</div>
<div fxFlex="100" fxFlex.gt-sm="17" fxLayoutAlign="start center" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
<button fxFlex="48" fxFlex.gt-sm="100" fxLayoutAlign="center center" mat-stroked-button color="primary" type="reset" (click)="onShowAdvanced()" tabindex="4">
<button fxFlex="48" fxFlex.gt-sm="100" fxLayoutAlign="center center" mat-stroked-button color="primary" type="button" (click)="onShowAdvanced()" tabindex="4">
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
</button>

@ -22,6 +22,7 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
})
export class CLChannelManageComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild('form', {static: true}) form: any;
public totalBalance = 0;
public selectedPeer = '';
public fundingAmount: number;
@ -33,7 +34,7 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
public showAdvanced = false;
public peerAddress = '';
public newlyAddedPeer = '';
public selFeeRate = '';
public selFeeRate = null;
public flgMinConf = false;
public minConfValue = null;
public moreOptions = false;
@ -60,12 +61,17 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
this.logger.info(rtlStore);
});
this.actions$.pipe(takeUntil(this.unSubs[1]),
filter((action) => action.type === RTLActions.SET_PEERS_CL))
.subscribe((action: RTLActions.SetPeersCL) => {
if(this.newlyAddedPeer !== '') {
this.snackBar.open('Peer added successfully. Proceed to open the channel.');
this.selectedPeer = this.newlyAddedPeer;
this.newlyAddedPeer = '';
filter((action) => action.type === RTLActions.SET_PEERS_CL || action.type === RTLActions.FETCH_CHANNELS_CL))
.subscribe((action: RTLActions.SetPeersCL | RTLActions.FetchChannelsCL) => {
if(action.type === RTLActions.SET_PEERS_CL) {
if(this.newlyAddedPeer !== '') {
this.snackBar.open('Peer added successfully. Proceed to open the channel.');
this.selectedPeer = this.newlyAddedPeer;
this.newlyAddedPeer = '';
}
}
if(action.type === RTLActions.FETCH_CHANNELS_CL) {
this.form.resetForm();
}
});
}
@ -84,16 +90,17 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
this.moreOptions = false;
this.flgMinConf = false;
this.isPrivate = false;
this.selFeeRate = '';
this.selFeeRate = null;
this.minConfValue = null;
this.showAdvanced = false;
this.form.resetForm();
}
onShowAdvanced() {
this.showAdvanced = !this.showAdvanced;
if (!this.showAdvanced) {
this.flgMinConf = false;
this.isPrivate = false;
this.selFeeRate = '';
this.selFeeRate = null;
this.minConfValue = null;
}
}
@ -115,9 +122,10 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
.subscribe(confirmRes => {
if (confirmRes) {
this.peerAddress = confirmRes[0].inputValue;
this.newlyAddedPeer = this.peerAddress;
const deviderIndex = this.peerAddress.search('@');
this.newlyAddedPeer = (deviderIndex<0) ? 'none' : this.peerAddress.substring(0, deviderIndex);
this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...'));
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress}));
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress, showOpenChannelModal: false}));
} else {
this.selectedPeer = '';
}

@ -93,9 +93,9 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
remoteNode = resLookup[1];
}
const reorderedChannelPolicy = [
[{key: 'base_fee_millisatoshi', value: remoteNode.base_fee_millisatoshi, title: 'Base Fees (mSats)', width: 32, type: DataTypeEnum.NUMBER},
{key: 'fee_per_millionth', value: remoteNode.fee_per_millionth, title: 'Fee/Millionth', width: 32, type: DataTypeEnum.NUMBER},
{key: 'delay', value: remoteNode.delay, title: 'Delay', width: 32, type: DataTypeEnum.NUMBER}]
[{key: 'base_fee_millisatoshi', value: remoteNode.base_fee_millisatoshi, title: 'Base Fees (mSats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'fee_per_millionth', value: remoteNode.fee_per_millionth, title: 'Fee/Millionth', width: 33, type: DataTypeEnum.NUMBER},
{key: 'delay', value: remoteNode.delay, title: 'Delay', width: 33, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,
@ -107,49 +107,50 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
}
onChannelUpdate(channelToUpdate: any) {
if(channelToUpdate !== 'all' && channelToUpdate.state === 'ONCHAIN') {
return;
}
if (channelToUpdate === 'all') {
const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Fee Policy for all Channels',
alertTitle: 'Update fee policy for all Channels',
noBtnText: 'Cancel',
yesBtnText: 'Update All Channels',
message: confirmationMsg,
flgShowInput: true,
getInputs: [
{placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1000, width: 32},
{placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1, min: 1, width: 32},
{placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 40, width: 32}
{placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: 1000, width: 48},
{placeholder: 'Fee Rate (mili mSats)', inputType: 'number', inputValue: 1, min: 1, width: 48}
]
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[2]))
.pipe(takeUntil(this.unSubs[1]))
.subscribe(confirmRes => {
if (confirmRes) {
const base_fee = confirmRes[0].inputValue;
const fee_rate = confirmRes[1].inputValue;
const time_lock_delta = confirmRes[2].inputValue;
this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...'));
this.store.dispatch(new RTLActions.UpdateChannelsCL({baseFeeMsat: base_fee, feeRate: fee_rate, channelId: 'all'}));
}
});
} else {
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0};
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0};
this.store.dispatch(new RTLActions.OpenSpinner('Fetching Channel Policy...'));
this.store.dispatch(new RTLActions.ChannelLookupCL(channelToUpdate.chan_id.toString()));
this.store.dispatch(new RTLActions.ChannelLookupCL(channelToUpdate.short_channel_id));
this.clEffects.setLookupCL
.pipe(take(1))
.subscribe(resLookup => {
if (resLookup.node1_pub === this.information.id) {
this.myChanPolicy = resLookup.node1_policy;
} else if (resLookup.node2_pub === this.information.id) {
this.myChanPolicy = resLookup.node2_policy;
.subscribe((resLookup: ChannelEdgeCL[]) => {
if (resLookup.length > 0 && resLookup[0].destination === this.information.id) {
this.myChanPolicy = {fee_base_msat: resLookup[0].base_fee_millisatoshi, fee_rate_milli_msat: resLookup[0].fee_per_millionth};
} else if (resLookup.length > 1 && resLookup[1].destination === this.information.id) {
this.myChanPolicy = {fee_base_msat: resLookup[1].base_fee_millisatoshi, fee_rate_milli_msat: resLookup[1].fee_per_millionth};
} else {
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0};
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0};
}
this.logger.info(this.myChanPolicy);
this.store.dispatch(new RTLActions.CloseSpinner());
const titleMsg = 'Update fee policy for channel point: ' + channelToUpdate.channel_point;
const titleMsg = 'Update fee policy for Channel: ' + channelToUpdate.channel_id;
const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM,
@ -160,19 +161,17 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
message: confirmationMsg,
flgShowInput: true,
getInputs: [
{placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 32},
{placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1, width: 32},
{placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.time_lock_delta, width: 32}
{placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 48},
{placeholder: 'Fee Rate (mili mSats)', inputType: 'number', inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1, width: 48}
]
}}));
});
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[4]))
.pipe(takeUntil(this.unSubs[2]))
.subscribe(confirmRes => {
if (confirmRes) {
const base_fee = confirmRes[0].inputValue;
const fee_rate = confirmRes[1].inputValue;
const time_lock_delta = confirmRes[2].inputValue;
this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...'));
this.store.dispatch(new RTLActions.UpdateChannelsCL({baseFeeMsat: base_fee, feeRate: fee_rate, channelId: channelToUpdate.channel_id}));
}
@ -190,7 +189,7 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
yesBtnText: 'Close Channel'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[5]))
.pipe(takeUntil(this.unSubs[3]))
.subscribe(confirmRes => {
if (confirmRes) {
this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...'));
@ -206,20 +205,19 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
onChannelClick(selChannel: ChannelCL, event: any) {
const reorderedChannel = [
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 100}],
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100}],
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 100}],
[{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 66},
{key: 'connected', value: selChannel.connected, title: 'Connected', width: 32, type: DataTypeEnum.BOOLEAN}],
[{key: 'private', value: selChannel.private, title: 'Private', width: 32, type: DataTypeEnum.BOOLEAN},
{key: 'state', value: selChannel.state, title: 'State', width: 32, type: DataTypeEnum.NUMBER},
{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 32, type: DataTypeEnum.NUMBER}],
[{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 32, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_to_them', value: selChannel.msatoshi_to_them, title: 'mSatoshi to Us', width: 32, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total mSatoshi', width: 32, type: DataTypeEnum.NUMBER}],
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve Satoshis', width: 32, type: DataTypeEnum.NUMBER},
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve Satoshis', width: 32, type: DataTypeEnum.NUMBER},
{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable mSatoshi', width: 32, type: DataTypeEnum.NUMBER}]
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 100, type: DataTypeEnum.STRING}],
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100, type: DataTypeEnum.STRING}],
[{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 100, type: DataTypeEnum.STRING}],
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 34, type: DataTypeEnum.STRING},
{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 66, type: DataTypeEnum.STRING}],
[{key: 'connected', value: selChannel.connected, title: 'Connected', width: 34, type: DataTypeEnum.BOOLEAN},
{key: 'private', value: selChannel.private, title: 'Private', width: 33, type: DataTypeEnum.BOOLEAN},
{key: 'state', value: selChannel.state, title: 'State', width: 33, type: DataTypeEnum.STRING}],
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve (Sats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve (Sats)', width: 33, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 33, type: DataTypeEnum.NUMBER}],
[{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable (mSats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total (mSats)', width: 66, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,

@ -34,9 +34,9 @@
{{channel?.msatoshi_to_us | number}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_total">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Total mSatoshis </th>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Total (Sats) </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">
{{channel?.msatoshi_total | number}} </span></td>
{{channel?.msatoshi_total/1000 | number}} </span></td>
</ng-container>
<ng-container matColumnDef="spendable_msatoshi">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before"> Spendable Satoshi </th>

@ -46,16 +46,16 @@ export class CLChannelPendingTableComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false;
this.displayedColumns = ['short_channel_id', 'state', 'msatoshi_total', 'actions'];
this.displayedColumns = ['alias', 'state', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false;
this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'actions'];
this.displayedColumns = ['alias', 'connected', 'state', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false;
this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'actions'];
this.displayedColumns = ['alias', 'connected', 'state', 'msatoshi_total', 'actions'];
} else {
this.flgSticky = true;
this.displayedColumns = ['short_channel_id', 'alias', 'state', 'msatoshi_total', 'actions'];
this.displayedColumns = ['alias', 'connected', 'state', 'msatoshi_total', 'actions'];
}
}
@ -88,25 +88,25 @@ export class CLChannelPendingTableComponent implements OnInit, OnDestroy {
onChannelClick(selChannel: ChannelCL, event: any) {
const reorderedChannel = [
[{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 40},
{key: 'connected', value: selChannel.connected, title: 'Connected', width: 30, type: DataTypeEnum.BOOLEAN},
{key: 'private', value: selChannel.private, title: 'Private', width: 30, type: DataTypeEnum.BOOLEAN}],
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100}],
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 100}],
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 50},
{key: 'state', value: selChannel.state, title: 'State', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve Satoshis', width: 50, type: DataTypeEnum.NUMBER},
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve Satoshis', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 50, type: DataTypeEnum.NUMBER},
{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable mSatoshi', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total mSatoshi', width: 50, type: DataTypeEnum.NUMBER},
{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 50, type: DataTypeEnum.NUMBER}]
[{key: 'channel_id', value: selChannel.channel_id, title: 'Channel ID', width: 100, type: DataTypeEnum.STRING}],
[{key: 'id', value: selChannel.id, title: 'Peer Public Key', width: 100, type: DataTypeEnum.STRING}],
[{key: 'funding_txid', value: selChannel.funding_txid, title: 'Funding Transaction Id', width: 100, type: DataTypeEnum.STRING}],
[{key: 'short_channel_id', value: selChannel.short_channel_id, title: 'Short Channel ID', width: 34, type: DataTypeEnum.STRING},
{key: 'alias', value: selChannel.alias, title: 'Peer Alias', width: 66, type: DataTypeEnum.STRING}],
[{key: 'connected', value: selChannel.connected, title: 'Connected', width: 34, type: DataTypeEnum.BOOLEAN},
{key: 'private', value: selChannel.private, title: 'Private', width: 33, type: DataTypeEnum.BOOLEAN},
{key: 'state', value: selChannel.state, title: 'State', width: 33, type: DataTypeEnum.STRING}],
[{key: 'our_channel_reserve_satoshis', value: selChannel.our_channel_reserve_satoshis, title: 'Our Channel Reserve (Sats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'their_channel_reserve_satoshis', value: selChannel.their_channel_reserve_satoshis, title: 'Their Channel Reserve (Sats)', width: 33, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_to_us', value: selChannel.msatoshi_to_us, title: 'mSatoshi to Us', width: 33, type: DataTypeEnum.NUMBER}],
[{key: 'spendable_msatoshi', value: selChannel.spendable_msatoshi, title: 'Spendable (mSats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_total', value: selChannel.msatoshi_total, title: 'Total (mSats)', width: 66, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Channel Information',
showCopyName: 'Short Channel ID',
showCopyField: selChannel.short_channel_id,
showCopyName: 'Channel ID',
showCopyField: selChannel.channel_id,
message: reorderedChannel
}}));
}

@ -26,13 +26,13 @@
<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 mat-cell *matCellDef="let peer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '15rem'}">
{{peer?.id}}
</td>
</ng-container>
<ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Alias </th>
<td mat-cell *matCellDef="let peer"> {{peer?.alias}} </td>
<td mat-cell *matCellDef="let peer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '15rem'}"> {{peer?.alias}} </td>
</ng-container>
<ng-container matColumnDef="connected">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Connected </th>

@ -5,14 +5,10 @@
text-overflow: ellipsis;
}
.mat-column-pub_key {
flex: 1 1 20%;
.mat-column-id {
flex: 1 1 10%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 2rem;
}
.mat-column-ping_time {
padding-right: 2rem;
}

@ -1,17 +1,17 @@
import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil, filter, take } from 'rxjs/operators';
import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faUsers } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { PeerCL, GetInfoCL } from '../../../shared/models/clModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, ScreenSizeEnum } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
import { OpenChannelComponent } from '../../../lnd/peers-channels/open-channel-modal/open-channel.component';
import { CLOpenChannelComponent } from '../../../shared/components/data-modal/open-channel-cl/open-channel.component';
import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation';
import { CLEffects } from '../../store/cl.effects';
import { RTLEffects } from '../../../store/rtl.effects';
@ -30,6 +30,7 @@ import * as fromRTLReducer from '../../../store/rtl.reducers';
export class CLPeersComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild('peersForm', {static: true}) form: any;
public faUsers = faUsers;
public newlyAddedPeer = '';
public flgAnimate = true;
@ -50,16 +51,16 @@ export class CLPeersComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false;
this.displayedColumns = ['id', 'actions'];
this.displayedColumns = ['alias', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false;
this.displayedColumns = ['id', 'alias', 'connected', 'actions'];
this.displayedColumns = ['id', 'alias', 'netaddr', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false;
this.displayedColumns = ['id', 'alias', 'connected', 'netaddr', 'actions'];
this.displayedColumns = ['id', 'alias', 'netaddr', 'globalfeatures', 'localfeatures', 'actions'];
} else {
this.flgSticky = true;
this.displayedColumns = ['id', 'alias', 'connected', 'netaddr', 'globalfeatures', 'localfeatures', 'actions'];
this.displayedColumns = ['id', 'alias', 'netaddr', 'globalfeatures', 'localfeatures', 'actions'];
}
}
@ -95,6 +96,7 @@ export class CLPeersComponent implements OnInit, OnDestroy {
).subscribe((setPeers: RTLActions.SetPeersCL) => {
this.peerAddress = undefined;
this.flgAnimate = true;
this.form.resetForm();
});
}
@ -103,16 +105,17 @@ export class CLPeersComponent implements OnInit, OnDestroy {
this.flgAnimate = true;
this.newlyAddedPeer = this.peerAddress;
this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...'));
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress}));
this.store.dispatch(new RTLActions.SaveNewPeerCL({id: this.peerAddress, showOpenChannelModal: true}));
}
onPeerClick(selPeer: PeerCL, event: any) {
const reorderedPeer = [
[{key: 'id', value: selPeer.id, title: 'Public Key', width: 100}],
[{key: 'netaddr', value: selPeer.netaddr, title: 'Address', width: 100}],
[{key: 'alias', value: selPeer.alias, title: 'Alias', width: 50}, {key: 'connected', value: selPeer.connected ? 'True' : 'False', title: 'Connected', width: 50}],
[{key: 'globalfeatures', value: selPeer.globalfeatures, title: 'Global Features', width: 100}],
[{key: 'localfeatures', value: selPeer.localfeatures, title: 'Local Features', width: 100}]
[{key: 'alias', value: selPeer.alias, title: 'Alias', width: 50},
{key: 'connected', value: selPeer.connected ? 'True' : 'False', title: 'Connected', width: 50}],
[{key: 'globalfeatures', value: selPeer.globalfeatures, title: 'Global Features', width: 50},
{key: 'localfeatures', value: selPeer.localfeatures, title: 'Local Features', width: 50}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,
@ -125,6 +128,7 @@ export class CLPeersComponent implements OnInit, OnDestroy {
resetData() {
this.peerAddress = '';
this.form.resetForm();
}
onOpenChannel(peerToAddChannel: PeerCL) {
@ -137,7 +141,7 @@ export class CLPeersComponent implements OnInit, OnDestroy {
alertTitle: 'Open Channel',
message: peerToAddChannelMessage,
newlyAdded: false,
component: OpenChannelComponent
component: CLOpenChannelComponent
}}));
}

@ -14,10 +14,12 @@ import { CommonService } from '../../shared/services/common.service';
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component';
import { CLInvoiceInformationComponent } from '../../shared/components/data-modal/invoice-information-cl/invoice-information.component';
import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRatesCL, ListInvoicesCL, InvoiceCL } from '../../shared/models/clModels';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import * as fromCLReducers from '../store/cl.reducers';
import { CLOpenChannelComponent } from '../../shared/components/data-modal/open-channel-cl/open-channel.component';
@Injectable()
export class CLEffects implements OnDestroy {
@ -209,17 +211,35 @@ export class CLEffects implements OnDestroy {
@Effect()
saveNewPeerCL = this.actions$.pipe(
ofType(RTLActions.SAVE_NEW_PEER_CL),
mergeMap((action: RTLActions.SaveNewPeerCL) => {
withLatestFrom(this.store.select('cl')),
mergeMap(([action, clData]: [RTLActions.SaveNewPeerCL, fromCLReducers.CLState]) => {
return this.httpClient.post(this.CHILD_API_URL + environment.PEERS_API, { id: action.payload.id })
.pipe(
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Connected', titleMessage: 'Peer Added Successfully!' }}));
return {
type: RTLActions.SET_PEERS_CL,
payload: (postRes && postRes.length > 0) ? postRes : []
};
this.store.dispatch(new RTLActions.SetPeersCL((postRes && postRes.length > 0) ? postRes : []));
if(action.payload.showOpenChannelModal) {
const peerToAddChannelMessage = {
peer: postRes[0],
information: clData.information,
balance: clData.balance.totalBalance || 0
};
return {
type: RTLActions.OPEN_ALERT,
payload: { width: '50%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Peer Connected',
message: peerToAddChannelMessage,
newlyAdded: true,
component: CLOpenChannelComponent
}}
};
} else {
return {
type: RTLActions.VOID
}
}
}),
catchError((err: any) => {
this.handleErrorWithAlert('ERROR', 'Add Peer Failed', this.CHILD_API_URL + environment.PEERS_API, err);
@ -285,6 +305,7 @@ export class CLEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Added Successfully!'));
return {
type: RTLActions.FETCH_CHANNELS_CL
};
@ -307,7 +328,11 @@ export class CLEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Updated Successfully!'));
if(action.payload.channelId === 'all') {
this.store.dispatch(new RTLActions.OpenSnackBar('All Channels Updated Successfully.'));
} else {
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Updated Successfully!'));
}
return {
type: RTLActions.FETCH_CHANNELS_CL
};
@ -331,6 +356,7 @@ export class CLEffects implements OnDestroy {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.FetchChannelsCL());
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Closed Successfully!'));
return {
type: RTLActions.REMOVE_CHANNEL_CL,
payload: { channelId: action.payload.channelId }

@ -58,7 +58,7 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
this.displayedColumns = ['created_at_str', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false;
this.displayedColumns = ['created_at_str', 'msatoshi_sent', 'msatoshi', 'actions'];
this.displayedColumns = ['created_at_str', 'msatoshi', 'actions'];
} else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false;
this.displayedColumns = ['created_at_str', 'msatoshi_sent', 'msatoshi', 'actions'];

@ -17,7 +17,7 @@
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" type="submit" tabindex="4">Query Route</button>
</div>
</form>
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2 mb-1">
<div fxFlex="70">
<fa-icon [icon]="faRoute" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Transaction Route</span>

@ -89,9 +89,9 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnDestroy {
[{key: 'tx_hash', value: selTransaction.tx_hash, title: 'Transaction Hash', width: 100}],
[{key: 'time_stamp_str', value: selTransaction.time_stamp_str, title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME},
{key: 'block_height', value: selTransaction.block_height, title: 'Block Height', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'num_confirmations', value: selTransaction.num_confirmations, title: 'Number of Confirmations', width: 32, type: DataTypeEnum.NUMBER},
{key: 'total_fees', value: selTransaction.total_fees, title: 'Total Fees (Sats)', width: 32, type: DataTypeEnum.NUMBER},
{key: 'amount', value: selTransaction.amount, title: 'Amount (Sats)', width: 32, type: DataTypeEnum.NUMBER}]
[{key: 'num_confirmations', value: selTransaction.num_confirmations, title: 'Number of Confirmations', width: 34, type: DataTypeEnum.NUMBER},
{key: 'total_fees', value: selTransaction.total_fees, title: 'Total Fees (Sats)', width: 33, type: DataTypeEnum.NUMBER},
{key: 'amount', value: selTransaction.amount, title: 'Amount (Sats)', width: 33, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,

@ -1,5 +1,5 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap">
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap">
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-sm="row wrap" #form="ngForm">
<mat-form-field fxFlex="40" fxFlex.gt-sm="30" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selectedPeer" placeholder="Alias" name="peer_alias" tabindex="1" required name="selPeer" #selPeer="ngModel">
<mat-option (click)="addNewPeer()" [value]="'new'">
@ -22,7 +22,7 @@
<mat-slide-toggle tabindex="3" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
</div>
<div fxFlex="100" fxFlex.gt-sm="17" fxLayoutAlign="start center" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">
<button fxFlex="48" fxFlex.gt-sm="100" fxLayoutAlign="center center" mat-stroked-button color="primary" type="reset" (click)="onShowAdvanced()" tabindex="4">
<button fxFlex="48" fxFlex.gt-sm="100" fxLayoutAlign="center center" mat-stroked-button color="primary" type="button" (click)="onShowAdvanced()" tabindex="4">
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
</button>

@ -22,6 +22,7 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
})
export class ChannelManageComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild('form', {static: true}) form: any;
public totalBalance = 0;
public selectedPeer = '';
public fundingAmount: number;
@ -59,12 +60,17 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
this.logger.info(rtlStore);
});
this.actions$.pipe(takeUntil(this.unSubs[1]),
filter((action) => action.type === RTLActions.SET_PEERS))
.subscribe((action: RTLActions.SetPeers) => {
if(this.newlyAddedPeer !== '') {
this.snackBar.open('Peer added successfully. Proceed to open the channel.');
this.selectedPeer = this.newlyAddedPeer;
this.newlyAddedPeer = '';
filter((action) => action.type === RTLActions.SET_PEERS || action.type === RTLActions.FETCH_ALL_CHANNELS))
.subscribe((action: RTLActions.SetPeers | RTLActions.FetchAllChannels) => {
if(action.type === RTLActions.SET_PEERS) {
if(this.newlyAddedPeer !== '') {
this.snackBar.open('Peer added successfully. Proceed to open the channel.');
this.selectedPeer = this.newlyAddedPeer;
this.newlyAddedPeer = '';
}
}
if(action.type === RTLActions.FETCH_ALL_CHANNELS) {
this.form.resetForm();
}
});
}
@ -91,6 +97,7 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
this.isPrivate = false;
this.selTransType = '0';
this.transTypeValue = {blocks: '', fees: ''};
this.form.resetForm();
}
onShowAdvanced() {

@ -82,15 +82,14 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
}
onViewRemotePolicy(selChannel: Channel) {
console.warn(selChannel);
this.store.dispatch(new RTLActions.ChannelLookup(selChannel.chan_id.toString() + '/' + this.information.identity_pubkey));
this.lndEffects.setLookup
.pipe(take(1))
.subscribe(resLookup => {
const reorderedChannelPolicy = [
[{key: 'fee_base_msat', value: resLookup.fee_base_msat, title: 'Base Fees (mSats)', width: 32, type: DataTypeEnum.NUMBER},
{key: 'fee_rate_milli_msat', value: resLookup.fee_rate_milli_msat, title: 'Fee Rate (milli mSats)', width: 32, type: DataTypeEnum.NUMBER},
{key: 'time_lock_delta', value: resLookup.time_lock_delta, title: 'Time Lock Delta', width: 32, type: DataTypeEnum.NUMBER}]
[{key: 'fee_base_msat', value: resLookup.fee_base_msat, title: 'Base Fees (mSats)', width: 34, type: DataTypeEnum.NUMBER},
{key: 'fee_rate_milli_msat', value: resLookup.fee_rate_milli_msat, title: 'Fee Rate (milli mSats)', width: 33, type: DataTypeEnum.NUMBER},
{key: 'time_lock_delta', value: resLookup.time_lock_delta, title: 'Time Lock Delta', width: 33, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION,
@ -106,7 +105,7 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Fee Policy for all Channels',
alertTitle: 'Update fee policy for all Channels',
noBtnText: 'Cancel',
yesBtnText: 'Update All Channels',
message: confirmationMsg,

@ -10,7 +10,7 @@
<mat-table #table [dataSource]="pendingOpenChannels" matSort [ngClass]="{'w-100 error-border bordered-box': flgLoading[0]==='error','bordered-box w-100': true}">
<ng-container matColumnDef="channel_point">
<mat-header-cell *matHeaderCellDef mat-sort-header> Channel Point </mat-header-cell>
<mat-cell *matCellDef="let channel">{{channel.channel.channel_point}}</mat-cell>
<mat-cell *matCellDef="let channel" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">{{channel.channel.channel_point}}</mat-cell>
</ng-container>
<ng-container matColumnDef="commit_fee">
<mat-header-cell fxLayoutAlign="end center" *matHeaderCellDef mat-sort-header arrowPosition="before">Commit Fee (Sats) </mat-header-cell>
@ -50,7 +50,7 @@
<mat-table #table [dataSource]="pendingForceClosingChannels" matSort [ngClass]="{'error-border bordered-box': flgLoading[0]==='error','bordered-box': true}">
<ng-container matColumnDef="channel_point">
<mat-header-cell *matHeaderCellDef mat-sort-header> Channel Point </mat-header-cell>
<mat-cell *matCellDef="let channel">{{channel.channel.channel_point}}</mat-cell>
<mat-cell *matCellDef="let channel" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">{{channel.channel.channel_point}}</mat-cell>
</ng-container>
<ng-container matColumnDef="recovered_balance">
<mat-header-cell fxLayoutAlign="end center" *matHeaderCellDef mat-sort-header arrowPosition="before">Recovered Balance (Sats) </mat-header-cell>
@ -91,7 +91,7 @@
[ngClass]="{'error-border bordered-box': flgLoading[0]==='error','bordered-box': true}">
<ng-container matColumnDef="channel_point">
<mat-header-cell class="pl-2" *matHeaderCellDef mat-sort-header> Channel Point </mat-header-cell>
<mat-cell class="pl-2" *matCellDef="let channel">{{channel.channel.channel_point}}</mat-cell>
<mat-cell class="pl-2" *matCellDef="let channel" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">{{channel.channel.channel_point}}</mat-cell>
</ng-container>
<ng-container matColumnDef="local_balance">
<mat-header-cell fxLayoutAlign="end center" *matHeaderCellDef mat-sort-header arrowPosition="before">
@ -138,7 +138,7 @@
[ngClass]="{'error-border bordered-box': flgLoading[0]==='error','bordered-box': true}">
<ng-container matColumnDef="channel_point">
<mat-header-cell class="pl-2" *matHeaderCellDef mat-sort-header> Channel Point </mat-header-cell>
<mat-cell class="pl-2" *matCellDef="let channel">{{channel.channel.channel_point}}</mat-cell>
<mat-cell class="pl-2" *matCellDef="let channel" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">{{channel.channel.channel_point}}</mat-cell>
</ng-container>
<ng-container matColumnDef="limbo_balance">
<mat-header-cell fxLayoutAlign="end center" *matHeaderCellDef mat-sort-header arrowPosition="before">

@ -1,3 +1,10 @@
.mat-column-channel_point {
flex: 1 1 10%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
tr.mat-footer-row td.mat-footer-cell {
border-bottom: none;
}

@ -30,6 +30,7 @@ import * as fromRTLReducer from '../../../store/rtl.reducers';
export class PeersComponent implements OnInit, OnDestroy {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild(MatPaginator, {static: true}) paginator: MatPaginator;
@ViewChild('peersForm', {static: true}) form: any;
public faUsers = faUsers;
public newlyAddedPeer = '';
public flgAnimate = true;
@ -95,6 +96,7 @@ export class PeersComponent implements OnInit, OnDestroy {
).subscribe((setPeers: RTLActions.SetPeers) => {
this.peerAddress = undefined;
this.flgAnimate = true;
this.form.resetForm();
});
}
@ -146,6 +148,7 @@ export class PeersComponent implements OnInit, OnDestroy {
resetData() {
this.peerAddress = '';
this.form.resetForm();
}
onOpenChannel(peerToAddChannel: Peer) {

@ -17,7 +17,7 @@
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" type="submit" tabindex="4">Query Route</button>
</div>
</form>
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-sub-title-container mt-2 mb-1">
<div fxFlex="70">
<fa-icon [icon]="faRoute" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Transaction Route</span>

@ -25,7 +25,7 @@
<span [ngSwitch]="obj.type" class="foreground-secondary-text" fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch">
<ng-container *ngSwitchCase="dataTypeEnum.ARRAY"><span *ngFor="let arrayObj of obj.value" class="display-block w-100">{{arrayObj}}</span></ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.NUMBER">{{obj.value | number:'1.0-3'}}</ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.BOOLEAN">{{obj.value === true ? 'True' : 'False'}}</ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.BOOLEAN">{{obj.value ? 'True' : 'False'}}</ng-container>
<ng-container *ngSwitchDefault>{{obj.value}}</ng-container>
</span>
</span>

@ -11,25 +11,25 @@
<mat-expansion-panel class="flat-expansion-panel">
<mat-expansion-panel-header>
<mat-panel-title>
<span>{{newlyAdded ? '' : 'Open channel with'}}&nbsp;</span><strong class="font-weight-900">{{peer.alias || peer.address}}</strong>&nbsp;{{newlyAdded ? 'added as a peer.' : '.'}}
<span>{{newlyAdded ? '' : 'Open channel with'}}&nbsp;</span><strong class="font-weight-900">{{peer.alias || peer.id}}</strong>&nbsp;{{newlyAdded ? 'added as a peer.' : '.'}}
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Pubkey</h4>
<span class="foreground-secondary-text">{{peer.pub_key}}</span>
<span class="foreground-secondary-text">{{peer.id}}</span>
</div>
</div>
<mat-divider class="w-100 my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Address</h4>
<span class="overflow-wrap foreground-secondary-text">{{peer.address}}</span>
<span class="overflow-wrap foreground-secondary-text">{{peer.netaddr}}</span>
</div>
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Inbound</h4>
<span class="overflow-wrap foreground-secondary-text">{{peer.inbound ? 'True' : 'False'}}</span>
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
<span class="overflow-wrap foreground-secondary-text">{{peer.connected ? 'True' : 'False'}}</span>
</div>
</div>
</div>
@ -46,38 +46,31 @@
Available balance: {{totalBalance | number}} {{information.smaller_currency_unit}}
</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center" class="mt-1">
<mat-form-field fxFlex="60" fxLayoutAlign="start end">
<input matInput [(ngModel)]="fundingAmount" placeholder="Amount" type="number" step="1000" min="1" max="{{totalBalance}}" tabindex="1" required name="amount" #amount="ngModel" nonNegativeAmount="{{totalBalance}}">
<mat-hint>(Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0)}})</mat-hint>
<span matSuffix> {{information?.smaller_currency_unit}} </span>
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
<input matInput [(ngModel)]="fundingAmount" placeholder="Amount" type="number" step="1000" min="1" tabindex="2" required name="amount" #amount="ngModel" nonNegativeAmount="{{totalBalance}}">
<mat-hint>(Wallet Bal: {{totalBalance}}, Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0)}})</mat-hint>
<span matSuffix> {{information?.smaller_currency_unit | titlecase}} </span>
<mat-error *ngIf="!fundingAmount">Amount is required.</mat-error>
<mat-error *ngIf="amount.errors?.negative">Amount must be less than or equal to {{totalBalance}}.</mat-error>
</mat-form-field>
<div fxFlex="35" fxLayoutAlign="start center">
<mat-slide-toggle tabindex="2" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
<div fxFlex="48" fxLayoutAlign="start center">
<mat-slide-toggle tabindex="3" color="primary" [(ngModel)]="isPrivate" name="isPrivate">Private Channel</mat-slide-toggle>
</div>
</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
<mat-form-field fxFlex="30" fxLayoutAlign="start end">
<mat-select tabindex="3" [(value)]="selTransType">
<mat-option *ngFor="let transType of transTypes" [value]="transType.id">
{{transType.name}}
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-select tabindex="4" placeholder="Fee Rate" [(value)]="selFeeRate">
<mat-option *ngFor="let feeRateType of feeRateTypes" [value]="feeRateType.feeRateId">
{{feeRateType.feeRateType}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="30" *ngIf="selTransType=='0'">
<input matInput placeholder="Default" disabled>
</mat-form-field>
<mat-form-field fxFlex="30" *ngIf="selTransType=='1'">
<input matInput [(ngModel)]="transTypeValue.blocks" placeholder="Target Confirmation Blocks" type="number" name="blocks" step="1" min="0" required tabindex="4" #blocks="ngModel">
<mat-error *ngIf="!transTypeValue.blocks">Target confirmation block is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex="30" *ngIf="selTransType=='2'">
<input matInput [(ngModel)]="transTypeValue.fees" placeholder="Fee ({{information?.smaller_currency_unit}}/Byte)" type="number" name="fees" step="1" min="0" required tabindex="5" #fees="ngModel">
<mat-error *ngIf="!transTypeValue.fees">Fee is required.</mat-error>
</mat-form-field>
<div fxFlex="35" fxLayoutAlign="start center">
<mat-slide-toggle tabindex="6" color="primary" [(ngModel)]="spendUnconfirmed" name="spendUnconfirmed">Spend Unconfirmed Output</mat-slide-toggle>
<div fxFlex="48" fxLayout="row" fxLayoutAlign="start center">
<mat-checkbox fxFlex="2" tabindex="5" color="primary" [(ngModel)]="flgMinConf" name="flgMinConf" fxLayoutAlign="stretch start" class="mr-2"></mat-checkbox>
<mat-form-field fxFlex="98">
<input matInput [(ngModel)]="minConfValue" placeholder="Min Confirmation Blocks" type="number" name="blocks" step="1" min="0" tabindex="8" #blocks="ngModel" [required]="flgMinConf" [disabled]="!flgMinConf">
<mat-error *ngIf="flgMinConf && !minConfValue">Min Confirmation Blocks is required.</mat-error>
</mat-form-field>
</div>
</div>
</div>

@ -2,9 +2,9 @@ import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Store } from '@ngrx/store';
import { Peer, GetInfo } from '../../../models/lndModels';
import { OpenChannelAlert } from '../../../models/alertData';
import { TRANS_TYPES } from '../../../services/consts-enums-functions';
import { PeerCL, GetInfoCL } from '../../../models/clModels';
import { CLOpenChannelAlert } from '../../../models/alertData';
import { FEE_RATE_TYPES } from '../../../services/consts-enums-functions';
import * as RTLActions from '../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../store/rtl.reducers';
@ -16,18 +16,20 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
})
export class CLOpenChannelComponent implements OnInit {
public alertTitle: string;
public peer: Peer;
public information: GetInfo;
public totalBalance = 0;
public peer: PeerCL;
public information: GetInfoCL;
public fundingAmount: number;
public myChanPolicy: any = {};
public isPrivate = false;
public selTransType = '0';
public feeRateTypes = FEE_RATE_TYPES;
public totalBalance = 0;
public newlyAdded = false;
public spendUnconfirmed = false;
public transTypeValue = {blocks: '', fees: ''};
public transTypes = TRANS_TYPES;
public selFeeRate = '';
public flgMinConf = false;
public minConfValue = null;
public moreOptions = false;
constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: OpenChannelAlert, private store: Store<fromRTLReducer.RTLState>) { }
constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>) {}
ngOnInit() {
this.peer = this.data.message.peer;
@ -42,25 +44,19 @@ export class CLOpenChannelComponent implements OnInit {
}
resetData() {
this.fundingAmount = null;
this.fundingAmount = 0;
this.moreOptions = false;
this.flgMinConf = false;
this.isPrivate = false;
this.spendUnconfirmed = false;
this.selTransType = '0';
this.transTypeValue = {blocks: '', fees: ''};
this.selFeeRate = '';
this.minConfValue = null;
}
onOpenChannel() {
if (!this.fundingAmount || ((this.totalBalance - this.fundingAmount) < 0) || (this.selTransType === '1' && !this.transTypeValue.blocks) || (this.selTransType === '2' && !this.transTypeValue.fees)) { return true; }
let transTypeValue = '0';
if (this.selTransType === '1') {
transTypeValue = this.transTypeValue.blocks;
} else if (this.selTransType === '2') {
transTypeValue = this.transTypeValue.fees;
}
if (!this.fundingAmount || (this.totalBalance - ((this.fundingAmount) ? this.fundingAmount : 0) < 0)) { return true; }
this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...'));
this.store.dispatch(new RTLActions.SaveNewChannel({
selectedPeerPubkey: this.peer.pub_key, fundingAmount: this.fundingAmount, private: this.isPrivate,
transType: this.selTransType, transTypeValue: transTypeValue, spendUnconfirmed: this.spendUnconfirmed
this.store.dispatch(new RTLActions.SaveNewChannelCL({
peerId: this.peer.id, satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null
}));
this.dialogRef.close(false);
}

@ -1,7 +1,7 @@
import { DataTypeEnum } from '../services/consts-enums-functions';
import { GetInfoRoot } from './RTLconfig';
import { GetInfo, Invoice } from './lndModels';
import { InvoiceCL } from './clModels';
import { InvoiceCL, GetInfoCL } from './clModels';
export interface MessageErrorField {
code: number;
@ -35,6 +35,14 @@ export interface OpenChannelAlert {
component?: any;
}
export interface CLOpenChannelAlert {
alertTitle?: string;
titleMessage?: string;
message?: { peer: any, information: GetInfoCL, balance: number };
newlyAdded?: boolean;
component?: any;
}
export interface InvoiceInformation {
invoice: Invoice;
newlyAdded?: boolean;
@ -93,5 +101,5 @@ export interface ErrorData {
export interface DialogConfig {
width?: string;
data: AlertData | ConfirmationData | ErrorData | OpenChannelAlert | InvoiceInformation | CLInvoiceInformation | OnChainAddressInformation | ShowPubkeyData;
data: AlertData | ConfirmationData | ErrorData | OpenChannelAlert | CLOpenChannelAlert | InvoiceInformation | CLInvoiceInformation | OnChainAddressInformation | ShowPubkeyData;
}

@ -676,7 +676,7 @@ export class SetPeersCL implements Action {
export class SaveNewPeerCL implements Action {
readonly type = SAVE_NEW_PEER_CL;
constructor(public payload: {id: string}) {}
constructor(public payload: {id: string, showOpenChannelModal: boolean}) {}
}
export class AddPeerCL implements Action {

Loading…
Cancel
Save