2021-02-21 19:02:31 +00:00
import { Injectable , OnDestroy } from '@angular/core' ;
2020-03-16 15:57:57 +00:00
import { HttpClient , HttpParams } from '@angular/common/http' ;
2022-05-01 17:35:20 +00:00
import { BehaviorSubject , Subject , throwError , of } from 'rxjs' ;
2021-08-28 21:03:18 +00:00
import { catchError , takeUntil , map } from 'rxjs/operators' ;
2020-03-16 15:57:57 +00:00
import { Store } from '@ngrx/store' ;
import { environment , API_URL } from '../../../environments/environment' ;
2021-08-28 21:03:18 +00:00
import { AlertTypeEnum , UI_MESSAGES } from '../../shared/services/consts-enums-functions' ;
import { LoopSwapStatus } from '../models/loopModels' ;
import { CommonService } from './common.service' ;
2020-03-16 15:57:57 +00:00
import { LoggerService } from '../../shared/services/logger.service' ;
2021-08-28 21:03:18 +00:00
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component' ;
2021-02-21 19:02:31 +00:00
2021-12-29 23:08:41 +00:00
import { RTLState } from '../../store/rtl.state' ;
import { closeSpinner , logout , openAlert , openSpinner } from '../../store/rtl.actions' ;
2020-03-16 15:57:57 +00:00
@Injectable ( )
2021-02-21 19:02:31 +00:00
export class LoopService implements OnDestroy {
2021-08-28 21:03:18 +00:00
2020-03-16 15:57:57 +00:00
private loopUrl = '' ;
2021-02-21 19:02:31 +00:00
private swaps : LoopSwapStatus [ ] = [ ] ;
public swapsChanged = new BehaviorSubject < LoopSwapStatus [ ] > ( [ ] ) ;
2021-08-28 21:03:18 +00:00
private unSubs : Array < Subject < void > > = [ new Subject ( ) , new Subject ( ) , new Subject ( ) , new Subject ( ) , new Subject ( ) ] ;
2020-03-16 15:57:57 +00:00
2021-12-29 23:08:41 +00:00
constructor ( private httpClient : HttpClient , private logger : LoggerService , private store : Store < RTLState > , private commonService : CommonService ) { }
2020-03-16 15:57:57 +00:00
2021-02-21 19:02:31 +00:00
getSwapsList() {
return this . swaps ;
}
listSwaps() {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( openSpinner ( { payload : UI_MESSAGES.GET_LOOP_SWAPS } ) ) ;
this . loopUrl = API_URL + environment . LOOP_API + '/swaps' ;
this . httpClient . get < LoopSwapStatus [ ] > ( this . loopUrl ) . pipe ( takeUntil ( this . unSubs [ 0 ] ) ) .
2021-08-28 21:03:18 +00:00
subscribe ( {
next : ( swapResponse : LoopSwapStatus [ ] ) = > {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : UI_MESSAGES.GET_LOOP_SWAPS } ) ) ;
2021-08-28 21:03:18 +00:00
this . swaps = swapResponse ;
this . swapsChanged . next ( this . swaps ) ;
2021-12-29 23:08:41 +00:00
} ,
2022-05-01 17:35:20 +00:00
error : ( err ) = > this . swapsChanged . error ( this . handleErrorWithAlert ( UI_MESSAGES . GET_LOOP_SWAPS , this . loopUrl , err ) )
2021-08-28 21:03:18 +00:00
} ) ;
2021-02-21 19:02:31 +00:00
}
2020-03-16 15:57:57 +00:00
loopOut ( amount : number , chanId : string , targetConf : number , swapRoutingFee : number , minerFee : number , prepayRoutingFee : number , prepayAmt : number , swapFee : number , swapPublicationDeadline : number , destAddress : string ) {
2021-08-28 21:03:18 +00:00
const requestBody = { amount : amount , targetConf : targetConf , swapRoutingFee : swapRoutingFee , minerFee : minerFee , prepayRoutingFee : prepayRoutingFee , prepayAmt : prepayAmt , swapFee : swapFee , swapPublicationDeadline : swapPublicationDeadline , destAddress : destAddress } ;
if ( chanId !== '' ) {
requestBody [ 'chanId' ] = chanId ;
}
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/out' ;
2021-08-28 21:03:18 +00:00
return this . httpClient . post ( this . loopUrl , requestBody ) . pipe ( catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop Out for Channel: ' + chanId , UI_MESSAGES . NO_SPINNER , err ) ) ) ;
2020-03-16 15:57:57 +00:00
}
getLoopOutTerms() {
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/out/terms' ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl ) . pipe ( catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop Out Terms' , UI_MESSAGES . NO_SPINNER , err ) ) ) ;
2020-03-16 15:57:57 +00:00
}
getLoopOutQuote ( amount : number , targetConf : number , swapPublicationDeadline : number ) {
let params = new HttpParams ( ) ;
params = params . append ( 'targetConf' , targetConf . toString ( ) ) ;
params = params . append ( 'swapPublicationDeadline' , swapPublicationDeadline . toString ( ) ) ;
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/out/quote/' + amount ;
this . store . dispatch ( openSpinner ( { payload : UI_MESSAGES.GET_QUOTE } ) ) ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl , { params : params } ) . pipe (
takeUntil ( this . unSubs [ 1 ] ) ,
map ( ( res ) = > {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : UI_MESSAGES.GET_QUOTE } ) ) ;
2021-08-28 21:03:18 +00:00
return res ;
} ) ,
catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop Out Quote' , UI_MESSAGES . GET_QUOTE , err ) )
) ;
2020-03-16 15:57:57 +00:00
}
getLoopOutTermsAndQuotes ( targetConf : number ) {
let params = new HttpParams ( ) ;
params = params . append ( 'targetConf' , targetConf . toString ( ) ) ;
params = params . append ( 'swapPublicationDeadline' , ( new Date ( ) . getTime ( ) + ( 30 * 60000 ) ) . toString ( ) ) ;
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/out/termsAndQuotes' ;
this . store . dispatch ( openSpinner ( { payload : UI_MESSAGES.GET_TERMS_QUOTES } ) ) ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl , { params : params } ) . pipe (
takeUntil ( this . unSubs [ 2 ] ) ,
map ( ( res ) = > {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : UI_MESSAGES.GET_TERMS_QUOTES } ) ) ;
2021-08-28 21:03:18 +00:00
return res ;
2022-05-01 17:35:20 +00:00
} ) , catchError ( ( err ) = > of ( this . handleErrorWithAlert ( UI_MESSAGES . GET_TERMS_QUOTES , this . loopUrl , err ) ) )
2021-08-28 21:03:18 +00:00
) ;
2020-03-16 15:57:57 +00:00
}
loopIn ( amount : number , swapFee : number , minerFee : number , lastHop : string , externalHtlc : boolean ) {
const requestBody = { amount : amount , swapFee : swapFee , minerFee : minerFee , lastHop : lastHop , externalHtlc : externalHtlc } ;
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/in' ;
2021-08-28 21:03:18 +00:00
return this . httpClient . post ( this . loopUrl , requestBody ) . pipe ( catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop In' , UI_MESSAGES . NO_SPINNER , err ) ) ) ;
2020-03-16 15:57:57 +00:00
}
getLoopInTerms() {
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/in/terms' ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl ) . pipe ( catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop In Terms' , UI_MESSAGES . NO_SPINNER , err ) ) ) ;
2020-03-16 15:57:57 +00:00
}
getLoopInQuote ( amount : number , targetConf : string , swapPublicationDeadline : number ) {
let params = new HttpParams ( ) ;
params = params . append ( 'targetConf' , targetConf . toString ( ) ) ;
params = params . append ( 'swapPublicationDeadline' , swapPublicationDeadline . toString ( ) ) ;
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/in/quote/' + amount ;
this . store . dispatch ( openSpinner ( { payload : UI_MESSAGES.GET_QUOTE } ) ) ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl , { params : params } ) . pipe (
takeUntil ( this . unSubs [ 3 ] ) ,
map ( ( res ) = > {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : UI_MESSAGES.GET_QUOTE } ) ) ;
2021-08-28 21:03:18 +00:00
return res ;
} ) ,
catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop In Qoute' , UI_MESSAGES . GET_QUOTE , err ) )
) ;
2020-03-16 15:57:57 +00:00
}
getLoopInTermsAndQuotes ( targetConf : number ) {
let params = new HttpParams ( ) ;
params = params . append ( 'targetConf' , targetConf . toString ( ) ) ;
params = params . append ( 'swapPublicationDeadline' , ( new Date ( ) . getTime ( ) + ( 30 * 60000 ) ) . toString ( ) ) ;
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/in/termsAndQuotes' ;
this . store . dispatch ( openSpinner ( { payload : UI_MESSAGES.GET_TERMS_QUOTES } ) ) ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl , { params : params } ) . pipe (
takeUntil ( this . unSubs [ 4 ] ) ,
map ( ( res ) = > {
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : UI_MESSAGES.GET_TERMS_QUOTES } ) ) ;
2021-08-28 21:03:18 +00:00
return res ;
2022-05-01 17:35:20 +00:00
} ) , catchError ( ( err ) = > of ( this . handleErrorWithAlert ( UI_MESSAGES . GET_TERMS_QUOTES , this . loopUrl , err ) ) )
2021-08-28 21:03:18 +00:00
) ;
2020-03-16 15:57:57 +00:00
}
getSwap ( id : string ) {
2021-12-29 23:08:41 +00:00
this . loopUrl = API_URL + environment . LOOP_API + '/swap/' + id ;
2021-08-28 21:03:18 +00:00
return this . httpClient . get ( this . loopUrl ) . pipe ( catchError ( ( err ) = > this . handleErrorWithoutAlert ( 'Loop Get Swap for ID: ' + id , UI_MESSAGES . NO_SPINNER , err ) ) ) ;
2020-03-16 15:57:57 +00:00
}
2021-08-28 21:03:18 +00:00
handleErrorWithoutAlert ( actionName : string , uiMessage : string , err : { status : number , error : any } ) {
let errMsg = '' ;
2020-03-16 15:57:57 +00:00
this . logger . error ( 'ERROR IN: ' + actionName + '\n' + JSON . stringify ( err ) ) ;
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : uiMessage } ) ) ;
2020-03-16 15:57:57 +00:00
if ( err . status === 401 ) {
2021-08-28 21:03:18 +00:00
errMsg = 'Unauthorized User.' ;
2020-03-16 15:57:57 +00:00
this . logger . info ( 'Redirecting to Login' ) ;
2021-12-29 23:08:41 +00:00
this . store . dispatch ( logout ( ) ) ;
2021-08-28 21:03:18 +00:00
} else if ( err . status === 503 ) {
errMsg = 'Unable to Connect to Loop Server.' ;
2021-12-29 23:08:41 +00:00
this . store . dispatch ( openAlert ( {
payload : {
data : {
type : 'ERROR' ,
alertTitle : 'Loop Not Connected' ,
message : { code : err.status , message : 'Unable to Connect to Loop Server' , URL : actionName } ,
component : ErrorMessageComponent
}
2020-03-16 15:57:57 +00:00
}
} ) ) ;
2021-08-28 21:03:18 +00:00
} else {
errMsg = this . commonService . extractErrorMessage ( err ) ;
2020-03-16 15:57:57 +00:00
}
2021-08-28 21:03:18 +00:00
return throwError ( ( ) = > new Error ( errMsg ) ) ;
2020-03-16 15:57:57 +00:00
}
2021-08-28 21:03:18 +00:00
handleErrorWithAlert ( uiMessage : string , errURL : string , err : any ) {
let errMsg = '' ;
2020-03-16 15:57:57 +00:00
this . logger . error ( err ) ;
2021-12-29 23:08:41 +00:00
this . store . dispatch ( closeSpinner ( { payload : uiMessage } ) ) ;
2020-03-16 15:57:57 +00:00
if ( err . status === 401 ) {
2021-08-28 21:03:18 +00:00
errMsg = 'Unauthorized User.' ;
2020-03-16 15:57:57 +00:00
this . logger . info ( 'Redirecting to Login' ) ;
2021-12-29 23:08:41 +00:00
this . store . dispatch ( logout ( ) ) ;
2021-08-28 21:03:18 +00:00
} else if ( err . status === 503 ) {
errMsg = 'Unable to Connect to Loop Server.' ;
2022-05-01 17:35:20 +00:00
setTimeout ( ( ) = > {
this . store . dispatch ( openAlert ( {
payload : {
data : {
type : 'ERROR' ,
alertTitle : 'Loop Not Connected' ,
message : { code : err.status , message : 'Unable to Connect to Loop Server' , URL : errURL } ,
component : ErrorMessageComponent
}
2021-12-29 23:08:41 +00:00
}
2022-05-01 17:35:20 +00:00
} ) ) ;
} , 100 ) ;
2020-03-16 15:57:57 +00:00
} else {
2021-08-28 21:03:18 +00:00
errMsg = this . commonService . extractErrorMessage ( err ) ;
const errCode = ( err . error && err . error . error && err . error . error . code ) ? err . error . error . code : ( err . error && err . error . code ) ? err.error.code : err.code ? err.code : err.status ;
2022-05-01 17:35:20 +00:00
setTimeout ( ( ) = > {
this . store . dispatch ( openAlert ( {
payload : {
data : {
type : AlertTypeEnum . ERROR ,
alertTitle : 'ERROR' ,
message : { code : errCode , message : errMsg , URL : errURL } ,
component : ErrorMessageComponent
}
2021-12-29 23:08:41 +00:00
}
2022-05-01 17:35:20 +00:00
} ) ) ;
} , 100 ) ;
2020-03-16 15:57:57 +00:00
}
2022-05-01 17:35:20 +00:00
return { message : errMsg } ;
2020-03-16 15:57:57 +00:00
}
2021-02-21 19:02:31 +00:00
ngOnDestroy() {
2021-08-28 21:03:18 +00:00
this . unSubs . forEach ( ( completeSub ) = > {
2021-06-20 20:27:08 +00:00
completeSub . next ( null ) ;
2021-02-21 19:02:31 +00:00
completeSub . complete ( ) ;
} ) ;
}
2021-08-28 21:03:18 +00:00
2020-03-16 15:57:57 +00:00
}