@metamask/assets-controllers 101.0.1 → 103.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +54 -1
  2. package/dist/AccountTrackerController-method-action-types.cjs +1 -1
  3. package/dist/AccountTrackerController-method-action-types.cjs.map +1 -1
  4. package/dist/AccountTrackerController-method-action-types.d.cts +1 -1
  5. package/dist/AccountTrackerController-method-action-types.d.mts +1 -1
  6. package/dist/AccountTrackerController-method-action-types.mjs +1 -1
  7. package/dist/AccountTrackerController-method-action-types.mjs.map +1 -1
  8. package/dist/AssetsContractController-method-action-types.cjs +1 -1
  9. package/dist/AssetsContractController-method-action-types.cjs.map +1 -1
  10. package/dist/AssetsContractController-method-action-types.d.cts +1 -1
  11. package/dist/AssetsContractController-method-action-types.d.mts +1 -1
  12. package/dist/AssetsContractController-method-action-types.mjs +1 -1
  13. package/dist/AssetsContractController-method-action-types.mjs.map +1 -1
  14. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.cjs +1 -1
  15. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.cjs.map +1 -1
  16. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.d.cts +1 -1
  17. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.d.mts +1 -1
  18. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.mjs +1 -1
  19. package/dist/MultichainAssetsController/MultichainAssetsController-method-action-types.mjs.map +1 -1
  20. package/dist/MultichainAssetsController/MultichainAssetsController.cjs +1 -4
  21. package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -1
  22. package/dist/MultichainAssetsController/MultichainAssetsController.d.cts +2 -2
  23. package/dist/MultichainAssetsController/MultichainAssetsController.d.cts.map +1 -1
  24. package/dist/MultichainAssetsController/MultichainAssetsController.d.mts +2 -2
  25. package/dist/MultichainAssetsController/MultichainAssetsController.d.mts.map +1 -1
  26. package/dist/MultichainAssetsController/MultichainAssetsController.mjs +1 -4
  27. package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -1
  28. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.cjs +1 -1
  29. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.cjs.map +1 -1
  30. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.d.cts +1 -1
  31. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.d.mts +1 -1
  32. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.mjs +1 -1
  33. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController-method-action-types.mjs.map +1 -1
  34. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
  35. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +2 -2
  36. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
  37. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +2 -2
  38. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
  39. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
  40. package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
  41. package/dist/MultichainBalancesController/MultichainBalancesController.d.cts +2 -2
  42. package/dist/MultichainBalancesController/MultichainBalancesController.d.cts.map +1 -1
  43. package/dist/MultichainBalancesController/MultichainBalancesController.d.mts +2 -2
  44. package/dist/MultichainBalancesController/MultichainBalancesController.d.mts.map +1 -1
  45. package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
  46. package/dist/TokenBalancesController-method-action-types.cjs +1 -1
  47. package/dist/TokenBalancesController-method-action-types.cjs.map +1 -1
  48. package/dist/TokenBalancesController-method-action-types.d.cts +1 -1
  49. package/dist/TokenBalancesController-method-action-types.d.mts +1 -1
  50. package/dist/TokenBalancesController-method-action-types.mjs +1 -1
  51. package/dist/TokenBalancesController-method-action-types.mjs.map +1 -1
  52. package/dist/TokenBalancesController.cjs +73 -39
  53. package/dist/TokenBalancesController.cjs.map +1 -1
  54. package/dist/TokenBalancesController.d.cts +20 -5
  55. package/dist/TokenBalancesController.d.cts.map +1 -1
  56. package/dist/TokenBalancesController.d.mts +20 -5
  57. package/dist/TokenBalancesController.d.mts.map +1 -1
  58. package/dist/TokenBalancesController.mjs +72 -39
  59. package/dist/TokenBalancesController.mjs.map +1 -1
  60. package/dist/TokenDetectionController-method-action-types.cjs +1 -1
  61. package/dist/TokenDetectionController-method-action-types.cjs.map +1 -1
  62. package/dist/TokenDetectionController-method-action-types.d.cts +1 -1
  63. package/dist/TokenDetectionController-method-action-types.d.mts +1 -1
  64. package/dist/TokenDetectionController-method-action-types.mjs +1 -1
  65. package/dist/TokenDetectionController-method-action-types.mjs.map +1 -1
  66. package/dist/TokensController-method-action-types.cjs +1 -1
  67. package/dist/TokensController-method-action-types.cjs.map +1 -1
  68. package/dist/TokensController-method-action-types.d.cts +1 -1
  69. package/dist/TokensController-method-action-types.d.mts +1 -1
  70. package/dist/TokensController-method-action-types.mjs +1 -1
  71. package/dist/TokensController-method-action-types.mjs.map +1 -1
  72. package/dist/multicall.cjs +2 -0
  73. package/dist/multicall.cjs.map +1 -1
  74. package/dist/multicall.d.cts.map +1 -1
  75. package/dist/multicall.d.mts.map +1 -1
  76. package/dist/multicall.mjs +2 -0
  77. package/dist/multicall.mjs.map +1 -1
  78. package/dist/selectors/token-selectors.cjs +2 -3
  79. package/dist/selectors/token-selectors.cjs.map +1 -1
  80. package/dist/selectors/token-selectors.d.cts +4 -42
  81. package/dist/selectors/token-selectors.d.cts.map +1 -1
  82. package/dist/selectors/token-selectors.d.mts +4 -42
  83. package/dist/selectors/token-selectors.d.mts.map +1 -1
  84. package/dist/selectors/token-selectors.mjs +2 -3
  85. package/dist/selectors/token-selectors.mjs.map +1 -1
  86. package/dist/token-prices-service/codefi-v2.cjs +9 -5
  87. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  88. package/dist/token-prices-service/codefi-v2.d.cts +4 -2
  89. package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
  90. package/dist/token-prices-service/codefi-v2.d.mts +4 -2
  91. package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
  92. package/dist/token-prices-service/codefi-v2.mjs +9 -5
  93. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  94. package/dist/utils/create-batch-handler.cjs +54 -0
  95. package/dist/utils/create-batch-handler.cjs.map +1 -0
  96. package/dist/utils/create-batch-handler.d.cts +16 -0
  97. package/dist/utils/create-batch-handler.d.cts.map +1 -0
  98. package/dist/utils/create-batch-handler.d.mts +16 -0
  99. package/dist/utils/create-batch-handler.d.mts.map +1 -0
  100. package/dist/utils/create-batch-handler.mjs +51 -0
  101. package/dist/utils/create-batch-handler.mjs.map +1 -0
  102. package/package.json +22 -22
@@ -1 +1 @@
1
- {"version":3,"file":"TokenBalancesController.mjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,YAAY,EAAE,iCAAiC;AAWxD,OAAO,EACL,OAAO,EACP,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,EACN,mCAAmC;AAoBpC,OAAO,EAAE,+BAA+B,EAAE,qCAAqC;AAW/E,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EACjB,wBAAwB;AACzB,OAAO,EAAE,OAAO,EAAE,cAAc;;;AAQhC,OAAO,EAAE,mCAAmC,EAAE,uCAAmC;AACjF,OAAO,EAAE,yBAAyB,EAAE,+DAA2D;AAM/F,OAAO,EAAE,iBAAiB,EAAE,8CAA0C;AAgBtE,MAAM,UAAU,GAAG,yBAAkC,CAAC;AACtD,MAAM,mBAAmB,GAAG,KAAM,CAAC,CAAC,aAAa;AACjD,MAAM,4CAA4C,GAAG,MAAO,CAAC,CAAC,YAAY;AAE1E,MAAM,QAAQ,GAAgD;IAC5D,aAAa,EAAE;QACb,kBAAkB,EAAE,KAAK;QACzB,OAAO,EAAE,IAAI;QACb,sBAAsB,EAAE,KAAK;QAC7B,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAoGF,MAAM,KAAK,GAAG,CAAQ,IAAW,EAAE,EAA+B,EAAS,EAAE,CAC3E,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAEpB,MAAM,YAAY,GAChB,4CAA+D,CAAC;AAElE,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAmB,EAAE,CACjD,oBAAoB,CAAC,IAAI,CAAoB,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAc,EAAE;IAC9D,IAAI,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;AAChF,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,SAAiB,EAA4B,EAAE;IAC5E,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE7C,IAAI,MAAM,CAAC,cAAc,KAAK,OAAO,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAQF,MAAM,yBAAyB,GAAG;IAChC,2BAA2B;IAC3B,uBAAuB;CACf,CAAC;AAEX,MAAM,OAAO,uBAAwB,SAAQ,+BAA+B,EAM3E;IAiDC,YAAY,EACV,SAAS,EACT,QAAQ,GAAG,mBAAmB,EAC9B,8BAA8B,GAAG,4CAA4C,EAC7E,qBAAqB,GAAG,EAAE,EAC1B,KAAK,GAAG,EAAE,EACV,qBAAqB,GAAG,IAAI,EAC5B,mBAAmB,GAAG,GAAiB,EAAE,CAAC,EAAE,EAC5C,qBAAqB,GAAG,GAAY,EAAE,CAAC,IAAI,EAC3C,QAAQ,EACR,WAAW,GAAG,GAAY,EAAE,CAAC,IAAI,GACF;QAC/B,KAAK,CAAC;YACJ,IAAI,EAAE,UAAU;YAChB,SAAS;YACT,QAAQ;YACR,KAAK,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE;SACvC,CAAC,CAAC;;QAjEI,oDAAkC;QAElC,4DAA2B;QAE3B,+DAAyC;QAEzC,iEAAsC;QAEtC,uDAA4B;QAE5B,2DAA8D;QAEvE,6CAAiD,EAAE,EAAC;QAEpD,kDAA8D,EAAE,EAAC;QAEjE,oDAA+D,EAAE,EAAC;QAElE,yEAAyE;QAChE,2DAAyB;QAElC,gFAAgF;QACvE,0EAAwC;QAEjD,sCAAsC;QAC7B,8DAA4D;QAErE,gDAAgD;QACvC,yDAAsD,IAAI,GAAG,EAAE,EAAC;QAEzE,kDAAkD;QAClD,6DAA6B,KAAK,EAAC;QAEnC,uCAAuC;QACvC,8CAAc,KAAK,EAAC;QAEpB,mEAAmE;QACnE,qDAAmC,EAAE,EAAC;QAEtC,0EAA0E;QACjE,yDAGL;YACF,KAAK,EAAE,IAAI;YACX,cAAc,EAAE,IAAI,GAAG,EAAE;SAC1B,EAAC;QAiMO,+CAAe,CAAC,OAAmB,EAAgB,EAAE;YAC5D,MAAM,EAAE,8BAA8B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC5D,4BAA4B,CAC7B,CAAC;YACF,MAAM,aAAa,GAAG,8BAA8B,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,EAAE,eAAe,EAAE,GACvB,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAChC,wCAAwC,EACxC,eAAe,CAChB,CAAC;YACF,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC,EAAC;QAEO,oDAAoB,CAC3B,OAAmB,EACiD,EAAE;YACtE,MAAM,EAAE,8BAA8B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC5D,4BAA4B,CAC7B,CAAC;YACF,MAAM,aAAa,GAAG,8BAA8B,CAAC,OAAO,CAAC,CAAC;YAC9D,MAAM,EAAE,eAAe,EAAE,GACvB,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CACxB,wCAAwC,EACxC,eAAe,CAChB,CAAC;QACJ,CAAC,EAAC;QAEO,4DAA4B,GAAmB,EAAE;YACxD,MAAM,eAAe,GAAG,IAAI,yBAAyB,CACnD,uBAAA,IAAI,yCAAU,EACd,uBAAA,IAAI,4CAAa,EACjB,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAC/B,CAAC;YAEF,OAAO;gBACL,wFAAwF;gBACxF,QAAQ,EAAE,CAAC,OAAmB,EAAW,EAAE,CACzC,uBAAA,IAAI,sDAAuB,MAA3B,IAAI,CAAyB;oBAC7B,uBAAA,IAAI,oDAAqB,MAAzB,IAAI,CAAuB,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAC7C,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACnC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;aACnD,CAAC;QACJ,CAAC,EAAC;QAmnBO,mDAAmB,KAAK,EAC/B,KAA4B,EACb,EAAE;YACjB,MAAM,OAAO,GAAiB,EAAE,CAAC;YACjC,IAAI,UAAU,GAAG,KAAK,CAAC;YAEvB,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;gBAC/B,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;gBAC/B,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;aACxC,CAAC,CAAC;YAEH,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;gBACvE,MAAM,EAAE,GAAG,OAAqB,CAAC;gBAEjC,MAAM,YAAY,GAChB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;oBACpE,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;wBAC1B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACzD,MAAM,eAAe,GACnB,CAAC,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;oBACpE,CAAC,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC;wBACvB,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAEtD,MAAM,cAAc,GAClB,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC,CAAC;oBAClD,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;gBAElE,OAAO,cAAc,IAAI,CAAC,CAAC,eAAe,IAAI,YAAY,CAAC,CAAC;YAC9D,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC;gBAC7B,uBAAA,IAAI,sCAAc,KAAK,CAAC,SAAS,MAAA,CAAC;gBAClC,uBAAA,IAAI,2CAAmB,KAAK,CAAC,iBAAiB,MAAA,CAAC;gBAC/C,OAAO;YACT,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3B,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;oBACvC,MAAM,EAAE,GAAG,OAAqB,CAAC;oBACjC,MAAM,YAAY,GAChB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;wBAClB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;wBAC9C,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;4BAC1B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBACzD,MAAM,eAAe,GACnB,CAAC,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC;wBAClB,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;wBAC9C,CAAC,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC;4BACvB,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAEtD,MAAM,aAAa,GACjB,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,uBAAA,IAAI,0CAAW,CAAC,EAAE,CAAC,CAAC;wBAClD,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,uBAAA,IAAI,+CAAgB,CAAC,EAAE,CAAC,CAAC,CAAC;oBAElE,IAAI,CAAC,aAAa,EAAE,CAAC;wBACnB,SAAS;oBACX,CAAC;oBAED,IAAI,YAAY,EAAE,CAAC;wBACjB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACnB,CAAC;yBAAM,IAAI,eAAe,EAAE,CAAC;wBAC3B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;4BAC9D,MAAM,UAAU,GAAG,OAA0B,CAAC;4BAC9C,IAAI,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;gCACjD,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;gCAChD,UAAU,GAAG,IAAI,CAAC;4BACpB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,uBAAA,IAAI,sCAAc,KAAK,CAAC,SAAS,MAAA,CAAC;YAClC,uBAAA,IAAI,2CAAmB,KAAK,CAAC,iBAAiB,MAAA,CAAC;YAC/C,uBAAA,IAAI,6CAAqB,KAAK,CAAC,gBAAgB,MAAA,CAAC;YAEhD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;gBAClC,IAAI,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACzD,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;gBACrE,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,EAAC;QAEO,oDAAoB,CAAC,KAAmB,EAAQ,EAAE;YACzD,MAAM,eAAe,GAAG,IAAI,GAAG,CAC7B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAClD,CAAC;YAEF,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;YAC/C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5D,MAAM,UAAU,GAAG,OAA0B,CAAC;gBAC9C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAC/B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,CAC3C,EAAE,CAAC;oBACF,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;YAED,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAC7D,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAC3C,CAAC;YAEF,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;gBAC5B,OAAO;YACT,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC9D,MAAM,UAAU,GAAG,OAA0B,CAAC;oBAC9C,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;wBAC7C,MAAM,UAAU,GAAG,cAA4B,CAAC;wBAChD,IAAI,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;4BACzD,OAAO,YAAY,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,CAAC;wBAC5D,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,EAAC;QAEO,oDAAoB,CAAC,IAAY,EAAQ,EAAE;YAClD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,EAAE;gBAC3B,OAAO,YAAY,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC,EAAC;QAEO,oDAAoB,GAAS,EAAE;YACtC,MAAM,QAAQ,GAAG,uBAAA,IAAI,uFAAoB,MAAxB,IAAI,CAAsB,CAAC;YAC5C,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC3C,iCAAiC;YACnC,CAAC,CAAC,CAAC;QACL,CAAC,EAAC;QAkEO,kEAAkC,KAAK,EAAE,EAChD,OAAO,EACP,KAAK,EACL,OAAO,GAKR,EAAiB,EAAE;YAClB,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;YAE7C,IAAI,CAAC;gBACH,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,oBAAoB,EAAE,GACtD,uBAAA,IAAI,0FAAuB,MAA3B,IAAI,EAAwB,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;gBAEpE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7B,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;;wBACpB,MAAM,gBAAgB,GACpB,kBAAkB,CAAC,WAAW,EAAqB,CAAC;wBACtD,MAAA,KAAK,CAAC,aAAa,EAAC,gBAAgB,SAAhB,gBAAgB,IAAM,EAAE,EAAC;wBAC7C,MAAA,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;wBAEtD,KAAK,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,aAAa,EAAE,CAAC;4BACtD,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC;gCAC1D,OAAO,CAAC;wBACZ,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,+CAA+C,EAC/C,oBAAoB,CACrB,CAAC;gBACJ,CAAC;gBAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,iDAAiD,EACjD;wBACE,WAAW,EAAE,SAAS;wBACtB,OAAO;qBACR,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CACV,iEAAiE,KAAK,aAAa,OAAO,GAAG,EAC7F,KAAK,CACN,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAEvE,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;oBAC5D,iCAAiC;gBACnC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,EAAC;QAEO,kEAAkC,CAAC,EAC1C,QAAQ,EACR,MAAM,GAIP,EAAQ,EAAE;YACT,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,uBAAA,IAAI,sDAAuB,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAClE,CAAC;YAED,IAAI,uBAAA,IAAI,sDAAuB,CAAC,KAAK,EAAE,CAAC;gBACtC,YAAY,CAAC,uBAAA,IAAI,sDAAuB,CAAC,KAAK,CAAC,CAAC;YAClD,CAAC;YAED,uBAAA,IAAI,sDAAuB,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAClD,uBAAA,IAAI,oGAAiC,MAArC,IAAI,CAAmC,CAAC;YAC1C,CAAC,EAAE,IAAI,CAAC,CAAC;QACX,CAAC,EAAC;QAnmCA,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,CAA6B,CAAC;QAElC,uBAAA,IAAI,qCAAa,QAAQ,IAAI,WAAW,MAAA,CAAC;QACzC,uBAAA,IAAI,6CAAqB,qBAAqB,MAAA,CAAC;QAC/C,uBAAA,IAAI,gDAAwB,mBAAmB,MAAA,CAAC;QAChD,uBAAA,IAAI,kDAA0B,qBAAqB,MAAA,CAAC;QACpD,uBAAA,IAAI,wCAAgB,WAAW,MAAA,CAAC;QAChC,uBAAA,IAAI,4CAAoB,QAAQ,MAAA,CAAC;QACjC,uBAAA,IAAI,2DAAmC,8BAA8B,MAAA,CAAC;QACtE,uBAAA,IAAI,+CAAuB,EAAE,GAAG,qBAAqB,EAAE,MAAA,CAAC;QAExD,kGAAkG;QAClG,uBAAA,IAAI,4CAAoB;YACtB;gBACE,OAAO,EAAE,uBAAA,IAAI,yDAA0B,MAA9B,IAAI,CAA4B;gBACzC,IAAI,EAAE,oBAAoB;aAC3B;YACD;gBACE,OAAO,EAAE,IAAI,iBAAiB,CAC5B,uBAAA,IAAI,4CAAa,EACjB,uBAAA,IAAI,iDAAkB,EACtB,GAAG,EAAE,CAAC,CAAC;oBACL,SAAS,EAAE,uBAAA,IAAI,0CAAW;oBAC1B,iBAAiB,EAAE,uBAAA,IAAI,+CAAgB;iBACxC,CAAC,CACH;gBACD,IAAI,EAAE,YAAY;aACnB;SACF,MAAA,CAAC;QAEF,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,GACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACnD,uBAAA,IAAI,sCAAc,SAAS,MAAA,CAAC;QAC5B,uBAAA,IAAI,2CAAmB,iBAAiB,MAAA,CAAC;QACzC,uBAAA,IAAI,6CAAqB,gBAAgB,MAAA,CAAC;QAE1C,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzE,uBAAA,IAAI,uCAAe,UAAU,MAAA,CAAC;QAE9B,uBAAA,IAAI,2FAAwB,MAA5B,IAAI,CAA0B,CAAC;QAC/B,SAAS,CAAC,4BAA4B,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;IAC1E,CAAC;IAwED;;;;;OAKG;IACH,IAAI,QAAQ;QACV,OAAO,uBAAA,IAAI,2CAAY,IAAI,uBAAA,IAAI,4CAAa,MAAjB,IAAI,CAAe,CAAC;IACjD,CAAC;IA+FQ,aAAa,CAAC,EAAE,QAAQ,EAA8B;QAC7D,uBAAA,IAAI,8CAAsB,CAAC,GAAG,QAAQ,CAAC,MAAA,CAAC;QACxC,uBAAA,IAAI,sDAA8B,IAAI,MAAA,CAAC;QACvC,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,EAA4B,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;IAqEQ,+BAA+B,CAAC,UAAkB;QACzD,IAAI,YAAY,GAAiB,EAAE,CAAC;QAEpC,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAChD,YAAY,GAAG,gBAAgB,CAAC,QAAQ,IAAI,EAAE,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;YACzE,uBAAA,IAAI,mFAAgB,MAApB,IAAI,CAAkB,CAAC;YACvB,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,uBAAA,IAAI,kDAAmB,CAAC,CAAC;QAC1D,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QAE5C,MAAM,gBAAgB,GACpB,gBAAgB,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI;YAC5C,CAAC,GAAG,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,IAAI,gBAAgB,EAAE,CAAC;YACrB,uBAAA,IAAI,mFAAgB,MAApB,IAAI,CAAkB,CAAC;QACzB,CAAC;IACH,CAAC;IASD,qBAAqB,CAAC,OAAmB;QACvC,OAAO,CACL,uBAAA,IAAI,mDAAoB,CAAC,OAAO,CAAC,IAAI;YACnC,QAAQ,EAAE,uBAAA,IAAI,gDAAiB;SAChC,CACF,CAAC;IACJ,CAAC;IAEQ,KAAK,CAAC,YAAY,CAAC,EAC1B,QAAQ,EACR,gBAAgB,GAAG,KAAK,GAIzB;QACC,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,yBAAyB,CACvB,OAA+C,EAC/C,UAA4C,EAAE,eAAe,EAAE,IAAI,EAAE;QAErE,MAAM,CAAC,MAAM,CAAC,uBAAA,IAAI,mDAAoB,EAAE,OAAO,CAAC,CAAC;QAEjD,IAAI,uBAAA,IAAI,0DAA2B,EAAE,CAAC;YACpC,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,EACF,uBAAA,IAAI,kDAAmB,EACvB,OAAO,CAAC,eAAe,CACxB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EACnB,QAAQ,EACR,cAAc,EACd,gBAAgB,GAAG,KAAK,MAKtB,EAAE;QACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,uBAAA,IAAI,oFAAiB,MAArB,IAAI,EAAkB,QAAQ,CAAC,CAAC;QACrD,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,MAAM,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,GAC9C,MAAM,uBAAA,IAAI,sFAAmB,MAAvB,IAAI,CAAqB,CAAC;QAElC,MAAM,kBAAkB,GAAG,MAAM,uBAAA,IAAI,qFAAkB,MAAtB,IAAI,EAAmB;YACtD,YAAY;YACZ,eAAe;YACf,WAAW;YACX,QAAQ;YACR,gBAAgB,EAAE,gBAAgB,IAAI,uBAAA,IAAI,iDAAkB;SAC7D,CAAC,CAAC;QAEH,MAAM,kBAAkB,GAAG,uBAAA,IAAI,2FAAwB,MAA5B,IAAI,EAC7B,kBAAkB,EAClB,cAAc,CACf,CAAC;QAEF,MAAM,iBAAiB,GAAG,uBAAA,IAAI,yFAAsB,MAA1B,IAAI,EAC5B,gBAAgB,EAChB,WAAW,EACX,eAAe,CAChB,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,EAA4B;YAC3C,IAAI;YACJ,YAAY;YACZ,iBAAiB;YACjB,QAAQ,EAAE,kBAAkB;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YAExB,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC7C,mCAAmC,CACpC,CAAC;YAEF,MAAM,aAAa,GAAG,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,EACxB,kBAAkB,EAClB,mBAAmB,CACpB,CAAC;YAEF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,+CAA+C,EAC/C,aAAa,CACd,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAG,uBAAA,IAAI,8FAA2B,MAA/B,IAAI,EACxB,kBAAkB,EAClB,mBAAmB,CACpB,CAAC;YAEF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,+CAA+C,EAC/C,aAAa,CACd,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,uBAAA,IAAI,0FAAuB,MAA3B,IAAI,EAAwB,kBAAkB,CAAC,CAAC;IACxD,CAAC;IA0XD,UAAU;QACR,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAiWQ,OAAO;QACd,uBAAA,IAAI,sDAA8B,KAAK,MAAA,CAAC;QACxC,uBAAA,IAAI,sDAAuB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;QACrE,uBAAA,IAAI,sDAAuB,CAAC,KAAK,EAAE,CAAC;QAEpC,IAAI,uBAAA,IAAI,sDAAuB,CAAC,KAAK,EAAE,CAAC;YACtC,YAAY,CAAC,uBAAA,IAAI,sDAAuB,CAAC,KAAK,CAAC,CAAC;YAChD,uBAAA,IAAI,sDAAuB,CAAC,KAAK,GAAG,IAAI,CAAC;QAC3C,CAAC;QAED,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF;;IA9mCG,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,8BAA8B,EAC9B,CAAC,WAAkC,EAAE,EAAE;QACrC,uBAAA,IAAI,gDAAiB,MAArB,IAAI,EAAkB,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACjD,OAAO,CAAC,IAAI,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,+BAA+B,EAC/B,uBAAA,IAAI,iDAAkB,CACvB,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxD,uBAAA,IAAI,uCAAe,IAAI,MAAA,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtD,uBAAA,IAAI,uCAAe,KAAK,MAAA,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,kCAAkC,EAClC,uBAAA,IAAI,iDAAkB,CACvB,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,6CAA6C,EAC7C,uBAAA,IAAI,iDAAkB,CACvB,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,uCAAuC,EACvC,CAAC,KAAK,EAAE,EAAE;QACR,uBAAA,IAAI,+DAAgC,MAApC,IAAI,EAAiC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1D,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,sCAAsC,EACtC,uBAAA,IAAI,+DAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAChD,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,4CAA4C,EAC5C,CAAC,eAAe,EAAE,EAAE;QAClB,IAAI,CAAC,cAAc,CAAC;YAClB,QAAQ,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC;SACpC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,wCAAwC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,oDAAoD,EACpD,CAAC,oBAAoB,EAAE,EAAE;QACvB,IAAI,CAAC,cAAc,CAAC;YAClB,QAAQ,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC;SACvD,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,wCAAwC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC;;IAiBC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IAC9C,MAAM,kBAAkB,GAAkB,EAAE,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAChD,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAqB,CAAC;QAClE,MAAM,eAAe,GAAG,YAAY,CAAC,OAA0B,CAAC,CAAC;QAEjE,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QAED,kBAAkB,CAAC,gBAAgB,MAAnC,kBAAkB,CAAC,gBAAgB,IAAM,EAAE,EAAC;QAE5C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACnD,MAAM,UAAU,GAAG,OAAqB,CAAC;YACzC,MAAA,kBAAkB,CAAC,gBAAgB,CAAC,EAAC,UAAU,SAAV,UAAU,IAAM,EAAE,EAAC;YAExD,MAAM,CAAC,MAAM,CACX,kBAAkB,CAAC,gBAAgB,CAAC,CAAC,UAAU,CAAC,EAChD,eAAe,CAAC,UAAU,CAAC,CAC5B,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IACE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM;QAC9B,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,MAAM;QACxC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,EACrE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;IAGC,OAAO;QACL,GAAG,IAAI,GAAG,CAAC;YACT,GAAG,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,0CAAW,CAAC;YAC/B,GAAG,MAAM,CAAC,IAAI,CAAC,uBAAA,IAAI,+CAAgB,CAAC;SACrC,CAAC;KACa,CAAC;AACpB,CAAC,mHAsD0B,QAAsB,EAAE,SAAS,GAAG,IAAI;IACjE,uBAAA,IAAI,sDAAuB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,uBAAA,IAAI,sDAAuB,CAAC,KAAK,EAAE,CAAC;IAEpC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,IAAI,cAAc,EAAE,CAAC;QACvD,uBAAA,IAAI,4FAAyB,MAA7B,IAAI,EAA0B,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IACpE,CAAC;AACH,CAAC,+GAGC,QAAgB,EAChB,QAAsB,EACtB,SAAS,GAAG,IAAI;IAEhB,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;QAC7C,IAAI,CAAC,uBAAA,IAAI,0DAA2B,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,6BAA6B,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,QAAQ,GAAG,EAC7E,KAAK,CACN,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,SAAS,EAAE,CAAC;QACd,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,OAAO,CAAC,IAAI,CACV,uCAAuC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAC7D,KAAK,CACN,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,uBAAA,IAAI,oFAAiB,MAArB,IAAI,EAAkB,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;AAC1D,CAAC,+FAGC,QAAgB,EAChB,QAAsB,EACtB,YAAiC;IAEjC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,OAAO,CAAC,IAAI,CACV,sCAAsC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAC5D,KAAK,CACN,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEb,uBAAA,IAAI,sDAAuB,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC;IA2BC,uBAAA,IAAI,sDAA8B,KAAK,MAAA,CAAC;IACxC,uBAAA,IAAI,8CAAsB,EAAE,MAAA,CAAC;IAC7B,uBAAA,IAAI,sDAAuB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,uBAAA,IAAI,sDAAuB,CAAC,KAAK,EAAE,CAAC;AACtC,CAAC,+FAqHgB,QAAuB;IACtC,OAAO,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,uBAAA,IAAI,uFAAoB,MAAxB,IAAI,CAAsB,CAAC;AAClE,CAAC,+CAED,KAAK;IAKH,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,uCAAuC,CACxC,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAE3E,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAC7C,GAAG,EAAE;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;IACxE,CAAC,EACD,KAAK,EACL,IAAI,CACL,CAAC;IAEF,OAAO;QACL,eAAe,EAAE,QAA2B;QAC5C,WAAW;QACX,QAAQ;KACT,CAAC;AACJ,CAAC,8CAED,KAAK,oDAAmB,EACtB,YAAY,EACZ,eAAe,EACf,WAAW,EACX,QAAQ,EACR,gBAAgB,GAOjB;IACC,MAAM,UAAU,GAAuB,EAAE,CAAC;IAC1C,IAAI,eAAe,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;IACxC,IAAI,yBAAwD,CAAC;IAC7D,IAAI,mBAAuC,CAAC;IAE5C,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,uBAAA,IAAI,gDAAiB,EAAE,CAAC;QACnE,MAAM,eAAe,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CACxB,CAAC;QACF,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC;gBACjC,QAAQ,EAAE,eAAe;gBACzB,gBAAgB;gBAChB,eAAe;gBACf,WAAW;gBACX,QAAQ;gBACR,iBAAiB,EAAE,yBAAyB;aAC7C,CAAC,CAAC;YAEH,6CAA6C;YAC7C,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAC5B,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAEpC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gBACjE,eAAe,GAAG,eAAe,CAAC,MAAM,CACtC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CACjC,CAAC;YACJ,CAAC;YAED,iEAAiE;YACjE,IAAI,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;gBAC3D,MAAM,uBAAuB,GAAG,MAAM,CAAC,mBAAmB,IAAI,EAAE,CAAC;gBACjE,MAAM,4BAA4B,GAAG,MAAM,CAAC,OAAO,CACjD,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAC/B,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAU,CAAC;gBACpE,MAAM,mBAAmB,GAAG,KAAK,CAAC,IAAI,CACpC,IAAI,GAAG,CAAC;oBACN,GAAG,uBAAuB;oBAC1B,GAAG,4BAA4B;iBAChC,CAAC,CACH,CAAC;gBAEF,eAAe,GAAG,KAAK,CAAC,IAAI,CAC1B,IAAI,GAAG,CAAC,CAAC,GAAG,eAAe,EAAE,GAAG,mBAAmB,CAAC,CAAC,CACtD,CAAC;gBAEF,IAAI,CAAC,SAAS;qBACX,IAAI,CAAC,uCAAuC,EAAE;oBAC7C,QAAQ,EAAE,mBAAmB;oBAC7B,QAAQ,EAAE,IAAI;iBACf,CAAC;qBACD,KAAK,CAAC,GAAG,EAAE;oBACV,yCAAyC;gBAC3C,CAAC,CAAC,CAAC;YACP,CAAC;YAED,gGAAgG;YAChG,MAAM,6BAA6B,GAAG,yBAAyB,CAAC;YAChE,IAAI,6BAA6B,IAAI,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAC7D,MAAM,0BAA0B,GAG1B,EAAE,CAAC;gBAET,sEAAsE;gBACtE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC9B,MAAM,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;oBACnD,MAAM,qBAAqB,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;oBAEtD,MAAM,gBAAgB,GACpB,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBAC/D,MAAM,aAAa,GAAG,6BAA6B,EAAE,CACnD,gBAAgB,CACjB,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;oBAElD,IAAI,gBAAgB,IAAI,aAAa,EAAE,CAAC;wBACtC,0BAA0B,CAAC,IAAI,CAAC;4BAC9B,OAAO,EAAE,GAAG,CAAC,OAAO;4BACpB,YAAY,EAAE,qBAAqB;yBACpC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,MAAM,gCAAgC,GACpC,0BAA0B,CAAC,GAAG,CAC5B,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,CACpD,CAAC;gBACJ,IAAI,0BAA0B,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,CAAC,IAAI,CACV,mCAAmC,mBAAmB,uDAAuD,WAAW,MAAM,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5K,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,0BAA0B;YAC1B,yBAAyB,GAAG,MAAM,CAAC,iBAAiB,CAAC;YACrD,mBAAmB,GAAG,WAAW,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,qCAAqC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CACpF,CAAC;YAEF,IAAI,CAAC,SAAS;iBACX,IAAI,CAAC,uCAAuC,EAAE;gBAC7C,QAAQ,EAAE,eAAe;gBACzB,QAAQ,EAAE,IAAI;aACf,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE;gBACV,yCAAyC;YAC3C,CAAC,CAAC,CAAC;QACP,CAAC;QAED,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC,6GAGC,QAA4B,EAC5B,cAAyB;IAEzB,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAC9C,CAAC;AACJ,CAAC,yGAGC,qBAA0C,EAC1C,WAA8B,EAC9B,eAAgC;IAEhC,MAAM,iBAAiB,GACrB,qBAAqB,IAAI,uBAAA,IAAI,iDAAkB,IAAI,KAAK,CAAC;IAE3D,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAA0B,CAAC,CAAC;AAC1E,CAAC,mHAE0B,EACzB,IAAI,EACJ,YAAY,EACZ,iBAAiB,EACjB,QAAQ,GAMT;IACC,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,EAAE;;QAChC,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;YACnC,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;gBACxC,MAAA,UAAU,CAAC,aAAa,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;gBACzC,MAAA,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC;gBAElD,MAAM,WAAW,GAAG,uBAAA,IAAI,0CAAW,CAAC,OAAO,CAAC,CAAC;gBAC7C,IAAI,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC3B,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CACzC,CAAC,KAA0B,EAAE,EAAE;;wBAC7B,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAC7C,MAAA,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAC,YAAY,SAAZ,YAAY,IACrD,KAAK,EAAC;oBACV,CAAC,CACF,CAAC;gBACJ,CAAC;gBAED,MAAM,mBAAmB,GAAG,uBAAA,IAAI,+CAAgB,CAAC,OAAO,CAAC,CAAC;gBAC1D,IAAI,mBAAmB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;oBACnC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CACjD,CAAC,KAA0B,EAAE,EAAE;;wBAC7B,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBAC7C,MAAA,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAC,YAAY,SAAZ,YAAY,IACrD,KAAK,EAAC;oBACV,CAAC,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;;YAC/D,IAAI,CAAC,OAAO,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,EAAqB,CAAC;YAClE,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAErC,MAAM,cAAc,GAClB,UAAU,CAAC,aAAa,CAAC,gBAAgB,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YAExE,IAAI,cAAc,KAAK,UAAU,EAAE,CAAC;gBAClC,OAAC,OAAC,UAAU,CAAC,aAAa,EAAC,gBAAgB,SAAhB,gBAAgB,IAAM,EAAE,EAAC,EAAC,OAAO,SAAP,OAAO,IAAM,EAAE,EAAC,CACnE,YAAY,CACb,GAAG,UAAU,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,mHAGC,QAA4B,EAC5B,mBAKC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CACpC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY,CAC/D,CAAC;IAEF,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,cAAc;SAClB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;KACxD,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,cAAc,GAClB,mBAAmB,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CACrD,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CACzB,EAAE,OAAO,CAAC;QACb,OAAO,cAAc,KAAK,MAAM,CAAC,OAAO,CAAC;IAC3C,CAAC,CAAC,CAAC;AACP,CAAC,mHAGC,QAA4B,EAC5B,mBAKC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;QACjD,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,sBAAsB,GAC1B,mCAAmC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvD,OAAO,CACL,sBAAsB,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CACtE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,cAAc;SAClB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;KAC5D,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QACjB,MAAM,oBAAoB,GACxB,mBAAmB,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CACrD,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CACzB,EAAE,aAAa,CAAC;QACnB,OAAO,oBAAoB,KAAK,MAAM,CAAC,aAAa,CAAC;IACvD,CAAC,CAAC,CAAC;AACP,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,yDAAwB,QAA4B;IACvD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEtD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,sEAAsE;QACtE,IACE,CAAC,OAAO,CAAC,OAAO;YAChB,OAAO,CAAC,KAAK,KAAK,YAAY;YAC9B,CAAC,OAAO,CAAC,KAAK;YACd,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,EACtB,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACrC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5B,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,gEAAgE;IAChE,KAAK,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,aAAa,EAAE,CAAC;QACtD,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,sDAAsD,EACtD;gBACE,WAAW,EAAE,cAAc;gBAC3B,OAAO;aACR,CACF,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC,6FAOC,YAAoB,EACpB,OAAwB,EACxB,OAAmB;IAEnB,MAAM,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEhD,IACE,uBAAA,IAAI,0CAAW,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,CACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,YAAY,CAC1C,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IACE,uBAAA,IAAI,iDAAkB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAC1D,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,YAAY,CAClC,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,2GA8IC,OAAwB,EACxB,OAAwB,EACxB,OAAmB;IAMnB,MAAM,aAAa,GAAsD,EAAE,CAAC;IAC5E,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,oBAAoB,GAA0B,EAAE,CAAC;IAEvD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;QAEtC,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,GAAG,MAAM,CAAC;QAE7C,IACE,CAAC,iBAAiB,CAAC,YAAY,CAAC;YAChC,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAChC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,oBAAoB,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,uBAAA,IAAI,mFAAgB,MAApB,IAAI,EACpB,oBAAoB,EACpB,OAAO,EACP,OAAO,CACR,CAAC;QAEF,MAAM,UAAU,GAAG,WAAW,CAAC,MAAa,CAAC;QAE7C,aAAa,CAAC,IAAI,CAAC;YACjB,YAAY,EAAE,oBAAoB;YAClC,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,IAAI,aAAa,EAAE,CAAC;YAClB,oBAAoB,CAAC,IAAI,CAAC;gBACxB,OAAO,EAAE,OAAO;gBAChB,OAAO;gBACP,OAAO,EAAE,UAAU;aACpB,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;YACjC,SAAS,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC;AAC5D,CAAC;IAkFC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CACxB,uBAAA,IAAI,sDAAuB,CAAC,cAAc,CAAC,OAAO,EAAE,CACrD,CAAC;IACF,uBAAA,IAAI,sDAAuB,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IACnD,uBAAA,IAAI,sDAAuB,CAAC,KAAK,GAAG,IAAI,CAAC;IAEzC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAA6C,EAAE,CAAC;QAElE,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxC,IACE,aAAa,CAAC,OAAO,CAAC;gBACtB,gBAAgB,CAAC,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAChD,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAE7C,YAAY,CAAC,UAAU,CAAC;gBACtB,MAAM,KAAK,MAAM;oBACf,CAAC,CAAC,EAAE,QAAQ,EAAE,uBAAA,IAAI,gDAAiB,EAAE;oBACrC,CAAC,CAAC,EAAE,QAAQ,EAAE,uBAAA,IAAI,+DAAgC,EAAE,CAAC;QAC3D,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,uBAAA,IAAI,gDAAiB,CAAC;QAC1D,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,yBAAyB,CAAC,YAAY,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC,EAAE,WAAW,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,KAAK,CAAC,CAAC;IACtE,CAAC;AACH,CAAC;AAgBH,eAAe,uBAAuB,CAAC","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type {\n BalanceUpdate,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n} from '@metamask/core-backend';\nimport type {\n KeyringControllerAccountRemovedEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipAssetType,\n isCaipChainId,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual } from 'lodash';\n\nimport type { AccountTrackerControllerGetStateAction } from './AccountTrackerController';\nimport type {\n AccountTrackerControllerUpdateNativeBalancesAction,\n AccountTrackerControllerUpdateStakedBalancesAction,\n} from './AccountTrackerController-method-action-types';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher';\nimport type {\n BalanceFetcher,\n ProcessedBalance,\n UnprocessedTokens,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\nimport type { TokenBalancesControllerMethodActions } from './TokenBalancesController-method-action-types';\nimport type {\n TokenDetectionControllerAddDetectedTokensViaPollingAction,\n TokenDetectionControllerAddDetectedTokensViaWsAction,\n TokenDetectionControllerDetectTokensAction,\n} from './TokenDetectionController-method-action-types';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerState,\n TokensControllerStateChangeEvent,\n} from './TokensController';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst CONTROLLER = 'TokenBalancesController' as const;\nconst DEFAULT_INTERVAL_MS = 30_000; // 30 seconds\nconst DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS = 300_000; // 5 minutes\n\nconst metadata: StateMetadata<TokenBalancesControllerState> = {\n tokenBalances: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n// account → chain → token → balance\nexport type TokenBalances = Record<\n ChecksumAddress,\n Record<ChainIdHex, Record<ChecksumAddress, Hex>>\n>;\n\nexport type TokenBalancesControllerState = {\n tokenBalances: TokenBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerActions =\n | TokenBalancesControllerGetStateAction\n | TokenBalancesControllerMethodActions;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof CONTROLLER, TokenBalancesControllerState>;\n\nexport type NativeBalanceEvent = {\n type: `${typeof CONTROLLER}:updatedNativeBalance`;\n payload: unknown[];\n};\n\nexport type TokenBalancesControllerEvents =\n | TokenBalancesControllerStateChangeEvent\n | NativeBalanceEvent;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | TokensControllerGetStateAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerDetectTokensAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerControllerGetStateAction\n | AccountTrackerControllerUpdateNativeBalancesAction\n | AccountTrackerControllerUpdateStakedBalancesAction\n | KeyringControllerGetStateAction\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\nexport type TokenBalancesControllerMessenger = Messenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents\n>;\n\nexport type ChainPollingConfig = {\n /** Polling interval in milliseconds for this chain */\n interval: number;\n};\n\nexport type UpdateChainPollingConfigsOptions = {\n /** Whether to immediately fetch balances after updating configs (default: true) */\n immediateUpdate?: boolean;\n};\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n /** Default interval for chains not specified in chainPollingIntervals */\n interval?: number;\n /** Per-chain polling configuration */\n chainPollingIntervals?: Record<ChainIdHex, ChainPollingConfig>;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Array of chainIds that should use Accounts-API strategy (if supported by API). */\n accountsApiChainIds?: () => ChainIdHex[];\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n platform?: 'extension' | 'mobile';\n /** Polling interval when WebSocket is active and providing real-time updates */\n websocketActivePollingInterval?: number;\n /** Whether the user has completed onboarding. If false, balance updates are skipped. */\n isOnboarded?: () => boolean;\n};\n\nconst draft = <State>(base: State, fn: (draftState: State) => void): State =>\n produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): ChainIdHex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Extract token address from asset type.\n *\n * @param assetType - Asset type string.\n * @returns Tuple of [tokenAddress, isNativeToken] or null if invalid.\n */\nexport const parseAssetType = (assetType: string): [string, boolean] | null => {\n if (!isCaipAssetType(assetType)) {\n return null;\n }\n\n const parsed = parseCaipAssetType(assetType);\n\n if (parsed.assetNamespace === 'erc20') {\n return [parsed.assetReference, false];\n }\n\n if (parsed.assetNamespace === 'slip44') {\n return [ZERO_ADDRESS, true];\n }\n\n return null;\n};\n\ntype NativeBalanceUpdate = { address: string; chainId: Hex; balance: Hex };\ntype StakedBalanceUpdate = {\n address: string;\n chainId: Hex;\n stakedBalance: Hex;\n};\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateChainPollingConfigs',\n 'getChainPollingConfig',\n] as const;\n\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #platform: 'extension' | 'mobile';\n\n readonly #queryAllAccounts: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #allowExternalServices: () => boolean;\n\n readonly #isOnboarded: () => boolean;\n\n readonly #balanceFetchers: { fetcher: BalanceFetcher; name: string }[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n #allIgnoredTokens: TokensControllerState['allIgnoredTokens'] = {};\n\n /** Default polling interval for chains without specific configuration */\n readonly #defaultInterval: number;\n\n /** Polling interval when WebSocket is active and providing real-time updates */\n readonly #websocketActivePollingInterval: number;\n\n /** Per-chain polling configuration */\n readonly #chainPollingConfig: Record<ChainIdHex, ChainPollingConfig>;\n\n /** Active polling timers grouped by interval */\n readonly #intervalPollingTimers: Map<number, NodeJS.Timeout> = new Map();\n\n /** Track if controller-level polling is active */\n #isControllerPollingActive = false;\n\n /** Track if the keyring is unlocked */\n #isUnlocked = false;\n\n /** Store original chainIds from startPolling to preserve intent */\n #requestedChainIds: ChainIdHex[] = [];\n\n /** Debouncing for rapid status changes to prevent excessive HTTP calls */\n readonly #statusChangeDebouncer: {\n timer: NodeJS.Timeout | null;\n pendingChanges: Map<string, 'up' | 'down'>;\n } = {\n timer: null,\n pendingChanges: new Map(),\n };\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n websocketActivePollingInterval = DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS,\n chainPollingIntervals = {},\n state = {},\n queryMultipleAccounts = true,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n platform,\n isOnboarded = (): boolean => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#normalizeAccountAddresses();\n\n this.#platform = platform ?? 'extension';\n this.#queryAllAccounts = queryMultipleAccounts;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#allowExternalServices = allowExternalServices;\n this.#isOnboarded = isOnboarded;\n this.#defaultInterval = interval;\n this.#websocketActivePollingInterval = websocketActivePollingInterval;\n this.#chainPollingConfig = { ...chainPollingIntervals };\n\n // Always include AccountsApiFetcher - it dynamically checks allowExternalServices() in supports()\n this.#balanceFetchers = [\n {\n fetcher: this.#createAccountsApiFetcher(),\n name: 'AccountsApiFetcher',\n },\n {\n fetcher: new RpcBalanceFetcher(\n this.#getProvider,\n this.#getNetworkClient,\n () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n }),\n ),\n name: 'RpcFetcher',\n },\n ];\n\n this.setIntervalLength(interval);\n\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n this.#allIgnoredTokens = allIgnoredTokens;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#subscribeToControllers();\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n }\n\n #subscribeToControllers(): void {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n (tokensState: TokensControllerState) => {\n this.#onTokensChanged(tokensState).catch((error) => {\n console.warn('Error handling token state change:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n\n this.messenger.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n this.#onAccountChanged,\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n (event) => {\n this.#onAccountActivityBalanceUpdate(event).catch((error) => {\n console.warn('Error handling balance update:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged.bind(this),\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.updateBalances({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n (incomingTransactions) => {\n this.updateBalances({\n chainIds: incomingTransactions.map((tx) => tx.chainId),\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n }\n\n /**\n * Whether the controller is active (keyring is unlocked and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return this.#isUnlocked && this.#isOnboarded();\n }\n\n /**\n * Normalize all account addresses to lowercase and merge duplicates\n * Handles migration from old state where addresses might be checksummed.\n */\n #normalizeAccountAddresses(): void {\n const currentState = this.state.tokenBalances;\n const normalizedBalances: TokenBalances = {};\n\n for (const address of Object.keys(currentState)) {\n const lowercaseAddress = address.toLowerCase() as ChecksumAddress;\n const accountBalances = currentState[address as ChecksumAddress];\n\n if (!accountBalances) {\n continue;\n }\n\n normalizedBalances[lowercaseAddress] ??= {};\n\n for (const chainId of Object.keys(accountBalances)) {\n const chainIdKey = chainId as ChainIdHex;\n normalizedBalances[lowercaseAddress][chainIdKey] ??= {};\n\n Object.assign(\n normalizedBalances[lowercaseAddress][chainIdKey],\n accountBalances[chainIdKey],\n );\n }\n }\n\n if (\n Object.keys(currentState).length !==\n Object.keys(normalizedBalances).length ||\n Object.keys(currentState).some((addr) => addr !== addr.toLowerCase())\n ) {\n this.update(() => ({ tokenBalances: normalizedBalances }));\n }\n }\n\n #chainIdsWithTokens(): ChainIdHex[] {\n return [\n ...new Set([\n ...Object.keys(this.#allTokens),\n ...Object.keys(this.#detectedTokens),\n ]),\n ] as ChainIdHex[];\n }\n\n readonly #getProvider = (chainId: ChainIdHex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (\n chainId: ChainIdHex,\n ): ReturnType<NetworkControllerGetNetworkClientByIdAction['handler']> => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n this.#platform,\n this.#getProvider,\n () => this.state.tokenBalances, // list of existing user tokens\n );\n\n return {\n // Dynamically check allowExternalServices() at call time, not just at construction time\n supports: (chainId: ChainIdHex): boolean =>\n this.#allowExternalServices() &&\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId),\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n override _startPolling({ chainIds }: { chainIds: ChainIdHex[] }): void {\n this.#requestedChainIds = [...chainIds];\n this.#isControllerPollingActive = true;\n this.#startIntervalGroupPolling(chainIds, true);\n }\n\n #startIntervalGroupPolling(chainIds: ChainIdHex[], immediate = true): void {\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n const intervalGroups = new Map<number, ChainIdHex[]>();\n\n for (const chainId of chainIds) {\n const config = this.getChainPollingConfig(chainId);\n const group = intervalGroups.get(config.interval) ?? [];\n group.push(chainId);\n intervalGroups.set(config.interval, group);\n }\n\n for (const [interval, chainIdsGroup] of intervalGroups) {\n this.#startPollingForInterval(interval, chainIdsGroup, immediate);\n }\n }\n\n #startPollingForInterval(\n interval: number,\n chainIds: ChainIdHex[],\n immediate = true,\n ): void {\n const pollFunction = async (): Promise<void> => {\n if (!this.#isControllerPollingActive) {\n return;\n }\n\n try {\n await this._executePoll({ chainIds });\n } catch (error) {\n console.warn(\n `Polling failed for chains ${chainIds.join(', ')} with interval ${interval}:`,\n error,\n );\n }\n };\n\n if (immediate) {\n pollFunction().catch((error) => {\n console.warn(\n `Immediate polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }\n\n this.#setPollingTimer(interval, chainIds, pollFunction);\n }\n\n #setPollingTimer(\n interval: number,\n chainIds: ChainIdHex[],\n pollFunction: () => Promise<void>,\n ): void {\n const timer = setInterval(() => {\n pollFunction().catch((error) => {\n console.warn(\n `Interval polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }, interval);\n\n this.#intervalPollingTimers.set(interval, timer);\n }\n\n override _stopPollingByPollingTokenSetId(tokenSetId: string): void {\n let chainsToStop: ChainIdHex[] = [];\n\n try {\n const parsedTokenSetId = JSON.parse(tokenSetId);\n chainsToStop = parsedTokenSetId.chainIds ?? [];\n } catch (error) {\n console.warn('Failed to parse tokenSetId, stopping all polling:', error);\n this.#stopAllPolling();\n return;\n }\n\n const currentChainsSet = new Set(this.#requestedChainIds);\n const stopChainsSet = new Set(chainsToStop);\n\n const isCurrentSession =\n currentChainsSet.size === stopChainsSet.size &&\n [...currentChainsSet].every((chain) => stopChainsSet.has(chain));\n\n if (isCurrentSession) {\n this.#stopAllPolling();\n }\n }\n\n #stopAllPolling(): void {\n this.#isControllerPollingActive = false;\n this.#requestedChainIds = [];\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n }\n\n getChainPollingConfig(chainId: ChainIdHex): ChainPollingConfig {\n return (\n this.#chainPollingConfig[chainId] ?? {\n interval: this.#defaultInterval,\n }\n );\n }\n\n override async _executePoll({\n chainIds,\n queryAllAccounts = false,\n }: {\n chainIds: ChainIdHex[];\n queryAllAccounts?: boolean;\n }): Promise<void> {\n await this.updateBalances({ chainIds, queryAllAccounts });\n }\n\n updateChainPollingConfigs(\n configs: Record<ChainIdHex, ChainPollingConfig>,\n options: UpdateChainPollingConfigsOptions = { immediateUpdate: true },\n ): void {\n Object.assign(this.#chainPollingConfig, configs);\n\n if (this.#isControllerPollingActive) {\n this.#startIntervalGroupPolling(\n this.#requestedChainIds,\n options.immediateUpdate,\n );\n }\n }\n\n async updateBalances({\n chainIds,\n tokenAddresses,\n queryAllAccounts = false,\n }: {\n chainIds?: ChainIdHex[];\n tokenAddresses?: string[];\n queryAllAccounts?: boolean;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const targetChains = this.#getTargetChains(chainIds);\n if (!targetChains.length) {\n return;\n }\n\n const { selectedAccount, allAccounts, jwtToken } =\n await this.#getAccountsAndJwt();\n\n const aggregatedBalances = await this.#fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts: queryAllAccounts ?? this.#queryAllAccounts,\n });\n\n const filteredAggregated = this.#filterByTokenAddresses(\n aggregatedBalances,\n tokenAddresses,\n );\n\n const accountsToProcess = this.#getAccountsToProcess(\n queryAllAccounts,\n allAccounts,\n selectedAccount,\n );\n\n const prev = this.state;\n const next = this.#applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances: filteredAggregated,\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const accountTrackerState = this.messenger.call(\n 'AccountTrackerController:getState',\n );\n\n const nativeUpdates = this.#buildNativeBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (nativeUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeUpdates,\n );\n }\n\n const stakedUpdates = this.#buildStakedBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (stakedUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedUpdates,\n );\n }\n }\n\n await this.#importUntrackedTokens(filteredAggregated);\n }\n\n #getTargetChains(chainIds?: ChainIdHex[]): ChainIdHex[] {\n return chainIds?.length ? chainIds : this.#chainIdsWithTokens();\n }\n\n async #getAccountsAndJwt(): Promise<{\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken: string | undefined;\n }> {\n const { address: selected } = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n\n const jwtToken = await safelyExecuteWithTimeout<string | undefined>(\n () => {\n return this.messenger.call('AuthenticationController:getBearerToken');\n },\n false,\n 5000,\n );\n\n return {\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n jwtToken,\n };\n }\n\n async #fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts,\n }: {\n targetChains: ChainIdHex[];\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n queryAllAccounts: boolean;\n }): Promise<ProcessedBalance[]> {\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n let previousUnprocessedTokens: UnprocessedTokens | undefined;\n let previousFetcherName: string | undefined;\n\n for (const { fetcher, name: fetcherName } of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chain) =>\n fetcher.supports(chain),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n unprocessedTokens: previousUnprocessedTokens,\n });\n\n // Add balances, and removed processed chains\n if (result.balances?.length) {\n aggregated.push(...result.balances);\n\n const processed = new Set(result.balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processed.has(chain),\n );\n }\n\n // Add unprocessed chains (from missing chains or missing tokens)\n if (result.unprocessedChainIds || result.unprocessedTokens) {\n const resultUnprocessedChains = result.unprocessedChainIds ?? [];\n const resultUnsupportedTokenChains = Object.entries(\n result.unprocessedTokens ?? {},\n ).flatMap(([_account, chainMap]) => Object.keys(chainMap)) as Hex[];\n const unprocessedChainIds = Array.from(\n new Set([\n ...resultUnprocessedChains,\n ...resultUnsupportedTokenChains,\n ]),\n );\n\n remainingChains = Array.from(\n new Set([...remainingChains, ...unprocessedChainIds]),\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: unprocessedChainIds,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n // Balance Error Reporting - for unprocessed tokens from last fetcher, if balances are retrieved\n const unprocessedTokensForReporting = previousUnprocessedTokens;\n if (unprocessedTokensForReporting && result.balances?.length) {\n const confirmedUnprocessedTokens: {\n chainId: string;\n tokenAddress: string;\n }[] = [];\n\n // Capture balances that were found (> 0 balance), and was unprocessed\n result.balances.forEach((bal) => {\n const lowercaseAccount = bal.account.toLowerCase();\n const lowercaseTokenAddress = bal.token.toLowerCase();\n\n const hasResultBalance =\n bal.success && bal.token && bal.value && !bal.value.isZero();\n const isUnprocessed = unprocessedTokensForReporting?.[\n lowercaseAccount\n ]?.[bal.chainId]?.includes(lowercaseTokenAddress);\n\n if (hasResultBalance && isUnprocessed) {\n confirmedUnprocessedTokens.push({\n chainId: bal.chainId,\n tokenAddress: lowercaseTokenAddress,\n });\n }\n });\n\n const confirmedUnprocessedTokenStrings =\n confirmedUnprocessedTokens.map(\n (token) => `${token.chainId}:${token.tokenAddress}`,\n );\n if (confirmedUnprocessedTokens.length) {\n console.warn(\n `TokenBalanceController: fetcher ${previousFetcherName} did not process tokens (instead handled by fetcher ${fetcherName}): ${confirmedUnprocessedTokenStrings.join(', ')}`,\n );\n }\n }\n\n // Set new previous fields\n previousUnprocessedTokens = result.unprocessedTokens;\n previousFetcherName = fetcherName;\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: supportedChains,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n if (!remainingChains.length) {\n break;\n }\n }\n\n return aggregated;\n }\n\n #filterByTokenAddresses(\n balances: ProcessedBalance[],\n tokenAddresses?: string[],\n ): ProcessedBalance[] {\n if (!tokenAddresses?.length) {\n return balances;\n }\n\n const lowered = tokenAddresses.map((a) => a.toLowerCase());\n return balances.filter((balance) =>\n lowered.includes(balance.token.toLowerCase()),\n );\n }\n\n #getAccountsToProcess(\n queryAllAccountsParam: boolean | undefined,\n allAccounts: InternalAccount[],\n selectedAccount: ChecksumAddress,\n ): ChecksumAddress[] {\n const effectiveQueryAll =\n queryAllAccountsParam ?? this.#queryAllAccounts ?? false;\n\n if (!effectiveQueryAll) {\n return [selectedAccount];\n }\n\n return allAccounts.map((account) => account.address as ChecksumAddress);\n }\n\n #applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances,\n }: {\n prev: TokenBalancesControllerState;\n targetChains: ChainIdHex[];\n accountsToProcess: ChecksumAddress[];\n balances: ProcessedBalance[];\n }): TokenBalancesControllerState {\n return draft(prev, (draftState) => {\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n draftState.tokenBalances[account] ??= {};\n draftState.tokenBalances[account][chainId] ??= {};\n\n const chainTokens = this.#allTokens[chainId];\n if (chainTokens?.[account]) {\n Object.values(chainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n\n const detectedChainTokens = this.#detectedTokens[chainId];\n if (detectedChainTokens?.[account]) {\n Object.values(detectedChainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n }\n }\n\n balances.forEach(({ success, value, account, token, chainId }) => {\n if (!success || value === undefined) {\n return;\n }\n\n const lowerCaseAccount = account.toLowerCase() as ChecksumAddress;\n const newBalance = toHex(value);\n const tokenAddress = checksum(token);\n\n const currentBalance =\n draftState.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress];\n\n if (currentBalance !== newBalance) {\n ((draftState.tokenBalances[lowerCaseAccount] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = newBalance;\n }\n });\n });\n }\n\n #buildNativeBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): NativeBalanceUpdate[] {\n const nativeBalances = balances.filter(\n (balance) => balance.success && balance.token === ZERO_ADDRESS,\n );\n\n if (!nativeBalances.length) {\n return [];\n }\n\n return nativeBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.balance;\n return currentBalance !== update.balance;\n });\n }\n\n #buildStakedBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): StakedBalanceUpdate[] {\n const stakedBalances = balances.filter((balance) => {\n if (!balance.success || balance.token === ZERO_ADDRESS) {\n return false;\n }\n\n const stakingContractAddress =\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[balance.chainId];\n return (\n stakingContractAddress?.toLowerCase() === balance.token.toLowerCase()\n );\n });\n\n if (!stakedBalances.length) {\n return [];\n }\n\n return stakedBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentStakedBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.stakedBalance;\n return currentStakedBalance !== update.stakedBalance;\n });\n }\n\n /**\n * Import untracked tokens that have non-zero balances.\n * This mirrors the v2 behavior where only tokens with actual balances are added.\n * Delegates to TokenDetectionController:addDetectedTokensViaPolling which handles:\n * - Checking if useTokenDetection preference is enabled\n * - Filtering tokens already in allTokens or allIgnoredTokens\n * - Token metadata lookup and addition via TokensController\n *\n * @param balances - Array of processed balance results from fetchers\n */\n async #importUntrackedTokens(balances: ProcessedBalance[]): Promise<void> {\n const tokensByChain = new Map<ChainIdHex, string[]>();\n\n for (const balance of balances) {\n // Skip failed fetches, native tokens, and zero balances (like v2 did)\n if (\n !balance.success ||\n balance.token === ZERO_ADDRESS ||\n !balance.value ||\n balance.value.isZero()\n ) {\n continue;\n }\n\n const tokenAddress = checksum(balance.token);\n const existing = tokensByChain.get(balance.chainId) ?? [];\n if (!existing.includes(tokenAddress)) {\n existing.push(tokenAddress);\n tokensByChain.set(balance.chainId, existing);\n }\n }\n\n // Add detected tokens via TokenDetectionController (handles preference check,\n // filtering of allTokens/allIgnoredTokens, and metadata lookup)\n for (const [chainId, tokenAddresses] of tokensByChain) {\n if (tokenAddresses.length) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaPolling',\n {\n tokensSlice: tokenAddresses,\n chainId,\n },\n );\n }\n }\n }\n\n resetState(): void {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n #isTokenTracked(\n tokenAddress: string,\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): boolean {\n const normalizedAccount = account.toLowerCase();\n\n if (\n this.#allTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token.address === tokenAddress,\n )\n ) {\n return true;\n }\n\n if (\n this.#allIgnoredTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token === tokenAddress,\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n readonly #onTokensChanged = async (\n state: TokensControllerState,\n ): Promise<void> => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n const relevantChainIds = Array.from(incomingChainIds).filter((chainId) => {\n const id = chainId as ChainIdHex;\n\n const hasTokensNow =\n (state.allTokens[id] && Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] && Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (!relevantChainIds.length) {\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n this.update((currentState) => {\n for (const chainId of relevantChainIds) {\n const id = chainId as ChainIdHex;\n const hasTokensNow =\n (state.allTokens[id] &&\n Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] &&\n Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const tokensChanged =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n if (!tokensChanged) {\n continue;\n }\n\n if (hasTokensNow) {\n changed.push(id);\n } else if (hadTokensBefore) {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (currentState.tokenBalances[addressKey]?.[id]) {\n currentState.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n this.#allIgnoredTokens = state.allIgnoredTokens;\n\n if (changed.length && !hasChanges) {\n this.updateBalances({ chainIds: changed }).catch((error) => {\n console.warn('Error updating balances after token change:', error);\n });\n }\n };\n\n readonly #onNetworkChanged = (state: NetworkState): void => {\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n const networksWithBalances = new Set<string>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const network of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n networksWithBalances.add(network);\n }\n }\n\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (!removedNetworks.length) {\n return;\n }\n\n this.update((currentState) => {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (currentState.tokenBalances[addressKey]?.[networkKey]) {\n delete currentState.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n };\n\n readonly #onAccountRemoved = (addr: string): void => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((currentState) => {\n delete currentState.tokenBalances[addr];\n });\n };\n\n readonly #onAccountChanged = (): void => {\n const chainIds = this.#chainIdsWithTokens();\n if (!chainIds.length) {\n return;\n }\n\n this.updateBalances({ chainIds }).catch(() => {\n // Silently handle polling errors\n });\n };\n\n #prepareBalanceUpdates(\n updates: BalanceUpdate[],\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): {\n tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[];\n newTokens: string[];\n nativeBalanceUpdates: NativeBalanceUpdate[];\n } {\n const tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[] = [];\n const newTokens: string[] = [];\n const nativeBalanceUpdates: NativeBalanceUpdate[] = [];\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (postBalance.error) {\n throw new Error('Balance update has error');\n }\n\n const parsed = parseAssetType(asset.type);\n if (!parsed) {\n throw new Error('Failed to parse asset type');\n }\n\n const [tokenAddress, isNativeToken] = parsed;\n\n if (\n !isStrictHexString(tokenAddress) ||\n !isValidHexAddress(tokenAddress)\n ) {\n throw new Error('Invalid token address');\n }\n\n const checksumTokenAddress = checksum(tokenAddress);\n const isTracked = this.#isTokenTracked(\n checksumTokenAddress,\n account,\n chainId,\n );\n\n const balanceHex = postBalance.amount as Hex;\n\n tokenBalances.push({\n tokenAddress: checksumTokenAddress,\n balance: balanceHex,\n });\n\n if (isNativeToken) {\n nativeBalanceUpdates.push({\n address: account,\n chainId,\n balance: balanceHex,\n });\n }\n\n if (!isNativeToken && !isTracked) {\n newTokens.push(checksumTokenAddress);\n }\n }\n\n return { tokenBalances, newTokens, nativeBalanceUpdates };\n }\n\n readonly #onAccountActivityBalanceUpdate = async ({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): Promise<void> => {\n const chainId = caipChainIdToHex(chain);\n const checksummedAccount = checksum(address);\n\n try {\n const { tokenBalances, newTokens, nativeBalanceUpdates } =\n this.#prepareBalanceUpdates(updates, checksummedAccount, chainId);\n\n if (tokenBalances.length > 0) {\n this.update((state) => {\n const lowercaseAccount =\n checksummedAccount.toLowerCase() as ChecksumAddress;\n state.tokenBalances[lowercaseAccount] ??= {};\n state.tokenBalances[lowercaseAccount][chainId] ??= {};\n\n for (const { tokenAddress, balance } of tokenBalances) {\n state.tokenBalances[lowercaseAccount][chainId][tokenAddress] =\n balance;\n }\n });\n }\n\n if (nativeBalanceUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeBalanceUpdates,\n );\n }\n\n if (newTokens.length > 0) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaWs',\n {\n tokensSlice: newTokens,\n chainId,\n },\n );\n }\n } catch (error) {\n console.warn(\n `Error updating balances from AccountActivityService for chain ${chain}, account ${address}:`,\n error,\n );\n console.warn('Balance update data:', JSON.stringify(updates, null, 2));\n\n await this.updateBalances({ chainIds: [chainId] }).catch(() => {\n // Silently handle polling errors\n });\n }\n };\n\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n }): void => {\n for (const chainId of chainIds) {\n this.#statusChangeDebouncer.pendingChanges.set(chainId, status);\n }\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n }\n\n this.#statusChangeDebouncer.timer = setTimeout(() => {\n this.#processAccumulatedStatusChanges();\n }, 5000);\n };\n\n #processAccumulatedStatusChanges(): void {\n const changes = Array.from(\n this.#statusChangeDebouncer.pendingChanges.entries(),\n );\n this.#statusChangeDebouncer.pendingChanges.clear();\n this.#statusChangeDebouncer.timer = null;\n\n if (!changes.length) {\n return;\n }\n\n try {\n const chainConfigs: Record<ChainIdHex, { interval: number }> = {};\n\n for (const [chainId, status] of changes) {\n if (\n isCaipChainId(chainId) &&\n parseCaipChainId(chainId).namespace !== 'eip155'\n ) {\n continue;\n }\n\n const hexChainId = caipChainIdToHex(chainId);\n\n chainConfigs[hexChainId] =\n status === 'down'\n ? { interval: this.#defaultInterval }\n : { interval: this.#websocketActivePollingInterval };\n }\n\n if (Object.keys(chainConfigs).length === 0) {\n return;\n }\n\n const jitterDelay = Math.random() * this.#defaultInterval;\n setTimeout(() => {\n this.updateChainPollingConfigs(chainConfigs, { immediateUpdate: true });\n }, jitterDelay);\n } catch (error) {\n console.warn('Error processing accumulated status changes:', error);\n }\n }\n\n override destroy(): void {\n this.#isControllerPollingActive = false;\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n this.#statusChangeDebouncer.timer = null;\n }\n\n super.destroy();\n }\n}\n\nexport default TokenBalancesController;\n"]}
1
+ {"version":3,"file":"TokenBalancesController.mjs","sourceRoot":"","sources":["../src/TokenBalancesController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Web3Provider } from '@ethersproject/providers';\nimport type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerListAccountsAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n StateMetadata,\n} from '@metamask/base-controller';\nimport {\n BNToHex,\n isValidHexAddress,\n safelyExecuteWithTimeout,\n toChecksumHexAddress,\n toHex,\n} from '@metamask/controller-utils';\nimport type {\n BalanceUpdate,\n AccountActivityServiceBalanceUpdatedEvent,\n AccountActivityServiceStatusChangedEvent,\n} from '@metamask/core-backend';\nimport type {\n KeyringControllerAccountRemovedEvent,\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\nimport type {\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetStateAction,\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { AuthenticationController } from '@metamask/profile-sync-controller';\nimport type {\n TransactionControllerIncomingTransactionsReceivedEvent,\n TransactionControllerTransactionConfirmedEvent,\n} from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport {\n isCaipAssetType,\n isCaipChainId,\n isStrictHexString,\n parseCaipAssetType,\n parseCaipChainId,\n} from '@metamask/utils';\nimport { produce } from 'immer';\nimport { isEqual, union } from 'lodash';\n\nimport type { AccountTrackerControllerGetStateAction } from './AccountTrackerController';\nimport type {\n AccountTrackerControllerUpdateNativeBalancesAction,\n AccountTrackerControllerUpdateStakedBalancesAction,\n} from './AccountTrackerController-method-action-types';\nimport { STAKING_CONTRACT_ADDRESS_BY_CHAINID } from './AssetsContractController';\nimport { AccountsApiBalanceFetcher } from './multi-chain-accounts-service/api-balance-fetcher';\nimport type {\n BalanceFetcher,\n ProcessedBalance,\n UnprocessedTokens,\n} from './multi-chain-accounts-service/api-balance-fetcher';\nimport { RpcBalanceFetcher } from './rpc-service/rpc-balance-fetcher';\nimport type { TokenBalancesControllerMethodActions } from './TokenBalancesController-method-action-types';\nimport type {\n TokenDetectionControllerAddDetectedTokensViaPollingAction,\n TokenDetectionControllerAddDetectedTokensViaWsAction,\n TokenDetectionControllerDetectTokensAction,\n} from './TokenDetectionController-method-action-types';\nimport type {\n TokensControllerGetStateAction,\n TokensControllerState,\n TokensControllerStateChangeEvent,\n} from './TokensController';\nimport { createBatchedHandler } from './utils/create-batch-handler';\n\nexport type ChainIdHex = Hex;\nexport type ChecksumAddress = Hex;\n\nconst CONTROLLER = 'TokenBalancesController' as const;\nconst DEFAULT_INTERVAL_MS = 30_000; // 30 seconds\nconst DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS = 300_000; // 5 minutes\n\n/** Debounce wait (ms) for coalescing rapid updateBalances calls before flush */\nexport const UPDATE_BALANCES_BATCH_MS = 200;\n\nexport type UpdateBalancesOptions = {\n chainIds?: ChainIdHex[];\n tokenAddresses?: string[];\n queryAllAccounts?: boolean;\n};\n\n/**\n * Merges two UpdateBalancesOptions per queue-and-merge rules:\n * - chainIds: union of both lists when each option includes `chainIds`; if either omits `chainIds`, the merged field is undefined (all chains).\n * - tokenAddresses: union of both lists when each option includes `tokenAddresses`; if either omits `tokenAddresses`, the merged field is undefined (all tokens).\n * - queryAllAccounts: true if either is true.\n * Exported for tests.\n *\n * @param a - First options (e.g. accumulated).\n * @param b - Second options to merge in.\n * @returns New merged options.\n */\nexport function mergeUpdateBalancesOptions(\n a: UpdateBalancesOptions,\n b: UpdateBalancesOptions,\n): UpdateBalancesOptions {\n const chainIds = a.chainIds && b.chainIds && union(a.chainIds, b.chainIds);\n const tokenAddresses =\n a.tokenAddresses &&\n b.tokenAddresses &&\n union(a.tokenAddresses, b.tokenAddresses);\n const queryAllAccounts =\n Boolean(a.queryAllAccounts) || Boolean(b.queryAllAccounts);\n return { chainIds, tokenAddresses, queryAllAccounts };\n}\nconst metadata: StateMetadata<TokenBalancesControllerState> = {\n tokenBalances: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n};\n\n// account → chain → token → balance\nexport type TokenBalances = Record<\n ChecksumAddress,\n Record<ChainIdHex, Record<ChecksumAddress, Hex>>\n>;\n\nexport type TokenBalancesControllerState = {\n tokenBalances: TokenBalances;\n};\n\nexport type TokenBalancesControllerGetStateAction = ControllerGetStateAction<\n typeof CONTROLLER,\n TokenBalancesControllerState\n>;\n\nexport type TokenBalancesControllerActions =\n | TokenBalancesControllerGetStateAction\n | TokenBalancesControllerMethodActions;\n\nexport type TokenBalancesControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof CONTROLLER, TokenBalancesControllerState>;\n\nexport type NativeBalanceEvent = {\n type: `${typeof CONTROLLER}:updatedNativeBalance`;\n payload: unknown[];\n};\n\nexport type TokenBalancesControllerEvents =\n | TokenBalancesControllerStateChangeEvent\n | NativeBalanceEvent;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetStateAction\n | TokensControllerGetStateAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerDetectTokensAction\n | PreferencesControllerGetStateAction\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerListAccountsAction\n | AccountTrackerControllerGetStateAction\n | AccountTrackerControllerUpdateNativeBalancesAction\n | AccountTrackerControllerUpdateStakedBalancesAction\n | KeyringControllerGetStateAction\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\nexport type AllowedEvents =\n | TokensControllerStateChangeEvent\n | PreferencesControllerStateChangeEvent\n | NetworkControllerStateChangeEvent\n | KeyringControllerAccountRemovedEvent\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | AccountActivityServiceBalanceUpdatedEvent\n | AccountActivityServiceStatusChangedEvent\n | AccountsControllerSelectedEvmAccountChangeEvent\n | TransactionControllerTransactionConfirmedEvent\n | TransactionControllerIncomingTransactionsReceivedEvent;\n\nexport type TokenBalancesControllerMessenger = Messenger<\n typeof CONTROLLER,\n TokenBalancesControllerActions | AllowedActions,\n TokenBalancesControllerEvents | AllowedEvents\n>;\n\nexport type ChainPollingConfig = {\n /** Polling interval in milliseconds for this chain */\n interval: number;\n};\n\nexport type UpdateChainPollingConfigsOptions = {\n /** Whether to immediately fetch balances after updating configs (default: true) */\n immediateUpdate?: boolean;\n};\n\nexport type TokenBalancesControllerOptions = {\n messenger: TokenBalancesControllerMessenger;\n /** Default interval for chains not specified in chainPollingIntervals */\n interval?: number;\n /** Per-chain polling configuration */\n chainPollingIntervals?: Record<ChainIdHex, ChainPollingConfig>;\n state?: Partial<TokenBalancesControllerState>;\n /** When `true`, balances for *all* known accounts are queried. */\n queryMultipleAccounts?: boolean;\n /** Array of chainIds that should use Accounts-API strategy (if supported by API). */\n accountsApiChainIds?: () => ChainIdHex[];\n /** Disable external HTTP calls (privacy / offline mode). */\n allowExternalServices?: () => boolean;\n /** Custom logger. */\n log?: (...args: unknown[]) => void;\n platform?: 'extension' | 'mobile';\n /** Polling interval when WebSocket is active and providing real-time updates */\n websocketActivePollingInterval?: number;\n /** Whether the user has completed onboarding. If false, balance updates are skipped. */\n isOnboarded?: () => boolean;\n};\n\nconst draft = <State>(base: State, fn: (draftState: State) => void): State =>\n produce(base, fn);\n\nconst ZERO_ADDRESS =\n '0x0000000000000000000000000000000000000000' as ChecksumAddress;\n\nconst checksum = (addr: string): ChecksumAddress =>\n toChecksumHexAddress(addr) as ChecksumAddress;\n\n/**\n * Convert CAIP chain ID or hex chain ID to hex chain ID.\n *\n * @param chainId - CAIP chain ID or hex chain ID.\n * @returns Hex chain ID.\n */\nexport const caipChainIdToHex = (chainId: string): ChainIdHex => {\n if (isStrictHexString(chainId)) {\n return chainId;\n }\n\n if (isCaipChainId(chainId)) {\n return toHex(parseCaipChainId(chainId).reference);\n }\n\n throw new Error('caipChainIdToHex - Failed to provide CAIP-2 or Hex chainId');\n};\n\n/**\n * Extract token address from asset type.\n *\n * @param assetType - Asset type string.\n * @returns Tuple of [tokenAddress, isNativeToken] or null if invalid.\n */\nexport const parseAssetType = (assetType: string): [string, boolean] | null => {\n if (!isCaipAssetType(assetType)) {\n return null;\n }\n\n const parsed = parseCaipAssetType(assetType);\n\n if (parsed.assetNamespace === 'erc20') {\n return [parsed.assetReference, false];\n }\n\n if (parsed.assetNamespace === 'slip44') {\n return [ZERO_ADDRESS, true];\n }\n\n return null;\n};\n\ntype NativeBalanceUpdate = { address: string; chainId: Hex; balance: Hex };\ntype StakedBalanceUpdate = {\n address: string;\n chainId: Hex;\n stakedBalance: Hex;\n};\nconst MESSENGER_EXPOSED_METHODS = [\n 'updateChainPollingConfigs',\n 'getChainPollingConfig',\n] as const;\n\nexport class TokenBalancesController extends StaticIntervalPollingController<{\n chainIds: ChainIdHex[];\n}>()<\n typeof CONTROLLER,\n TokenBalancesControllerState,\n TokenBalancesControllerMessenger\n> {\n readonly #platform: 'extension' | 'mobile';\n\n readonly #queryAllAccounts: boolean;\n\n readonly #accountsApiChainIds: () => ChainIdHex[];\n\n readonly #allowExternalServices: () => boolean;\n\n readonly #isOnboarded: () => boolean;\n\n readonly #balanceFetchers: { fetcher: BalanceFetcher; name: string }[];\n\n #allTokens: TokensControllerState['allTokens'] = {};\n\n #detectedTokens: TokensControllerState['allDetectedTokens'] = {};\n\n #allIgnoredTokens: TokensControllerState['allIgnoredTokens'] = {};\n\n /** Default polling interval for chains without specific configuration */\n readonly #defaultInterval: number;\n\n /** Polling interval when WebSocket is active and providing real-time updates */\n readonly #websocketActivePollingInterval: number;\n\n /** Per-chain polling configuration */\n readonly #chainPollingConfig: Record<ChainIdHex, ChainPollingConfig>;\n\n /** Active polling timers grouped by interval */\n readonly #intervalPollingTimers: Map<number, NodeJS.Timeout> = new Map();\n\n /** Track if controller-level polling is active */\n #isControllerPollingActive = false;\n\n /** Track if the keyring is unlocked */\n #isUnlocked = false;\n\n /** Store original chainIds from startPolling to preserve intent */\n #requestedChainIds: ChainIdHex[] = [];\n\n /** Debouncing for rapid status changes to prevent excessive HTTP calls */\n readonly #statusChangeDebouncer: {\n timer: NodeJS.Timeout | null;\n pendingChanges: Map<string, 'up' | 'down'>;\n } = {\n timer: null,\n pendingChanges: new Map(),\n };\n\n readonly #batchedUpdateBalances: (\n options: UpdateBalancesOptions,\n ) => Promise<void>;\n\n constructor({\n messenger,\n interval = DEFAULT_INTERVAL_MS,\n websocketActivePollingInterval = DEFAULT_WEBSOCKET_ACTIVE_POLLING_INTERVAL_MS,\n chainPollingIntervals = {},\n state = {},\n queryMultipleAccounts = true,\n accountsApiChainIds = (): ChainIdHex[] => [],\n allowExternalServices = (): boolean => true,\n platform,\n isOnboarded = (): boolean => true,\n }: TokenBalancesControllerOptions) {\n super({\n name: CONTROLLER,\n messenger,\n metadata,\n state: { tokenBalances: {}, ...state },\n });\n\n this.#normalizeAccountAddresses();\n\n this.#platform = platform ?? 'extension';\n this.#queryAllAccounts = queryMultipleAccounts;\n this.#accountsApiChainIds = accountsApiChainIds;\n this.#allowExternalServices = allowExternalServices;\n this.#isOnboarded = isOnboarded;\n this.#defaultInterval = interval;\n this.#websocketActivePollingInterval = websocketActivePollingInterval;\n this.#chainPollingConfig = { ...chainPollingIntervals };\n\n // Always include AccountsApiFetcher - it dynamically checks allowExternalServices() in supports()\n this.#balanceFetchers = [\n {\n fetcher: this.#createAccountsApiFetcher(),\n name: 'AccountsApiFetcher',\n },\n {\n fetcher: new RpcBalanceFetcher(\n this.#getProvider,\n this.#getNetworkClient,\n () => ({\n allTokens: this.#allTokens,\n allDetectedTokens: this.#detectedTokens,\n }),\n ),\n name: 'RpcFetcher',\n },\n ];\n\n this.setIntervalLength(interval);\n\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n this.#allTokens = allTokens;\n this.#detectedTokens = allDetectedTokens;\n this.#allIgnoredTokens = allIgnoredTokens;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#batchedUpdateBalances = createBatchedHandler(\n (buffer) =>\n buffer.length === 0\n ? {}\n : buffer\n .slice(1)\n .reduce<UpdateBalancesOptions>(\n (acc, opts) => mergeUpdateBalancesOptions(acc, opts),\n buffer[0],\n ),\n UPDATE_BALANCES_BATCH_MS,\n (merged: UpdateBalancesOptions): Promise<void> =>\n this.#executeUpdateBalances(merged),\n );\n\n this.#subscribeToControllers();\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n }\n\n #subscribeToControllers(): void {\n this.messenger.subscribe(\n 'TokensController:stateChange',\n (tokensState: TokensControllerState) => {\n this.#onTokensChanged(tokensState).catch((error) => {\n console.warn('Error handling token state change:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'NetworkController:stateChange',\n this.#onNetworkChanged,\n );\n\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n });\n\n this.messenger.subscribe(\n 'KeyringController:accountRemoved',\n this.#onAccountRemoved,\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n this.#onAccountChanged,\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:balanceUpdated',\n (event) => {\n this.#onAccountActivityBalanceUpdate(event).catch((error) => {\n console.warn('Error handling balance update:', error);\n });\n },\n );\n\n this.messenger.subscribe(\n 'AccountActivityService:statusChanged',\n this.#onAccountActivityStatusChanged.bind(this),\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.updateBalances({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:incomingTransactionsReceived',\n (incomingTransactions) => {\n this.updateBalances({\n chainIds: incomingTransactions.map((tx) => tx.chainId),\n }).catch(() => {\n // Silently handle balance update errors\n });\n },\n );\n }\n\n /**\n * Whether the controller is active (keyring is unlocked and user is onboarded).\n * When locked or not onboarded, balance updates should be skipped.\n *\n * @returns Whether the controller should perform balance updates.\n */\n get isActive(): boolean {\n return this.#isUnlocked && this.#isOnboarded();\n }\n\n /**\n * Normalize all account addresses to lowercase and merge duplicates\n * Handles migration from old state where addresses might be checksummed.\n */\n #normalizeAccountAddresses(): void {\n const currentState = this.state.tokenBalances;\n const normalizedBalances: TokenBalances = {};\n\n for (const address of Object.keys(currentState)) {\n const lowercaseAddress = address.toLowerCase() as ChecksumAddress;\n const accountBalances = currentState[address as ChecksumAddress];\n\n if (!accountBalances) {\n continue;\n }\n\n normalizedBalances[lowercaseAddress] ??= {};\n\n for (const chainId of Object.keys(accountBalances)) {\n const chainIdKey = chainId as ChainIdHex;\n normalizedBalances[lowercaseAddress][chainIdKey] ??= {};\n\n Object.assign(\n normalizedBalances[lowercaseAddress][chainIdKey],\n accountBalances[chainIdKey],\n );\n }\n }\n\n if (\n Object.keys(currentState).length !==\n Object.keys(normalizedBalances).length ||\n Object.keys(currentState).some((addr) => addr !== addr.toLowerCase())\n ) {\n this.update(() => ({ tokenBalances: normalizedBalances }));\n }\n }\n\n #chainIdsWithTokens(): ChainIdHex[] {\n return [\n ...new Set([\n ...Object.keys(this.#allTokens),\n ...Object.keys(this.#detectedTokens),\n ]),\n ] as ChainIdHex[];\n }\n\n readonly #getProvider = (chainId: ChainIdHex): Web3Provider => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n const client = this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n return new Web3Provider(client.provider);\n };\n\n readonly #getNetworkClient = (\n chainId: ChainIdHex,\n ): ReturnType<NetworkControllerGetNetworkClientByIdAction['handler']> => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n const networkConfig = networkConfigurationsByChainId[chainId];\n const { networkClientId } =\n networkConfig.rpcEndpoints[networkConfig.defaultRpcEndpointIndex];\n return this.messenger.call(\n 'NetworkController:getNetworkClientById',\n networkClientId,\n );\n };\n\n readonly #createAccountsApiFetcher = (): BalanceFetcher => {\n const originalFetcher = new AccountsApiBalanceFetcher(\n this.#platform,\n this.#getProvider,\n () => this.state.tokenBalances, // list of existing user tokens\n );\n\n return {\n // Dynamically check allowExternalServices() at call time, not just at construction time\n supports: (chainId: ChainIdHex): boolean =>\n this.#allowExternalServices() &&\n this.#accountsApiChainIds().includes(chainId) &&\n originalFetcher.supports(chainId),\n fetch: originalFetcher.fetch.bind(originalFetcher),\n };\n };\n\n override _startPolling({ chainIds }: { chainIds: ChainIdHex[] }): void {\n this.#requestedChainIds = [...chainIds];\n this.#isControllerPollingActive = true;\n this.#startIntervalGroupPolling(chainIds, true);\n }\n\n #startIntervalGroupPolling(chainIds: ChainIdHex[], immediate = true): void {\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n const intervalGroups = new Map<number, ChainIdHex[]>();\n\n for (const chainId of chainIds) {\n const config = this.getChainPollingConfig(chainId);\n const group = intervalGroups.get(config.interval) ?? [];\n group.push(chainId);\n intervalGroups.set(config.interval, group);\n }\n\n for (const [interval, chainIdsGroup] of intervalGroups) {\n this.#startPollingForInterval(interval, chainIdsGroup, immediate);\n }\n }\n\n #startPollingForInterval(\n interval: number,\n chainIds: ChainIdHex[],\n immediate = true,\n ): void {\n const pollFunction = async (): Promise<void> => {\n if (!this.#isControllerPollingActive) {\n return;\n }\n\n try {\n await this._executePoll({ chainIds });\n } catch (error) {\n console.warn(\n `Polling failed for chains ${chainIds.join(', ')} with interval ${interval}:`,\n error,\n );\n }\n };\n\n if (immediate) {\n pollFunction().catch((error) => {\n console.warn(\n `Immediate polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }\n\n this.#setPollingTimer(interval, chainIds, pollFunction);\n }\n\n #setPollingTimer(\n interval: number,\n chainIds: ChainIdHex[],\n pollFunction: () => Promise<void>,\n ): void {\n const timer = setInterval(() => {\n pollFunction().catch((error) => {\n console.warn(\n `Interval polling failed for chains ${chainIds.join(', ')}:`,\n error,\n );\n });\n }, interval);\n\n this.#intervalPollingTimers.set(interval, timer);\n }\n\n override _stopPollingByPollingTokenSetId(tokenSetId: string): void {\n let chainsToStop: ChainIdHex[] = [];\n\n try {\n const parsedTokenSetId = JSON.parse(tokenSetId);\n chainsToStop = parsedTokenSetId.chainIds ?? [];\n } catch (error) {\n console.warn('Failed to parse tokenSetId, stopping all polling:', error);\n this.#stopAllPolling();\n return;\n }\n\n const currentChainsSet = new Set(this.#requestedChainIds);\n const stopChainsSet = new Set(chainsToStop);\n\n const isCurrentSession =\n currentChainsSet.size === stopChainsSet.size &&\n [...currentChainsSet].every((chain) => stopChainsSet.has(chain));\n\n if (isCurrentSession) {\n this.#stopAllPolling();\n }\n }\n\n #stopAllPolling(): void {\n this.#isControllerPollingActive = false;\n this.#requestedChainIds = [];\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n }\n\n getChainPollingConfig(chainId: ChainIdHex): ChainPollingConfig {\n return (\n this.#chainPollingConfig[chainId] ?? {\n interval: this.#defaultInterval,\n }\n );\n }\n\n override async _executePoll({\n chainIds,\n queryAllAccounts = false,\n }: {\n chainIds: ChainIdHex[];\n queryAllAccounts?: boolean;\n }): Promise<void> {\n await this.#executeUpdateBalances({ chainIds, queryAllAccounts });\n }\n\n updateChainPollingConfigs(\n configs: Record<ChainIdHex, ChainPollingConfig>,\n options: UpdateChainPollingConfigsOptions = { immediateUpdate: true },\n ): void {\n Object.assign(this.#chainPollingConfig, configs);\n\n if (this.#isControllerPollingActive) {\n this.#startIntervalGroupPolling(\n this.#requestedChainIds,\n options.immediateUpdate,\n );\n }\n }\n\n async updateBalances(options: UpdateBalancesOptions = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.#batchedUpdateBalances(options);\n }\n\n async #executeUpdateBalances({\n chainIds,\n tokenAddresses,\n queryAllAccounts = false,\n }: UpdateBalancesOptions = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const targetChains = this.#getTargetChains(chainIds);\n if (!targetChains.length) {\n return;\n }\n\n const { selectedAccount, allAccounts, jwtToken } =\n await this.#getAccountsAndJwt();\n\n const aggregatedBalances = await this.#fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts: queryAllAccounts ?? this.#queryAllAccounts,\n });\n\n const filteredAggregated = this.#filterByTokenAddresses(\n aggregatedBalances,\n tokenAddresses,\n );\n\n const accountsToProcess = this.#getAccountsToProcess(\n queryAllAccounts,\n allAccounts,\n selectedAccount,\n );\n\n const prev = this.state;\n const next = this.#applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances: filteredAggregated,\n });\n\n if (!isEqual(prev, next)) {\n this.update(() => next);\n\n const accountTrackerState = this.messenger.call(\n 'AccountTrackerController:getState',\n );\n\n const nativeUpdates = this.#buildNativeBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (nativeUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeUpdates,\n );\n }\n\n const stakedUpdates = this.#buildStakedBalanceUpdates(\n filteredAggregated,\n accountTrackerState,\n );\n\n if (stakedUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateStakedBalances',\n stakedUpdates,\n );\n }\n }\n\n await this.#importUntrackedTokens(filteredAggregated);\n }\n\n #getTargetChains(chainIds?: ChainIdHex[]): ChainIdHex[] {\n return chainIds?.length ? chainIds : this.#chainIdsWithTokens();\n }\n\n async #getAccountsAndJwt(): Promise<{\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken: string | undefined;\n }> {\n const { address: selected } = this.messenger.call(\n 'AccountsController:getSelectedAccount',\n );\n const allAccounts = this.messenger.call('AccountsController:listAccounts');\n\n const jwtToken = await safelyExecuteWithTimeout<string | undefined>(\n () => {\n return this.messenger.call('AuthenticationController:getBearerToken');\n },\n false,\n 5000,\n );\n\n return {\n selectedAccount: selected as ChecksumAddress,\n allAccounts,\n jwtToken,\n };\n }\n\n async #fetchAllBalances({\n targetChains,\n selectedAccount,\n allAccounts,\n jwtToken,\n queryAllAccounts,\n }: {\n targetChains: ChainIdHex[];\n selectedAccount: ChecksumAddress;\n allAccounts: InternalAccount[];\n jwtToken?: string;\n queryAllAccounts: boolean;\n }): Promise<ProcessedBalance[]> {\n const aggregated: ProcessedBalance[] = [];\n let remainingChains = [...targetChains];\n let previousUnprocessedTokens: UnprocessedTokens | undefined;\n let previousFetcherName: string | undefined;\n\n for (const { fetcher, name: fetcherName } of this.#balanceFetchers) {\n const supportedChains = remainingChains.filter((chain) =>\n fetcher.supports(chain),\n );\n if (!supportedChains.length) {\n continue;\n }\n\n try {\n const result = await fetcher.fetch({\n chainIds: supportedChains,\n queryAllAccounts,\n selectedAccount,\n allAccounts,\n jwtToken,\n unprocessedTokens: previousUnprocessedTokens,\n });\n\n // Add balances, and removed processed chains\n if (result.balances?.length) {\n aggregated.push(...result.balances);\n\n const processed = new Set(result.balances.map((b) => b.chainId));\n remainingChains = remainingChains.filter(\n (chain) => !processed.has(chain),\n );\n }\n\n // Add unprocessed chains (from missing chains or missing tokens)\n if (result.unprocessedChainIds || result.unprocessedTokens) {\n const resultUnprocessedChains = result.unprocessedChainIds ?? [];\n const resultUnsupportedTokenChains = Object.entries(\n result.unprocessedTokens ?? {},\n ).flatMap(([_account, chainMap]) => Object.keys(chainMap)) as Hex[];\n const unprocessedChainIds = Array.from(\n new Set([\n ...resultUnprocessedChains,\n ...resultUnsupportedTokenChains,\n ]),\n );\n\n remainingChains = Array.from(\n new Set([...remainingChains, ...unprocessedChainIds]),\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: unprocessedChainIds,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n // Balance Error Reporting - for unprocessed tokens from last fetcher, if balances are retrieved\n const unprocessedTokensForReporting = previousUnprocessedTokens;\n if (unprocessedTokensForReporting && result.balances?.length) {\n const confirmedUnprocessedTokens: {\n chainId: string;\n tokenAddress: string;\n }[] = [];\n\n // Capture balances that were found (> 0 balance), and was unprocessed\n result.balances.forEach((bal) => {\n const lowercaseAccount = bal.account.toLowerCase();\n const lowercaseTokenAddress = bal.token.toLowerCase();\n\n const hasResultBalance =\n bal.success && bal.token && bal.value && !bal.value.isZero();\n const isUnprocessed = unprocessedTokensForReporting?.[\n lowercaseAccount\n ]?.[bal.chainId]?.includes(lowercaseTokenAddress);\n\n if (hasResultBalance && isUnprocessed) {\n confirmedUnprocessedTokens.push({\n chainId: bal.chainId,\n tokenAddress: lowercaseTokenAddress,\n });\n }\n });\n\n const confirmedUnprocessedTokenStrings =\n confirmedUnprocessedTokens.map(\n (token) => `${token.chainId}:${token.tokenAddress}`,\n );\n if (confirmedUnprocessedTokens.length) {\n console.warn(\n `TokenBalanceController: fetcher ${previousFetcherName} did not process tokens (instead handled by fetcher ${fetcherName}): ${confirmedUnprocessedTokenStrings.join(', ')}`,\n );\n }\n }\n\n // Set new previous fields\n previousUnprocessedTokens = result.unprocessedTokens;\n previousFetcherName = fetcherName;\n } catch (error) {\n console.warn(\n `Balance fetcher failed for chains ${supportedChains.join(', ')}: ${String(error)}`,\n );\n\n this.messenger\n .call('TokenDetectionController:detectTokens', {\n chainIds: supportedChains,\n forceRpc: true,\n })\n .catch(() => {\n // Silently handle token detection errors\n });\n }\n\n if (!remainingChains.length) {\n break;\n }\n }\n\n return aggregated;\n }\n\n #filterByTokenAddresses(\n balances: ProcessedBalance[],\n tokenAddresses?: string[],\n ): ProcessedBalance[] {\n if (!tokenAddresses?.length) {\n return balances;\n }\n\n const lowered = tokenAddresses.map((a) => a.toLowerCase());\n return balances.filter((balance) =>\n lowered.includes(balance.token.toLowerCase()),\n );\n }\n\n #getAccountsToProcess(\n queryAllAccountsParam: boolean | undefined,\n allAccounts: InternalAccount[],\n selectedAccount: ChecksumAddress,\n ): ChecksumAddress[] {\n const effectiveQueryAll =\n queryAllAccountsParam ?? this.#queryAllAccounts ?? false;\n\n if (!effectiveQueryAll) {\n return [selectedAccount];\n }\n\n return allAccounts.map((account) => account.address as ChecksumAddress);\n }\n\n #applyTokenBalancesToState({\n prev,\n targetChains,\n accountsToProcess,\n balances,\n }: {\n prev: TokenBalancesControllerState;\n targetChains: ChainIdHex[];\n accountsToProcess: ChecksumAddress[];\n balances: ProcessedBalance[];\n }): TokenBalancesControllerState {\n return draft(prev, (draftState) => {\n for (const chainId of targetChains) {\n for (const account of accountsToProcess) {\n draftState.tokenBalances[account] ??= {};\n draftState.tokenBalances[account][chainId] ??= {};\n\n const chainTokens = this.#allTokens[chainId];\n if (chainTokens?.[account]) {\n Object.values(chainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n\n const detectedChainTokens = this.#detectedTokens[chainId];\n if (detectedChainTokens?.[account]) {\n Object.values(detectedChainTokens[account]).forEach(\n (token: { address: string }) => {\n const tokenAddress = checksum(token.address);\n draftState.tokenBalances[account][chainId][tokenAddress] ??=\n '0x0';\n },\n );\n }\n }\n }\n\n balances.forEach(({ success, value, account, token, chainId }) => {\n if (!success || value === undefined) {\n return;\n }\n\n const lowerCaseAccount = account.toLowerCase() as ChecksumAddress;\n const newBalance = toHex(value);\n const tokenAddress = checksum(token);\n\n const currentBalance =\n draftState.tokenBalances[lowerCaseAccount]?.[chainId]?.[tokenAddress];\n\n if (currentBalance !== newBalance) {\n ((draftState.tokenBalances[lowerCaseAccount] ??= {})[chainId] ??= {})[\n tokenAddress\n ] = newBalance;\n }\n });\n });\n }\n\n #buildNativeBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): NativeBalanceUpdate[] {\n const nativeBalances = balances.filter(\n (balance) => balance.success && balance.token === ZERO_ADDRESS,\n );\n\n if (!nativeBalances.length) {\n return [];\n }\n\n return nativeBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n balance: balance.value ? BNToHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.balance;\n return currentBalance !== update.balance;\n });\n }\n\n #buildStakedBalanceUpdates(\n balances: ProcessedBalance[],\n accountTrackerState: {\n accountsByChainId: Record<\n string,\n Record<string, { balance?: string; stakedBalance?: string }>\n >;\n },\n ): StakedBalanceUpdate[] {\n const stakedBalances = balances.filter((balance) => {\n if (!balance.success || balance.token === ZERO_ADDRESS) {\n return false;\n }\n\n const stakingContractAddress =\n STAKING_CONTRACT_ADDRESS_BY_CHAINID[balance.chainId];\n return (\n stakingContractAddress?.toLowerCase() === balance.token.toLowerCase()\n );\n });\n\n if (!stakedBalances.length) {\n return [];\n }\n\n return stakedBalances\n .map((balance) => ({\n address: balance.account,\n chainId: balance.chainId,\n stakedBalance: balance.value ? toHex(balance.value) : '0x0',\n }))\n .filter((update) => {\n const currentStakedBalance =\n accountTrackerState.accountsByChainId[update.chainId]?.[\n checksum(update.address)\n ]?.stakedBalance;\n return currentStakedBalance !== update.stakedBalance;\n });\n }\n\n /**\n * Import untracked tokens that have non-zero balances.\n * This mirrors the v2 behavior where only tokens with actual balances are added.\n * Delegates to TokenDetectionController:addDetectedTokensViaPolling which handles:\n * - Checking if useTokenDetection preference is enabled\n * - Filtering tokens already in allTokens or allIgnoredTokens\n * - Token metadata lookup and addition via TokensController\n *\n * @param balances - Array of processed balance results from fetchers\n */\n async #importUntrackedTokens(balances: ProcessedBalance[]): Promise<void> {\n const tokensByChain = new Map<ChainIdHex, string[]>();\n\n for (const balance of balances) {\n // Skip failed fetches, native tokens, and zero balances (like v2 did)\n if (\n !balance.success ||\n balance.token === ZERO_ADDRESS ||\n !balance.value ||\n balance.value.isZero()\n ) {\n continue;\n }\n\n const tokenAddress = checksum(balance.token);\n const existing = tokensByChain.get(balance.chainId) ?? [];\n if (!existing.includes(tokenAddress)) {\n existing.push(tokenAddress);\n tokensByChain.set(balance.chainId, existing);\n }\n }\n\n // Add detected tokens via TokenDetectionController (handles preference check,\n // filtering of allTokens/allIgnoredTokens, and metadata lookup)\n for (const [chainId, tokenAddresses] of tokensByChain) {\n if (tokenAddresses.length) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaPolling',\n {\n tokensSlice: tokenAddresses,\n chainId,\n },\n );\n }\n }\n }\n\n resetState(): void {\n this.update(() => ({ tokenBalances: {} }));\n }\n\n #isTokenTracked(\n tokenAddress: string,\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): boolean {\n const normalizedAccount = account.toLowerCase();\n\n if (\n this.#allTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token.address === tokenAddress,\n )\n ) {\n return true;\n }\n\n if (\n this.#allIgnoredTokens?.[chainId]?.[normalizedAccount]?.some(\n (token) => token === tokenAddress,\n )\n ) {\n return true;\n }\n\n return false;\n }\n\n readonly #onTokensChanged = async (\n state: TokensControllerState,\n ): Promise<void> => {\n const changed: ChainIdHex[] = [];\n let hasChanges = false;\n\n const incomingChainIds = new Set([\n ...Object.keys(state.allTokens),\n ...Object.keys(state.allDetectedTokens),\n ]);\n\n const relevantChainIds = Array.from(incomingChainIds).filter((chainId) => {\n const id = chainId as ChainIdHex;\n\n const hasTokensNow =\n (state.allTokens[id] && Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] && Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const hasTokenChange =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n return hasTokenChange || (!hadTokensBefore && hasTokensNow);\n });\n\n if (!relevantChainIds.length) {\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n return;\n }\n\n this.update((currentState) => {\n for (const chainId of relevantChainIds) {\n const id = chainId as ChainIdHex;\n const hasTokensNow =\n (state.allTokens[id] &&\n Object.keys(state.allTokens[id]).length > 0) ||\n (state.allDetectedTokens[id] &&\n Object.keys(state.allDetectedTokens[id]).length > 0);\n const hadTokensBefore =\n (this.#allTokens[id] &&\n Object.keys(this.#allTokens[id]).length > 0) ||\n (this.#detectedTokens[id] &&\n Object.keys(this.#detectedTokens[id]).length > 0);\n\n const tokensChanged =\n !isEqual(state.allTokens[id], this.#allTokens[id]) ||\n !isEqual(state.allDetectedTokens[id], this.#detectedTokens[id]);\n\n if (!tokensChanged) {\n continue;\n }\n\n if (hasTokensNow) {\n changed.push(id);\n } else if (hadTokensBefore) {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n if (currentState.tokenBalances[addressKey]?.[id]) {\n currentState.tokenBalances[addressKey][id] = {};\n hasChanges = true;\n }\n }\n }\n }\n });\n\n this.#allTokens = state.allTokens;\n this.#detectedTokens = state.allDetectedTokens;\n this.#allIgnoredTokens = state.allIgnoredTokens;\n\n if (changed.length && !hasChanges) {\n this.updateBalances({ chainIds: changed }).catch((error) => {\n console.warn('Error updating balances after token change:', error);\n });\n }\n };\n\n readonly #onNetworkChanged = (state: NetworkState): void => {\n const currentNetworks = new Set(\n Object.keys(state.networkConfigurationsByChainId),\n );\n\n const networksWithBalances = new Set<string>();\n for (const address of Object.keys(this.state.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const network of Object.keys(\n this.state.tokenBalances[addressKey] || {},\n )) {\n networksWithBalances.add(network);\n }\n }\n\n const removedNetworks = Array.from(networksWithBalances).filter(\n (network) => !currentNetworks.has(network),\n );\n\n if (!removedNetworks.length) {\n return;\n }\n\n this.update((currentState) => {\n for (const address of Object.keys(currentState.tokenBalances)) {\n const addressKey = address as ChecksumAddress;\n for (const removedNetwork of removedNetworks) {\n const networkKey = removedNetwork as ChainIdHex;\n if (currentState.tokenBalances[addressKey]?.[networkKey]) {\n delete currentState.tokenBalances[addressKey][networkKey];\n }\n }\n }\n });\n };\n\n readonly #onAccountRemoved = (addr: string): void => {\n if (!isStrictHexString(addr) || !isValidHexAddress(addr)) {\n return;\n }\n this.update((currentState) => {\n delete currentState.tokenBalances[addr];\n });\n };\n\n readonly #onAccountChanged = (): void => {\n const chainIds = this.#chainIdsWithTokens();\n if (!chainIds.length) {\n return;\n }\n\n this.updateBalances({ chainIds }).catch(() => {\n // Silently handle polling errors\n });\n };\n\n #prepareBalanceUpdates(\n updates: BalanceUpdate[],\n account: ChecksumAddress,\n chainId: ChainIdHex,\n ): {\n tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[];\n newTokens: string[];\n nativeBalanceUpdates: NativeBalanceUpdate[];\n } {\n const tokenBalances: { tokenAddress: ChecksumAddress; balance: Hex }[] = [];\n const newTokens: string[] = [];\n const nativeBalanceUpdates: NativeBalanceUpdate[] = [];\n\n for (const update of updates) {\n const { asset, postBalance } = update;\n\n if (postBalance.error) {\n throw new Error('Balance update has error');\n }\n\n const parsed = parseAssetType(asset.type);\n if (!parsed) {\n throw new Error('Failed to parse asset type');\n }\n\n const [tokenAddress, isNativeToken] = parsed;\n\n if (\n !isStrictHexString(tokenAddress) ||\n !isValidHexAddress(tokenAddress)\n ) {\n throw new Error('Invalid token address');\n }\n\n const checksumTokenAddress = checksum(tokenAddress);\n const isTracked = this.#isTokenTracked(\n checksumTokenAddress,\n account,\n chainId,\n );\n\n const balanceHex = postBalance.amount as Hex;\n\n tokenBalances.push({\n tokenAddress: checksumTokenAddress,\n balance: balanceHex,\n });\n\n if (isNativeToken) {\n nativeBalanceUpdates.push({\n address: account,\n chainId,\n balance: balanceHex,\n });\n }\n\n if (!isNativeToken && !isTracked) {\n newTokens.push(checksumTokenAddress);\n }\n }\n\n return { tokenBalances, newTokens, nativeBalanceUpdates };\n }\n\n readonly #onAccountActivityBalanceUpdate = async ({\n address,\n chain,\n updates,\n }: {\n address: string;\n chain: string;\n updates: BalanceUpdate[];\n }): Promise<void> => {\n const chainId = caipChainIdToHex(chain);\n const checksummedAccount = checksum(address);\n\n try {\n const { tokenBalances, newTokens, nativeBalanceUpdates } =\n this.#prepareBalanceUpdates(updates, checksummedAccount, chainId);\n\n if (tokenBalances.length > 0) {\n this.update((state) => {\n const lowercaseAccount =\n checksummedAccount.toLowerCase() as ChecksumAddress;\n state.tokenBalances[lowercaseAccount] ??= {};\n state.tokenBalances[lowercaseAccount][chainId] ??= {};\n\n for (const { tokenAddress, balance } of tokenBalances) {\n state.tokenBalances[lowercaseAccount][chainId][tokenAddress] =\n balance;\n }\n });\n }\n\n if (nativeBalanceUpdates.length > 0) {\n this.messenger.call(\n 'AccountTrackerController:updateNativeBalances',\n nativeBalanceUpdates,\n );\n }\n\n if (newTokens.length > 0) {\n await this.messenger.call(\n 'TokenDetectionController:addDetectedTokensViaWs',\n {\n tokensSlice: newTokens,\n chainId,\n },\n );\n }\n } catch (error) {\n console.warn(\n `Error updating balances from AccountActivityService for chain ${chain}, account ${address}:`,\n error,\n );\n console.warn('Balance update data:', JSON.stringify(updates, null, 2));\n\n await this.updateBalances({ chainIds: [chainId] }).catch(() => {\n // Silently handle polling errors\n });\n }\n };\n\n readonly #onAccountActivityStatusChanged = ({\n chainIds,\n status,\n }: {\n chainIds: string[];\n status: 'up' | 'down';\n }): void => {\n for (const chainId of chainIds) {\n this.#statusChangeDebouncer.pendingChanges.set(chainId, status);\n }\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n }\n\n this.#statusChangeDebouncer.timer = setTimeout(() => {\n this.#processAccumulatedStatusChanges();\n }, 5000);\n };\n\n #processAccumulatedStatusChanges(): void {\n const changes = Array.from(\n this.#statusChangeDebouncer.pendingChanges.entries(),\n );\n this.#statusChangeDebouncer.pendingChanges.clear();\n this.#statusChangeDebouncer.timer = null;\n\n if (!changes.length) {\n return;\n }\n\n try {\n const chainConfigs: Record<ChainIdHex, { interval: number }> = {};\n\n for (const [chainId, status] of changes) {\n if (\n isCaipChainId(chainId) &&\n parseCaipChainId(chainId).namespace !== 'eip155'\n ) {\n continue;\n }\n\n const hexChainId = caipChainIdToHex(chainId);\n\n chainConfigs[hexChainId] =\n status === 'down'\n ? { interval: this.#defaultInterval }\n : { interval: this.#websocketActivePollingInterval };\n }\n\n if (Object.keys(chainConfigs).length === 0) {\n return;\n }\n\n const jitterDelay = Math.random() * this.#defaultInterval;\n setTimeout(() => {\n this.updateChainPollingConfigs(chainConfigs, { immediateUpdate: true });\n }, jitterDelay);\n } catch (error) {\n console.warn('Error processing accumulated status changes:', error);\n }\n }\n\n override destroy(): void {\n this.#isControllerPollingActive = false;\n this.#intervalPollingTimers.forEach((timer) => clearInterval(timer));\n this.#intervalPollingTimers.clear();\n\n if (this.#statusChangeDebouncer.timer) {\n clearTimeout(this.#statusChangeDebouncer.timer);\n this.#statusChangeDebouncer.timer = null;\n }\n\n super.destroy();\n }\n}\n\nexport default TokenBalancesController;\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
3
+ * This file is auto generated.
4
4
  * Do not edit manually.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController-method-action-types.cjs","sourceRoot":"","sources":["../src/TokenDetectionController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { TokenDetectionController } from './TokenDetectionController';\n\n/**\n * Allows controller to make active and passive polling requests\n */\nexport type TokenDetectionControllerEnableAction = {\n type: `TokenDetectionController:enable`;\n handler: TokenDetectionController['enable'];\n};\n\n/**\n * Blocks controller from making network calls\n */\nexport type TokenDetectionControllerDisableAction = {\n type: `TokenDetectionController:disable`;\n handler: TokenDetectionController['disable'];\n};\n\n/**\n * Start polling for detected tokens.\n */\nexport type TokenDetectionControllerStartAction = {\n type: `TokenDetectionController:start`;\n handler: TokenDetectionController['start'];\n};\n\n/**\n * Stop polling for detected tokens.\n */\nexport type TokenDetectionControllerStopAction = {\n type: `TokenDetectionController:stop`;\n handler: TokenDetectionController['stop'];\n};\n\n/**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n * @param options.forceRpc - Force RPC-based token detection for all specified chains,\n * bypassing external services check and ensuring RPC is used even for chains\n * that might otherwise be handled by the Accounts API.\n */\nexport type TokenDetectionControllerDetectTokensAction = {\n type: `TokenDetectionController:detectTokens`;\n handler: TokenDetectionController['detectTokens'];\n};\n\n/**\n * Add tokens detected from websocket balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the websocket\n * - Ignored tokens have been filtered out by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from websocket (already filtered to exclude ignored tokens)\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaWsAction = {\n type: `TokenDetectionController:addDetectedTokensViaWs`;\n handler: TokenDetectionController['addDetectedTokensViaWs'];\n};\n\n/**\n * Add tokens detected from polling balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Filters out tokens already in allTokens or allIgnoredTokens\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from polling\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaPollingAction = {\n type: `TokenDetectionController:addDetectedTokensViaPolling`;\n handler: TokenDetectionController['addDetectedTokensViaPolling'];\n};\n\n/**\n * Union of all TokenDetectionController action types.\n */\nexport type TokenDetectionControllerMethodActions =\n | TokenDetectionControllerEnableAction\n | TokenDetectionControllerDisableAction\n | TokenDetectionControllerStartAction\n | TokenDetectionControllerStopAction\n | TokenDetectionControllerDetectTokensAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction;\n"]}
1
+ {"version":3,"file":"TokenDetectionController-method-action-types.cjs","sourceRoot":"","sources":["../src/TokenDetectionController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { TokenDetectionController } from './TokenDetectionController';\n\n/**\n * Allows controller to make active and passive polling requests\n */\nexport type TokenDetectionControllerEnableAction = {\n type: `TokenDetectionController:enable`;\n handler: TokenDetectionController['enable'];\n};\n\n/**\n * Blocks controller from making network calls\n */\nexport type TokenDetectionControllerDisableAction = {\n type: `TokenDetectionController:disable`;\n handler: TokenDetectionController['disable'];\n};\n\n/**\n * Start polling for detected tokens.\n */\nexport type TokenDetectionControllerStartAction = {\n type: `TokenDetectionController:start`;\n handler: TokenDetectionController['start'];\n};\n\n/**\n * Stop polling for detected tokens.\n */\nexport type TokenDetectionControllerStopAction = {\n type: `TokenDetectionController:stop`;\n handler: TokenDetectionController['stop'];\n};\n\n/**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n * @param options.forceRpc - Force RPC-based token detection for all specified chains,\n * bypassing external services check and ensuring RPC is used even for chains\n * that might otherwise be handled by the Accounts API.\n */\nexport type TokenDetectionControllerDetectTokensAction = {\n type: `TokenDetectionController:detectTokens`;\n handler: TokenDetectionController['detectTokens'];\n};\n\n/**\n * Add tokens detected from websocket balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the websocket\n * - Ignored tokens have been filtered out by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from websocket (already filtered to exclude ignored tokens)\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaWsAction = {\n type: `TokenDetectionController:addDetectedTokensViaWs`;\n handler: TokenDetectionController['addDetectedTokensViaWs'];\n};\n\n/**\n * Add tokens detected from polling balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Filters out tokens already in allTokens or allIgnoredTokens\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from polling\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaPollingAction = {\n type: `TokenDetectionController:addDetectedTokensViaPolling`;\n handler: TokenDetectionController['addDetectedTokensViaPolling'];\n};\n\n/**\n * Union of all TokenDetectionController action types.\n */\nexport type TokenDetectionControllerMethodActions =\n | TokenDetectionControllerEnableAction\n | TokenDetectionControllerDisableAction\n | TokenDetectionControllerStartAction\n | TokenDetectionControllerStopAction\n | TokenDetectionControllerDetectTokensAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction;\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { TokenDetectionController } from "./TokenDetectionController.cjs";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { TokenDetectionController } from "./TokenDetectionController.mjs";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController-method-action-types.mjs","sourceRoot":"","sources":["../src/TokenDetectionController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { TokenDetectionController } from './TokenDetectionController';\n\n/**\n * Allows controller to make active and passive polling requests\n */\nexport type TokenDetectionControllerEnableAction = {\n type: `TokenDetectionController:enable`;\n handler: TokenDetectionController['enable'];\n};\n\n/**\n * Blocks controller from making network calls\n */\nexport type TokenDetectionControllerDisableAction = {\n type: `TokenDetectionController:disable`;\n handler: TokenDetectionController['disable'];\n};\n\n/**\n * Start polling for detected tokens.\n */\nexport type TokenDetectionControllerStartAction = {\n type: `TokenDetectionController:start`;\n handler: TokenDetectionController['start'];\n};\n\n/**\n * Stop polling for detected tokens.\n */\nexport type TokenDetectionControllerStopAction = {\n type: `TokenDetectionController:stop`;\n handler: TokenDetectionController['stop'];\n};\n\n/**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n * @param options.forceRpc - Force RPC-based token detection for all specified chains,\n * bypassing external services check and ensuring RPC is used even for chains\n * that might otherwise be handled by the Accounts API.\n */\nexport type TokenDetectionControllerDetectTokensAction = {\n type: `TokenDetectionController:detectTokens`;\n handler: TokenDetectionController['detectTokens'];\n};\n\n/**\n * Add tokens detected from websocket balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the websocket\n * - Ignored tokens have been filtered out by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from websocket (already filtered to exclude ignored tokens)\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaWsAction = {\n type: `TokenDetectionController:addDetectedTokensViaWs`;\n handler: TokenDetectionController['addDetectedTokensViaWs'];\n};\n\n/**\n * Add tokens detected from polling balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Filters out tokens already in allTokens or allIgnoredTokens\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from polling\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaPollingAction = {\n type: `TokenDetectionController:addDetectedTokensViaPolling`;\n handler: TokenDetectionController['addDetectedTokensViaPolling'];\n};\n\n/**\n * Union of all TokenDetectionController action types.\n */\nexport type TokenDetectionControllerMethodActions =\n | TokenDetectionControllerEnableAction\n | TokenDetectionControllerDisableAction\n | TokenDetectionControllerStartAction\n | TokenDetectionControllerStopAction\n | TokenDetectionControllerDetectTokensAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction;\n"]}
1
+ {"version":3,"file":"TokenDetectionController-method-action-types.mjs","sourceRoot":"","sources":["../src/TokenDetectionController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { TokenDetectionController } from './TokenDetectionController';\n\n/**\n * Allows controller to make active and passive polling requests\n */\nexport type TokenDetectionControllerEnableAction = {\n type: `TokenDetectionController:enable`;\n handler: TokenDetectionController['enable'];\n};\n\n/**\n * Blocks controller from making network calls\n */\nexport type TokenDetectionControllerDisableAction = {\n type: `TokenDetectionController:disable`;\n handler: TokenDetectionController['disable'];\n};\n\n/**\n * Start polling for detected tokens.\n */\nexport type TokenDetectionControllerStartAction = {\n type: `TokenDetectionController:start`;\n handler: TokenDetectionController['start'];\n};\n\n/**\n * Stop polling for detected tokens.\n */\nexport type TokenDetectionControllerStopAction = {\n type: `TokenDetectionController:stop`;\n handler: TokenDetectionController['stop'];\n};\n\n/**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.chainIds - The chain IDs of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n * @param options.forceRpc - Force RPC-based token detection for all specified chains,\n * bypassing external services check and ensuring RPC is used even for chains\n * that might otherwise be handled by the Accounts API.\n */\nexport type TokenDetectionControllerDetectTokensAction = {\n type: `TokenDetectionController:detectTokens`;\n handler: TokenDetectionController['detectTokens'];\n};\n\n/**\n * Add tokens detected from websocket balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the websocket\n * - Ignored tokens have been filtered out by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from websocket (already filtered to exclude ignored tokens)\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaWsAction = {\n type: `TokenDetectionController:addDetectedTokensViaWs`;\n handler: TokenDetectionController['addDetectedTokensViaWs'];\n};\n\n/**\n * Add tokens detected from polling balance updates\n * This method:\n * - Checks if useTokenDetection preference is enabled (skips if disabled)\n * - Checks if external services are enabled (skips if disabled)\n * - Filters out tokens already in allTokens or allIgnoredTokens\n * - Tokens are expected to be in the tokensChainsCache with full metadata\n * - Balance fetching is skipped since balances are provided by the caller\n *\n * @param options - The options object\n * @param options.tokensSlice - Array of token addresses detected from polling\n * @param options.chainId - Hex chain ID\n * @returns Promise that resolves when tokens are added\n */\nexport type TokenDetectionControllerAddDetectedTokensViaPollingAction = {\n type: `TokenDetectionController:addDetectedTokensViaPolling`;\n handler: TokenDetectionController['addDetectedTokensViaPolling'];\n};\n\n/**\n * Union of all TokenDetectionController action types.\n */\nexport type TokenDetectionControllerMethodActions =\n | TokenDetectionControllerEnableAction\n | TokenDetectionControllerDisableAction\n | TokenDetectionControllerStartAction\n | TokenDetectionControllerStopAction\n | TokenDetectionControllerDetectTokensAction\n | TokenDetectionControllerAddDetectedTokensViaWsAction\n | TokenDetectionControllerAddDetectedTokensViaPollingAction;\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
3
+ * This file is auto generated.
4
4
  * Do not edit manually.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -1 +1 @@
1
- {"version":3,"file":"TokensController-method-action-types.cjs","sourceRoot":"","sources":["../src/TokensController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { TokensController } from './TokensController';\n\n/**\n * Adds a token to the stored token list.\n *\n * @param options - The method argument object.\n * @param options.address - Hex address of the token contract.\n * @param options.symbol - Symbol of the token.\n * @param options.decimals - Number of decimals the token uses.\n * @param options.name - Name of the token.\n * @param options.image - Image of the token.\n * @param options.interactingAddress - The address of the account to add a token to.\n * @param options.networkClientId - Network Client ID.\n * @param options.rwaData - Optional RWA data for the token.\n * @returns Current token list.\n */\nexport type TokensControllerAddTokenAction = {\n type: `TokensController:addToken`;\n handler: TokensController['addToken'];\n};\n\n/**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerAddTokensAction = {\n type: `TokensController:addTokens`;\n handler: TokensController['addTokens'];\n};\n\n/**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerIgnoreTokensAction = {\n type: `TokensController:ignoreTokens`;\n handler: TokensController['ignoreTokens'];\n};\n\n/**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\nexport type TokensControllerAddDetectedTokensAction = {\n type: `TokensController:addDetectedTokens`;\n handler: TokensController['addDetectedTokens'];\n};\n\n/**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @param networkClientId - The network client ID of the network on which the token is detected.\n * @returns The new token object with the added isERC721 field.\n */\nexport type TokensControllerUpdateTokenTypeAction = {\n type: `TokensController:updateTokenType`;\n handler: TokensController['updateTokenType'];\n};\n\n/**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param options - The method options.\n * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param options.type - The asset type.\n * @param options.interactingAddress - The address of the account that is requesting to watch the asset.\n * @param options.networkClientId - Network Client ID.\n * @param options.origin - The origin to set on the approval request.\n * @param options.pageMeta - The metadata for the page initiating the request.\n * @param options.requestMetadata - Metadata for the request, including pageMeta and origin.\n * @returns A promise that resolves if the asset was watched successfully, and rejects otherwise.\n */\nexport type TokensControllerWatchAssetAction = {\n type: `TokensController:watchAsset`;\n handler: TokensController['watchAsset'];\n};\n\n/**\n * Removes all tokens from the ignored list.\n */\nexport type TokensControllerClearIgnoredTokensAction = {\n type: `TokensController:clearIgnoredTokens`;\n handler: TokensController['clearIgnoredTokens'];\n};\n\n/**\n * Reset the controller state to the default state.\n */\nexport type TokensControllerResetStateAction = {\n type: `TokensController:resetState`;\n handler: TokensController['resetState'];\n};\n\n/**\n * Union of all TokensController action types.\n */\nexport type TokensControllerMethodActions =\n | TokensControllerAddTokenAction\n | TokensControllerAddTokensAction\n | TokensControllerIgnoreTokensAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerUpdateTokenTypeAction\n | TokensControllerWatchAssetAction\n | TokensControllerClearIgnoredTokensAction\n | TokensControllerResetStateAction;\n"]}
1
+ {"version":3,"file":"TokensController-method-action-types.cjs","sourceRoot":"","sources":["../src/TokensController-method-action-types.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { TokensController } from './TokensController';\n\n/**\n * Adds a token to the stored token list.\n *\n * @param options - The method argument object.\n * @param options.address - Hex address of the token contract.\n * @param options.symbol - Symbol of the token.\n * @param options.decimals - Number of decimals the token uses.\n * @param options.name - Name of the token.\n * @param options.image - Image of the token.\n * @param options.interactingAddress - The address of the account to add a token to.\n * @param options.networkClientId - Network Client ID.\n * @param options.rwaData - Optional RWA data for the token.\n * @returns Current token list.\n */\nexport type TokensControllerAddTokenAction = {\n type: `TokensController:addToken`;\n handler: TokensController['addToken'];\n};\n\n/**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerAddTokensAction = {\n type: `TokensController:addTokens`;\n handler: TokensController['addTokens'];\n};\n\n/**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerIgnoreTokensAction = {\n type: `TokensController:ignoreTokens`;\n handler: TokensController['ignoreTokens'];\n};\n\n/**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\nexport type TokensControllerAddDetectedTokensAction = {\n type: `TokensController:addDetectedTokens`;\n handler: TokensController['addDetectedTokens'];\n};\n\n/**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @param networkClientId - The network client ID of the network on which the token is detected.\n * @returns The new token object with the added isERC721 field.\n */\nexport type TokensControllerUpdateTokenTypeAction = {\n type: `TokensController:updateTokenType`;\n handler: TokensController['updateTokenType'];\n};\n\n/**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param options - The method options.\n * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param options.type - The asset type.\n * @param options.interactingAddress - The address of the account that is requesting to watch the asset.\n * @param options.networkClientId - Network Client ID.\n * @param options.origin - The origin to set on the approval request.\n * @param options.pageMeta - The metadata for the page initiating the request.\n * @param options.requestMetadata - Metadata for the request, including pageMeta and origin.\n * @returns A promise that resolves if the asset was watched successfully, and rejects otherwise.\n */\nexport type TokensControllerWatchAssetAction = {\n type: `TokensController:watchAsset`;\n handler: TokensController['watchAsset'];\n};\n\n/**\n * Removes all tokens from the ignored list.\n */\nexport type TokensControllerClearIgnoredTokensAction = {\n type: `TokensController:clearIgnoredTokens`;\n handler: TokensController['clearIgnoredTokens'];\n};\n\n/**\n * Reset the controller state to the default state.\n */\nexport type TokensControllerResetStateAction = {\n type: `TokensController:resetState`;\n handler: TokensController['resetState'];\n};\n\n/**\n * Union of all TokensController action types.\n */\nexport type TokensControllerMethodActions =\n | TokensControllerAddTokenAction\n | TokensControllerAddTokensAction\n | TokensControllerIgnoreTokensAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerUpdateTokenTypeAction\n | TokensControllerWatchAssetAction\n | TokensControllerClearIgnoredTokensAction\n | TokensControllerResetStateAction;\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { TokensController } from "./TokensController.cjs";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  import type { TokensController } from "./TokensController.mjs";
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file is auto generated by `scripts/generate-method-action-types.ts`.
2
+ * This file is auto generated.
3
3
  * Do not edit manually.
4
4
  */
5
5
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"TokensController-method-action-types.mjs","sourceRoot":"","sources":["../src/TokensController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated by `scripts/generate-method-action-types.ts`.\n * Do not edit manually.\n */\n\nimport type { TokensController } from './TokensController';\n\n/**\n * Adds a token to the stored token list.\n *\n * @param options - The method argument object.\n * @param options.address - Hex address of the token contract.\n * @param options.symbol - Symbol of the token.\n * @param options.decimals - Number of decimals the token uses.\n * @param options.name - Name of the token.\n * @param options.image - Image of the token.\n * @param options.interactingAddress - The address of the account to add a token to.\n * @param options.networkClientId - Network Client ID.\n * @param options.rwaData - Optional RWA data for the token.\n * @returns Current token list.\n */\nexport type TokensControllerAddTokenAction = {\n type: `TokensController:addToken`;\n handler: TokensController['addToken'];\n};\n\n/**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerAddTokensAction = {\n type: `TokensController:addTokens`;\n handler: TokensController['addTokens'];\n};\n\n/**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerIgnoreTokensAction = {\n type: `TokensController:ignoreTokens`;\n handler: TokensController['ignoreTokens'];\n};\n\n/**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\nexport type TokensControllerAddDetectedTokensAction = {\n type: `TokensController:addDetectedTokens`;\n handler: TokensController['addDetectedTokens'];\n};\n\n/**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @param networkClientId - The network client ID of the network on which the token is detected.\n * @returns The new token object with the added isERC721 field.\n */\nexport type TokensControllerUpdateTokenTypeAction = {\n type: `TokensController:updateTokenType`;\n handler: TokensController['updateTokenType'];\n};\n\n/**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param options - The method options.\n * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param options.type - The asset type.\n * @param options.interactingAddress - The address of the account that is requesting to watch the asset.\n * @param options.networkClientId - Network Client ID.\n * @param options.origin - The origin to set on the approval request.\n * @param options.pageMeta - The metadata for the page initiating the request.\n * @param options.requestMetadata - Metadata for the request, including pageMeta and origin.\n * @returns A promise that resolves if the asset was watched successfully, and rejects otherwise.\n */\nexport type TokensControllerWatchAssetAction = {\n type: `TokensController:watchAsset`;\n handler: TokensController['watchAsset'];\n};\n\n/**\n * Removes all tokens from the ignored list.\n */\nexport type TokensControllerClearIgnoredTokensAction = {\n type: `TokensController:clearIgnoredTokens`;\n handler: TokensController['clearIgnoredTokens'];\n};\n\n/**\n * Reset the controller state to the default state.\n */\nexport type TokensControllerResetStateAction = {\n type: `TokensController:resetState`;\n handler: TokensController['resetState'];\n};\n\n/**\n * Union of all TokensController action types.\n */\nexport type TokensControllerMethodActions =\n | TokensControllerAddTokenAction\n | TokensControllerAddTokensAction\n | TokensControllerIgnoreTokensAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerUpdateTokenTypeAction\n | TokensControllerWatchAssetAction\n | TokensControllerClearIgnoredTokensAction\n | TokensControllerResetStateAction;\n"]}
1
+ {"version":3,"file":"TokensController-method-action-types.mjs","sourceRoot":"","sources":["../src/TokensController-method-action-types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * This file is auto generated.\n * Do not edit manually.\n */\n\nimport type { TokensController } from './TokensController';\n\n/**\n * Adds a token to the stored token list.\n *\n * @param options - The method argument object.\n * @param options.address - Hex address of the token contract.\n * @param options.symbol - Symbol of the token.\n * @param options.decimals - Number of decimals the token uses.\n * @param options.name - Name of the token.\n * @param options.image - Image of the token.\n * @param options.interactingAddress - The address of the account to add a token to.\n * @param options.networkClientId - Network Client ID.\n * @param options.rwaData - Optional RWA data for the token.\n * @returns Current token list.\n */\nexport type TokensControllerAddTokenAction = {\n type: `TokensController:addToken`;\n handler: TokensController['addToken'];\n};\n\n/**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerAddTokensAction = {\n type: `TokensController:addTokens`;\n handler: TokensController['addTokens'];\n};\n\n/**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\nexport type TokensControllerIgnoreTokensAction = {\n type: `TokensController:ignoreTokens`;\n handler: TokensController['ignoreTokens'];\n};\n\n/**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\nexport type TokensControllerAddDetectedTokensAction = {\n type: `TokensController:addDetectedTokens`;\n handler: TokensController['addDetectedTokens'];\n};\n\n/**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @param networkClientId - The network client ID of the network on which the token is detected.\n * @returns The new token object with the added isERC721 field.\n */\nexport type TokensControllerUpdateTokenTypeAction = {\n type: `TokensController:updateTokenType`;\n handler: TokensController['updateTokenType'];\n};\n\n/**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param options - The method options.\n * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param options.type - The asset type.\n * @param options.interactingAddress - The address of the account that is requesting to watch the asset.\n * @param options.networkClientId - Network Client ID.\n * @param options.origin - The origin to set on the approval request.\n * @param options.pageMeta - The metadata for the page initiating the request.\n * @param options.requestMetadata - Metadata for the request, including pageMeta and origin.\n * @returns A promise that resolves if the asset was watched successfully, and rejects otherwise.\n */\nexport type TokensControllerWatchAssetAction = {\n type: `TokensController:watchAsset`;\n handler: TokensController['watchAsset'];\n};\n\n/**\n * Removes all tokens from the ignored list.\n */\nexport type TokensControllerClearIgnoredTokensAction = {\n type: `TokensController:clearIgnoredTokens`;\n handler: TokensController['clearIgnoredTokens'];\n};\n\n/**\n * Reset the controller state to the default state.\n */\nexport type TokensControllerResetStateAction = {\n type: `TokensController:resetState`;\n handler: TokensController['resetState'];\n};\n\n/**\n * Union of all TokensController action types.\n */\nexport type TokensControllerMethodActions =\n | TokensControllerAddTokenAction\n | TokensControllerAddTokensAction\n | TokensControllerIgnoreTokensAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerUpdateTokenTypeAction\n | TokensControllerWatchAssetAction\n | TokensControllerClearIgnoredTokensAction\n | TokensControllerResetStateAction;\n"]}
@@ -313,6 +313,8 @@ const MULTICALL_CONTRACT_BY_CHAINID = {
313
313
  '0xdef1': '0xcA11bde05977b3631167028862bE2a173976CA11',
314
314
  // Stable (988)
315
315
  '0x3dc': '0xcA11bde05977b3631167028862bE2a173976CA11',
316
+ // Tempo Testnet Moderato (42431)
317
+ '0xa5bf': '0xcA11bde05977b3631167028862bE2a173976CA11',
316
318
  };
317
319
  const multicallAbi = [
318
320
  {