@@ -332,95 +332,100 @@ export class MultichainAccountWallet<
332
332
*
333
333
* NOTE: This method should only be called on a newly created wallet.
334
334
*
335
- * @param opts - The options for the discovery and creation of accounts.
336
- * @param opts.skippedProviders - The providers to skip.
337
335
* @returns The accounts for each provider.
338
336
*/
339
- async discoverAndCreateAccounts ( {
340
- skippedProviders = [ ] ,
341
- } : {
342
- skippedProviders : AccountProviderType [ ] ;
343
- } ) : Promise < {
344
- [ AccountProviderType ] : Bip44Account < KeyringAccount > [ ] ;
345
- } > {
346
- const providers = this . #providers. filter (
347
- ( provider ) => ! skippedProviders . includes ( provider . providerType ) ,
348
- ) ;
337
+ async discoverAndCreateAccounts ( ) : Promise < Record < string , number > > {
338
+ const providers = this . #providers;
339
+ const providerContexts = new Map <
340
+ Bip44Provider ,
341
+ {
342
+ stopped : boolean ;
343
+ running ?: Promise < void > ;
344
+ index : number ;
345
+ count : number ;
346
+ }
347
+ > ( ) ;
349
348
350
- const results : Record < AccountProviderType , Bip44Account < KeyringAccount > [ ] > =
351
- { } ;
352
- const nextIndex = new Map < Bip44Provider , number > (
353
- providers . map ( ( p ) => [ p , 0 ] ) ,
354
- ) ;
355
- const stopped = new Set < Bip44Provider > ( ) ;
356
- const inFlight = new Map < Bip44Provider , Promise < void > > ( ) ;
349
+ for ( const p of providers ) {
350
+ providerContexts . set ( p , { stopped : false , index : 0 , count : 0 } ) ;
351
+ }
357
352
358
- let high = 0 ;
353
+ let maxGroupIndex = 0 ;
359
354
360
355
const schedule = ( p : Bip44Provider , index : number ) => {
361
- const run = ( async ( ) => {
356
+ const providerCtx = providerContexts . get ( p ) ;
357
+ if ( ! providerCtx ) {
358
+ throw new Error ( `Provider ${ p } not found in providerContexts` ) ;
359
+ }
360
+
361
+ if ( providerCtx . stopped || providerCtx . running ) {
362
+ return ;
363
+ }
364
+
365
+ providerCtx . index = index ;
366
+
367
+ providerCtx . running = ( async ( ) => {
362
368
try {
363
369
const accounts = await p . discoverAndCreateAccounts ( {
364
370
entropySource : this . #entropySource,
365
371
groupIndex : index ,
366
372
} ) ;
367
373
368
- inFlight . delete ( p ) ;
369
-
370
- if ( accounts . length > 0 ) {
371
- stopped . add ( p ) ;
372
- } else {
373
- results [ p . providerType ] = [
374
- ...( results [ p . providerType ] ?? [ ] ) ,
375
- ...accounts ,
376
- ] ;
377
-
378
- const next = index + 1 ;
379
- nextIndex . set ( p , next ) ;
380
- if ( next > high ) {
381
- high = next ;
382
-
383
- for ( const q of providers ) {
384
- if (
385
- ! stopped . has ( q ) &&
386
- ! inFlight . has ( q ) &&
387
- ( nextIndex . get ( q ) ?? 0 ) < high
388
- ) {
389
- schedule ( q , high ) ;
390
- }
391
- }
392
- }
374
+ if ( ! accounts . length ) {
375
+ providerCtx . stopped = true ;
376
+ return ;
377
+ }
378
+
379
+ providerCtx . count += accounts . length ;
393
380
394
- if ( ! stopped . has ( p ) ) {
395
- const target = Math . max ( high , nextIndex . get ( p ) ?? 0 ) ;
396
- schedule ( p , target ) ;
381
+ const next = index + 1 ;
382
+ providerCtx . index = next ;
383
+
384
+ if ( next > maxGroupIndex ) {
385
+ maxGroupIndex = next ;
386
+ for ( const [ q , qCtx ] of providerContexts ) {
387
+ if (
388
+ ! qCtx . stopped &&
389
+ ! qCtx . running &&
390
+ qCtx . index < maxGroupIndex
391
+ ) {
392
+ schedule ( q , maxGroupIndex ) ;
393
+ }
397
394
}
398
395
}
399
- } catch {
400
- inFlight . delete ( p ) ;
401
- stopped . add ( p ) ;
396
+ } catch ( err ) {
397
+ providerCtx . stopped = true ;
398
+ console . error ( err ) ;
399
+ } finally {
400
+ providerCtx . running = undefined ;
401
+ if ( ! providerCtx . stopped ) {
402
+ const target = Math . max ( maxGroupIndex , providerCtx . index ) ;
403
+ schedule ( p , target ) ;
404
+ }
402
405
}
403
406
} ) ( ) ;
404
-
405
- inFlight . set ( p , run ) ;
406
407
} ;
407
408
408
409
for ( const p of providers ) {
409
410
schedule ( p , 0 ) ;
410
411
}
411
412
412
- while ( inFlight . size > 0 ) {
413
- await Promise . race ( inFlight . values ( ) ) ;
413
+ while ( [ ...providerContexts . values ( ) ] . some ( ( ctx ) => Boolean ( ctx . running ) ) ) {
414
+ const racers = [ ...providerContexts . values ( ) ]
415
+ . map ( ( c ) => c . running )
416
+ . filter ( Boolean ) as Promise < void > [ ] ;
417
+ await Promise . race ( racers ) ;
414
418
}
415
419
416
420
await this . alignGroups ( ) ;
417
421
418
- const out : Record < AccountProviderType , Bip44Account < KeyringAccount > [ ] > = { } ;
422
+ const discoveredAccounts : Record < string , number > = { } ;
419
423
420
- for ( const p of providers ) {
421
- out [ p . providerType ] = results [ p . providerType ] ?? [ ] ;
424
+ for ( const [ p , ctx ] of providerContexts ) {
425
+ const groupKey = p . snapId ?? 'Evm' ;
426
+ discoveredAccounts [ groupKey ] = ctx . count ;
422
427
}
423
428
424
- return out ;
429
+ return discoveredAccounts ;
425
430
}
426
431
}
0 commit comments