import { Injectable , OnDestroy } from '@angular/core' ;
import { HttpClient } from '@angular/common/http' ;
import { Router } from '@angular/router' ;
import { Store } from '@ngrx/store' ;
import { Actions , Effect , ofType } from '@ngrx/effects' ;
import { of , Subject } from 'rxjs' ;
import { map , mergeMap , catchError , withLatestFrom , takeUntil } from 'rxjs/operators' ;
import { Location } from '@angular/common' ;
import { MatDialog } from '@angular/material' ;
import { environment , API_URL } from '../../../environments/environment' ;
import { LoggerService } from '../../shared/services/logger.service' ;
import { CommonService } from '../../shared/services/common.service' ;
import { SessionService } from '../../shared/services/session.service' ;
import { GetInfo , GetInfoChain , Fees , Balance , NetworkInfo , Payment , GraphNode , Transaction , SwitchReq , ListInvoices , PendingChannelsGroup } from '../../shared/models/lndModels' ;
import { InvoiceInformationComponent } from '../../shared/components/data-modal/invoice-information-lnd/invoice-information.component' ;
import { OpenChannelComponent } from '../../shared/components/data-modal/open-channel-lnd/open-channel.component' ;
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component' ;
import { CurrencyUnitEnum , AlertTypeEnum , FEE_LIMIT_TYPES , PAGE_SIZE } from '../../shared/services/consts-enums-functions' ;
import * as RTLActions from '../../store/rtl.actions' ;
import * as fromRTLReducer from '../../store/rtl.reducers' ;
import * as fromLNDReducers from '../store/lnd.reducers' ;
@Injectable ( )
export class LNDEffects implements OnDestroy {
dialogRef : any ;
CHILD_API_URL = API_URL + '/lnd' ;
private unSubs : Array < Subject < void > > = [ new Subject ( ) , new Subject ( ) ] ;
constructor (
private actions$ : Actions ,
private httpClient : HttpClient ,
private store : Store < fromRTLReducer.RTLState > ,
private logger : LoggerService ,
private commonService : CommonService ,
private sessionService : SessionService ,
public dialog : MatDialog ,
private router : Router ,
private location : Location ) { }
@Effect ( )
infoFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_INFO ) ,
withLatestFrom ( this . store . select ( 'root' ) ) ,
mergeMap ( ( [ action , store ] : [ RTLActions . FetchInfo , fromRTLReducer . RootState ] ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchInfo' ) ) ;
return this . httpClient . get < GetInfo > ( this . CHILD_API_URL + environment . GETINFO_API )
. pipe (
takeUntil ( this . actions $ . pipe ( ofType ( RTLActions . SET_SELECTED_NODE ) ) ) ,
map ( ( info ) = > {
this . logger . info ( info ) ;
if ( undefined === info . identity_pubkey ) {
this . sessionService . removeItem ( 'lndUnlocked' ) ;
this . logger . info ( 'Redirecting to Unlock' ) ;
this . router . navigate ( [ '/lnd/wallet' ] ) ;
return {
type : RTLActions . SET_INFO ,
payload : { }
} ;
} else {
info . lnImplementation = 'LND' ;
this . initializeRemainingData ( info , action . payload . loadPage ) ;
return {
type : RTLActions . SET_INFO ,
payload : info ? info : { }
} ;
}
} ) ,
catchError ( ( err ) = > {
if ( ( typeof err . error . error === 'string' && err . error . error . includes ( 'Not Found' ) ) || err . status === 502 ) {
this . sessionService . removeItem ( 'lndUnlocked' ) ;
this . logger . info ( 'Redirecting to Unlock' ) ;
this . router . navigate ( [ '/lnd/wallet' ] ) ;
this . handleErrorWithoutAlert ( 'FetchInfo' , err ) ;
} else {
let code = err . status ? err . status : '' ;
let message = err . error . message ? err . error . message + ' ' : '' ;
if ( err . error && err . error . error ) {
if ( err . error . error . code ) {
code = err . error . error . code ;
} else if ( err . error . error . message && err . error . error . message . code ) {
code = err . error . error . message . code ;
}
if ( typeof err . error . error === 'string' ) {
message = message + err . error . error ;
} else if ( err . error . error . error ) {
message = message + err . error . error . error ;
} else if ( err . error . error . errno ) {
message = message + err . error . error . errno ;
}
}
this . router . navigate ( [ '/error' ] , { state : { errorCode : code , errorMessage : message } } ) ;
this . handleErrorWithoutAlert ( 'FetchInfo' , err ) ;
}
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
peersFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_PEERS ) ,
mergeMap ( ( action : RTLActions.FetchPeers ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchPeers' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . PEERS_API )
. pipe (
map ( ( peers : any ) = > {
this . logger . info ( peers ) ;
return {
type : RTLActions . SET_PEERS ,
payload : peers ? peers : [ ]
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchPeers' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
saveNewPeer = this . actions $ . pipe (
ofType ( RTLActions . SAVE_NEW_PEER ) ,
withLatestFrom ( this . store . select ( 'lnd' ) ) ,
mergeMap ( ( [ action , lndData ] : [ RTLActions . SaveNewPeer , fromLNDReducers . LNDState ] ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . PEERS_API , { pubkey : action.payload.pubkey , host : action.payload.host , perm : action.payload.perm } )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . SetPeers ( ( postRes && postRes . length > 0 ) ? postRes : [ ] ) ) ;
if ( action . payload . showOpenChannelModal ) {
const peerToAddChannelMessage = {
peer : postRes [ 0 ] ,
information : lndData.information ,
balance : lndData.blockchainBalance.total_balance || 0
} ;
return {
type : RTLActions . OPEN_ALERT ,
payload : { width : '50%' , data : {
type : AlertTypeEnum . INFORMATION ,
alertTitle : 'Peer Connected' ,
message : peerToAddChannelMessage ,
newlyAdded : true ,
component : OpenChannelComponent
} }
} ;
} else {
return {
type : RTLActions . VOID
}
}
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Add Peer Failed' , this . CHILD_API_URL + environment . PEERS_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
detachPeer = this . actions $ . pipe (
ofType ( RTLActions . DETACH_PEER ) ,
mergeMap ( ( action : RTLActions.DetachPeer ) = > {
return this . httpClient . delete ( this . CHILD_API_URL + environment . PEERS_API + '/' + action . payload . pubkey )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenSnackBar ( 'Peer Disconnected Successfully.' ) ) ;
return {
type : RTLActions . REMOVE_PEER ,
payload : { pubkey : action.payload.pubkey }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Unable to Detach Peer. Try again later.' , this . CHILD_API_URL + environment . PEERS_API + '/' + action . payload . pubkey , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
saveNewInvoice = this . actions $ . pipe (
ofType ( RTLActions . SAVE_NEW_INVOICE ) ,
mergeMap ( ( action : RTLActions.SaveNewInvoice ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . INVOICES_API , {
memo : action.payload.memo , amount : action.payload.invoiceValue , private : action . payload . private , expiry : action.payload.expiry
} )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . FetchInvoices ( { num_max_invoices : action.payload.pageSize , reversed : true } ) ) ;
postRes . memo = action . payload . memo ;
postRes . value = action . payload . invoiceValue ;
postRes . expiry = action . payload . expiry ;
postRes . cltv_expiry = '144' ;
postRes . private = action . payload . private ;
postRes . creation_date = Math . round ( new Date ( ) . getTime ( ) / 1000 ) . toString ( ) ;
postRes . creation_date_str = this . commonService . convertTimestampToDate ( + postRes . creation_date ) ;
if ( action . payload . openModal ) {
return {
type : RTLActions . OPEN_ALERT ,
payload : { data : {
invoice : postRes ,
newlyAdded : true ,
component : InvoiceInformationComponent
} }
}
} else {
return {
type : RTLActions . NEWLY_SAVED_INVOICE ,
payload : { paymentRequest : postRes.payment_request }
}
}
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Add Invoice Failed' , this . CHILD_API_URL + environment . INVOICES_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
openNewChannel = this . actions $ . pipe (
ofType ( RTLActions . SAVE_NEW_CHANNEL ) ,
mergeMap ( ( action : RTLActions.SaveNewChannel ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . CHANNELS_API , {
node_pubkey : action.payload.selectedPeerPubkey , local_funding_amount : action.payload.fundingAmount , private : action . payload . private ,
trans_type : action.payload.transType , trans_type_value : action.payload.transTypeValue , spend_unconfirmed : action.payload.spendUnconfirmed
} )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'blockchain' ) ) ;
this . store . dispatch ( new RTLActions . FetchAllChannels ( ) ) ;
this . store . dispatch ( new RTLActions . BackupChannels ( { channelPoint : 'ALL' , showMessage : 'Channel Added Successfully!' } ) ) ;
return {
type : RTLActions . FETCH_PENDING_CHANNELS
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Open Channel Failed' , this . CHILD_API_URL + environment . CHANNELS_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
updateChannel = this . actions $ . pipe (
ofType ( RTLActions . UPDATE_CHANNELS ) ,
mergeMap ( ( action : RTLActions.UpdateChannels ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . CHANNELS_API + '/chanPolicy' ,
{ baseFeeMsat : action.payload.baseFeeMsat , feeRate : action.payload.feeRate , timeLockDelta : action.payload.timeLockDelta , chanPoint : action.payload.chanPoint } )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
if ( action . payload . chanPoint === '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_ALL_CHANNELS
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Update Channel Failed' , this . CHILD_API_URL + environment . CHANNELS_API + '/chanPolicy' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
closeChannel = this . actions $ . pipe (
ofType ( RTLActions . CLOSE_CHANNEL ) ,
mergeMap ( ( action : RTLActions.CloseChannel ) = > {
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 (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'channels' ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'blockchain' ) ) ;
this . store . dispatch ( new RTLActions . FetchAllChannels ( ) ) ;
if ( action . payload . forcibly ) {
this . store . dispatch ( new RTLActions . FetchPendingChannels ( ) ) ;
} else {
this . store . dispatch ( new RTLActions . FetchClosedChannels ( ) ) ;
}
this . store . dispatch ( new RTLActions . BackupChannels ( { channelPoint : 'ALL' , showMessage : 'Channel Closed Successfully!' } ) ) ;
return {
type : RTLActions . REMOVE_CHANNEL ,
payload : { channelPoint : action.payload.channelPoint }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Unable to Close Channel. Try again later.' , this . CHILD_API_URL + environment . CHANNELS_API + '/' + action . payload . channelPoint + '?force=' + action . payload . forcibly , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
backupChannels = this . actions $ . pipe (
ofType ( RTLActions . BACKUP_CHANNELS ) ,
mergeMap ( ( action : RTLActions.BackupChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'BackupChannels' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/' + action . payload . channelPoint )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenSnackBar ( action . payload . showMessage + ' ' + postRes . message ) ) ;
return {
type : RTLActions . BACKUP_CHANNELS_RES ,
payload : postRes.message
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'BackupChannels' , code : err.status , message : err.error.error } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , action . payload . showMessage + ' ' + 'Unable to Backup Channel. Try again later.' , this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/' + action . payload . channelPoint , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
verifyChannels = this . actions $ . pipe (
ofType ( RTLActions . VERIFY_CHANNELS ) ,
mergeMap ( ( action : RTLActions.VerifyChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'VerifyChannels' ) ) ;
return this . httpClient . post ( this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/verify/' + action . payload . channelPoint , { } )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenSnackBar ( postRes . message ) ) ;
return {
type : RTLActions . VERIFY_CHANNELS_RES ,
payload : postRes.message
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'VerifyChannels' , code : err.status , message : err.error.error } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Unable to Verify Channel. Try again later.' , this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/verify/' + action . payload . channelPoint , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
restoreChannels = this . actions $ . pipe (
ofType ( RTLActions . RESTORE_CHANNELS ) ,
mergeMap ( ( action : RTLActions.RestoreChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'RestoreChannels' ) ) ;
return this . httpClient . post ( this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/restore/' + action . payload . channelPoint , { } )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenSnackBar ( postRes . message ) ) ;
this . store . dispatch ( new RTLActions . SetRestoreChannelsList ( postRes . list ) ) ;
return {
type : RTLActions . RESTORE_CHANNELS_RES ,
payload : postRes.message
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'RestoreChannels' , code : err.status , message : err.error.error } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Unable to Restore Channel. Try again later.' , this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/restore/' + action . payload . channelPoint , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
fetchFees = this . actions $ . pipe (
ofType ( RTLActions . FETCH_FEES ) ,
mergeMap ( ( action : RTLActions.FetchFees ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchFees' ) ) ;
return this . httpClient . get < Fees > ( this . CHILD_API_URL + environment . FEES_API ) ;
} ) ,
map ( ( fees ) = > {
this . logger . info ( fees ) ;
return {
type : RTLActions . SET_FEES ,
payload : fees ? fees : { }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchFees' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
@Effect ( )
balanceFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_BALANCE ) ,
mergeMap ( ( action : RTLActions.FetchBalance ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchBalance/' + action . payload ) ) ;
return this . httpClient . get < Balance > ( this . CHILD_API_URL + environment . BALANCE_API + '/' + action . payload )
. pipe (
map ( ( res : any ) = > {
if ( action . payload === 'channels' ) {
this . store . dispatch ( new RTLActions . FetchBalance ( 'blockchain' ) ) ;
}
this . logger . info ( res ) ;
const emptyRes = ( action . payload === 'channels' ) ? { balance : '' , btc_balance : '' } : { total_balance : '' , btc_total_balance : '' } ;
return {
type : RTLActions . SET_BALANCE ,
payload : res ? { target : action.payload , balance : res } : { target : action.payload , balance : emptyRes }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchBalance/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
}
) ) ;
}
) ) ;
@Effect ( )
networkInfoFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_NETWORK ) ,
mergeMap ( ( action : RTLActions.FetchNetwork ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchNetwork' ) ) ;
return this . httpClient . get < NetworkInfo > ( this . CHILD_API_URL + environment . NETWORK_API + '/info' ) ;
} ) ,
map ( ( networkInfo ) = > {
this . logger . info ( networkInfo ) ;
return {
type : RTLActions . SET_NETWORK ,
payload : networkInfo ? networkInfo : { }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchNetwork' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
}
) ) ;
@Effect ( )
channelsAllFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_ALL_CHANNELS ) ,
mergeMap ( ( action : RTLActions.FetchAllChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchChannels/all' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . CHANNELS_API )
. pipe (
map ( ( channels : any ) = > {
this . logger . info ( channels ) ;
return {
type : RTLActions . SET_ALL_CHANNELS ,
payload : ( channels && channels . channels && channels . channels . length > 0 ) ? channels . channels : [ ]
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchChannels/all' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
channelsPendingFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_PENDING_CHANNELS ) ,
mergeMap ( ( action : RTLActions.FetchPendingChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchChannels/pending' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . CHANNELS_API + '/pending' )
. pipe (
map ( ( channels : any ) = > {
this . logger . info ( channels ) ;
let pendingChannels : PendingChannelsGroup = { open : { num_channels : 0 , limbo_balance : 0 } , closing : { num_channels : 0 , limbo_balance : 0 } , force_closing : { num_channels : 0 , limbo_balance : 0 } , waiting_close : { num_channels : 0 , limbo_balance : 0 } , total_channels : 0 , total_limbo_balance : 0 } ;
if ( channels ) {
pendingChannels . total_limbo_balance = channels . total_limbo_balance ;
if ( channels . pending_closing_channels ) {
pendingChannels . closing . num_channels = channels . pending_closing_channels . length ;
pendingChannels . total_channels = pendingChannels . total_channels + channels . pending_closing_channels . length ;
channels . pending_closing_channels . forEach ( closingChannel = > {
pendingChannels . closing . limbo_balance = + pendingChannels . closing . limbo_balance + ( closingChannel . channel . local_balance ? + closingChannel.channel.local_balance : 0 ) ;
} ) ;
}
if ( channels . pending_force_closing_channels ) {
pendingChannels . force_closing . num_channels = channels . pending_force_closing_channels . length ;
pendingChannels . total_channels = pendingChannels . total_channels + channels . pending_force_closing_channels . length ;
channels . pending_force_closing_channels . forEach ( closingChannel = > {
pendingChannels . force_closing . limbo_balance = + pendingChannels . force_closing . limbo_balance + ( closingChannel . channel . local_balance ? + closingChannel.channel.local_balance : 0 ) ;
} ) ;
}
if ( channels . pending_open_channels ) {
pendingChannels . open . num_channels = channels . pending_open_channels . length ;
pendingChannels . total_channels = pendingChannels . total_channels + channels . pending_open_channels . length ;
channels . pending_open_channels . forEach ( openingChannel = > {
pendingChannels . open . limbo_balance = + pendingChannels . open . limbo_balance + ( openingChannel . channel . local_balance ? + openingChannel.channel.local_balance : 0 ) ;
} ) ;
}
if ( channels . waiting_close_channels ) {
pendingChannels . waiting_close . num_channels = channels . waiting_close_channels . length ;
pendingChannels . total_channels = pendingChannels . total_channels + channels . waiting_close_channels . length ;
channels . waiting_close_channels . forEach ( closingChannel = > {
pendingChannels . waiting_close . limbo_balance = + pendingChannels . waiting_close . limbo_balance + ( closingChannel . channel . local_balance ? + closingChannel.channel.local_balance : 0 ) ;
} ) ;
}
}
return {
type : RTLActions . SET_PENDING_CHANNELS ,
payload : channels ? { channels : channels , pendingChannels : pendingChannels } : { channels : { } , pendingChannels : pendingChannels }
} ;
} ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchChannels/pending' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ) ;
}
) ) ;
@Effect ( )
channelsClosedFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_CLOSED_CHANNELS ) ,
mergeMap ( ( action : RTLActions.FetchClosedChannels ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchChannels/closed' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . CHANNELS_API + '/closed' )
. pipe (
map ( ( channels : any ) = > {
this . logger . info ( channels ) ;
return {
type : RTLActions . SET_CLOSED_CHANNELS ,
payload : ( channels && channels . channels && channels . channels . length > 0 ) ? channels . channels : [ ]
} ;
} ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchChannels/closed' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ) ;
}
) ) ;
@Effect ( )
invoicesFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_INVOICES ) ,
mergeMap ( ( action : RTLActions.FetchInvoices ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchInvoices' ) ) ;
const num_max_invoices = ( action . payload . num_max_invoices ) ? action.payload.num_max_invoices : 100 ;
const index_offset = ( action . payload . index_offset ) ? action.payload.index_offset : 0 ;
const reversed = ( action . payload . reversed ) ? action.payload.reversed : false ;
return this . httpClient . get < ListInvoices > ( this . CHILD_API_URL + environment . INVOICES_API + '?num_max_invoices=' + num_max_invoices + '&index_offset=' + index_offset + '&reversed=' + reversed )
. pipe ( map ( ( res : ListInvoices ) = > {
this . logger . info ( res ) ;
if ( action . payload . reversed && ! action . payload . index_offset ) {
this . store . dispatch ( new RTLActions . SetTotalInvoices ( + res . last_index_offset ) ) ;
}
return {
type : RTLActions . SET_INVOICES ,
payload : res
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchInvoices' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
}
) ) ;
} ) ) ;
@Effect ( )
transactionsFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_TRANSACTIONS ) ,
mergeMap ( ( action : RTLActions.FetchTransactions ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchTransactions' ) ) ;
return this . httpClient . get < Transaction [ ] > ( this . CHILD_API_URL + environment . TRANSACTIONS_API ) ;
} ) ,
map ( ( transactions ) = > {
this . logger . info ( transactions ) ;
return {
type : RTLActions . SET_TRANSACTIONS ,
payload : ( transactions && transactions . length > 0 ) ? transactions : [ ]
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchTransactions' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
}
) ) ;
@Effect ( )
paymentsFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_PAYMENTS ) ,
mergeMap ( ( action : RTLActions.FetchPayments ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'FetchPayments' ) ) ;
return this . httpClient . get < Payment [ ] > ( this . CHILD_API_URL + environment . PAYMENTS_API ) ;
} ) ,
map ( ( payments ) = > {
this . logger . info ( payments ) ;
return {
type : RTLActions . SET_PAYMENTS ,
payload : payments ? payments : [ ]
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithoutAlert ( 'FetchPayments' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
}
) ) ;
@Effect ( )
decodePayment = this . actions $ . pipe (
ofType ( RTLActions . DECODE_PAYMENT ) ,
mergeMap ( ( action : RTLActions.DecodePayment ) = > {
return this . httpClient . get ( this . CHILD_API_URL + environment . PAYREQUEST_API + '/' + action . payload )
. pipe (
map ( ( decodedPayment ) = > {
this . logger . info ( decodedPayment ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_DECODED_PAYMENT ,
payload : decodedPayment ? decodedPayment : { }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Decode Payment Failed' , this . CHILD_API_URL + environment . PAYREQUEST_API + '/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( { dispatch : false } )
setDecodedPayment = this . actions $ . pipe (
ofType ( RTLActions . SET_DECODED_PAYMENT ) ,
map ( ( action : RTLActions.SetDecodedPayment ) = > {
this . logger . info ( action . payload ) ;
return action . payload ;
} )
) ;
@Effect ( )
sendPayment = this . actions $ . pipe (
ofType ( RTLActions . SEND_PAYMENT ) ,
withLatestFrom ( this . store . select ( 'root' ) ) ,
mergeMap ( ( [ action , store ] : [ RTLActions . SendPayment , any ] ) = > {
let queryHeaders = { } ;
if ( action . payload . outgoingChannel ) { queryHeaders [ 'outgoingChannel' ] = action . payload . outgoingChannel . chan_id ; }
if ( action . payload . allowSelfPayment ) { queryHeaders [ 'allowSelfPayment' ] = action . payload . allowSelfPayment ; }
if ( action . payload . lastHopPubkey ) { queryHeaders [ 'lastHopPubkey' ] = action . payload . lastHopPubkey ; }
if ( action . payload . feeLimitType && action . payload . feeLimitType !== FEE_LIMIT_TYPES [ 0 ] ) {
queryHeaders [ 'feeLimit' ] = { } ;
queryHeaders [ 'feeLimit' ] [ action . payload . feeLimitType . id ] = action . payload . feeLimit ;
}
if ( action . payload . zeroAmtInvoice ) {
queryHeaders [ 'paymentDecoded' ] = action . payload . paymentDecoded ;
} else {
queryHeaders [ 'paymentReq' ] = action . payload . paymentReq ;
}
return this . httpClient . post ( this . CHILD_API_URL + environment . CHANNELS_API + '/transactions' , queryHeaders )
. pipe (
map ( ( sendRes : any ) = > {
this . logger . info ( sendRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
if ( sendRes . payment_error ) {
this . logger . error ( 'Error: ' + sendRes . payment_error ) ;
const myErr = { status : sendRes.payment_error.status , error : sendRes.payment_error.error.message } ;
this . handleErrorWithAlert ( 'ERROR' , 'Send Payment Failed' , this . CHILD_API_URL + environment . CHANNELS_API + '/transactions/' + action . payload . paymentReq , myErr ) ;
return of ( { type : RTLActions . VOID } ) ;
} else {
let msg = 'Payment Sent Successfully.' ;
if ( sendRes . payment_route && sendRes . payment_route . total_fees_msat ) {
msg = 'Payment sent successfully with the total fee ' + sendRes . payment_route . total_fees_msat + ' (mSats).' ;
}
this . store . dispatch ( new RTLActions . OpenSnackBar ( msg ) ) ;
this . store . dispatch ( new RTLActions . FetchAllChannels ( ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'channels' ) ) ;
this . store . dispatch ( new RTLActions . FetchPayments ( ) ) ;
if ( action . payload . allowSelfPayment ) {
this . store . dispatch ( new RTLActions . FetchInvoices ( { num_max_invoices : PAGE_SIZE , reversed : true } ) ) ;
}
return {
type : RTLActions . SET_DECODED_PAYMENT ,
payload : { }
} ;
}
} ) ,
catchError ( ( err : any ) = > {
const myErr = { status : err.status , error : err.error && err . error . error && typeof ( err . error . error ) === 'object' ? err . error . error : { error : err.error && err . error . error ? err . error . error : 'Unknown Error' } } ;
this . handleErrorWithAlert ( 'ERROR' , 'Send Payment Failed' , this . CHILD_API_URL + environment . CHANNELS_API + '/transactions' , myErr ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( )
graphNodeFetch = this . actions $ . pipe (
ofType ( RTLActions . FETCH_GRAPH_NODE ) ,
mergeMap ( ( action : RTLActions.FetchGraphNode ) = > {
return this . httpClient . get < GraphNode > ( this . CHILD_API_URL + environment . NETWORK_API + '/node/' + action . payload )
. pipe ( map ( ( graphNode : any ) = > {
this . logger . info ( graphNode ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_GRAPH_NODE ,
payload : graphNode ? graphNode : { }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Get Node Address Failed' , this . CHILD_API_URL + environment . NETWORK_API + '/node/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} ) ) ;
}
) ) ;
@Effect ( { dispatch : false } )
setGraphNode = this . actions $ . pipe (
ofType ( RTLActions . SET_GRAPH_NODE ) ,
map ( ( action : RTLActions.SetGraphNode ) = > {
this . logger . info ( action . payload ) ;
return action . payload ;
} )
) ;
@Effect ( )
getNewAddress = this . actions $ . pipe (
ofType ( RTLActions . GET_NEW_ADDRESS ) ,
mergeMap ( ( action : RTLActions.GetNewAddress ) = > {
return this . httpClient . get ( this . CHILD_API_URL + environment . NEW_ADDRESS_API + '?type=' + action . payload . addressId )
. pipe ( map ( ( newAddress : any ) = > {
this . logger . info ( newAddress ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_NEW_ADDRESS ,
payload : ( newAddress && newAddress . address ) ? newAddress . address : { }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Generate New Address Failed' , this . CHILD_API_URL + environment . NEW_ADDRESS_API + '?type=' + action . payload . addressId , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} ) ) ;
} )
) ;
@Effect ( { dispatch : false } )
setNewAddress = this . actions $ . pipe (
ofType ( RTLActions . SET_NEW_ADDRESS ) ,
map ( ( action : RTLActions.SetNewAddress ) = > {
this . logger . info ( action . payload ) ;
return action . payload ;
} )
) ;
@Effect ( )
SetChannelTransaction = this . actions $ . pipe (
ofType ( RTLActions . SET_CHANNEL_TRANSACTION ) ,
mergeMap ( ( action : RTLActions.SetChannelTransaction ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'SetChannelTransaction' ) ) ;
return this . httpClient . post ( this . CHILD_API_URL + environment . TRANSACTIONS_API ,
{ amount : action.payload.amount , address : action.payload.address , sendAll : action.payload.sendAll , fees : action.payload.fees , blocks : action.payload.blocks }
)
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'blockchain' ) ) ;
return {
type : RTLActions . OPEN_SNACK_BAR ,
payload : 'Fund Sent Successfully!'
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'SetChannelTransaction' , code : err.status , message : err.error.error } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Sending Fund Failed' , this . CHILD_API_URL + environment . TRANSACTIONS_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} ) ) ;
} )
) ;
@Effect ( )
fetchForwardingHistory = this . actions $ . pipe (
ofType ( RTLActions . GET_FORWARDING_HISTORY ) ,
mergeMap ( ( action : RTLActions.GetForwardingHistory ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'GetForwardingHistory' ) ) ;
const queryHeaders : SwitchReq = {
num_max_events : action.payload.num_max_events , index_offset : action.payload.index_offset , end_time : action.payload.end_time , start_time : action.payload.start_time
} ;
return this . httpClient . post ( this . CHILD_API_URL + environment . SWITCH_API , queryHeaders )
. pipe (
map ( ( fhRes : any ) = > {
this . logger . info ( fhRes ) ;
return {
type : RTLActions . SET_FORWARDING_HISTORY ,
payload : fhRes
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'GetForwardingHistory' , code : err.status , message : err.error.error } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Get Forwarding History Failed' , this . CHILD_API_URL + environment . SWITCH_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( )
queryRoutesFetch = this . actions $ . pipe (
ofType ( RTLActions . GET_QUERY_ROUTES ) ,
mergeMap ( ( action : RTLActions.GetQueryRoutes ) = > {
return this . httpClient . get ( this . CHILD_API_URL + environment . NETWORK_API + '/routes/' + action . payload . destPubkey + '/' + action . payload . amount )
. pipe (
map ( ( qrRes : any ) = > {
this . logger . info ( qrRes ) ;
return {
type : RTLActions . SET_QUERY_ROUTES ,
payload : qrRes
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . SetQueryRoutes ( { } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Get Query Routes Failed' , this . CHILD_API_URL + environment . NETWORK_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( { dispatch : false } )
setQueryRoutes = this . actions $ . pipe (
ofType ( RTLActions . SET_QUERY_ROUTES ) ,
map ( ( action : RTLActions.SetQueryRoutes ) = > {
return action . payload ;
} )
) ;
@Effect ( )
genSeed = this . actions $ . pipe (
ofType ( RTLActions . GEN_SEED ) ,
mergeMap ( ( action : RTLActions.GenSeed ) = > {
return this . httpClient . get ( this . CHILD_API_URL + environment . WALLET_API + '/genseed/' + action . payload )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( 'Generated GenSeed!' ) ;
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . GEN_SEED_RESPONSE ,
payload : postRes.cipher_seed_mnemonic
} ;
} ) ,
catchError ( ( err ) = > {
this . handleErrorWithAlert ( 'ERROR' , err . error . message + ' ' + err . error . error . code , this . CHILD_API_URL + environment . WALLET_API + '/genseed/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
updateSelNodeOptions = this . actions $ . pipe (
ofType ( RTLActions . UPDATE_SELECTED_NODE_OPTIONS ) ,
mergeMap ( ( action : RTLActions.UpdateSelectedNodeOptions ) = > {
return this . httpClient . get ( this . CHILD_API_URL + environment . WALLET_API + '/updateSelNodeOptions' )
. pipe (
map ( ( postRes : any ) = > {
this . logger . info ( 'Update Sel Node Successfull' ) ;
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . VOID
} ;
} ) ,
catchError ( ( err ) = > {
this . handleErrorWithAlert ( 'ERROR' , 'Update macaroon for newly initialized node failed! Please check the macaroon path and restart the server!' , 'Update Macaroon' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( { dispatch : false } )
genSeedResponse = this . actions $ . pipe (
ofType ( RTLActions . GEN_SEED_RESPONSE ) ,
map ( ( action : RTLActions.GenSeedResponse ) = > {
return action . payload ;
} )
) ;
@Effect ( { dispatch : false } )
initWalletRes = this . actions $ . pipe (
ofType ( RTLActions . INIT_WALLET_RESPONSE ) ,
map ( ( action : RTLActions.InitWalletResponse ) = > {
return action . payload ;
} )
) ;
@Effect ( )
initWallet = this . actions $ . pipe (
ofType ( RTLActions . INIT_WALLET ) ,
mergeMap ( ( action : RTLActions.InitWallet ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . WALLET_API + '/initwallet' ,
{
wallet_password : action.payload.pwd ,
cipher_seed_mnemonic : action.payload.cipher ? action . payload . cipher : '' ,
aezeed_passphrase : action.payload.passphrase ? action . payload . passphrase : ''
} )
. pipe (
map ( ( postRes ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . INIT_WALLET_RESPONSE ,
payload : postRes
} ;
} ) ,
catchError ( ( err ) = > {
this . handleErrorWithAlert ( 'ERROR' , err . error . error , this . CHILD_API_URL + environment . WALLET_API + '/initwallet' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( { dispatch : false } )
unlockWallet = this . actions $ . pipe (
ofType ( RTLActions . UNLOCK_WALLET ) ,
mergeMap ( ( action : RTLActions.UnlockWallet ) = > {
return this . httpClient . post ( this . CHILD_API_URL + environment . WALLET_API + '/unlockwallet' , { wallet_password : action.payload.pwd } )
. pipe (
map ( ( postRes ) = > {
this . logger . info ( postRes ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenSpinner ( 'Initializing Node...' ) ) ;
this . logger . info ( 'Successfully Unlocked!' ) ;
this . sessionService . setItem ( 'lndUnlocked' , 'true' ) ;
setTimeout ( ( ) = > {
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . logger . info ( 'Successfully Initialized!' ) ;
this . store . dispatch ( new RTLActions . FetchInfo ( { loadPage : 'HOME' } ) ) ;
} , 1000 * 5 ) ;
return { type : RTLActions . VOID } ;
} ) ,
catchError ( ( err ) = > {
this . handleErrorWithAlert ( 'ERROR' , err . error . error , this . CHILD_API_URL + environment . WALLET_API + '/unlockwallet' , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
}
) ) ;
@Effect ( )
peerLookup = this . actions $ . pipe (
ofType ( RTLActions . PEER_LOOKUP ) ,
mergeMap ( ( action : RTLActions.PeerLookup ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'Lookup' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . NETWORK_API + '/node/' + action . payload )
. pipe (
map ( ( resPeer ) = > {
this . logger . info ( resPeer ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_LOOKUP ,
payload : resPeer
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'Lookup' , code : err.status , message : err.error.message } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Peer Lookup Failed' , this . CHILD_API_URL + environment . NETWORK_API + '/node/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( )
channelLookup = this . actions $ . pipe (
ofType ( RTLActions . CHANNEL_LOOKUP ) ,
mergeMap ( ( action : RTLActions.ChannelLookup ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'Lookup' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . NETWORK_API + '/edge/' + action . payload )
. pipe (
map ( ( resChannel ) = > {
this . logger . info ( resChannel ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_LOOKUP ,
payload : resChannel
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'Lookup' , code : err.status , message : err.error.message } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Channel Lookup Failed' , this . CHILD_API_URL + environment . NETWORK_API + '/edge/' + action . payload , err ) ;
this . store . dispatch ( new RTLActions . SetLookup ( { } ) ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( )
invoiceLookup = this . actions $ . pipe (
ofType ( RTLActions . INVOICE_LOOKUP ) ,
mergeMap ( ( action : RTLActions.InvoiceLookup ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'Lookup' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . INVOICES_API + '/' + action . payload )
. pipe (
map ( ( resInvoice ) = > {
this . logger . info ( resInvoice ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_LOOKUP ,
payload : resInvoice
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'Lookup' , code : err.status , message : err.error.message } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Invoice Lookup Failed' , this . CHILD_API_URL + environment . INVOICES_API + '/' + action . payload , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( { dispatch : false } )
setLookup = this . actions $ . pipe (
ofType ( RTLActions . SET_LOOKUP ) ,
map ( ( action : RTLActions.SetLookup ) = > {
this . logger . info ( action . payload ) ;
return action . payload ;
} )
) ;
@Effect ( )
getRestoreChannelList = this . actions $ . pipe (
ofType ( RTLActions . RESTORE_CHANNELS_LIST ) ,
mergeMap ( ( action : RTLActions.RestoreChannelsList ) = > {
this . store . dispatch ( new RTLActions . ClearEffectErrorLnd ( 'RestoreChannelsList' ) ) ;
return this . httpClient . get ( this . CHILD_API_URL + environment . CHANNELS_BACKUP_API + '/restore/list' )
. pipe (
map ( ( resRestoreList ) = > {
this . logger . info ( resRestoreList ) ;
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
return {
type : RTLActions . SET_RESTORE_CHANNELS_LIST ,
payload : ( resRestoreList ) ? resRestoreList : { all_restore_exists : false , files : [ ] }
} ;
} ) ,
catchError ( ( err : any ) = > {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : 'RestoreChannelsList' , code : err.status , message : err.error.message } ) ) ;
this . handleErrorWithAlert ( 'ERROR' , 'Restore Channels List Failed' , this . CHILD_API_URL + environment . CHANNELS_BACKUP_API , err ) ;
return of ( { type : RTLActions . VOID } ) ;
} )
) ;
} )
) ;
@Effect ( { dispatch : false } )
setRestoreChannelList = this . actions $ . pipe (
ofType ( RTLActions . SET_RESTORE_CHANNELS_LIST ) ,
map ( ( action : RTLActions.SetRestoreChannelsList ) = > {
this . logger . info ( action . payload ) ;
return action . payload ;
} )
) ;
initializeRemainingData ( info : any , landingPage : string ) {
this . sessionService . setItem ( 'lndUnlocked' , 'true' ) ;
if ( info . chains ) {
if ( typeof info . chains [ 0 ] === 'string' ) {
info . smaller_currency_unit = ( info . chains [ 0 ] . toString ( ) . toLowerCase ( ) . indexOf ( 'bitcoin' ) < 0 ) ? CurrencyUnitEnum.LITOSHIS : CurrencyUnitEnum.SATS ;
info . currency_unit = ( info . chains [ 0 ] . toString ( ) . toLowerCase ( ) . indexOf ( 'bitcoin' ) < 0 ) ? CurrencyUnitEnum.LTC : CurrencyUnitEnum.BTC ;
} else if ( typeof info . chains [ 0 ] === 'object' && info . chains [ 0 ] . hasOwnProperty ( 'chain' ) ) {
const getInfoChain = < GetInfoChain > info . chains [ 0 ] ;
info . smaller_currency_unit = ( getInfoChain . chain . toLowerCase ( ) . indexOf ( 'bitcoin' ) < 0 ) ? CurrencyUnitEnum.LITOSHIS : CurrencyUnitEnum.SATS ;
info . currency_unit = ( getInfoChain . chain . toLowerCase ( ) . indexOf ( 'bitcoin' ) < 0 ) ? CurrencyUnitEnum.LTC : CurrencyUnitEnum.BTC ;
}
info . version = ( undefined === info . version ) ? '' : info . version . split ( ' ' ) [ 0 ] ;
} else {
info . smaller_currency_unit = CurrencyUnitEnum . SATS ;
info . currency_unit = CurrencyUnitEnum . BTC ;
info . version = ( undefined === info . version ) ? '' : info . version . split ( ' ' ) [ 0 ] ;
}
const node_data = {
identity_pubkey : info.identity_pubkey ,
alias : info.alias ,
testnet : info.testnet ,
chains : info.chains ,
uris : info.uris ,
version : info.version ,
currency_unit : info.currency_unit ,
smaller_currency_unit : info.smaller_currency_unit
} ;
this . store . dispatch ( new RTLActions . SetNodeData ( node_data ) ) ;
this . store . dispatch ( new RTLActions . FetchFees ( ) ) ;
this . store . dispatch ( new RTLActions . FetchPeers ( ) ) ;
this . store . dispatch ( new RTLActions . FetchBalance ( 'channels' ) ) ;
this . store . dispatch ( new RTLActions . FetchNetwork ( ) ) ;
this . store . dispatch ( new RTLActions . FetchAllChannels ( ) ) ;
this . store . dispatch ( new RTLActions . FetchPendingChannels ( ) ) ;
this . store . dispatch ( new RTLActions . FetchClosedChannels ( ) ) ;
this . store . dispatch ( new RTLActions . FetchInvoices ( { num_max_invoices : 10 , reversed : true } ) ) ;
this . store . dispatch ( new RTLActions . FetchPayments ( ) ) ;
let newRoute = this . location . path ( ) ;
if ( newRoute . includes ( '/cl/' ) ) {
newRoute = newRoute . replace ( '/cl/' , '/lnd/' ) ;
}
if ( newRoute . includes ( '/unlock' ) || newRoute . includes ( '/login' ) || newRoute . includes ( '/error' ) || newRoute === '' || landingPage === 'HOME' || newRoute . includes ( '?access-key=' ) ) {
newRoute = '/lnd/home' ;
}
this . router . navigate ( [ newRoute ] ) ;
}
handleErrorWithoutAlert ( actionName : string , err : { status : number , error : any } ) {
this . logger . error ( 'ERROR IN: ' + actionName + '\n' + JSON . stringify ( err ) ) ;
if ( err . status === 401 ) {
this . logger . info ( 'Redirecting to Login' ) ;
this . store . dispatch ( new RTLActions . Logout ( ) ) ;
} else {
this . store . dispatch ( new RTLActions . EffectErrorLnd ( { action : actionName , code : err.status.toString ( ) , message : err.error.error } ) ) ;
}
}
handleErrorWithAlert ( alertType : string , alertTitle : string , errURL : string , err : { status : number , error : any } ) {
this . logger . error ( err ) ;
if ( err . status === 401 ) {
this . logger . info ( 'Redirecting to Login' ) ;
this . store . dispatch ( new RTLActions . Logout ( ) ) ;
} else {
this . store . dispatch ( new RTLActions . CloseSpinner ( ) ) ;
this . store . dispatch ( new RTLActions . OpenAlert ( {
data : {
type : alertType ,
alertTitle : alertTitle ,
message : { code : err.status , message : err.error.error , URL : errURL } ,
component : ErrorMessageComponent
}
} ) ) ;
}
}
ngOnDestroy() {
this . unSubs . forEach ( completeSub = > {
completeSub . next ( ) ;
completeSub . complete ( ) ;
} ) ;
}
}