@@ -141,6 +141,10 @@ class LightningManager {
141141 private forceSync : boolean = false ;
142142 private pendingSyncPromises : Array < ( result : Result < string > ) => void > = [ ] ;
143143
144+ private isStarting : boolean = false ;
145+ private pendingStartPromises : Array < ( result : Result < string > ) => void > = [ ] ;
146+ private previousAccountName : string = '' ;
147+
144148 constructor ( ) {
145149 // Step 0: Subscribe to all events
146150 ldk . onEvent ( EEventTypes . native_log , ( line ) => {
@@ -236,6 +240,33 @@ class LightningManager {
236240 return ok ( 'Storage set' ) ;
237241 }
238242
243+ /**
244+ * Resolves all pending start promises with the provided result.
245+ * @private
246+ * @param {Result<string> } result
247+ * @returns {void }
248+ */
249+ private resolveAllPendingStartPromises ( result : Result < string > ) : void {
250+ while ( this . pendingStartPromises . length > 0 ) {
251+ const resolve = this . pendingStartPromises . shift ( ) ;
252+ if ( resolve ) {
253+ resolve ( result ) ;
254+ }
255+ }
256+ }
257+
258+ /**
259+ * Sets isStarting to false, resolves all start promises and returns error.
260+ * @private
261+ * @param {Err<string> } e
262+ * @returns {Promise<Result<string>> }
263+ */
264+ private handleStartError = ( e : Err < string > ) : Result < string > => {
265+ this . isStarting = false ;
266+ this . resolveAllPendingStartPromises ( e ) ;
267+ return e ;
268+ } ;
269+
239270 /**
240271 * Spins up and syncs all processes
241272 * @param {string } seed
@@ -281,6 +312,19 @@ class LightningManager {
281312 return err ( 'getTransactionPosition is not set in start method.' ) ;
282313 }
283314
315+ // Retry start method if presented with a new account name.
316+ if ( this . previousAccountName !== account . name ) {
317+ this . isStarting = false ;
318+ this . previousAccountName = account . name ;
319+ }
320+
321+ if ( this . isStarting ) {
322+ return new Promise < Result < string > > ( ( resolve ) => {
323+ this . pendingStartPromises . push ( resolve ) ;
324+ } ) ;
325+ }
326+ this . isStarting = true ;
327+
284328 // Ensure the start params function as expected.
285329 const paramCheckResponse = await startParamCheck ( {
286330 account,
@@ -294,7 +338,7 @@ class LightningManager {
294338 network,
295339 } ) ;
296340 if ( paramCheckResponse . isErr ( ) ) {
297- return err ( paramCheckResponse . error . message ) ;
341+ return this . handleStartError ( paramCheckResponse ) ;
298342 }
299343
300344 this . getBestBlock = getBestBlock ;
@@ -313,14 +357,16 @@ class LightningManager {
313357 this . trustedZeroConfPeers = trustedZeroConfPeers ;
314358
315359 if ( ! this . baseStoragePath ) {
316- return err (
317- 'baseStoragePath required for wallet persistence. Call setBaseStoragePath(path) first.' ,
360+ return this . handleStartError (
361+ err (
362+ 'baseStoragePath required for wallet persistence. Call setBaseStoragePath(path) first.' ,
363+ ) ,
318364 ) ;
319365 }
320366
321367 const storageSetRes = await this . setStorage ( account ) ;
322368 if ( storageSetRes . isErr ( ) ) {
323- return err ( storageSetRes . error ) ;
369+ return this . handleStartError ( storageSetRes ) ;
324370 }
325371
326372 //Validate we didn't change the seed for this account if one exists
@@ -338,15 +384,17 @@ class LightningManager {
338384 remotePersist : false ,
339385 } ) ;
340386 if ( writeRes . isErr ( ) ) {
341- return err ( writeRes . error ) ;
387+ return this . handleStartError ( err ( writeRes . error ) ) ;
342388 }
343389 } else {
344- return err ( readSeed . error ) ;
390+ return this . handleStartError ( err ( readSeed . error ) ) ;
345391 }
346392 } else {
347393 //Cannot start an existing node with a different seed
348394 if ( readSeed . value . content !== account . seed ) {
349- return err ( 'Seed for current node cannot be changed.' ) ;
395+ return this . handleStartError (
396+ err ( 'Seed for current node cannot be changed.' ) ,
397+ ) ;
350398 }
351399 }
352400
@@ -358,7 +406,7 @@ class LightningManager {
358406 details : backupServerDetails ,
359407 } ) ;
360408 if ( backupSetupRes . isErr ( ) ) {
361- return err ( backupSetupRes . error ) ;
409+ return this . handleStartError ( err ( backupSetupRes . error ) ) ;
362410 }
363411 }
364412
@@ -390,13 +438,13 @@ class LightningManager {
390438 // Step 5: Initialize the ChainMonitor
391439 const chainMonitorRes = await ldk . initChainMonitor ( ) ;
392440 if ( chainMonitorRes . isErr ( ) ) {
393- return chainMonitorRes ;
441+ return this . handleStartError ( chainMonitorRes ) ;
394442 }
395443
396444 // Step 6: Initialize the KeysManager
397445 const keysManager = await ldk . initKeysManager ( this . account . seed ) ;
398446 if ( keysManager . isErr ( ) ) {
399- return keysManager ;
447+ return this . handleStartError ( keysManager ) ;
400448 }
401449
402450 // Step 7: Read ChannelMonitors state from disk
@@ -413,22 +461,22 @@ class LightningManager {
413461 rapidGossipSyncUrl,
414462 } ) ;
415463 if ( networkGraphRes . isErr ( ) ) {
416- return networkGraphRes ;
464+ return this . handleStartError ( networkGraphRes ) ;
417465 }
418466
419467 // Step 8: Initialize the UserConfig ChannelManager
420468 const confRes = await ldk . initUserConfig ( userConfig ) ;
421469
422470 if ( confRes . isErr ( ) ) {
423- return confRes ;
471+ return this . handleStartError ( confRes ) ;
424472 }
425473
426474 const channelManagerRes = await ldk . initChannelManager ( {
427475 network : this . network ,
428476 bestBlock,
429477 } ) ;
430478 if ( channelManagerRes . isErr ( ) ) {
431- return channelManagerRes ;
479+ return this . handleStartError ( channelManagerRes ) ;
432480 }
433481
434482 // Attempt to abandon any stored payment ids.
@@ -468,7 +516,10 @@ class LightningManager {
468516 //Writes node state to log files
469517 ldk . nodeStateDump ( ) . catch ( console . error ) ;
470518
471- return ok ( 'Node running' ) ;
519+ this . isStarting = false ;
520+ const result = ok ( 'Node started' ) ;
521+ this . resolveAllPendingStartPromises ( result ) ;
522+ return result ;
472523 }
473524
474525 async setStorage ( account : TAccount ) : Promise < Result < string > > {
0 commit comments