Set priority on Close channel #233

Set priority on Close channel #233
pull/266/head
Shahana Farooqui 4 years ago
parent 88ad7b250c
commit d8835d2fcc

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -12,5 +12,5 @@
<link rel="stylesheet" href="styles.dc87b0a5f469f6ecc1b4.css"></head> <link rel="stylesheet" href="styles.dc87b0a5f469f6ecc1b4.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.c8822f1c20b7d0adf80c.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.19e9baa2c34b93ea45c9.js" defer></script></body> <script src="runtime.987de13467a4c3a263de.js" defer></script><script src="polyfills-es5.37b2eeccc22c1df73ce7.js" nomodule defer></script><script src="polyfills.f1c3d2a0bcdfc4e93ca8.js" defer></script><script src="main.d1d565730bda0bc69787.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 +1 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=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(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,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:"b78c4146e439be098e08",6:"8aa10e4ae13dec29a6c4",7:"76596f454a7dc11bfa15"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target: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 l=0;l<i.length;l++)r(i[l]);var f=c;t()}([]); !function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=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(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,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:"b78c4146e439be098e08",6:"1cabd441a095f3055cd4",7:"18eeb6e2c81e91aa476c"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target: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 l=0;l<i.length;l++)r(i[l]);var f=c;t()}([]);

@ -193,6 +193,8 @@ exports.closeChannel = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
let channelpoint = req.params.channelPoint.replace(':', '/'); let channelpoint = req.params.channelPoint.replace(':', '/');
options.url = common.getSelLNServerUrl() + '/channels/' + channelpoint + '?force=' + req.query.force; options.url = common.getSelLNServerUrl() + '/channels/' + channelpoint + '?force=' + req.query.force;
if(req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; }
if(req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; }
logger.info({fileName: 'Channels', msg: 'Closing Channel: ' + options.url}); logger.info({fileName: 'Channels', msg: 'Closing Channel: ' + options.url});
request.delete(options).then((body) => { request.delete(options).then((body) => {
logger.info({fileName: 'Channels', msg: 'Close Channel Response: ' + JSON.stringify(body)}); logger.info({fileName: 'Channels', msg: 'Close Channel Response: ' + JSON.stringify(body)});

@ -26,11 +26,6 @@ import { RTLReducer } from './store/rtl.reducers';
import { RTLEffects } from './store/rtl.effects'; import { RTLEffects } from './store/rtl.effects';
import { LNDEffects } from './lnd/store/lnd.effects'; import { LNDEffects } from './lnd/store/lnd.effects';
import { CLEffects } from './clightning/store/cl.effects'; import { CLEffects } from './clightning/store/cl.effects';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatCardModule } from '@angular/material/card';
import { MatMenuModule } from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { LayoutModule } from '@angular/cdk/layout'; import { LayoutModule } from '@angular/cdk/layout';
@NgModule({ @NgModule({
@ -43,11 +38,6 @@ import { LayoutModule } from '@angular/cdk/layout';
StoreModule.forRoot(RTLReducer), StoreModule.forRoot(RTLReducer),
EffectsModule.forRoot([RTLEffects, LNDEffects, CLEffects]), EffectsModule.forRoot([RTLEffects, LNDEffects, CLEffects]),
!environment.production ? StoreDevtoolsModule.instrument() : [], !environment.production ? StoreDevtoolsModule.instrument() : [],
MatGridListModule,
MatCardModule,
MatMenuModule,
MatIconModule,
MatButtonModule,
LayoutModule LayoutModule
], ],
declarations: [ declarations: [

@ -113,6 +113,7 @@ export class CLChannelManageComponent implements OnInit, OnDestroy {
noBtnText: 'Do it Later', noBtnText: 'Do it Later',
yesBtnText: 'Add Peer', yesBtnText: 'Add Peer',
flgShowInput: true, flgShowInput: true,
titleMessage: 'Enter Lightning Address',
getInputs: [ getInputs: [
{placeholder: 'Lightning Address (pubkey OR pubkey@ip:port)', inputType: DataTypeEnum.STRING, inputValue: '', width: 100} {placeholder: 'Lightning Address (pubkey OR pubkey@ip:port)', inputType: DataTypeEnum.STRING, inputValue: '', width: 100}
] ]

@ -115,10 +115,11 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
const confirmationMsg = []; const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM, type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update fee policy for all Channels', alertTitle: 'Update Fee Policy',
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Update All Channels', yesBtnText: 'Update All Channels',
message: confirmationMsg, message: confirmationMsg,
titleMessage: 'Update fee policy for all channels',
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: 1000, width: 48}, {placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: 1000, width: 48},
@ -156,10 +157,10 @@ export class CLChannelOpenTableComponent implements OnInit, OnDestroy {
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM, type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Fee Policy', alertTitle: 'Update Fee Policy',
titleMessage: titleMsg,
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Update Channel', yesBtnText: 'Update Channel',
message: confirmationMsg, message: confirmationMsg,
titleMessage: titleMsg,
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 48}, {placeholder: 'Base Fee (mSats)', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 48},

@ -134,11 +134,11 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM, type: AlertTypeEnum.CONFIRM,
alertTitle: 'Enter Amount and Confirm Send Payment', alertTitle: 'Enter Amount and Confirm Send Payment',
titleMessage: titleMsg,
message: reorderedPaymentDecoded, message: reorderedPaymentDecoded,
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Send Payment', yesBtnText: 'Send Payment',
flgShowInput: true, flgShowInput: true,
titleMessage: titleMsg,
getInputs: [ getInputs: [
{placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: '', width: 30} {placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: '', width: 30}
] ]

@ -85,7 +85,7 @@ import { LNDUnlockedGuard } from '../shared/services/auth.guard';
ChannelStatusInfoComponent, ChannelStatusInfoComponent,
ChannelCapacityInfoComponent, ChannelCapacityInfoComponent,
ChannelLiquidityInfoComponent, ChannelLiquidityInfoComponent,
NetworkInfoComponent NetworkInfoComponent,
], ],
providers: [ providers: [
LNDUnlockedGuard LNDUnlockedGuard

@ -124,7 +124,7 @@ export class OnChainSendComponent implements OnInit, OnDestroy {
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Authorize And Sweep All', yesBtnText: 'Authorize And Sweep All',
flgShowInput: true, flgShowInput: true,
getInputs: [{placeholder: 'Enter Login Password', inputType: 'password', inputValue: '', width: 30}] getInputs: [{placeholder: 'Enter Login Password', inputType: 'password', inputValue: '', width: 100}]
}})); }}));
} else { } else {
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {

@ -116,6 +116,7 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
message: '', message: '',
noBtnText: 'Do it Later', noBtnText: 'Do it Later',
yesBtnText: 'Add Peer', yesBtnText: 'Add Peer',
titleMessage: 'Enter Lightning Address',
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{placeholder: 'Lightning Address (pubkey OR pubkey@ip:port)', inputType: DataTypeEnum.STRING, inputValue: '', width: 100} {placeholder: 'Lightning Address (pubkey OR pubkey@ip:port)', inputType: DataTypeEnum.STRING, inputValue: '', width: 100}

@ -15,6 +15,7 @@ import { LNDEffects } from '../../../../store/lnd.effects';
import { RTLEffects } from '../../../../../store/rtl.effects'; import { RTLEffects } from '../../../../../store/rtl.effects';
import * as RTLActions from '../../../../../store/rtl.actions'; import * as RTLActions from '../../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../../store/rtl.reducers'; import * as fromRTLReducer from '../../../../../store/rtl.reducers';
import { CloseChannelLndComponent } from '../../../../../shared/components/data-modal/close-channel-lnd/close-channel-lnd.component';
@Component({ @Component({
selector: 'rtl-channel-open-table', selector: 'rtl-channel-open-table',
@ -116,10 +117,11 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
const confirmationMsg = []; const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM, type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update fee policy for all Channels', alertTitle: 'Update Fee Policy',
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Update All Channels', yesBtnText: 'Update All Channels',
message: confirmationMsg, message: confirmationMsg,
titleMessage: 'Update fee policy for all channels',
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1000, width: 32}, {placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1000, width: 32},
@ -187,21 +189,10 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
} }
onChannelClose(channelToClose: Channel) { onChannelClose(channelToClose: Channel) {
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenAlert({width: '70%', data: {
type: AlertTypeEnum.CONFIRM, channel: channelToClose,
alertTitle: 'Close Channel', component: CloseChannelLndComponent
titleMessage: 'Closing channel: ' + channelToClose.channel_point, }}));
noBtnText: 'Cancel',
yesBtnText: 'Close Channel'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[4]))
.subscribe(confirmRes => {
if (confirmRes) {
this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...'));
this.store.dispatch(new RTLActions.CloseChannel({channelPoint: channelToClose.channel_point, forcibly: !channelToClose.active}));
}
});
} }
applyFilter() { applyFilter() {

@ -286,7 +286,10 @@ export class LNDEffects implements OnDestroy {
closeChannel = this.actions$.pipe( closeChannel = this.actions$.pipe(
ofType(RTLActions.CLOSE_CHANNEL), ofType(RTLActions.CLOSE_CHANNEL),
mergeMap((action: RTLActions.CloseChannel) => { mergeMap((action: RTLActions.CloseChannel) => {
return this.httpClient.delete(this.CHILD_API_URL + environment.CHANNELS_API + '/' + action.payload.channelPoint + '?force=' + action.payload.forcibly) let reqUrl = this.CHILD_API_URL + environment.CHANNELS_API + '/' + action.payload.channelPoint + '?force=' + action.payload.forcibly;
if(action.payload.targetConf) { reqUrl = reqUrl + '&target_conf=' + action.payload.targetConf; }
if(action.payload.satPerByte) { reqUrl = reqUrl + '&sat_per_byte=' + action.payload.satPerByte; }
return this.httpClient.delete(reqUrl)
.pipe( .pipe(
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);

@ -5,34 +5,36 @@
<button tabindex="7" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button> <button tabindex="7" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
</mat-card-header> </mat-card-header>
<mat-card-content class="mt-5px"> <mat-card-content class="mt-5px">
<p fxLayoutAlign="start center" class="pb-1">Rebalancing for Channel: {{selChannel.chan_id}}</p>
<form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="space-between stretch" #form="ngForm"> <form fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign="space-between stretch" #form="ngForm">
<div fxLayout="column" fxLayout.gt-sm="row wrap" fxFlex="100" fxLayoutAlign="space-between stretch"> <div fxLayout="column" class="bordered-box p-2">
<mat-form-field fxFlex="30"> <p fxLayoutAlign="start center" class="pb-1">Rebalancing for Channel: {{selChannel.chan_id}}</p>
<input autoFocus matInput [(ngModel)]="rebalanceAmount" (change)="filterActiveChannels()" placeholder="Amount" type="number" step="100" min="1" tabindex="1" required name="amount" #amount="ngModel" max="{{selChannel?.local_balance}}"> <div fxLayout="column" fxLayout.gt-sm="row wrap" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-hint>(Local Bal: {{selChannel?.local_balance}}, Remaining: {{selChannel?.local_balance - ((rebalanceAmount) ? rebalanceAmount : 0)}})</mat-hint> <mat-form-field fxFlex="30">
<span matSuffix>Sats</span> <input autoFocus matInput [(ngModel)]="rebalanceAmount" (change)="filterActiveChannels()" placeholder="Amount" type="number" step="100" min="1" tabindex="1" required name="amount" #amount="ngModel" max="{{selChannel?.local_balance}}">
<mat-error *ngIf="!rebalanceAmount">Amount is required.</mat-error> <mat-hint>(Local Bal: {{selChannel?.local_balance}}, Remaining: {{selChannel?.local_balance - ((rebalanceAmount) ? rebalanceAmount : 0)}})</mat-hint>
<mat-error *ngIf="amount.errors?.max">Amount must be less than or equal to {{selChannel?.local_balance}}.</mat-error> <span matSuffix>Sats</span>
</mat-form-field> <mat-error *ngIf="!rebalanceAmount">Amount is required.</mat-error>
<mat-form-field fxFlex="30" fxLayoutAlign="start end"> <mat-error *ngIf="amount.errors?.max">Amount must be less than or equal to {{selChannel?.local_balance}}.</mat-error>
<mat-select tabindex="2" [(value)]="selRebalancePeer" placeholder="Rebalancing Channel"> </mat-form-field>
<mat-option *ngFor="let activeChannel of activeChannels" [value]="activeChannel"> <mat-form-field fxFlex="30" fxLayoutAlign="start end">
{{activeChannel.remote_alias || activeChannel.chan_id}} <mat-select tabindex="2" [(value)]="selRebalancePeer" placeholder="Rebalancing Channel">
</mat-option> <mat-option *ngFor="let activeChannel of activeChannels" [value]="activeChannel">
</mat-select> {{activeChannel.remote_alias || activeChannel.chan_id}}
</mat-form-field> </mat-option>
<mat-form-field fxFlex="15" fxLayoutAlign="start end"> </mat-select>
<mat-select tabindex="3" [(value)]="selFeeLimitType" Placeholder="Fee Limits" required> </mat-form-field>
<mat-option *ngFor="let feeLimitType of feeLimitTypes" [value]="feeLimitType"> <mat-form-field fxFlex="15" fxLayoutAlign="start end">
{{feeLimitType.name}} <mat-select tabindex="3" [(value)]="selFeeLimitType" Placeholder="Fee Limits" required>
</mat-option> <mat-option *ngFor="let feeLimitType of feeLimitTypes" [value]="feeLimitType">
</mat-select> {{feeLimitType.name}}
</mat-form-field> </mat-option>
<mat-form-field fxFlex="20"> </mat-select>
<input matInput [(ngModel)]="feeLimit" [placeholder]="selFeeLimitType.placeholder" type="number" name="feeLimit" step="1" min="0" required tabindex="4" #feeLmt="ngModel"> </mat-form-field>
<mat-error *ngIf="!feeLimit">{{selFeeLimitType.placeholder}} is required.</mat-error> <mat-form-field fxFlex="20">
</mat-form-field> <input matInput [(ngModel)]="feeLimit" [placeholder]="selFeeLimitType?.placeholder" type="number" name="feeLimit" step="1" min="0" required tabindex="4" #feeLmt="ngModel">
<mat-error *ngIf="!feeLimit">{{selFeeLimitType?.placeholder}} is required.</mat-error>
</mat-form-field>
</div>
</div> </div>
<div class="mt-2" fxLayout="row" fxLayoutAlign="end center" fxFlex="100"> <div class="mt-2" fxLayout="row" fxLayoutAlign="end center" fxFlex="100">
<button fxFlex="48" fxFlex.gt-sm="20" fxLayoutAlign="center center" mat-stroked-button class="mr-2" color="primary" tabindex="5" type="reset" (click)="resetData()">Clear Field</button> <button fxFlex="48" fxFlex.gt-sm="20" fxLayoutAlign="center center" mat-stroked-button class="mr-2" color="primary" tabindex="5" type="reset" (click)="resetData()">Clear Field</button>

@ -5,7 +5,7 @@ import { takeUntil, filter } from 'rxjs/operators';
import { Actions } from '@ngrx/effects'; import { Actions } from '@ngrx/effects';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { ChannelRebalanceInformation } from '../../../models/alertData'; import { ChannelInformation } from '../../../models/alertData';
import { LoggerService } from '../../../services/logger.service'; import { LoggerService } from '../../../services/logger.service';
import { Channel } from '../../../models/lndModels'; import { Channel } from '../../../models/lndModels';
import { FEE_LIMIT_TYPES, PAGE_SIZE } from '../../../services/consts-enums-functions'; import { FEE_LIMIT_TYPES, PAGE_SIZE } from '../../../services/consts-enums-functions';
@ -25,13 +25,19 @@ export class ChannelRebalanceComponent implements OnInit, OnDestroy {
public selRebalancePeer: Channel = {}; public selRebalancePeer: Channel = {};
public activeChannels = []; public activeChannels = [];
public feeLimit = null; public feeLimit = null;
public selFeeLimitType = FEE_LIMIT_TYPES[1]; public selFeeLimitType = {id:'', name: '', placeholder: ''};
public feeLimitTypes = FEE_LIMIT_TYPES.splice(1); public feeLimitTypes = [];
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(public dialogRef: MatDialogRef<ChannelRebalanceComponent>, @Inject(MAT_DIALOG_DATA) public data: ChannelRebalanceInformation, private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) { } constructor(public dialogRef: MatDialogRef<ChannelRebalanceComponent>, @Inject(MAT_DIALOG_DATA) public data: ChannelInformation, private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) { }
ngOnInit() { ngOnInit() {
FEE_LIMIT_TYPES.forEach((FEE_LIMIT_TYPE, i) => {
if(i > 0) {
this.feeLimitTypes.push(FEE_LIMIT_TYPE);
}
});
this.selFeeLimitType = this.feeLimitTypes[0];
this.selChannel = this.data.channel; this.selChannel = this.data.channel;
this.store.select('lnd') this.store.select('lnd')
.pipe(takeUntil(this.unSubs[0])) .pipe(takeUntil(this.unSubs[0]))

@ -0,0 +1,43 @@
<div fxLayout="row">
<div fxFlex="100" class="padding-gap-large">
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
<div fxFlex="95" fxLayoutAlign="start start">
<span class="page-title">Close Channel</span>
</div>
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
</mat-card-header>
<mat-card-content class="mt-5px">
<form fxLayout="column">
<div fxLayout="column" class="bordered-box my-2 p-2">
<p fxLayoutAlign="start center" class="pb-1">Closing channel: {{channelToClose.channel_point}}</p>
<div fxLayoutAlign="space-between center">
<mat-form-field fxFlex.gt-sm="48">
<mat-select [(value)]="selTransType" tabindex="1">
<mat-option *ngFor="let transType of transTypes" [value]="transType.id">
{{transType.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="48" *ngIf="selTransType=='0'">
<input matInput placeholder="Default" disabled>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='1'">
<input matInput [(ngModel)]="blocks" placeholder="Number of Blocks" type="number" name="blocks" step="1"
min="0" required tabindex="2" #blcks="ngModel">
<mat-error *ngIf="!blocks">Number of blocks is required.</mat-error>
</mat-form-field>
<mat-form-field fxFlex.gt-sm="48" fxLayoutAlign="start end" *ngIf="selTransType=='2'">
<input matInput [(ngModel)]="fees" placeholder="Fees (Sats/Byte)"
type="number" name="fees" step="1" min="0" required tabindex="3" #fee="ngModel">
<mat-error *ngIf="!fees">Fees is required.</mat-error>
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="end center">
<button mat-stroked-button color="primary" fxFlex="48" fxFlex.gt-sm="20" type="reset" fxLayoutAlign="center center" class="mr-2" (click)="resetData()" tabindex="2" default>Clear</button>
<button mat-flat-button color="primary" fxLayoutAlign="center center" fxFlex="48" fxFlex.gt-sm="25" type="submit" tabindex="4" (click)="onCloseChannel()">Close Channel</button>
</div>
</form>
</mat-card-content>
</div>
</div>

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

@ -0,0 +1,49 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Store } from '@ngrx/store';
import { Channel } from '../../../models/lndModels';
import { ChannelInformation } from '../../../models/alertData';
import { TRANS_TYPES } from '../../../services/consts-enums-functions';
import * as RTLActions from '../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../store/rtl.reducers';
@Component({
selector: 'rtl-close-channel-lnd',
templateUrl: './close-channel-lnd.component.html',
styleUrls: ['./close-channel-lnd.component.scss']
})
export class CloseChannelLndComponent implements OnInit {
public channelToClose: Channel;
public transTypes = TRANS_TYPES;
public selTransType = '0';
public blocks = null;
public fees = null;
constructor(public dialogRef: MatDialogRef<CloseChannelLndComponent>, @Inject(MAT_DIALOG_DATA) public data: ChannelInformation, private store: Store<fromRTLReducer.RTLState>) {}
ngOnInit() {
this.channelToClose = this.data.channel;
}
onCloseChannel() {
if ((this.selTransType === '1' && (!this.blocks || this.blocks === 0)) || (this.selTransType === '2' && (!this.fees || this.fees === 0))) { return true; }
let closeChannelParams: any = { channelPoint: this.channelToClose.channel_point, forcibly: !this.channelToClose.active };
if (this.blocks) { closeChannelParams.targetConf = this.blocks; }
if (this.fees) { closeChannelParams.satPerByte = this.fees; }
this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...'));
this.store.dispatch(new RTLActions.CloseChannel(closeChannelParams));
this.dialogRef.close(false);
}
resetData() {
this.selTransType = '0';
this.blocks = null;
this.fees = null;
}
onClose() {
this.dialogRef.close(false);
}
}

@ -8,13 +8,7 @@
</mat-card-header> </mat-card-header>
<mat-card-content class="mt-5px"> <mat-card-content class="mt-5px">
<form fxLayout="column"> <form fxLayout="column">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p> <p *ngIf="data.titleMessage && !flgShowInput" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<div *ngIf="flgShowInput" fxLayoutAlign="space-between center" class="mb-2">
<mat-form-field *ngFor="let getInput of getInputs; index as i" [fxFlex]="getInput.width">
<input matInput [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [step]="getInput.step" [type]="getInput.inputType | lowercase" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required>
<mat-error *ngIf="!getInput.inputValue">{{getInput.placeholder}} is required.</mat-error>
</mat-form-field>
</div>
<div *ngIf="messageObjs?.length>0"> <div *ngIf="messageObjs?.length>0">
<div *ngFor="let objs of messageObjs; index as i;"> <div *ngFor="let objs of messageObjs; index as i;">
<div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutAlign.gt-md="space-between start"> <div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutAlign.gt-md="space-between start">
@ -36,8 +30,18 @@
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="flgShowInput" fxLayout="column" class="bordered-box my-2 p-2">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<div fxLayoutAlign="space-between center">
<mat-form-field *ngFor="let getInput of getInputs; index as i" [fxFlex]="getInput.width">
<input *ngIf="i === 0" autoFocus matInput [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [step]="getInput.step" [type]="getInput.inputType | lowercase" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required>
<input *ngIf="i !== 0" matInput [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [step]="getInput.step" [type]="getInput.inputType | lowercase" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required>
<mat-error *ngIf="!getInput.inputValue">{{getInput.placeholder}} is required.</mat-error>
</mat-form-field>
</div>
</div>
<div fxLayout="row" fxLayoutAlign="end center"> <div fxLayout="row" fxLayoutAlign="end center">
<button autoFocus mat-stroked-button color="primary" fxFlex="48" fxFlex.gt-sm="20" type="reset" fxLayoutAlign="center center" class="mr-2" (click)="onClose(false)" tabindex="2" default>{{noBtnText}}</button> <button mat-stroked-button color="primary" fxFlex="48" fxFlex.gt-sm="20" type="reset" fxLayoutAlign="center center" class="mr-2" (click)="onClose(false)" tabindex="2" default>{{noBtnText}}</button>
<button *ngIf="flgShowInput" mat-flat-button color="primary" fxLayoutAlign="center center" fxFlex="48" fxFlex.gt-sm="25" type="submit" tabindex="3" (click)="onClose(getInputs)">{{yesBtnText}}</button> <button *ngIf="flgShowInput" mat-flat-button color="primary" fxLayoutAlign="center center" fxFlex="48" fxFlex.gt-sm="25" type="submit" tabindex="3" (click)="onClose(getInputs)">{{yesBtnText}}</button>
<button *ngIf="!flgShowInput" mat-flat-button color="primary" fxLayoutAlign="center center" fxFlex="48" fxFlex.gt-sm="25" type="submit" tabindex="4" (click)="onClose(true)">{{yesBtnText}}</button> <button *ngIf="!flgShowInput" mat-flat-button color="primary" fxLayoutAlign="center center" fxFlex="48" fxFlex.gt-sm="25" type="submit" tabindex="4" (click)="onClose(true)">{{yesBtnText}}</button>
</div> </div>

@ -29,11 +29,11 @@ export class ConfirmationMessageComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.flgShowInput = this.data.flgShowInput; this.flgShowInput = this.data.flgShowInput;
this.getInputs = this.data.getInputs; this.getInputs = this.data.getInputs;
this.noBtnText = (undefined !== this.data.noBtnText) ? this.data.noBtnText : 'No'; this.noBtnText = (this.data.noBtnText) ? this.data.noBtnText : 'No';
this.yesBtnText = (undefined !== this.data.yesBtnText) ? this.data.yesBtnText : 'Yes'; this.yesBtnText = (this.data.yesBtnText) ? this.data.yesBtnText : 'Yes';
this.messageObjs = this.data.message; this.messageObjs = this.data.message;
if (this.data.type === AlertTypeEnum.ERROR) { if (this.data.type === AlertTypeEnum.ERROR) {
if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjs.length <= 0) { if (!this.data.message && !this.data.titleMessage && this.messageObjs.length <= 0) {
this.data.titleMessage = 'Please Check Server Connection'; this.data.titleMessage = 'Please Check Server Connection';
} }
} }

@ -55,7 +55,7 @@ export interface CLInvoiceInformation {
component?: any; component?: any;
} }
export interface ChannelRebalanceInformation { export interface ChannelInformation {
channel: Invoice; channel: Invoice;
component?: any; component?: any;
} }
@ -106,5 +106,5 @@ export interface ErrorData {
export interface DialogConfig { export interface DialogConfig {
width?: string; width?: string;
data: AlertData | ConfirmationData | ErrorData | OpenChannelAlert | CLOpenChannelAlert | InvoiceInformation | CLInvoiceInformation | ChannelRebalanceInformation | OnChainAddressInformation | ShowPubkeyData; data: AlertData | ConfirmationData | ErrorData | OpenChannelAlert | CLOpenChannelAlert | InvoiceInformation | CLInvoiceInformation | ChannelInformation | OnChainAddressInformation | ShowPubkeyData;
} }

@ -53,6 +53,7 @@ import { MinValidator } from './directive/min-amount.directive';
import { RemoveLeadingZerosPipe } from './pipes/app.pipe'; import { RemoveLeadingZerosPipe } from './pipes/app.pipe';
import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.service'; import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.service';
import { CloseChannelLndComponent } from './components/data-modal/close-channel-lnd/close-channel-lnd.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -187,7 +188,8 @@ import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.s
CLOpenChannelComponent, CLOpenChannelComponent,
OpenChannelComponent, OpenChannelComponent,
ShowPubkeyComponent, ShowPubkeyComponent,
AuthSettingsComponent AuthSettingsComponent,
CloseChannelLndComponent
], ],
entryComponents: [ entryComponents: [
CLInvoiceInformationComponent, CLInvoiceInformationComponent,
@ -200,7 +202,8 @@ import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.s
SpinnerDialogComponent, SpinnerDialogComponent,
AlertMessageComponent, AlertMessageComponent,
ConfirmationMessageComponent, ConfirmationMessageComponent,
ErrorMessageComponent ErrorMessageComponent,
CloseChannelLndComponent
], ],
providers: [ providers: [
{ provide: LoggerService, useClass: ConsoleLoggerService }, { provide: LoggerService, useClass: ConsoleLoggerService },

@ -395,7 +395,7 @@ export class SaveNewChannel implements Action {
export class CloseChannel implements Action { export class CloseChannel implements Action {
readonly type = CLOSE_CHANNEL; readonly type = CLOSE_CHANNEL;
constructor(public payload: {channelPoint: string, forcibly: boolean}) {} constructor(public payload: {channelPoint: string, forcibly: boolean, targetConf?: number, satPerByte?: number}) {}
} }
export class RemoveChannel implements Action { export class RemoveChannel implements Action {

Loading…
Cancel
Save