@@ -155,6 +155,48 @@ export const balanceQueryKeys = {
155155 QUERY_KEY_TAGS . TOKEN ,
156156 assetId ,
157157 ] as const ,
158+ byTokensAndIndices : ( walletId : string , accountIndices : number [ ] , assetIds : string [ ] ) => {
159+ const sortedIndices = [ ...accountIndices ] . sort ( ( a , b ) => a - b )
160+ const sortedAssetIds = [ ...assetIds ] . sort ( )
161+
162+ return [
163+ QUERY_KEY_TAGS . BALANCES ,
164+ QUERY_KEY_TAGS . WALLET ,
165+ walletId ,
166+ sortedIndices ,
167+ sortedAssetIds ,
168+ 'multi'
169+ ]
170+ }
171+ }
172+
173+ async function promisePool < T > (
174+ promiseFns : ( ( ) => Promise < T > ) [ ] ,
175+ concurrency = 2
176+ ) : Promise < T [ ] > {
177+ const results : T [ ] = new Array ( promiseFns . length )
178+ let index = 0
179+
180+ const runNext = async ( ) : Promise < void > => {
181+ if ( index >= promiseFns . length ) {
182+ return
183+ }
184+
185+ const currentIndex = index ++
186+ const promiseFn = promiseFns [ currentIndex ] !
187+
188+ results [ currentIndex ] = await promiseFn ( )
189+
190+ await runNext ( )
191+ }
192+
193+ const workers = Array ( Math . min ( concurrency , promiseFns . length ) )
194+ . fill ( null )
195+ . map ( ( ) => runNext ( ) )
196+
197+ await Promise . all ( workers )
198+
199+ return results
158200}
159201
160202/**
@@ -283,7 +325,7 @@ export function useBalancesForWallet(
283325 error : addressesError ,
284326 } = useMultiAddressLoader ( {
285327 networks : uniqueNetworks ,
286- accountIndex,
328+ accountIndices : [ accountIndex ] ,
287329 enabled : options ?. enabled ,
288330 } ) ;
289331
@@ -332,6 +374,97 @@ export function useBalancesForWallet(
332374 return { ...query , isLoading, error : error as Error | null } ;
333375}
334376
377+ export type UseBalancesForWalletsResult = Omit <
378+ UseQueryResult < BalanceFetchResult [ ] , Error > ,
379+ 'isLoading' | 'error'
380+ > & {
381+ isLoading : boolean ;
382+ error : Error | null ;
383+ } ;
384+
385+ export function useBalancesForWallets (
386+ accountIndices : number [ ] ,
387+ assetConfigs : IAsset [ ] ,
388+ options ?: BalanceQueryOptions & { concurrencyLimit ?: number }
389+ ) : UseBalancesForWalletsResult {
390+ const uniqueNetworks = useMemo (
391+ ( ) => [ ...new Set ( assetConfigs . map ( ( asset ) => asset . getNetwork ( ) ) ) ] ,
392+ [ assetConfigs ] ,
393+ ) ;
394+
395+ const {
396+ isLoading : areAddressesLoading ,
397+ error : addressesError ,
398+ } = useMultiAddressLoader ( {
399+ networks : uniqueNetworks ,
400+ accountIndices : accountIndices ,
401+ enabled : options ?. enabled ,
402+ } ) ;
403+
404+ const walletId = getWalletStore ( ) ( ( state ) => state . activeWalletId ) ;
405+
406+ const initialData : BalanceFetchResult [ ] | undefined = ( ( ) => {
407+ if ( ! walletId || assetConfigs . length === 0 ) {
408+ return undefined ;
409+ }
410+
411+ return accountIndices . flatMap ( ( accountIndex ) => {
412+ return assetConfigs . map ( ( asset ) => {
413+ const balance = BalanceService . getBalance (
414+ accountIndex ,
415+ asset . getNetwork ( ) ,
416+ asset . getId ( ) ,
417+ walletId ,
418+ ) ;
419+
420+ return {
421+ success : true ,
422+ network : asset . getNetwork ( ) ,
423+ accountIndex : accountIndex ,
424+ assetId : asset . getId ( ) ,
425+ balance,
426+ } ;
427+ } )
428+ } ) ;
429+ } ) ( ) ;
430+
431+ const query = useQuery ( {
432+ queryKey : balanceQueryKeys . byTokensAndIndices ( walletId || '' , accountIndices , assetConfigs . map ( ( asset ) => asset . getId ( ) ) ) ,
433+ queryFn : async ( ) => {
434+ const concurrency = options ?. concurrencyLimit ?? 2 ;
435+ const tasks = accountIndices . map ( ( accountIndex ) => async ( ) : Promise < BalanceFetchResult [ ] > => {
436+ try {
437+ return await fetchBalances ( accountIndex , assetConfigs ) ;
438+ } catch ( error ) {
439+ return assetConfigs . map ( ( asset ) => ( {
440+ success : false ,
441+ network : asset . getNetwork ( ) ,
442+ accountIndex,
443+ assetId : asset . getId ( ) ,
444+ balance : null ,
445+ error : error instanceof Error ? error . message : String ( error ) ,
446+ } ) ) ;
447+ }
448+ } ) ;
449+ const results = await promisePool ( tasks , concurrency ) ;
450+ return results . flat ( ) ;
451+ } ,
452+ enabled : isQueryEnabled (
453+ options ?. enabled ,
454+ ! ! walletId && ! areAddressesLoading && assetConfigs . length > 0 ,
455+ ) ,
456+ refetchInterval : options ?. refetchInterval ,
457+ staleTime : options ?. staleTime ?? DEFAULT_QUERY_STALE_TIME_MS ,
458+ gcTime : DEFAULT_QUERY_GC_TIME_MS ,
459+ initialData,
460+ } ) ;
461+
462+ const isLoading = areAddressesLoading || query . isLoading ;
463+ const error = addressesError || query . error ;
464+
465+ return { ...query , isLoading, error : error as Error | null } ;
466+ }
467+
335468/**
336469 * Invalidate balance queries based on refresh type
337470 */
0 commit comments