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>
<body>
<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>

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))
.subscribe((action: CLActions.EffectError | CLActions.SetChannelTransactionRes) => {
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.dialogRef.close();
}
@ -121,6 +120,8 @@ export class CLOnChainSendComponent implements OnInit, OnDestroy {
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;
}
}

View file

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

View file

@ -98,6 +98,14 @@
</mat-form-field>
</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>
</mat-expansion-panel>
</form>

View file

@ -1,5 +1,6 @@
import { Component, OnInit, Inject, OnDestroy, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { DecimalPipe } from '@angular/common';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Subject, Observable } from 'rxjs';
import { takeUntil, filter, startWith, map } from 'rxjs/operators';
@ -7,7 +8,7 @@ import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
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 { FEE_RATE_TYPES } from '../../../../shared/services/consts-enums-functions';
@ -29,6 +30,9 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
public peers: Peer[];
public sortedPeers: Peer[];
public filteredPeers: Observable<Peer[]>;
public transactions: Transaction[] = [];
public selUTXOs = [];
public totalSelectedUTXOAmount = 0;
public channelConnectionError = '';
public advancedTitle = 'Advanced Options';
public information: GetInfo;
@ -42,11 +46,12 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
public minConfValue = null;
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() {
this.information = this.data.message.information;
this.totalBalance = this.data.message.balance;
this.transactions = this.data.message.transactions;
this.alertTitle = this.data.alertTitle;
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 : [];
@ -112,18 +117,30 @@ export class CLOpenChannelComponent implements OnInit, OnDestroy {
onAdvancedPanelToggle(isClosed: boolean) {
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 {
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() {
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 CLActions.SaveNewChannel({
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
}));
this.store.dispatch(new CLActions.SaveNewChannel(newChannel));
}
ngOnDestroy() {

View file

@ -2,12 +2,13 @@ import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
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 { 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 fromRTLReducer from '../../store/rtl.reducers';
@ -21,6 +22,7 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
public selNode: SelNodeChild = {};
public information: GetInfo = {};
public peers: Peer[] = [];
public transactions: Transaction[] = [];
public totalBalance = 0;
public activePeers = 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}];
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() {
this.store.select('cl')
@ -38,10 +40,12 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
this.selNode = rtlStore.nodeSettings;
this.information = rtlStore.information;
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.activeChannels = rtlStore.information.num_active_channels;
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.logger.info(rtlStore);
});
}
@ -49,7 +53,8 @@ export class CLPeersChannelsComponent implements OnInit, OnDestroy {
const peerToAddChannelMessage = {
peers: this.peers,
information: this.information,
balance: this.totalBalance
balance: this.totalBalance,
transactions: this.transactions
};
this.store.dispatch(new RTLActions.OpenAlert({ data: {
alertTitle: 'Open Channel',

View file

@ -226,7 +226,7 @@ export class UpdateChannels implements Action {
export class SaveNewChannel implements Action {
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 {

View file

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

View file

@ -1,7 +1,7 @@
import { DataTypeEnum, SwapTypeEnum } from '../services/consts-enums-functions';
import { GetInfoRoot, RTLConfiguration } from './RTLconfig';
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 { LoopQuote } from './loopModels';
@ -44,7 +44,7 @@ export interface OpenChannelAlert {
export interface CLOpenChannelAlert {
alertTitle?: 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;
component?: any;
}