@@ -254,7 +254,9 @@ export class TokenBalancesController extends StaticIntervalPollingController<Tok
254
254
255
255
this . #allTokens = allTokens ;
256
256
this . #allDetectedTokens = allDetectedTokens ;
257
- this . updateBalances ( { chainIds : chainIdsToUpdate } ) . catch ( console . error ) ;
257
+ this . #handleTokensControllerStateChange( {
258
+ chainIds : chainIdsToUpdate ,
259
+ } ) . catch ( console . error ) ;
258
260
} ;
259
261
260
262
/**
@@ -331,37 +333,68 @@ export class TokenBalancesController extends StaticIntervalPollingController<Tok
331
333
) ;
332
334
}
333
335
334
- #cleanupCurrentTokenBalances(
335
- accountTokenPairs : { accountAddress : Hex ; tokenAddress : Hex } [ ] ,
336
- chainId : Hex ,
337
- ) {
338
- // TODO move this to a private fct
339
- const currentTokenBalances = this . messagingSystem . call (
336
+ async #handleTokensControllerStateChange( {
337
+ chainIds,
338
+ } : { chainIds ?: Hex [ ] } = { } ) {
339
+ const currentTokenBalancesState = this . messagingSystem . call (
340
340
'TokenBalancesController:getState' ,
341
341
) ;
342
+ const currentTokenBalances = currentTokenBalancesState . tokenBalances ;
343
+ const currentAllTokens = this . #allTokens;
344
+
345
+ // first we check if the state change was due to a token being removed
346
+ const accKeys = Object . keys ( currentTokenBalances ) ;
347
+ for ( const currentAccount of accKeys ) {
348
+ const allChains = currentTokenBalances [ currentAccount as `0x${string } `] ;
349
+ const chainsArray = Object . keys ( allChains ) ;
350
+
351
+ for ( const currentChain of chainsArray ) {
352
+ const tokensObject = allChains [ currentChain as Hex ] ;
353
+ const allCurrentTokens = Object . keys ( tokensObject ) ;
354
+ const existingTokensInState =
355
+ currentAllTokens [ currentChain as Hex ] ?. [
356
+ currentAccount as `0x${string } `
357
+ ] || [ ] ;
358
+ const existingSet = new Set (
359
+ existingTokensInState . map ( ( elm ) => elm . address ) ,
360
+ ) ;
361
+
362
+ for ( const singleToken of allCurrentTokens ) {
363
+ if ( ! existingSet . has ( singleToken ) ) {
364
+ this . update ( ( state ) => {
365
+ delete state . tokenBalances [ currentAccount as Hex ] [
366
+ currentChain as Hex
367
+ ] [ singleToken as `0x${string } `] ;
368
+ } ) ;
369
+ }
370
+ }
371
+ }
372
+ }
342
373
343
- // in case currentTokenBalances has a token that is not in accountTokenPairs, we will remove it from currentTokenBalances
344
- // loop through currentTokenBalances.tokenBalances, for each account loop though the account[chainId] array of tokens and check if the token is in accountTokenPairs
345
- // if not, remove it from currentTokenBalances
346
- for ( const accountAddress of Object . keys (
347
- currentTokenBalances . tokenBalances ,
348
- ) ) {
349
- for ( const tokenAddress of Object . keys (
350
- currentTokenBalances . tokenBalances [ accountAddress as `0x${string } `] [
351
- chainId
352
- ] ,
353
- ) ) {
354
- if (
355
- ! accountTokenPairs . some ( ( pair ) => pair . tokenAddress === tokenAddress )
356
- ) {
357
- this . update ( ( state ) => {
358
- delete state . tokenBalances [ accountAddress as Hex ] [ chainId as Hex ] [
359
- tokenAddress as `0x${string } `
360
- ] ;
361
- } ) ;
374
+ // then we check if the state change was due to a token being added
375
+ let shouldUpdate = false ;
376
+ const allTokensStateChains = Object . keys ( currentAllTokens ) ;
377
+ for ( const currentChain of allTokensStateChains ) {
378
+ const accountsPerChain = currentAllTokens [ currentChain as Hex ] ;
379
+ const allAccounts = Object . keys ( accountsPerChain ) ;
380
+
381
+ for ( const currentAccount of allAccounts ) {
382
+ const tokensList = accountsPerChain [ currentAccount as `0x${string } `] ;
383
+ const tokenBalancesObject =
384
+ currentTokenBalances [ currentAccount as `0x${string } `] ?. [
385
+ currentChain as Hex
386
+ ] || { } ;
387
+ for ( const singleToken of tokensList ) {
388
+ if ( ! tokenBalancesObject ?. [ singleToken . address as `0x${string } `] ) {
389
+ shouldUpdate = true ;
390
+ break ;
391
+ }
362
392
}
363
393
}
364
394
}
395
+ if ( shouldUpdate ) {
396
+ await this . updateBalances ( { chainIds } ) . catch ( console . error ) ;
397
+ }
365
398
}
366
399
367
400
/**
@@ -396,8 +429,6 @@ export class TokenBalancesController extends StaticIntervalPollingController<Tok
396
429
397
430
let results : MulticallResult [ ] = [ ] ;
398
431
399
- // in case currentTokenBalances has a token that is not in accountTokenPairs, we will remove it from currentTokenBalances
400
- this . #cleanupCurrentTokenBalances( accountTokenPairs , chainId ) ;
401
432
const currentTokenBalances = this . messagingSystem . call (
402
433
'TokenBalancesController:getState' ,
403
434
) ;
0 commit comments