Closing coin selection on open channel #409 (#423)

Closing coin selection on open channel #409
This commit is contained in:
ShahanaFarooqui 2020-08-14 18:13:55 -04:00 committed by GitHub
parent 1409042275
commit da553bc055
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 74 additions and 40 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -15,5 +15,5 @@
<link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head> <link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.2493904abb92f5d5f622.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.8a5e79e0326ca1db85cb.js" defer></script></body> <script src="runtime.49fb4993ddaaa7d367b3.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.63add4e662e0f112964c.js" defer></script></body>
</html> </html>

File diff suppressed because one or more lines are too long

View file

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

View file

@ -71,7 +71,6 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
filter(action => action.type === CLActions.EFFECT_ERROR_CL || action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL)) filter(action => action.type === CLActions.EFFECT_ERROR_CL || action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL))
.subscribe((action: CLActions.EffectError | CLActions.SetChannelTransactionRes) => { .subscribe((action: CLActions.EffectError | CLActions.SetChannelTransactionRes) => {
if (action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL) { if (action.type === CLActions.SET_CHANNEL_TRANSACTION_RES_CL) {
this.store.dispatch(new CLActions.FetchTransactions());
this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully!')); this.store.dispatch(new RTLActions.OpenSnackBar('Fund Sent Successfully!'));
this.dialogRef.close(); this.dialogRef.close();
} }
@ -121,6 +120,8 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
let utxoNew = {value: 0}; let utxoNew = {value: 0};
if (this.selUTXOs.length && this.selUTXOs.length > 0) { if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => {utxoNew.value = a.value + b.value; return utxoNew;}).value; this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => {utxoNew.value = a.value + b.value; return utxoNew;}).value;
} else {
this.totalSelectedUTXOAmount = 0;
} }
} }

View file

@ -57,7 +57,7 @@ export class CLOnChainTransactionHistoryComponent implements OnInit, OnDestroy {
} }
ngOnInit() { ngOnInit() {
this.store.dispatch(new CLActions.FetchTransactions()); // this.store.dispatch(new CLActions.FetchTransactions());
this.store.select('cl') this.store.select('cl')
.pipe(takeUntil(this.unsub[0])) .pipe(takeUntil(this.unsub[0]))
.subscribe((rtlStore) => { .subscribe((rtlStore) => {

View file

@ -98,6 +98,14 @@
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between center">
<mat-form-field fxFlex="48" fxLayoutAlign="start end">
<mat-select tabindex="6" placeholder="Coin Selection" (selectionChange)="onUTXOSelectionChange($event)" [(value)]="selUTXOs" multiple>
<mat-select-trigger>{{totalSelectedUTXOAmount | number}} Sats ({{selUTXOs.length > 1 ? selUTXOs.length + ' UTXOs' : '1 UTXO'}})</mat-select-trigger>
<mat-option *ngFor="let transaction of transactions" [value]="transaction">{{transaction.value | number}} Sats</mat-option>
</mat-select>
</mat-form-field>
</div>
</div> </div>
</mat-expansion-panel> </mat-expansion-panel>
</form> </form>

View file

@ -1,5 +1,6 @@
import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core'; import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms'; import { FormControl } from '@angular/forms';
import { DecimalPipe } from '@angular/common';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Subject, Observable } from 'rxjs'; import { Subject, Observable } from 'rxjs';
import { takeUntil, filter, startWith, map } from 'rxjs/operators'; import { takeUntil, filter, startWith, map } from 'rxjs/operators';
@ -7,7 +8,7 @@ import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects'; import { Actions } from '@ngrx/effects';
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { Peer, GetInfo } from '../../../../shared/models/clModels'; import { Peer, GetInfo, Transaction } from '../../../../shared/models/clModels';
import { CLOpenChannelAlert } from '../../../../shared/models/alertData'; import { CLOpenChannelAlert } from '../../../../shared/models/alertData';
import { FEE_RATE_TYPES } from '../../../../shared/services/consts-enums-functions'; import { FEE_RATE_TYPES } from '../../../../shared/services/consts-enums-functions';
@ -29,6 +30,9 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
public peers: Peer[]; public peers: Peer[];
public sortedPeers: Peer[]; public sortedPeers: Peer[];
public filteredPeers: Observable<Peer[]>; public filteredPeers: Observable<Peer[]>;
public transactions: Transaction[] = [];
public selUTXOs = [];
public totalSelectedUTXOAmount = 0;
public channelConnectionError = ''; public channelConnectionError = '';
public advancedTitle = 'Advanced Options'; public advancedTitle = 'Advanced Options';
public information: GetInfo; public information: GetInfo;
@ -42,11 +46,12 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
public minConfValue = null; public minConfValue = null;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {} constructor(public dialogRef: MatDialogRef<CLOpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: CLOpenChannelAlert, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions, private decimalPipe: DecimalPipe) {}
ngOnInit() { ngOnInit() {
this.information = this.data.message.information; this.information = this.data.message.information;
this.totalBalance = this.data.message.balance; this.totalBalance = this.data.message.balance;
this.transactions = this.data.message.transactions;
this.alertTitle = this.data.alertTitle; this.alertTitle = this.data.alertTitle;
this.peer = this.data.message.peer ? this.data.message.peer : null; this.peer = this.data.message.peer ? this.data.message.peer : null;
this.peers = this.data.message.peers && this.data.message.peers.length ? this.data.message.peers : []; this.peers = this.data.message.peers && this.data.message.peers.length ? this.data.message.peers : [];
@ -112,18 +117,30 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
onAdvancedPanelToggle(isClosed: boolean) { onAdvancedPanelToggle(isClosed: boolean) {
if (isClosed) { if (isClosed) {
this.advancedTitle = (!this.flgMinConf && !this.selFeeRate) ? 'Advanced Options' : 'Advanced Options | ' + (this.flgMinConf ? 'Min Confirmation Blocks: ' : 'Fee Rate: ') + (this.flgMinConf ? this.minConfValue : (this.selFeeRate ? this.feeRateTypes.find(feeRateType => feeRateType.feeRateId === this.selFeeRate).feeRateType : '')); this.advancedTitle = (!this.flgMinConf && !this.selFeeRate) ? 'Advanced Options' : 'Advanced Options | ' + (this.flgMinConf ? 'Min Confirmation Blocks: ' : 'Fee Rate: ') + (this.flgMinConf ? this.minConfValue : (this.selFeeRate ? this.feeRateTypes.find(feeRateType => feeRateType.feeRateId === this.selFeeRate).feeRateType : '') + ((this.selUTXOs.length && this.selUTXOs.length > 0) ? ' | Selected UTXOs: ' + this.selUTXOs.length + ' | Total Amount: ' + this.decimalPipe.transform(this.totalSelectedUTXOAmount) + ' Sats' : ''));
} else { } else {
this.advancedTitle = 'Advanced Options'; this.advancedTitle = 'Advanced Options';
} }
} }
onUTXOSelectionChange(event: any) {
let utxoNew = {value: 0};
if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs.reduce((a, b) => {utxoNew.value = a.value + b.value; return utxoNew;}).value;
} else {
this.totalSelectedUTXOAmount = 0;
}
}
onOpenChannel() { onOpenChannel() {
if ((!this.peer && !this.selectedPubkey) || (!this.fundingAmount || ((this.totalBalance - this.fundingAmount) < 0) || (this.flgMinConf && !this.minConfValue))) { return true; } if ((!this.peer && !this.selectedPubkey) || (!this.fundingAmount || ((this.totalBalance - this.fundingAmount) < 0) || (this.flgMinConf && !this.minConfValue))) { return true; }
let newChannel = { peerId: ((!this.peer || !this.peer.id) ? this.selectedPubkey : this.peer.id), satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null };
if (this.selUTXOs.length && this.selUTXOs.length > 0) {
newChannel['utxos'] = [];
this.selUTXOs.forEach(utxo => newChannel['utxos'].push(utxo.txid + ':' + utxo.output));
}
this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...')); this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...'));
this.store.dispatch(new CLActions.SaveNewChannel({ this.store.dispatch(new CLActions.SaveNewChannel(newChannel));
peerId: ((!this.peer || !this.peer.id) ? this.selectedPubkey : this.peer.id), satoshis: this.fundingAmount, announce: !this.isPrivate, feeRate: this.selFeeRate, minconf: this.flgMinConf ? this.minConfValue : null
}));
} }
ngOnDestroy() { ngOnDestroy() {

View file

@ -2,12 +2,13 @@ import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs'; import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faUsers, faChartPie } from '@fortawesome/free-solid-svg-icons'; import { faUsers, faChartPie } from '@fortawesome/free-solid-svg-icons';
import { GetInfo, Peer } from '../../shared/models/clModels'; import { GetInfo, Peer, Transaction } from '../../shared/models/clModels';
import { CLOpenChannelComponent } from './channels/open-channel-modal/open-channel.component'; import { CLOpenChannelComponent } from './channels/open-channel-modal/open-channel.component';
import { SelNodeChild } from '../../shared/models/RTLconfig'; import { SelNodeChild } from '../../shared/models/RTLconfig';
import { LoggerService } from '../../shared/services/logger.service';
import { CommonService } from '../../shared/services/common.service';
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';
@ -21,6 +22,7 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
public selNode: SelNodeChild = {}; public selNode: SelNodeChild = {};
public information: GetInfo = {}; public information: GetInfo = {};
public peers: Peer[] = []; public peers: Peer[] = [];
public transactions: Transaction[] = [];
public totalBalance = 0; public totalBalance = 0;
public activePeers = 0; public activePeers = 0;
public activeChannels = 0; public activeChannels = 0;
@ -29,7 +31,7 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
public balances = [{title: 'Total Balance', dataValue: 0}, {title: 'Confirmed', dataValue: 0}, {title: 'Unconfirmed', dataValue: 0}]; public balances = [{title: 'Total Balance', dataValue: 0}, {title: 'Confirmed', dataValue: 0}, {title: 'Unconfirmed', dataValue: 0}];
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(private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {} constructor(private store: Store<fromRTLReducer.RTLState>, private logger: LoggerService, private commonService: CommonService) {}
ngOnInit() { ngOnInit() {
this.store.select('cl') this.store.select('cl')
@ -38,10 +40,12 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
this.selNode = rtlStore.nodeSettings; this.selNode = rtlStore.nodeSettings;
this.information = rtlStore.information; this.information = rtlStore.information;
this.peers = rtlStore.peers; this.peers = rtlStore.peers;
this.transactions = this.commonService.sortAscByKey(rtlStore.transactions.filter(tran => tran.status === 'confirmed'), 'value');
this.activePeers = (rtlStore.peers && rtlStore.peers.length) ? rtlStore.peers.length : 0; this.activePeers = (rtlStore.peers && rtlStore.peers.length) ? rtlStore.peers.length : 0;
this.activeChannels = rtlStore.information.num_active_channels; this.activeChannels = rtlStore.information.num_active_channels;
this.totalBalance = rtlStore.balance.totalBalance; this.totalBalance = rtlStore.balance.totalBalance;
this.balances = [{title: 'Total Balance', dataValue: rtlStore.balance.totalBalance || 0}, {title: 'Confirmed', dataValue: rtlStore.balance.confBalance}, {title: 'Unconfirmed', dataValue: rtlStore.balance.unconfBalance}]; this.balances = [{title: 'Total Balance', dataValue: rtlStore.balance.totalBalance || 0}, {title: 'Confirmed', dataValue: rtlStore.balance.confBalance}, {title: 'Unconfirmed', dataValue: rtlStore.balance.unconfBalance}];
this.logger.info(rtlStore);
}); });
} }
@ -49,7 +53,8 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
const peerToAddChannelMessage = { const peerToAddChannelMessage = {
peers: this.peers, peers: this.peers,
information: this.information, information: this.information,
balance: this.totalBalance balance: this.totalBalance,
transactions: this.transactions
}; };
this.store.dispatch(new RTLActions.OpenAlert({ data: { this.store.dispatch(new RTLActions.OpenAlert({ data: {
alertTitle: 'Open Channel', alertTitle: 'Open Channel',

View file

@ -226,7 +226,7 @@ export class UpdateChannels implements Action {
export class SaveNewChannel implements Action { export class SaveNewChannel implements Action {
readonly type = SAVE_NEW_CHANNEL_CL; readonly type = SAVE_NEW_CHANNEL_CL;
constructor(public payload: {peerId: string, satoshis: number, feeRate: string, announce: boolean, minconf?: number}) {} constructor(public payload: {peerId: string, satoshis: number, feeRate: string, announce: boolean, minconf?: number, utxos?: string[]}) {}
} }
export class CloseChannel implements Action { export class CloseChannel implements Action {

View file

@ -37,7 +37,7 @@ export class CLEffects implements OnDestroy {
this.store.select('cl') this.store.select('cl')
.pipe(takeUntil(this.unSubs[0])) .pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => { .subscribe((rtlStore) => {
if(rtlStore.initialAPIResponseStatus[0] === 'INCOMPLETE' && rtlStore.initialAPIResponseStatus.length > 7) { if(rtlStore.initialAPIResponseStatus[0] === 'INCOMPLETE' && rtlStore.initialAPIResponseStatus.length > 8) {
rtlStore.initialAPIResponseStatus[0] = 'COMPLETE'; rtlStore.initialAPIResponseStatus[0] = 'COMPLETE';
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
} }
@ -279,24 +279,23 @@ export class CLEffects implements OnDestroy {
ofType(CLActions.SAVE_NEW_CHANNEL_CL), ofType(CLActions.SAVE_NEW_CHANNEL_CL),
mergeMap((action: CLActions.SaveNewChannel) => { mergeMap((action: CLActions.SaveNewChannel) => {
this.store.dispatch(new CLActions.ClearEffectError('SaveNewChannel')); this.store.dispatch(new CLActions.ClearEffectError('SaveNewChannel'));
return this.httpClient.post(this.CHILD_API_URL + environment.CHANNELS_API, { let newPayload = {id: action.payload.peerId, satoshis: action.payload.satoshis, feeRate: action.payload.feeRate, announce: action.payload.announce, minconf: (action.payload.minconf) ? action.payload.minconf : null};
id: action.payload.peerId, satoshis: action.payload.satoshis, feeRate: action.payload.feeRate, announce: action.payload.announce, minconf: (action.payload.minconf) ? action.payload.minconf : null if (action.payload.utxos) { newPayload['utxos'] = action.payload.utxos; }
}) return this.httpClient.post(this.CHILD_API_URL + environment.CHANNELS_API, newPayload)
.pipe( .pipe(map((postRes: any) => {
map((postRes: any) => { this.logger.info(postRes);
this.logger.info(postRes); this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenSnackBar('Channel Added Successfully!'));
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Added Successfully!')); this.store.dispatch(new CLActions.FetchBalance());
this.store.dispatch(new CLActions.FetchBalance()); this.store.dispatch(new CLActions.FetchTransactions());
return { return {
type: CLActions.FETCH_CHANNELS_CL type: CLActions.FETCH_CHANNELS_CL
}; };
}), }),
catchError((err: any) => { catchError((err: any) => {
this.handleErrorWithoutAlert('SaveNewChannel', 'Opening Channel Failed.', err); this.handleErrorWithoutAlert('SaveNewChannel', 'Opening Channel Failed.', err);
return of({type: RTLActions.VOID}); return of({type: RTLActions.VOID});
}) }));
);
} }
)); ));
@ -688,6 +687,7 @@ export class CLEffects implements OnDestroy {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new CLActions.FetchBalance()); this.store.dispatch(new CLActions.FetchBalance());
this.store.dispatch(new CLActions.FetchTransactions());
return { return {
type: CLActions.SET_CHANNEL_TRANSACTION_RES_CL, type: CLActions.SET_CHANNEL_TRANSACTION_RES_CL,
payload: postRes payload: postRes
@ -743,6 +743,7 @@ export class CLEffects implements OnDestroy {
this.store.dispatch(new CLActions.FetchFeeRates('perkw')); this.store.dispatch(new CLActions.FetchFeeRates('perkw'));
this.store.dispatch(new CLActions.FetchFeeRates('perkb')); this.store.dispatch(new CLActions.FetchFeeRates('perkb'));
this.store.dispatch(new CLActions.FetchPeers()); this.store.dispatch(new CLActions.FetchPeers());
this.store.dispatch(new CLActions.FetchTransactions());
let newRoute = this.location.path(); let newRoute = this.location.path();
if(newRoute.includes('/lnd/')) { if(newRoute.includes('/lnd/')) {
newRoute = newRoute.replace('/lnd/', '/cl/'); newRoute = newRoute.replace('/lnd/', '/cl/');

View file

@ -175,11 +175,11 @@ export function CLReducer(state = initCLState, action: CLActions.CLActions) {
action.payload.forwarding_events.forEach(event => { action.payload.forwarding_events.forEach(event => {
if (storedChannels && storedChannels.length > 0) { if (storedChannels && storedChannels.length > 0) {
for (let idx = 0; idx < storedChannels.length; idx++) { for (let idx = 0; idx < storedChannels.length; idx++) {
if (storedChannels[idx].short_channel_id === event.in_channel) { if (storedChannels[idx].short_channel_id && storedChannels[idx].short_channel_id === event.in_channel) {
event.in_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : event.in_channel; event.in_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : event.in_channel;
if (event.out_channel_alias) { return; } if (event.out_channel_alias) { return; }
} }
if (storedChannels[idx].short_channel_id.toString() === event.out_channel) { if (storedChannels[idx].short_channel_id && storedChannels[idx].short_channel_id.toString() === event.out_channel) {
event.out_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : event.out_channel; event.out_channel_alias = storedChannels[idx].alias ? storedChannels[idx].alias : event.out_channel;
if (event.in_channel_alias) { return; } if (event.in_channel_alias) { return; }
} }
@ -214,8 +214,10 @@ export function CLReducer(state = initCLState, action: CLActions.CLActions) {
totalInvoices: action.payload totalInvoices: action.payload
}; };
case CLActions.SET_TRANSACTIONS_CL: case CLActions.SET_TRANSACTIONS_CL:
newAPIStatus = [...state.initialAPIResponseStatus, 'TRANSACTIONS'];
return { return {
...state, ...state,
initialAPIResponseStatus: newAPIStatus,
transactions: action.payload transactions: action.payload
}; };
default: default:

View file

@ -1,7 +1,7 @@
import { DataTypeEnum, SwapTypeEnum } from '../services/consts-enums-functions'; import { DataTypeEnum, SwapTypeEnum } from '../services/consts-enums-functions';
import { GetInfoRoot, RTLConfiguration } from './RTLconfig'; import { GetInfoRoot, RTLConfiguration } from './RTLconfig';
import { GetInfo, Invoice, Channel, Peer } from './lndModels'; import { GetInfo, Invoice, Channel, Peer } from './lndModels';
import { Invoice as InvoiceCL, GetInfo as GetInfoCL, Peer as PeerCL, Channel as ChannelCL } from './clModels'; import { Invoice as InvoiceCL, GetInfo as GetInfoCL, Peer as PeerCL, Channel as ChannelCL, Transaction as TransactionCL } from './clModels';
import { GetInfo as GetInfoECL, Peer as PeerECL, Channel as ChannelECL, Invoice as InvoiceECL, PaymentSent as PaymentSentECL } from './eclModels'; import { GetInfo as GetInfoECL, Peer as PeerECL, Channel as ChannelECL, Invoice as InvoiceECL, PaymentSent as PaymentSentECL } from './eclModels';
import { LoopQuote } from './loopModels'; import { LoopQuote } from './loopModels';
@ -44,7 +44,7 @@ export interface OpenChannelAlert {
export interface CLOpenChannelAlert { export interface CLOpenChannelAlert {
alertTitle?: string; alertTitle?: string;
titleMessage?: string; titleMessage?: string;
message?: { information: GetInfoCL, balance: number, peer?: PeerCL, peers?: PeerCL[] }; message?: { information: GetInfoCL, balance: number, transactions: TransactionCL[], peer?: PeerCL, peers?: PeerCL[] };
newlyAdded?: boolean; newlyAdded?: boolean;
component?: any; component?: any;
} }