1+ import { EventEmitter } from 'events' ;
12import Config from '../Config' ;
2- import SwapClient from './SwapClient' ;
3+ import { SwapClientType } from '../constants/enums' ;
4+ import { Models } from '../db/DB' ;
35import LndClient from '../lndclient/LndClient' ;
46import { LndInfo } from '../lndclient/types' ;
5- import RaidenClient from '../raidenclient/RaidenClient' ;
67import { Loggers } from '../Logger' ;
78import { Currency } from '../orderbook/types' ;
8- import { Models } from '../db/DB' ;
9- import { SwapClientType } from '../constants/enums' ;
10- import { EventEmitter } from 'events' ;
119import Peer from '../p2p/Peer' ;
12- import { UnitConverter } from '../utils/UnitConverter ' ;
10+ import RaidenClient from '../raidenclient/RaidenClient ' ;
1311import seedutil from '../utils/seedutil' ;
12+ import { UnitConverter } from '../utils/UnitConverter' ;
1413import errors from './errors' ;
14+ import SwapClient , { ClientStatus } from './SwapClient' ;
15+ import lndErrors from '../lndclient/errors' ;
1516
1617export function isRaidenClient ( swapClient : SwapClient ) : swapClient is RaidenClient {
1718 return ( swapClient . type === SwapClientType . Raiden ) ;
@@ -38,7 +39,7 @@ interface SwapClientManager {
3839}
3940
4041class SwapClientManager extends EventEmitter {
41- /** A map between currencies and all swap clients */
42+ /** A map between currencies and all enabled swap clients */
4243 public swapClients = new Map < string , SwapClient > ( ) ;
4344 public raidenClient : RaidenClient ;
4445 private walletPassword ?: string ;
@@ -105,24 +106,63 @@ class SwapClientManager extends EventEmitter {
105106 }
106107 }
107108
109+ /**
110+ * Checks to make sure all enabled lnd instances are available and waits
111+ * up to a short time for them to become available in case they are not.
112+ * Throws an error if any lnd clients remain unreachable.
113+ */
114+ public waitForLnd = async ( ) => {
115+ const lndClients = this . getLndClientsMap ( ) . values ( ) ;
116+ const lndAvailablePromises : Promise < void > [ ] = [ ] ;
117+ for ( const lndClient of lndClients ) {
118+ lndAvailablePromises . push ( new Promise < void > ( ( resolve , reject ) => {
119+ if ( lndClient . isDisconnected ( ) || lndClient . isNotInitialized ( ) ) {
120+ const onAvailable = ( ) => {
121+ clearTimeout ( timer ) ;
122+ lndClient . removeListener ( 'locked' , onAvailable ) ;
123+ lndClient . removeListener ( 'connectionVerified' , onAvailable ) ;
124+ resolve ( ) ;
125+ } ;
126+ lndClient . once ( 'connectionVerified' , onAvailable ) ;
127+ lndClient . once ( 'locked' , onAvailable ) ;
128+ const timer = setTimeout ( ( ) => {
129+ lndClient . removeListener ( 'connectionVerified' , onAvailable ) ;
130+ lndClient . removeListener ( 'locked' , onAvailable ) ;
131+ reject ( lndClient . currency ) ;
132+ } , SwapClient . RECONNECT_TIME_LIMIT ) ;
133+ } else {
134+ resolve ( ) ;
135+ }
136+ } ) ) ;
137+ }
138+
139+ try {
140+ await Promise . all ( lndAvailablePromises ) ;
141+ } catch ( currency ) {
142+ throw lndErrors . UNAVAILABLE ( currency , ClientStatus . Disconnected ) ;
143+ }
144+ }
145+
108146 /**
109147 * Generates a cryptographically random 24 word seed mnemonic from an lnd client.
110148 */
111149 public genSeed = async ( ) => {
150+ const lndClients = this . getLndClientsMap ( ) . values ( ) ;
112151 // loop through swap clients until we find an lnd client awaiting unlock
113- for ( const swapClient of this . swapClients . values ( ) ) {
114- if ( isLndClient ( swapClient ) && swapClient . isWaitingUnlock ( ) ) {
152+ for ( const lndClient of lndClients ) {
153+ if ( lndClient . isWaitingUnlock ( ) ) {
115154 try {
116- const seed = await swapClient . genSeed ( ) ;
155+ const seed = await lndClient . genSeed ( ) ;
117156 return seed ;
118157 } catch ( err ) {
119- swapClient . logger . error ( 'could not generate seed' , err ) ;
158+ lndClient . logger . error ( 'could not generate seed' , err ) ;
120159 }
121160 }
122161 }
123162
124- // TODO: use seedutil tool to generate a seed
125- return undefined ;
163+ // TODO: use seedutil tool to generate a seed instead of throwing error
164+ // when we can't generate one with lnd
165+ throw errors . SWAP_CLIENT_WALLET_NOT_CREATED ( 'could not generate aezeed' ) ;
126166 }
127167
128168 /**
@@ -131,18 +171,23 @@ class SwapClientManager extends EventEmitter {
131171 public initWallets = async ( walletPassword : string , seedMnemonic : string [ ] ) => {
132172 this . walletPassword = walletPassword ;
133173
134- // loop through swap clients to find locked lnd clients
174+ // loop through swap clients to initialize locked lnd clients
175+ const lndClients = this . getLndClientsMap ( ) . values ( ) ;
135176 const initWalletPromises : Promise < any > [ ] = [ ] ;
136177 const initializedLndWallets : string [ ] = [ ] ;
137178 let initializedRaiden = false ;
138- for ( const swapClient of this . swapClients . values ( ) ) {
139- if ( isLndClient ( swapClient ) && swapClient . isWaitingUnlock ( ) ) {
140- const initWalletPromise = swapClient . initWallet ( walletPassword , seedMnemonic ) . then ( ( ) => {
141- initializedLndWallets . push ( swapClient . currency ) ;
142- } ) . catch ( ( err ) => {
143- swapClient . logger . debug ( `could not initialize wallet: ${ err . message } ` ) ;
144- } ) ;
145- initWalletPromises . push ( initWalletPromise ) ;
179+
180+ for ( const lndClient of lndClients ) {
181+ if ( isLndClient ( lndClient ) ) {
182+ if ( lndClient . isWaitingUnlock ( ) ) {
183+ const initWalletPromise = lndClient . initWallet ( walletPassword , seedMnemonic ) . then ( ( ) => {
184+ initializedLndWallets . push ( lndClient . currency ) ;
185+ } ) . catch ( ( err ) => {
186+ lndClient . logger . error ( `could not initialize wallet: ${ err . message } ` ) ;
187+ throw errors . SWAP_CLIENT_WALLET_NOT_CREATED ( `could not initialize lnd-${ lndClient . currency } : ${ err . message } ` ) ;
188+ } ) ;
189+ initWalletPromises . push ( initWalletPromise ) ;
190+ }
146191 }
147192 }
148193
@@ -154,8 +199,9 @@ class SwapClientManager extends EventEmitter {
154199 const keystorePromise = seedutil ( seedMnemonic , '' , keystorepath ) . then ( ( ) => {
155200 this . raidenClient . logger . info ( `created raiden keystore with master seed and empty password in ${ keystorepath } ` ) ;
156201 initializedRaiden = true ;
157- } ) . catch ( ( ) => {
158- this . raidenClient . logger . warn ( 'could not create keystore' ) ;
202+ } ) . catch ( ( err ) => {
203+ this . raidenClient . logger . error ( 'could not create keystore' ) ;
204+ throw errors . SWAP_CLIENT_WALLET_NOT_CREATED ( `could not create keystore: ${ err } ` ) ;
159205 } ) ;
160206 initWalletPromises . push ( keystorePromise ) ;
161207 }
0 commit comments