@metamask/assets-controllers 104.3.0 → 105.1.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 (74) hide show
  1. package/CHANGELOG.md +52 -1
  2. package/dist/CurrencyRateController-method-action-types.cjs +7 -0
  3. package/dist/CurrencyRateController-method-action-types.cjs.map +1 -0
  4. package/dist/CurrencyRateController-method-action-types.d.cts +28 -0
  5. package/dist/CurrencyRateController-method-action-types.d.cts.map +1 -0
  6. package/dist/CurrencyRateController-method-action-types.d.mts +28 -0
  7. package/dist/CurrencyRateController-method-action-types.d.mts.map +1 -0
  8. package/dist/CurrencyRateController-method-action-types.mjs +6 -0
  9. package/dist/CurrencyRateController-method-action-types.mjs.map +1 -0
  10. package/dist/CurrencyRateController.cjs +5 -0
  11. package/dist/CurrencyRateController.cjs.map +1 -1
  12. package/dist/CurrencyRateController.d.cts +3 -2
  13. package/dist/CurrencyRateController.d.cts.map +1 -1
  14. package/dist/CurrencyRateController.d.mts +3 -2
  15. package/dist/CurrencyRateController.d.mts.map +1 -1
  16. package/dist/CurrencyRateController.mjs +5 -0
  17. package/dist/CurrencyRateController.mjs.map +1 -1
  18. package/dist/MultichainAssetsController/MultichainAssetsController.cjs +7 -15
  19. package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -1
  20. package/dist/MultichainAssetsController/MultichainAssetsController.d.cts.map +1 -1
  21. package/dist/MultichainAssetsController/MultichainAssetsController.d.mts.map +1 -1
  22. package/dist/MultichainAssetsController/MultichainAssetsController.mjs +7 -15
  23. package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -1
  24. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.cjs.map +1 -1
  25. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts +2 -2
  26. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.cts.map +1 -1
  27. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts +2 -2
  28. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.d.mts.map +1 -1
  29. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
  30. package/dist/TokenDetectionController.cjs +85 -2
  31. package/dist/TokenDetectionController.cjs.map +1 -1
  32. package/dist/TokenDetectionController.d.cts +2 -2
  33. package/dist/TokenDetectionController.d.cts.map +1 -1
  34. package/dist/TokenDetectionController.d.mts +2 -2
  35. package/dist/TokenDetectionController.d.mts.map +1 -1
  36. package/dist/TokenDetectionController.mjs +85 -2
  37. package/dist/TokenDetectionController.mjs.map +1 -1
  38. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.cjs.map +1 -1
  39. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts +2 -2
  40. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.cts.map +1 -1
  41. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts +2 -2
  42. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.d.mts.map +1 -1
  43. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.mjs.map +1 -1
  44. package/dist/TokensController.cjs +100 -4
  45. package/dist/TokensController.cjs.map +1 -1
  46. package/dist/TokensController.d.cts +4 -4
  47. package/dist/TokensController.d.cts.map +1 -1
  48. package/dist/TokensController.d.mts +4 -4
  49. package/dist/TokensController.d.mts.map +1 -1
  50. package/dist/TokensController.mjs +100 -4
  51. package/dist/TokensController.mjs.map +1 -1
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +1 -0
  54. package/dist/index.d.cts.map +1 -1
  55. package/dist/index.d.mts +1 -0
  56. package/dist/index.d.mts.map +1 -1
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/selectors/token-selectors.cjs +3 -0
  59. package/dist/selectors/token-selectors.cjs.map +1 -1
  60. package/dist/selectors/token-selectors.d.cts +0 -36
  61. package/dist/selectors/token-selectors.d.cts.map +1 -1
  62. package/dist/selectors/token-selectors.d.mts +0 -36
  63. package/dist/selectors/token-selectors.d.mts.map +1 -1
  64. package/dist/selectors/token-selectors.mjs +3 -0
  65. package/dist/selectors/token-selectors.mjs.map +1 -1
  66. package/dist/token-prices-service/codefi-v2.cjs +1 -0
  67. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  68. package/dist/token-prices-service/codefi-v2.d.cts +2 -1
  69. package/dist/token-prices-service/codefi-v2.d.cts.map +1 -1
  70. package/dist/token-prices-service/codefi-v2.d.mts +2 -1
  71. package/dist/token-prices-service/codefi-v2.d.mts.map +1 -1
  72. package/dist/token-prices-service/codefi-v2.mjs +1 -0
  73. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  74. package/package.json +10 -10
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.mjs","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AASA,OAAO,YAAW,oCAAoC;;AACtD,OAAO,EACL,WAAW,EACX,OAAO,EACP,KAAK,EACL,aAAa,EACb,sBAAsB,EACtB,oBAAoB,EACrB,mCAAmC;AAgBpC,OAAO,EAAE,+BAA+B,EAAE,qCAAqC;;;AAW/E,OAAO,EAAE,mCAAmC,EAAE,yBAAqB;AACnE,OAAO,EAAE,kCAAkC,EAAE,wBAAoB;AAejE,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAoBhC,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC,OAAO,CACrD,WAAW,CACZ,CAAC,MAAM,CAAoB,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE;IACpD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,GAAG,QAAQ,CAAC;IAC3D,OAAO;QACL,GAAG,GAAG;QACN,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE;YACpB,GAAG,aAAa;YAChB,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE;YAC3B,OAAO,EAAE,mBAAmB,IAAI,EAAE;YAClC,WAAW,EAAE,EAAE;SAChB;KACF,CAAC;AACJ,CAAC,EAAE,EAAE,CAAC,CAAC;AAEP;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACxC,iBAAoC;IAEpC,OAAO,SAAS,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE;QAC5C,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACvC,OAAO,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,0BAA0B,CAAC;AAuDzD,MAAM,yBAAyB,GAAG;IAChC,wBAAwB;IACxB,6BAA6B;IAC7B,cAAc;IACd,QAAQ;IACR,SAAS;IACT,OAAO;IACP,MAAM;CACE,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,wBAAyB,SAAQ,+BAA+B,EAI5E;IA+BC;;;;;;;;;;;OAWG;IACH,YAAY,EACV,QAAQ,GAAG,gBAAgB,EAC3B,QAAQ,GAAG,IAAI,EACf,uBAAuB,EACvB,qBAAqB,EACrB,SAAS,EACT,iBAAiB,GAAG,GAAY,EAAE,CAAC,IAAI,EACvC,mBAAmB,GAAG,GAAY,EAAE,CAAC,IAAI,GAmB1C;QACC,KAAK,CAAC;YACJ,IAAI,EAAE,cAAc;YACpB,SAAS;YACT,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;;QA1EL,uDAA4C;QAE5C,8DAA2B;QAE3B,sDAAwC,EAAE,EAAC;QAE3C,qDAAmB;QAEnB,uDAAqB;QAErB,8EAA4C;QAEnC,8DAAkC;QAElC,gEAAoC;QAEpC,oEAA8E;QAE9E,kEAUE;QAgDT,SAAS,CAAC,4BAA4B,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAAC;QAExE,uBAAA,IAAI,sCAAa,QAAQ,MAAA,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAEjC,uBAAA,IAAI,+CAAsB,uBAAA,IAAI,yFAAoB,MAAxB,IAAI,CAAsB,CAAC,EAAE,MAAA,CAAC;QAExD,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,8BAA8B,CAC/B,CAAC;QAEF,uBAAA,IAAI,+CAAsB,iBAAiB,MAAA,CAAC;QAE5C,MAAM,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACzE,gCAAgC,CACjC,CAAC;QACF,uBAAA,IAAI,+DAAsC,wBAAwB,MAAA,CAAC;QAEnE,uBAAA,IAAI,qDAA4B,uBAAuB,MAAA,CAAC;QAExD,uBAAA,IAAI,mDAA0B,qBAAqB,MAAA,CAAC;QAEpD,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QACzE,uBAAA,IAAI,wCAAe,UAAU,MAAA,CAAC;QAE9B,uBAAA,IAAI,+CAAsB,iBAAiB,MAAA,CAAC;QAC5C,uBAAA,IAAI,iDAAwB,mBAAmB,MAAA,CAAC;QAEhD,uBAAA,IAAI,6FAAwB,MAA5B,IAAI,CAA0B,CAAC;IACjC,CAAC;IAsFD;;OAEG;IACH,MAAM;QACJ,uBAAA,IAAI,sCAAa,KAAK,MAAA,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,OAAO;QACL,uBAAA,IAAI,sCAAa,IAAI,MAAA,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACV,OAAO,CAAC,uBAAA,IAAI,0CAAU,IAAI,uBAAA,IAAI,4CAAY,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,uBAAA,IAAI,mFAAc,MAAlB,IAAI,CAAgB,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IACtB,CAAC;IA+ED,KAAK,CAAC,YAAY,CAAC,EACjB,QAAQ,EACR,OAAO,GACoB;QAC3B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,YAAY,CAAC;YACtB,QAAQ;YACR,eAAe,EAAE,OAAO;SACzB,CAAC,CAAC;IACL,CAAC;IA2ED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,YAAY,CAAC,EACjB,QAAQ,EACR,eAAe,EACf,QAAQ,GAAG,KAAK,MAKd,EAAE;QACJ,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,yFAAyF;QACzF,IAAI,CAAC,QAAQ,IAAI,CAAC,uBAAA,IAAI,mDAAmB,MAAvB,IAAI,CAAqB,EAAE,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,QAAQ,IAAI,CAAC,uBAAA,IAAI,qDAAqB,MAAzB,IAAI,CAAuB,EAAE,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,eAAe,GAAG,eAAe,IAAI,uBAAA,IAAI,yFAAoB,MAAxB,IAAI,CAAsB,CAAC;QACtE,MAAM,cAAc,GAAG,uBAAA,IAAI,yGAAoC,MAAxC,IAAI,EAAqC,QAAQ,CAAC,CAAC;QAE1E,8CAA8C;QAC9C,iGAAiG;QACjG,MAAM,sBAAsB,GAAG,QAAQ;YACrC,CAAC,CAAC,cAAc;YAChB,CAAC,CAAC,cAAc,CAAC,MAAM,CACnB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CACd,CAAC,kCAAkC,CAAC,QAAQ,CAAC,OAAO,CAAC,CACxD,CAAC;QAEN,IAAI,sBAAsB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,MAAM,uBAAA,IAAI,2FAAsB,MAA1B,IAAI,EAAuB,sBAAsB,EAAE,eAAe,CAAC,CAAC;IAC5E,CAAC;IAgID;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,sBAAsB,CAAC,EAC3B,WAAW,EACX,OAAO,GAIR;QACC,sDAAsD;QACtD,IAAI,CAAC,uBAAA,IAAI,mDAAmB,MAAvB,IAAI,CAAqB,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,gFAAgF;QAChF,IAAI,CAAC,uBAAA,IAAI,qDAAqB,MAAzB,IAAI,CAAuB,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,+EAA+E;QAC/E,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,8BAA8B,CAC/B,CAAC;QACF,uBAAA,IAAI,+CAAsB,iBAAiB,IAAI,EAAE,MAAA,CAAC;QAElD,MAAM,iBAAiB,GAAY,EAAE,CAAC;QACtC,MAAM,kBAAkB,GAAa,EAAE,CAAC;QAExC,KAAK,MAAM,YAAY,IAAI,WAAW,EAAE,CAAC;YACvC,6DAA6D;YAC7D,MAAM,qBAAqB,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;YACzD,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;YAEnE,2DAA2D;YAC3D,MAAM,SAAS,GACb,uBAAA,IAAI,mDAAmB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,qBAAqB,CAAC,CAAC;YAElE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAC7D,SAAS,CAAC;YAEZ,iEAAiE;YACjE,kBAAkB,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,uBAAuB,EAAE,CAAC,CAAC;YAClE,iBAAiB,CAAC,IAAI,CAAC;gBACrB,OAAO,EAAE,uBAAuB;gBAChC,QAAQ;gBACR,MAAM;gBACN,WAAW;gBACX,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,KAAK;gBACf,IAAI;gBACJ,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,mBAAmB;QACnB,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;YAC7B,uBAAA,IAAI,uDAAuB,MAA3B,IAAI,EAAwB;gBAC1B,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE;oBACV,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,KAAK;oBACrB,UAAU,EAAE,WAAW,CAAC,KAAK;iBAC9B;aACF,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,gDAAgD,EAChD,OAAO,CACR,CAAC;YAEF,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,4BAA4B,EAC5B,iBAAiB,EACjB,eAAe,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,2BAA2B,CAAC,EAChC,WAAW,EACX,OAAO,GAIR;QACC,sDAAsD;QACtD,IAAI,CAAC,uBAAA,IAAI,mDAAmB,MAAvB,IAAI,CAAqB,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,sFAAsF;QACtF,IAAI,CAAC,uBAAA,IAAI,qDAAqB,MAAzB,IAAI,CAAuB,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QAED,sEAAsE;QACtE,+EAA+E;QAC/E,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,8BAA8B,CAC/B,CAAC;QACF,uBAAA,IAAI,+CAAsB,iBAAiB,IAAI,EAAE,MAAA,CAAC;QAElD,MAAM,eAAe,GAAG,uBAAA,IAAI,yFAAoB,MAAxB,IAAI,CAAsB,CAAC;QAEnD,wEAAwE;QACxE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACzD,2BAA2B,CAC5B,CAAC;QAEF,MAAM,sBAAsB,GAAG,CAC7B,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,CAC5C,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAE9C,MAAM,qBAAqB,GAAG,CAC5B,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,CACnD,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QAE1C,MAAM,iBAAiB,GAAY,EAAE,CAAC;QACtC,MAAM,kBAAkB,GAAa,EAAE,CAAC;QAExC,KAAK,MAAM,YAAY,IAAI,WAAW,EAAE,CAAC;YACvC,MAAM,qBAAqB,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;YACzD,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;YAEnE,mCAAmC;YACnC,IAAI,sBAAsB,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAC3D,SAAS;YACX,CAAC;YAED,kCAAkC;YAClC,IAAI,qBAAqB,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;gBAC1D,SAAS;YACX,CAAC;YAED,2DAA2D;YAC3D,MAAM,SAAS,GACb,uBAAA,IAAI,mDAAmB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,qBAAqB,CAAC,CAAC;YAElE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS;YACX,CAAC;YAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAC7D,SAAS,CAAC;YAEZ,kBAAkB,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,uBAAuB,EAAE,CAAC,CAAC;YAClE,iBAAiB,CAAC,IAAI,CAAC;gBACrB,OAAO,EAAE,uBAAuB;gBAChC,QAAQ;gBACR,MAAM;gBACN,WAAW;gBACX,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,KAAK;gBACf,IAAI;gBACJ,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,mBAAmB;QACnB,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;YAC7B,uBAAA,IAAI,uDAAuB,MAA3B,IAAI,EAAwB;gBAC1B,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE;oBACV,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,KAAK;oBACrB,UAAU,EAAE,WAAW,CAAC,KAAK;iBAC9B;aACF,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACzC,gDAAgD,EAChD,OAAO,CACR,CAAC;YAEF,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,4BAA4B,EAC5B,iBAAiB,EACjB,eAAe,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;CAcF;;IAhrBG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxD,uBAAA,IAAI,wCAAe,IAAI,MAAA,CAAC;QACxB,uBAAA,IAAI,4FAAuB,MAA3B,IAAI,CAAyB,CAAC,KAAK,CAAC,GAAG,EAAE;YACvC,yCAAyC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtD,uBAAA,IAAI,wCAAe,KAAK,MAAA,CAAC;QACzB,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,iCAAiC,EACjC,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE;QACxB,MAAM,aAAa,GAAG,uBAAA,IAAI,+FAA0B,MAA9B,IAAI,EACxB,iBAAiB,EACjB,uBAAA,IAAI,mDAAmB,CACxB,CAAC;QACF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,uBAAA,IAAI,4FAAuB,MAA3B,IAAI,CAAyB,CAAC,KAAK,CAAC,GAAG,EAAE;gBACvC,yCAAyC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,mCAAmC,EACnC,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE;QACxB,MAAM,eAAe,GAAG,uBAAA,IAAI,yFAAoB,MAAxB,IAAI,CAAsB,CAAC;QACnD,MAAM,iCAAiC,GACrC,uBAAA,IAAI,mEAAmC,KAAK,iBAAiB,CAAC;QAEhE,uBAAA,IAAI,+DAAsC,iBAAiB,MAAA,CAAC;QAE5D,IAAI,iCAAiC,EAAE,CAAC;YACtC,uBAAA,IAAI,4FAAuB,MAA3B,IAAI,EAAwB;gBAC1B,eAAe,EAAE,eAAe,CAAC,OAAO;aACzC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACZ,yCAAyC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,6CAA6C,EAC7C,CAAC,eAAe,EAAE,EAAE;QAClB,MAAM,EAAE,8BAA8B,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC5D,4BAA4B,CAC7B,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAU,CAAC;QACtE,MAAM,0BAA0B,GAC9B,uBAAA,IAAI,mDAAmB,KAAK,eAAe,CAAC,EAAE,CAAC;QACjD,IAAI,0BAA0B,EAAE,CAAC;YAC/B,uBAAA,IAAI,+CAAsB,eAAe,CAAC,EAAE,MAAA,CAAC;YAC7C,uBAAA,IAAI,4FAAuB,MAA3B,IAAI,EAAwB;gBAC1B,eAAe,EAAE,eAAe,CAAC,OAAO;gBACxC,QAAQ;aACT,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACZ,yCAAyC;YAC3C,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CACF,CAAC;IAEF,IAAI,CAAC,SAAS,CAAC,SAAS,CACtB,4CAA4C,EAC5C,CAAC,eAAe,EAAE,EAAE;QAClB,IAAI,CAAC,YAAY,CAAC;YAChB,QAAQ,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC;SACpC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,yCAAyC;QAC3C,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC;IA0CC,IAAI,uBAAA,IAAI,4CAAY,EAAE,CAAC;QACrB,aAAa,CAAC,uBAAA,IAAI,4CAAY,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK;IACH,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IACD,uBAAA,IAAI,kFAAa,MAAjB,IAAI,CAAe,CAAC;IACpB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC1B,gFAAgF;IAChF,kEAAkE;IAClE,uBAAA,IAAI,wCAAe,WAAW,CAAC,KAAK,IAAI,EAAE;QACxC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAA,CAAC;AAC/B,CAAC,mHAWC,iBAAoC,EACpC,yBAA4C;IAE5C,MAAM,8BAA8B,GAAG,0BAA0B,CAC/D,yBAAyB,CAC1B,CAAC;IACF,MAAM,sBAAsB,GAC1B,0BAA0B,CAAC,iBAAiB,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,OAAO,CAC3B,sBAAsB,EACtB,8BAA8B,CAC/B,CAAC;IACF,OAAO,aAAa,CAAC;AACvB,CAAC,uIAGC,QAA2B;IAE3B,MAAM,EAAE,8BAA8B,EAAE,uBAAuB,EAAE,GAC/D,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAEpD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,oBAAoB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC9C,4DAA4D,EAC5D,uBAAuB,CACxB,CAAC;QAEF,OAAO;YACL;gBACE,OAAO,EAAE,oBAAoB,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO;gBACzD,eAAe,EAAE,uBAAuB;aACzC;SACF,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,MAAM,aAAa,GAAG,8BAA8B,CAAC,OAAO,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO;YACP,eAAe,EACb,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,uBAAuB,CAAC;iBAC9D,eAAe;SACrB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAeD;;;;;;;GAOG;AACH,KAAK,0DAAwB,EAC3B,eAAe,EACf,QAAQ,MAIN,EAAE;IACJ,MAAM,IAAI,CAAC,YAAY,CAAC;QACtB,QAAQ;QACR,eAAe;KAChB,CAAC,CAAC;IACH,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAC3C,CAAC,uGAEmB,OAAY;IAC9B,IAAI,CAAC,mCAAmC,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IACE,CAAC,uBAAA,IAAI,mEAAmC;QACxC,OAAO,KAAK,OAAO,CAAC,OAAO,EAC3B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,0BAA0B,GAC9B,CAAC,uBAAA,IAAI,mEAAmC,IAAI,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC;IAC1E,IAAI,0BAA0B,EAAE,CAAC;QAC/B,uBAAA,IAAI,+CAAsB,uBAAA,IAAI,yGAAoC,MAAxC,IAAI,CAAsC,MAAA,CAAC;IACvE,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAC/C,8BAA8B,CAC/B,CAAC;QACF,uBAAA,IAAI,+CAAsB,iBAAiB,IAAI,EAAE,MAAA,CAAC;IACpD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,mDAED,KAAK,yDACH,sBAAuC,EACvC,eAAuB;IAEvB,KAAK,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,sBAAsB,EAAE,CAAC;QAClE,IAAI,CAAC,uBAAA,IAAI,yFAAoB,MAAxB,IAAI,EAAqB,OAAO,CAAC,EAAE,CAAC;YACvC,SAAS;QACX,CAAC;QAED,MAAM,oBAAoB,GAAG,uBAAA,IAAI,gGAA2B,MAA/B,IAAI,EAA4B;YAC3D,OAAO;YACP,eAAe,EAAE,eAAe;SACjC,CAAC,CAAC;QACH,MAAM,sBAAsB,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CACtE,uBAAA,IAAI,wFAAmB,MAAvB,IAAI,EAAoB;YACtB,WAAW;YACX,eAAe,EAAE,eAAe;YAChC,eAAe;YACf,OAAO;SACR,CAAC,CACH,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC,qHAuD0B,EACzB,OAAO,EACP,eAAe,GAIhB;IACC,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,GACtD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACnD,MAAM,CAAC,eAAe,EAAE,uBAAuB,EAAE,sBAAsB,CAAC,GAAG;QACzE,SAAS;QACT,iBAAiB;QACjB,gBAAgB;KACjB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACf,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACvD,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAClD,CACF,CAAC;IAEF,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,IAAI,CACpC,uBAAA,IAAI,mDAAmB,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,EAAE,CAC/C,EAAE,CAAC;QACF,IACE;YACE,eAAe;YACf,uBAAuB;YACvB,sBAAsB;SACvB,CAAC,KAAK,CACL,CAAC,SAAS,EAAE,EAAE,CACZ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1B,sBAAsB,CAAC,OAAO,EAAE,YAAY,CAAC,CAC9C,CACJ,EACD,CAAC;YACD,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,MAAM,sBAAsB,GAAG,EAAE,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAClE,sBAAsB,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,sBAAsB,CAAC;AAChC,CAAC;IAGC,MAAM,IAAI,GAAiB,MAAM,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,MAAM,CACzE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACtB,GAAG,GAAG;QACN,CAAC,GAAG,CAAC,EAAE;YACL,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,KAAK,EAAE,OAAO;SACxB;KACF,CAAC,EACF,EAAE,CACH,CAAC;IACF,OAAO;QACL,KAAK,EAAE;YACL,IAAI;YACJ,SAAS,EAAE,CAAC;SACb;KACF,CAAC;AACJ,CAAC,gDAED,KAAK,sDAAoB,EACvB,WAAW,EACX,eAAe,EACf,eAAe,EACf,OAAO,GAMR;IACC,MAAM,aAAa,CAAC,KAAK,IAAI,EAAE;QAC7B,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,yDAAyB,MAA7B,IAAI,EACzB,eAAe,EACf,WAAW,EACX,eAAe,CAChB,CAAC;QAEF,MAAM,iBAAiB,GAAY,EAAE,CAAC;QACtC,MAAM,kBAAkB,GAAa,EAAE,CAAC;QACxC,KAAK,MAAM,mBAAmB,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAC7D,uBAAA,IAAI,mDAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC7D,kBAAkB,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,mBAAmB,EAAE,CAAC,CAAC;YAC9D,iBAAiB,CAAC,IAAI,CAAC;gBACrB,OAAO,EAAE,mBAAmB;gBAC5B,QAAQ;gBACR,MAAM;gBACN,WAAW;gBACX,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,KAAK;gBACf,IAAI;gBACJ,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;YAC7B,uBAAA,IAAI,uDAAuB,MAA3B,IAAI,EAAwB;gBAC1B,KAAK,EAAE,gBAAgB;gBACvB,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE;oBACV,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,KAAK;oBACrB,UAAU,EAAE,WAAW,CAAC,KAAK;iBAC9B;aACF,CAAC,CAAC;YAEH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CACvB,4BAA4B,EAC5B,iBAAiB,EACjB,eAAe,CAChB,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;IA0NC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;AACtE,CAAC;IAGC,oGAAoG;IACpG,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CACjC,+BAA+B,EAC/B,uBAAA,IAAI,mDAAmB,CACxB,CAAC;IACF,OAAO,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;AAChC,CAAC;AAGH,eAAe,wBAAwB,CAAC","sourcesContent":["import type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerGetAccountAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport {\n ASSET_TYPES,\n ChainId,\n ERC20,\n safelyExecute,\n isEqualCaseInsensitive,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type {\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 NetworkClientId,\n NetworkControllerFindNetworkClientIdByChainIdAction,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkDidChangeEvent,\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 { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual, mapValues, isObject, get } from 'lodash';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from './constants';\nimport type { TokenDetectionControllerMethodActions } from './TokenDetectionController-method-action-types';\nimport type {\n GetTokenListState,\n TokenListMap,\n TokenListStateChange,\n TokensChainsCache,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type { TokensControllerGetStateAction } from './TokensController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerAddTokensAction,\n} from './TokensController-method-action-types';\n\nconst DEFAULT_INTERVAL = 180000;\n\ntype LegacyToken = {\n name: string;\n logo: `${string}.svg`;\n symbol: string;\n decimals: number;\n erc20?: boolean;\n erc721?: boolean;\n};\n\ntype TokenDetectionMap = {\n [P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;\n};\n\ntype NetworkClient = {\n chainId: Hex;\n networkClientId: string;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<TokenDetectionMap>((acc, [base, contract]) => {\n const { logo, erc20, erc721, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\n/**\n * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.\n *\n * @param tokensChainsCache - TokensChainsCache input object\n * @returns returns the map of chainId with TokenListMap\n */\nexport function mapChainIdWithTokenListMap(\n tokensChainsCache: TokensChainsCache,\n): Record<string, unknown> {\n return mapValues(tokensChainsCache, (value) => {\n if (isObject(value) && 'data' in value) {\n return get(value, ['data']);\n }\n return value;\n });\n}\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n | TokenDetectionControllerGetStateAction\n | TokenDetectionControllerMethodActions;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetAccountAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | NetworkControllerGetStateAction\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerAddTokensAction\n | NetworkControllerFindNetworkClientIdByChainIdAction\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent\n | TransactionControllerTransactionConfirmedEvent;\n\nexport type TokenDetectionControllerMessenger = Messenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents\n>;\n\n/** The input to start polling for the {@link TokenDetectionController} */\ntype TokenDetectionPollingInput = {\n chainIds: Hex[];\n address: string;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'addDetectedTokensViaWs',\n 'addDetectedTokensViaPolling',\n 'detectTokens',\n 'enable',\n 'disable',\n 'start',\n 'stop',\n] as const;\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n *\n * intervalId - Polling interval used to fetch new token rates\n *\n * selectedAddress - Vault selected address\n *\n * networkClientId - The network client ID of the current selected network\n *\n * disabled - Boolean to track if network requests are blocked\n *\n * isUnlocked - Boolean to track if the keyring state is unlocked\n *\n * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n *\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<TokenDetectionPollingInput>()<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #selectedAccountId: string;\n\n #tokensChainsCache: TokensChainsCache = {};\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n readonly #useTokenDetection: () => boolean;\n\n readonly #useExternalServices: () => boolean;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messenger.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n * @param options.useTokenDetection - Feature Switch for using token detection (default: true)\n * @param options.useExternalServices - Feature Switch for using external services (default: false)\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n useTokenDetection = (): boolean => true,\n useExternalServices = (): boolean => true,\n }: {\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n useTokenDetection?: () => boolean;\n useExternalServices?: () => boolean;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#selectedAccountId = this.#getSelectedAccount().id;\n\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n\n this.#tokensChainsCache = tokensChainsCache;\n\n const { useTokenDetection: defaultUseTokenDetection } = this.messenger.call(\n 'PreferencesController:getState',\n );\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#useTokenDetection = useTokenDetection;\n this.#useExternalServices = useExternalServices;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messenger subscriptions to controller events.\n */\n #registerEventListeners(): void {\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n this.#restartTokenDetection().catch(() => {\n // Silently handle token detection errors\n });\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messenger.subscribe(\n 'TokenListController:stateChange',\n ({ tokensChainsCache }) => {\n const isEqualValues = this.#compareTokensChainsCache(\n tokensChainsCache,\n this.#tokensChainsCache,\n );\n if (!isEqualValues) {\n this.#restartTokenDetection().catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'PreferencesController:stateChange',\n ({ useTokenDetection }) => {\n const selectedAccount = this.#getSelectedAccount();\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (isDetectionChangedFromPreferences) {\n this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n }).catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n (selectedAccount) => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = Object.keys(networkConfigurationsByChainId) as Hex[];\n const isSelectedAccountIdChanged =\n this.#selectedAccountId !== selectedAccount.id;\n if (isSelectedAccountIdChanged) {\n this.#selectedAccountId = selectedAccount.id;\n this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n chainIds,\n }).catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.detectTokens({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle token detection errors\n });\n },\n );\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n /**\n * Internal isActive state\n *\n * @returns Whether the controller is active (not disabled and keyring is unlocked)\n */\n get isActive(): boolean {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start(): Promise<void> {\n this.enable();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop(): void {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling(): void {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n /**\n * Compares current and previous tokensChainsCache object focusing only on the data object.\n *\n * @param tokensChainsCache - current tokensChainsCache input object\n * @param previousTokensChainsCache - previous tokensChainsCache input object\n * @returns boolean indicating if the two objects are equal\n */\n\n #compareTokensChainsCache(\n tokensChainsCache: TokensChainsCache,\n previousTokensChainsCache: TokensChainsCache,\n ): boolean {\n const cleanPreviousTokensChainsCache = mapChainIdWithTokenListMap(\n previousTokensChainsCache,\n );\n const cleanTokensChainsCache =\n mapChainIdWithTokenListMap(tokensChainsCache);\n const isEqualValues = isEqual(\n cleanTokensChainsCache,\n cleanPreviousTokensChainsCache,\n );\n return isEqualValues;\n }\n\n #getCorrectNetworkClientIdByChainId(\n chainIds: Hex[] | undefined,\n ): { chainId: Hex; networkClientId: NetworkClientId }[] {\n const { networkConfigurationsByChainId, selectedNetworkClientId } =\n this.messenger.call('NetworkController:getState');\n\n if (!chainIds) {\n const networkConfiguration = this.messenger.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n selectedNetworkClientId,\n );\n\n return [\n {\n chainId: networkConfiguration?.chainId ?? ChainId.mainnet,\n networkClientId: selectedNetworkClientId,\n },\n ];\n }\n\n return chainIds.map((chainId) => {\n const configuration = networkConfigurationsByChainId[chainId];\n return {\n chainId,\n networkClientId:\n configuration.rpcEndpoints[configuration.defaultRpcEndpointIndex]\n .networkClientId,\n };\n });\n }\n\n async _executePoll({\n chainIds,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n chainIds,\n selectedAddress: address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.chainIds - The chain IDs of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n chainIds,\n }: {\n selectedAddress?: string;\n chainIds?: Hex[];\n } = {}): Promise<void> {\n await this.detectTokens({\n chainIds,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n #shouldDetectTokens(chainId: Hex): boolean {\n if (!isTokenDetectionSupportedForNetwork(chainId)) {\n return false;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainId !== ChainId.mainnet\n ) {\n return false;\n }\n\n const isMainnetDetectionInactive =\n !this.#isDetectionEnabledFromPreferences && chainId === ChainId.mainnet;\n if (isMainnetDetectionInactive) {\n this.#tokensChainsCache = this.#getConvertedStaticMainnetTokenList();\n } else {\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n }\n\n return true;\n }\n\n async #detectTokensUsingRpc(\n chainsToDetectUsingRpc: NetworkClient[],\n addressToDetect: string,\n ): Promise<void> {\n for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {\n if (!this.#shouldDetectTokens(chainId)) {\n continue;\n }\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress: addressToDetect,\n });\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressToDetect,\n networkClientId,\n chainId,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\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 */\n async detectTokens({\n chainIds,\n selectedAddress,\n forceRpc = false,\n }: {\n chainIds?: Hex[];\n selectedAddress?: string;\n forceRpc?: boolean;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n // When forceRpc is true, bypass the useTokenDetection check to ensure RPC detection runs\n if (!forceRpc && !this.#useTokenDetection()) {\n return;\n }\n\n // If external services are disabled and not forcing RPC, skip all detection\n if (!forceRpc && !this.#useExternalServices()) {\n return;\n }\n\n const addressToDetect = selectedAddress ?? this.#getSelectedAddress();\n const clientNetworks = this.#getCorrectNetworkClientIdByChainId(chainIds);\n\n // If forceRpc is true, use RPC for all chains\n // Otherwise, skip chains supported by Accounts API (they are handled by TokenBalancesController)\n const chainsToDetectUsingRpc = forceRpc\n ? clientNetworks\n : clientNetworks.filter(\n ({ chainId }) =>\n !SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId),\n );\n\n if (chainsToDetectUsingRpc.length === 0) {\n return;\n }\n\n await this.#detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect);\n }\n\n #getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n }: {\n chainId: Hex;\n selectedAddress: string;\n }): string[][] {\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [\n allTokens,\n allDetectedTokens,\n allIgnoredTokens,\n ].map((tokens) =>\n (tokens[chainId]?.[selectedAddress] ?? []).map((value) =>\n typeof value === 'string' ? value : value.address,\n ),\n );\n\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(\n this.#tokensChainsCache?.[chainId]?.data || {},\n )) {\n if (\n [\n tokensAddresses,\n detectedTokensAddresses,\n ignoredTokensAddresses,\n ].every(\n (addresses) =>\n !addresses.find((address) =>\n isEqualCaseInsensitive(address, tokenAddress),\n ),\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n\n const slicesOfTokensToDetect = [];\n for (let i = 0, size = 1000; i < tokensToDetect.length; i += size) {\n slicesOfTokensToDetect.push(tokensToDetect.slice(i, i + size));\n }\n\n return slicesOfTokensToDetect;\n }\n\n #getConvertedStaticMainnetTokenList(): TokensChainsCache {\n const data: TokenListMap = Object.entries(STATIC_MAINNET_TOKEN_LIST).reduce(\n (acc, [key, value]) => ({\n ...acc,\n [key]: {\n name: value.name,\n symbol: value.symbol,\n decimals: value.decimals,\n address: value.address,\n aggregators: [],\n iconUrl: value?.iconUrl,\n },\n }),\n {},\n );\n return {\n '0x1': {\n data,\n timestamp: 0,\n },\n };\n }\n\n async #addDetectedTokens({\n tokensSlice,\n selectedAddress,\n networkClientId,\n chainId,\n }: {\n tokensSlice: string[];\n selectedAddress: string;\n networkClientId: NetworkClientId;\n chainId: Hex;\n }): Promise<void> {\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n selectedAddress,\n tokensSlice,\n networkClientId,\n );\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n for (const nonZeroTokenAddress of Object.keys(balances)) {\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n this.#tokensChainsCache[chainId].data[nonZeroTokenAddress];\n eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);\n tokensWithBalance.push({\n address: nonZeroTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\n });\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 */\n async addDetectedTokensViaWs({\n tokensSlice,\n chainId,\n }: {\n tokensSlice: string[];\n chainId: Hex;\n }): Promise<void> {\n // Check if token detection is enabled via preferences\n if (!this.#useTokenDetection()) {\n return;\n }\n\n // Check if external services are enabled (websocket requires external services)\n if (!this.#useExternalServices()) {\n return;\n }\n\n // Refresh the token cache to ensure we have the latest token metadata\n // This fixes a bug where the cache from construction time could be stale/empty\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n for (const tokenAddress of tokensSlice) {\n // Normalize addresses explicitly (don't assume input format)\n const lowercaseTokenAddress = tokenAddress.toLowerCase();\n const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);\n\n // Check map of validated tokens (cache keys are lowercase)\n const tokenData =\n this.#tokensChainsCache[chainId]?.data?.[lowercaseTokenAddress];\n\n if (!tokenData) {\n continue;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n tokenData;\n\n // Push to lists with checksummed address (for allTokens storage)\n eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);\n tokensWithBalance.push({\n address: checksummedTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n // Perform addition\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\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 */\n async addDetectedTokensViaPolling({\n tokensSlice,\n chainId,\n }: {\n tokensSlice: string[];\n chainId: Hex;\n }): Promise<void> {\n // Check if token detection is enabled via preferences\n if (!this.#useTokenDetection()) {\n return;\n }\n\n // Check if external services are enabled (polling via API requires external services)\n if (!this.#useExternalServices()) {\n return;\n }\n\n // Refresh the token cache to ensure we have the latest token metadata\n // This fixes a bug where the cache from construction time could be stale/empty\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n\n const selectedAddress = this.#getSelectedAddress();\n\n // Get current token states to filter out already tracked/ignored tokens\n const { allTokens, allIgnoredTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n const existingTokenAddresses = (\n allTokens[chainId]?.[selectedAddress] ?? []\n ).map((token) => token.address.toLowerCase());\n\n const ignoredTokenAddresses = (\n allIgnoredTokens[chainId]?.[selectedAddress] ?? []\n ).map((address) => address.toLowerCase());\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n for (const tokenAddress of tokensSlice) {\n const lowercaseTokenAddress = tokenAddress.toLowerCase();\n const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);\n\n // Skip tokens already in allTokens\n if (existingTokenAddresses.includes(lowercaseTokenAddress)) {\n continue;\n }\n\n // Skip tokens in allIgnoredTokens\n if (ignoredTokenAddresses.includes(lowercaseTokenAddress)) {\n continue;\n }\n\n // Check map of validated tokens (cache keys are lowercase)\n const tokenData =\n this.#tokensChainsCache[chainId]?.data?.[lowercaseTokenAddress];\n\n if (!tokenData) {\n continue;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n tokenData;\n\n eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);\n tokensWithBalance.push({\n address: checksummedTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n // Perform addition\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\n }\n\n #getSelectedAccount(): InternalAccount {\n return this.messenger.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedAddress(): string {\n // If the address is not defined (or empty), we fallback to the currently selected account's address\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n this.#selectedAccountId,\n );\n return account?.address ?? '';\n }\n}\n\nexport default TokenDetectionController;\n"]}
1
+ {"version":3,"file":"TokenDetectionController.mjs","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerGetAccountAction,\n AccountsControllerSelectedEvmAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport {\n ASSET_TYPES,\n ChainId,\n ERC20,\n safelyExecute,\n isEqualCaseInsensitive,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type {\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 NetworkClientId,\n NetworkControllerFindNetworkClientIdByChainIdAction,\n NetworkControllerGetNetworkClientByIdAction,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n NetworkControllerGetStateAction,\n NetworkControllerNetworkAddedEvent,\n NetworkControllerNetworkDidChangeEvent,\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 { TransactionControllerTransactionConfirmedEvent } from '@metamask/transaction-controller';\nimport type { Hex } from '@metamask/utils';\nimport { isEqual, mapValues, isObject, get } from 'lodash';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport { SUPPORTED_NETWORKS_ACCOUNTS_API_V4 } from './constants';\nimport type { TokenDetectionControllerMethodActions } from './TokenDetectionController-method-action-types';\nimport type {\n GetTokenListState,\n TokenListMap,\n TokenListStateChange,\n TokensChainsCache,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type { TokensControllerGetStateAction } from './TokensController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerAddTokensAction,\n} from './TokensController-method-action-types';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * Canonical contract address for MetaMask USD (mUSD) — same across every\n * chain we deploy it to.\n */\nconst MUSD_ADDRESS = '0xaca92e438df0b2401ff60da7e4337b687a2435da';\n\n/**\n * Pre-built Token entry for mUSD — used when seeding default state.\n */\nconst MUSD_TOKEN: Token = {\n address: MUSD_ADDRESS,\n decimals: 6,\n symbol: 'mUSD',\n name: 'MetaMask USD',\n};\n\n/**\n * Hex chain IDs on which mUSD is deployed and should be added by default.\n * - 0x1 — Ethereum mainnet (1)\n * - 0xe708 — Linea (59144)\n * - 0x8f — Monad mainnet (143)\n * - 0x279f — Monad testnet (10143)\n */\nconst MUSD_SUPPORTED_CHAIN_IDS: ReadonlySet<Hex> = new Set<Hex>([\n '0x1',\n '0xe708',\n '0x8f',\n '0x279f',\n]);\n\ntype LegacyToken = {\n name: string;\n logo: `${string}.svg`;\n symbol: string;\n decimals: number;\n erc20?: boolean;\n erc721?: boolean;\n};\n\ntype TokenDetectionMap = {\n [P in keyof TokenListMap]: Omit<TokenListMap[P], 'occurrences'>;\n};\n\ntype NetworkClient = {\n chainId: Hex;\n networkClientId: string;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<TokenDetectionMap>((acc, [base, contract]) => {\n const { logo, erc20, erc721, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\n/**\n * Function that takes a TokensChainsCache object and maps chainId with TokenListMap.\n *\n * @param tokensChainsCache - TokensChainsCache input object\n * @returns returns the map of chainId with TokenListMap\n */\nexport function mapChainIdWithTokenListMap(\n tokensChainsCache: TokensChainsCache,\n): Record<string, unknown> {\n return mapValues(tokensChainsCache, (value) => {\n if (isObject(value) && 'data' in value) {\n return get(value, ['data']);\n }\n return value;\n });\n}\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n | TokenDetectionControllerGetStateAction\n | TokenDetectionControllerMethodActions;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | AccountsControllerGetAccountAction\n | NetworkControllerGetNetworkClientByIdAction\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | NetworkControllerGetStateAction\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction\n | TokensControllerAddTokensAction\n | NetworkControllerFindNetworkClientIdByChainIdAction\n | AuthenticationController.AuthenticationControllerGetBearerTokenAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedEvmAccountChangeEvent\n | NetworkControllerNetworkAddedEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent\n | TransactionControllerTransactionConfirmedEvent;\n\nexport type TokenDetectionControllerMessenger = Messenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents\n>;\n\n/** The input to start polling for the {@link TokenDetectionController} */\ntype TokenDetectionPollingInput = {\n chainIds: Hex[];\n address: string;\n};\n\nconst MESSENGER_EXPOSED_METHODS = [\n 'addDetectedTokensViaWs',\n 'addDetectedTokensViaPolling',\n 'detectTokens',\n 'enable',\n 'disable',\n 'start',\n 'stop',\n] as const;\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n *\n * intervalId - Polling interval used to fetch new token rates\n *\n * selectedAddress - Vault selected address\n *\n * networkClientId - The network client ID of the current selected network\n *\n * disabled - Boolean to track if network requests are blocked\n *\n * isUnlocked - Boolean to track if the keyring state is unlocked\n *\n * isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n *\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<TokenDetectionPollingInput>()<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #selectedAccountId: string;\n\n #tokensChainsCache: TokensChainsCache = {};\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n readonly #useTokenDetection: () => boolean;\n\n readonly #useExternalServices: () => boolean;\n\n /** Tracks whether default tokens (mUSD) have been seeded for the current session. */\n #defaultTokensSeeded = false;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messenger.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n * @param options.useTokenDetection - Feature Switch for using token detection (default: true)\n * @param options.useExternalServices - Feature Switch for using external services (default: false)\n */\n constructor({\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n useTokenDetection = (): boolean => true,\n useExternalServices = (): boolean => true,\n }: {\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n // eslint-disable-next-line @typescript-eslint/naming-convention\n token_standard: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n useTokenDetection?: () => boolean;\n useExternalServices?: () => boolean;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n messenger.registerMethodActionHandlers(this, MESSENGER_EXPOSED_METHODS);\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#selectedAccountId = this.#getSelectedAccount().id;\n\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n\n this.#tokensChainsCache = tokensChainsCache;\n\n const { useTokenDetection: defaultUseTokenDetection } = this.messenger.call(\n 'PreferencesController:getState',\n );\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messenger.call('KeyringController:getState');\n this.#isUnlocked = isUnlocked;\n\n this.#useTokenDetection = useTokenDetection;\n this.#useExternalServices = useExternalServices;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messenger subscriptions to controller events.\n */\n #registerEventListeners(): void {\n this.messenger.subscribe('KeyringController:unlock', () => {\n this.#isUnlocked = true;\n this.#restartTokenDetection().catch(() => {\n // Silently handle token detection errors\n });\n });\n\n this.messenger.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messenger.subscribe(\n 'TokenListController:stateChange',\n ({ tokensChainsCache }) => {\n const isEqualValues = this.#compareTokensChainsCache(\n tokensChainsCache,\n this.#tokensChainsCache,\n );\n if (!isEqualValues) {\n this.#restartTokenDetection().catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'PreferencesController:stateChange',\n ({ useTokenDetection }) => {\n const selectedAccount = this.#getSelectedAccount();\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (isDetectionChangedFromPreferences) {\n this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n }).catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'AccountsController:selectedEvmAccountChange',\n (selectedAccount) => {\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n const chainIds = Object.keys(networkConfigurationsByChainId) as Hex[];\n const isSelectedAccountIdChanged =\n this.#selectedAccountId !== selectedAccount.id;\n if (isSelectedAccountIdChanged) {\n this.#selectedAccountId = selectedAccount.id;\n // Re-seed mUSD for the newly selected account. addTokens only adds\n // tokens for the currently selected account, so we need to re-run\n // it whenever the active account changes.\n this.#defaultTokensSeeded = false;\n this.#seedDefaultTokens().catch(() => {\n // Silently handle default-token seeding errors\n });\n this.#restartTokenDetection({\n selectedAddress: selectedAccount.address,\n chainIds,\n }).catch(() => {\n // Silently handle token detection errors\n });\n }\n },\n );\n\n this.messenger.subscribe(\n 'TransactionController:transactionConfirmed',\n (transactionMeta) => {\n this.detectTokens({\n chainIds: [transactionMeta.chainId],\n }).catch(() => {\n // Silently handle token detection errors\n });\n },\n );\n\n // Re-seed mUSD whenever a network is added. Covers the case where the\n // user adds a supported chain (e.g. Monad testnet) after the controller\n // has already started — the chain wasn't configured at start() time so\n // findNetworkClientIdByChainId would have skipped it.\n this.messenger.subscribe(\n 'NetworkController:networkAdded',\n ({ chainId }) => {\n if (!MUSD_SUPPORTED_CHAIN_IDS.has(chainId)) {\n return;\n }\n this.#defaultTokensSeeded = false;\n this.#seedDefaultTokens().catch(() => {\n // Silently handle default-token seeding errors\n });\n },\n );\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable(): void {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable(): void {\n this.#disabled = true;\n }\n\n /**\n * Internal isActive state\n *\n * @returns Whether the controller is active (not disabled and keyring is unlocked)\n */\n get isActive(): boolean {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start(): Promise<void> {\n this.enable();\n // Seed mUSD as a default token via TokensController:addTokens. Runs\n // once per session; idempotent because addTokens dedupes on address.\n await this.#seedDefaultTokens();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop(): void {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling(): void {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\n // TODO: Either fix this lint violation or explain why it's necessary to ignore.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n /**\n * Compares current and previous tokensChainsCache object focusing only on the data object.\n *\n * @param tokensChainsCache - current tokensChainsCache input object\n * @param previousTokensChainsCache - previous tokensChainsCache input object\n * @returns boolean indicating if the two objects are equal\n */\n\n #compareTokensChainsCache(\n tokensChainsCache: TokensChainsCache,\n previousTokensChainsCache: TokensChainsCache,\n ): boolean {\n const cleanPreviousTokensChainsCache = mapChainIdWithTokenListMap(\n previousTokensChainsCache,\n );\n const cleanTokensChainsCache =\n mapChainIdWithTokenListMap(tokensChainsCache);\n const isEqualValues = isEqual(\n cleanTokensChainsCache,\n cleanPreviousTokensChainsCache,\n );\n return isEqualValues;\n }\n\n #getCorrectNetworkClientIdByChainId(\n chainIds: Hex[] | undefined,\n ): { chainId: Hex; networkClientId: NetworkClientId }[] {\n const { networkConfigurationsByChainId, selectedNetworkClientId } =\n this.messenger.call('NetworkController:getState');\n\n if (!chainIds) {\n const networkConfiguration = this.messenger.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n selectedNetworkClientId,\n );\n\n return [\n {\n chainId: networkConfiguration?.chainId ?? ChainId.mainnet,\n networkClientId: selectedNetworkClientId,\n },\n ];\n }\n\n return chainIds.map((chainId) => {\n const configuration = networkConfigurationsByChainId[chainId];\n return {\n chainId,\n networkClientId:\n configuration.rpcEndpoints[configuration.defaultRpcEndpointIndex]\n .networkClientId,\n };\n });\n }\n\n async _executePoll({\n chainIds,\n address,\n }: TokenDetectionPollingInput): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n chainIds,\n selectedAddress: address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.chainIds - The chain IDs of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n chainIds,\n }: {\n selectedAddress?: string;\n chainIds?: Hex[];\n } = {}): Promise<void> {\n await this.detectTokens({\n chainIds,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n #shouldDetectTokens(chainId: Hex): boolean {\n if (!isTokenDetectionSupportedForNetwork(chainId)) {\n return false;\n }\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainId !== ChainId.mainnet\n ) {\n return false;\n }\n\n const isMainnetDetectionInactive =\n !this.#isDetectionEnabledFromPreferences && chainId === ChainId.mainnet;\n if (isMainnetDetectionInactive) {\n this.#tokensChainsCache = this.#getConvertedStaticMainnetTokenList();\n } else {\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n }\n\n return true;\n }\n\n async #detectTokensUsingRpc(\n chainsToDetectUsingRpc: NetworkClient[],\n addressToDetect: string,\n ): Promise<void> {\n for (const { chainId, networkClientId } of chainsToDetectUsingRpc) {\n if (!this.#shouldDetectTokens(chainId)) {\n continue;\n }\n\n const tokenCandidateSlices = this.#getSlicesOfTokensToDetect({\n chainId,\n selectedAddress: addressToDetect,\n });\n const tokenDetectionPromises = tokenCandidateSlices.map((tokensSlice) =>\n this.#addDetectedTokens({\n tokensSlice,\n selectedAddress: addressToDetect,\n networkClientId,\n chainId,\n }),\n );\n\n await Promise.all(tokenDetectionPromises);\n }\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 */\n async detectTokens({\n chainIds,\n selectedAddress,\n forceRpc = false,\n }: {\n chainIds?: Hex[];\n selectedAddress?: string;\n forceRpc?: boolean;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n // When forceRpc is true, bypass the useTokenDetection check to ensure RPC detection runs\n if (!forceRpc && !this.#useTokenDetection()) {\n return;\n }\n\n // If external services are disabled and not forcing RPC, skip all detection\n if (!forceRpc && !this.#useExternalServices()) {\n return;\n }\n\n const addressToDetect = selectedAddress ?? this.#getSelectedAddress();\n const clientNetworks = this.#getCorrectNetworkClientIdByChainId(chainIds);\n\n // If forceRpc is true, use RPC for all chains\n // Otherwise, skip chains supported by Accounts API (they are handled by TokenBalancesController)\n const chainsToDetectUsingRpc = forceRpc\n ? clientNetworks\n : clientNetworks.filter(\n ({ chainId }) =>\n !SUPPORTED_NETWORKS_ACCOUNTS_API_V4.includes(chainId),\n );\n\n if (chainsToDetectUsingRpc.length === 0) {\n return;\n }\n\n await this.#detectTokensUsingRpc(chainsToDetectUsingRpc, addressToDetect);\n }\n\n #getSlicesOfTokensToDetect({\n chainId,\n selectedAddress,\n }: {\n chainId: Hex;\n selectedAddress: string;\n }): string[][] {\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messenger.call('TokensController:getState');\n const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [\n allTokens,\n allDetectedTokens,\n allIgnoredTokens,\n ].map((tokens) =>\n (tokens[chainId]?.[selectedAddress] ?? []).map((value) =>\n typeof value === 'string' ? value : value.address,\n ),\n );\n\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(\n this.#tokensChainsCache?.[chainId]?.data || {},\n )) {\n if (\n [\n tokensAddresses,\n detectedTokensAddresses,\n ignoredTokensAddresses,\n ].every(\n (addresses) =>\n !addresses.find((address) =>\n isEqualCaseInsensitive(address, tokenAddress),\n ),\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n\n const slicesOfTokensToDetect = [];\n for (let i = 0, size = 1000; i < tokensToDetect.length; i += size) {\n slicesOfTokensToDetect.push(tokensToDetect.slice(i, i + size));\n }\n\n return slicesOfTokensToDetect;\n }\n\n #getConvertedStaticMainnetTokenList(): TokensChainsCache {\n const data: TokenListMap = Object.entries(STATIC_MAINNET_TOKEN_LIST).reduce(\n (acc, [key, value]) => ({\n ...acc,\n [key]: {\n name: value.name,\n symbol: value.symbol,\n decimals: value.decimals,\n address: value.address,\n aggregators: [],\n iconUrl: value?.iconUrl,\n },\n }),\n {},\n );\n return {\n '0x1': {\n data,\n timestamp: 0,\n },\n };\n }\n\n /**\n * Seed mUSD into `TokensController.allTokens` via the public `addTokens`\n * action for every supported chain that is currently configured in\n * `NetworkController`.\n *\n * Runs once per session (idempotent guard via `#defaultTokensSeeded`), but\n * `addTokens` itself dedupes by contract address so re-running is safe.\n *\n * @returns Promise that resolves once seeding has been attempted on every\n * supported chain.\n */\n async #seedDefaultTokens(): Promise<void> {\n if (this.#defaultTokensSeeded) {\n return;\n }\n this.#defaultTokensSeeded = true;\n\n const { networkConfigurationsByChainId } = this.messenger.call(\n 'NetworkController:getState',\n );\n\n for (const supportedChainId of MUSD_SUPPORTED_CHAIN_IDS) {\n if (!networkConfigurationsByChainId[supportedChainId]) {\n continue;\n }\n\n try {\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n supportedChainId,\n );\n await this.messenger.call(\n 'TokensController:addTokens',\n [MUSD_TOKEN],\n networkClientId,\n );\n } catch {\n // Silently handle per-chain seeding errors so one failure does not\n // block seeding on the remaining supported chains.\n }\n }\n }\n\n async #addDetectedTokens({\n tokensSlice,\n selectedAddress,\n networkClientId,\n chainId,\n }: {\n tokensSlice: string[];\n selectedAddress: string;\n networkClientId: NetworkClientId;\n chainId: Hex;\n }): Promise<void> {\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n selectedAddress,\n tokensSlice,\n networkClientId,\n );\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n for (const nonZeroTokenAddress of Object.keys(balances)) {\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n this.#tokensChainsCache[chainId].data[nonZeroTokenAddress];\n eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);\n tokensWithBalance.push({\n address: nonZeroTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\n });\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 */\n async addDetectedTokensViaWs({\n tokensSlice,\n chainId,\n }: {\n tokensSlice: string[];\n chainId: Hex;\n }): Promise<void> {\n // Check if token detection is enabled via preferences\n if (!this.#useTokenDetection()) {\n return;\n }\n\n // Check if external services are enabled (websocket requires external services)\n if (!this.#useExternalServices()) {\n return;\n }\n\n // Refresh the token cache to ensure we have the latest token metadata\n // This fixes a bug where the cache from construction time could be stale/empty\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n for (const tokenAddress of tokensSlice) {\n // Normalize addresses explicitly (don't assume input format)\n const lowercaseTokenAddress = tokenAddress.toLowerCase();\n const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);\n\n // Check map of validated tokens (cache keys are lowercase)\n const tokenData =\n this.#tokensChainsCache[chainId]?.data?.[lowercaseTokenAddress];\n\n if (!tokenData) {\n continue;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n tokenData;\n\n // Push to lists with checksummed address (for allTokens storage)\n eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);\n tokensWithBalance.push({\n address: checksummedTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n // Perform addition\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\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 */\n async addDetectedTokensViaPolling({\n tokensSlice,\n chainId,\n }: {\n tokensSlice: string[];\n chainId: Hex;\n }): Promise<void> {\n // Check if token detection is enabled via preferences\n if (!this.#useTokenDetection()) {\n return;\n }\n\n // Check if external services are enabled (polling via API requires external services)\n if (!this.#useExternalServices()) {\n return;\n }\n\n // Refresh the token cache to ensure we have the latest token metadata\n // This fixes a bug where the cache from construction time could be stale/empty\n const { tokensChainsCache } = this.messenger.call(\n 'TokenListController:getState',\n );\n this.#tokensChainsCache = tokensChainsCache ?? {};\n\n const selectedAddress = this.#getSelectedAddress();\n\n // Get current token states to filter out already tracked/ignored tokens\n const { allTokens, allIgnoredTokens } = this.messenger.call(\n 'TokensController:getState',\n );\n\n const existingTokenAddresses = (\n allTokens[chainId]?.[selectedAddress] ?? []\n ).map((token) => token.address.toLowerCase());\n\n const ignoredTokenAddresses = (\n allIgnoredTokens[chainId]?.[selectedAddress] ?? []\n ).map((address) => address.toLowerCase());\n\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n\n for (const tokenAddress of tokensSlice) {\n const lowercaseTokenAddress = tokenAddress.toLowerCase();\n const checksummedTokenAddress = toChecksumHexAddress(tokenAddress);\n\n // Skip tokens already in allTokens\n if (existingTokenAddresses.includes(lowercaseTokenAddress)) {\n continue;\n }\n\n // Skip tokens in allIgnoredTokens\n if (ignoredTokenAddresses.includes(lowercaseTokenAddress)) {\n continue;\n }\n\n // Check map of validated tokens (cache keys are lowercase)\n const tokenData =\n this.#tokensChainsCache[chainId]?.data?.[lowercaseTokenAddress];\n\n if (!tokenData) {\n continue;\n }\n\n const { decimals, symbol, aggregators, iconUrl, name, rwaData } =\n tokenData;\n\n eventTokensDetails.push(`${symbol} - ${checksummedTokenAddress}`);\n tokensWithBalance.push({\n address: checksummedTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n ...(rwaData && { rwaData }),\n });\n }\n\n // Perform addition\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: ERC20,\n asset_type: ASSET_TYPES.TOKEN,\n },\n });\n\n const networkClientId = this.messenger.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n\n await this.messenger.call(\n 'TokensController:addTokens',\n tokensWithBalance,\n networkClientId,\n );\n }\n }\n\n #getSelectedAccount(): InternalAccount {\n return this.messenger.call('AccountsController:getSelectedAccount');\n }\n\n #getSelectedAddress(): string {\n // If the address is not defined (or empty), we fallback to the currently selected account's address\n const account = this.messenger.call(\n 'AccountsController:getAccount',\n this.#selectedAccountId,\n );\n return account?.address ?? '';\n }\n}\n\nexport default TokenDetectionController;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.cjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.cjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { CurrencyRateControllerGetStateAction } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = CurrencyRateControllerGetStateAction;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
@@ -2,7 +2,7 @@ import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { Hex } from "@metamask/utils";
5
- import type { GetCurrencyRateState } from "../CurrencyRateController.cjs";
5
+ import type { CurrencyRateControllerGetStateAction } from "../CurrencyRateController.cjs";
6
6
  import type { AbstractTokenPricesService } from "../token-prices-service/index.cjs";
7
7
  import type { TokenDisplayData } from "./types.cjs";
8
8
  export declare const controllerName = "TokenSearchDiscoveryDataController";
@@ -23,7 +23,7 @@ export type TokenSearchDiscoveryDataControllerActions = TokenSearchDiscoveryData
23
23
  /**
24
24
  * All actions that {@link TokenSearchDiscoveryDataController} calls internally.
25
25
  */
26
- export type AllowedActions = GetCurrencyRateState;
26
+ export type AllowedActions = CurrencyRateControllerGetStateAction;
27
27
  /**
28
28
  * The event that {@link TokenSearchDiscoveryDataController} publishes when updating
29
29
  * state.
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.d.cts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.d.cts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oCAAoC,EAAE,sCAAkC;AACtF,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
@@ -2,7 +2,7 @@ import { BaseController } from "@metamask/base-controller";
2
2
  import type { ControllerGetStateAction, ControllerStateChangeEvent } from "@metamask/base-controller";
3
3
  import type { Messenger } from "@metamask/messenger";
4
4
  import type { Hex } from "@metamask/utils";
5
- import type { GetCurrencyRateState } from "../CurrencyRateController.mjs";
5
+ import type { CurrencyRateControllerGetStateAction } from "../CurrencyRateController.mjs";
6
6
  import type { AbstractTokenPricesService } from "../token-prices-service/index.mjs";
7
7
  import type { TokenDisplayData } from "./types.mjs";
8
8
  export declare const controllerName = "TokenSearchDiscoveryDataController";
@@ -23,7 +23,7 @@ export type TokenSearchDiscoveryDataControllerActions = TokenSearchDiscoveryData
23
23
  /**
24
24
  * All actions that {@link TokenSearchDiscoveryDataController} calls internally.
25
25
  */
26
- export type AllowedActions = GetCurrencyRateState;
26
+ export type AllowedActions = CurrencyRateControllerGetStateAction;
27
27
  /**
28
28
  * The event that {@link TokenSearchDiscoveryDataController} publishes when updating
29
29
  * state.
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.d.mts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,sCAAkC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.d.mts","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,kCAAkC;AAC3D,OAAO,KAAK,EAEV,wBAAwB,EACxB,0BAA0B,EAC3B,kCAAkC;AACnC,OAAO,KAAK,EAAE,SAAS,EAAE,4BAA4B;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAG3C,OAAO,KAAK,EAAE,oCAAoC,EAAE,sCAAkC;AACtF,OAAO,KAAK,EAAE,0BAA0B,EAAE,0CAAgC;AAM1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAgB;AAIhD,eAAO,MAAM,cAAc,uCAAuC,CAAC;AAEnE,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAIhD,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;CACtC,CAAC;AAcF;;;GAGG;AACH,MAAM,MAAM,gDAAgD,GAC1D,wBAAwB,CACtB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,yCAAyC,GACnD,gDAAgD,CAAC;AAEnD;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAElE;;;GAGG;AACH,MAAM,MAAM,kDAAkD,GAC5D,0BAA0B,CACxB,OAAO,cAAc,EACrB,uCAAuC,CACxC,CAAC;AAEJ;;;GAGG;AACH,MAAM,MAAM,wCAAwC,GAClD,kDAAkD,CAAC;AAErD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC;AAElC;;;GAGG;AACH,MAAM,MAAM,2CAA2C,GAAG,SAAS,CACjE,OAAO,cAAc,EACrB,yCAAyC,GAAG,cAAc,EAC1D,wCAAwC,GAAG,aAAa,CACzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,iDAAiD,IAAI,uCAAuC,CAI3G;AAED;;;GAGG;AACH,qBAAa,kCAAmC,SAAQ,cAAc,CACpE,OAAO,cAAc,EACrB,uCAAuC,EACvC,2CAA2C,CAC5C;;gBAKa,EACV,KAAU,EACV,SAAS,EACT,kBAAkB,GACnB,EAAE;QACD,KAAK,CAAC,EAAE,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACzD,SAAS,EAAE,2CAA2C,CAAC;QACvD,kBAAkB,EAAE,0BAA0B,CAAC;KAChD;IAiCK,qBAAqB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4D1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenSearchDiscoveryDataController.mjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { GetCurrencyRateState } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = GetCurrencyRateState;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"TokenSearchDiscoveryDataController.mjs","sourceRoot":"","sources":["../../src/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseController } from '@metamask/base-controller';\nimport type {\n StateMetadata,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport type { Messenger } from '@metamask/messenger';\nimport type { Hex } from '@metamask/utils';\n\nimport { formatIconUrlWithProxy } from '../assetsUtil';\nimport type { CurrencyRateControllerGetStateAction } from '../CurrencyRateController';\nimport type { AbstractTokenPricesService } from '../token-prices-service';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from '../token-service';\nimport type { TokenListToken } from '../TokenListController';\nimport type { TokenDisplayData } from './types';\n\n// === GENERAL ===\n\nexport const controllerName = 'TokenSearchDiscoveryDataController';\n\nexport const MAX_TOKEN_DISPLAY_DATA_LENGTH = 10;\n\n// === STATE ===\n\nexport type TokenSearchDiscoveryDataControllerState = {\n tokenDisplayData: TokenDisplayData[];\n};\n\nconst tokenSearchDiscoveryDataControllerMetadata: StateMetadata<TokenSearchDiscoveryDataControllerState> =\n {\n tokenDisplayData: {\n includeInStateLogs: false,\n persist: true,\n includeInDebugSnapshot: false,\n usedInUi: true,\n },\n } as const;\n\n// === MESSENGER ===\n\n/**\n * The action which can be used to retrieve the state of the\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerGetStateAction =\n ControllerGetStateAction<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} registers, to be\n * called externally.\n */\nexport type TokenSearchDiscoveryDataControllerActions =\n TokenSearchDiscoveryDataControllerGetStateAction;\n\n/**\n * All actions that {@link TokenSearchDiscoveryDataController} calls internally.\n */\nexport type AllowedActions = CurrencyRateControllerGetStateAction;\n\n/**\n * The event that {@link TokenSearchDiscoveryDataController} publishes when updating\n * state.\n */\nexport type TokenSearchDiscoveryDataControllerStateChangeEvent =\n ControllerStateChangeEvent<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState\n >;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} publishes, to be\n * subscribed to externally.\n */\nexport type TokenSearchDiscoveryDataControllerEvents =\n TokenSearchDiscoveryDataControllerStateChangeEvent;\n\n/**\n * All events that {@link TokenSearchDiscoveryDataController} subscribes to internally.\n */\nexport type AllowedEvents = never;\n\n/**\n * The messenger which is restricted to actions and events accessed by\n * {@link TokenSearchDiscoveryDataController}.\n */\nexport type TokenSearchDiscoveryDataControllerMessenger = Messenger<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerActions | AllowedActions,\n TokenSearchDiscoveryDataControllerEvents | AllowedEvents\n>;\n\n/**\n * Constructs the default {@link TokenSearchDiscoveryDataController} state. This allows\n * consumers to provide a partial state object when initializing the controller\n * and also helps in constructing complete state objects for this controller in\n * tests.\n *\n * @returns The default {@link TokenSearchDiscoveryDataController} state.\n */\nexport function getDefaultTokenSearchDiscoveryDataControllerState(): TokenSearchDiscoveryDataControllerState {\n return {\n tokenDisplayData: [],\n };\n}\n\n/**\n * The TokenSearchDiscoveryDataController manages the retrieval of token search results and token discovery.\n * It fetches token metadata from the Token API and token prices from the token prices service.\n */\nexport class TokenSearchDiscoveryDataController extends BaseController<\n typeof controllerName,\n TokenSearchDiscoveryDataControllerState,\n TokenSearchDiscoveryDataControllerMessenger\n> {\n readonly #abortController: AbortController;\n\n readonly #tokenPricesService: AbstractTokenPricesService;\n\n constructor({\n state = {},\n messenger,\n tokenPricesService,\n }: {\n state?: Partial<TokenSearchDiscoveryDataControllerState>;\n messenger: TokenSearchDiscoveryDataControllerMessenger;\n tokenPricesService: AbstractTokenPricesService;\n }) {\n super({\n name: controllerName,\n metadata: tokenSearchDiscoveryDataControllerMetadata,\n messenger,\n state: {\n ...getDefaultTokenSearchDiscoveryDataControllerState(),\n ...state,\n },\n });\n\n this.#abortController = new AbortController();\n this.#tokenPricesService = tokenPricesService;\n }\n\n async #fetchPriceData(chainId: Hex, address: string) {\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n try {\n const pricesData = await this.#tokenPricesService.fetchTokenPrices({\n assets: [{ chainId, tokenAddress: address as Hex }],\n currency: currentCurrency,\n });\n\n return pricesData[0] ?? null;\n } catch (error) {\n console.error(error);\n return null;\n }\n }\n\n async fetchTokenDisplayData(chainId: Hex, address: string): Promise<void> {\n let tokenMetadata: TokenListToken | undefined;\n try {\n tokenMetadata = await fetchTokenMetadata<TokenListToken>(\n chainId,\n address,\n this.#abortController.signal,\n );\n } catch (error) {\n if (\n !(error instanceof Error) ||\n !error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n throw error;\n }\n }\n\n const { currentCurrency } = this.messenger.call(\n 'CurrencyRateController:getState',\n );\n\n let tokenDisplayData: TokenDisplayData;\n if (!tokenMetadata) {\n tokenDisplayData = {\n found: false,\n address,\n chainId,\n currency: currentCurrency,\n };\n } else {\n const priceData = await this.#fetchPriceData(chainId, address);\n tokenDisplayData = {\n found: true,\n address,\n chainId,\n currency: currentCurrency,\n token: {\n ...tokenMetadata,\n isERC721: false,\n image: formatIconUrlWithProxy({\n chainId,\n tokenAddress: address,\n }),\n },\n price: priceData,\n };\n }\n\n this.update((state) => {\n state.tokenDisplayData = [\n tokenDisplayData,\n ...state.tokenDisplayData.filter(\n (token) =>\n token.address !== address ||\n token.chainId !== chainId ||\n token.currency !== currentCurrency,\n ),\n ].slice(0, MAX_TOKEN_DISPLAY_DATA_LENGTH);\n });\n }\n}\n"]}
@@ -13,7 +13,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
15
15
  };
16
- var _TokensController_instances, _TokensController_mutex, _TokensController_selectedAccountId, _TokensController_provider, _TokensController_abortController, _TokensController_handleOnAccountRemoved, _TokensController_onNetworkStateChange, _TokensController_onSelectedAccountChange, _TokensController_fetchTokenMetadata, _TokensController_detectIsERC721, _TokensController_getProvider, _TokensController_createEthersContract, _TokensController_generateRandomId, _TokensController_getNewAllTokensState, _TokensController_getAddressOrSelectedAddress, _TokensController_requestApproval, _TokensController_getSelectedAccount, _TokensController_getSelectedAddress;
16
+ var _TokensController_instances, _TokensController_mutex, _TokensController_selectedAccountId, _TokensController_provider, _TokensController_abortController, _TokensController_handleOnAccountRemoved, _TokensController_onNetworkAdded, _TokensController_onNetworkStateChange, _TokensController_onSelectedAccountChange, _TokensController_fetchTokenMetadata, _TokensController_detectIsERC721, _TokensController_getProvider, _TokensController_createEthersContract, _TokensController_generateRandomId, _TokensController_getNewAllTokensState, _TokensController_getAddressOrSelectedAddress, _TokensController_requestApproval, _TokensController_seedMusdForAccount, _TokensController_seedMusdForAllAccounts, _TokensController_seedMusdFromExistingState, _TokensController_getSelectedAccount, _TokensController_getSelectedAddress;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TokensController = exports.getDefaultTokensState = void 0;
19
19
  const contracts_1 = require("@ethersproject/contracts");
@@ -55,6 +55,31 @@ const metadata = {
55
55
  },
56
56
  };
57
57
  const controllerName = 'TokensController';
58
+ /**
59
+ * Canonical contract address for MetaMask USD (mUSD) — same across every
60
+ * chain we deploy it to.
61
+ */
62
+ const MUSD_ADDRESS = '0xaca92e438df0b2401ff60da7e4337b687a2435da';
63
+ /**
64
+ * Pre-built Token entry for mUSD — used when seeding default state.
65
+ */
66
+ const MUSD_TOKEN = {
67
+ address: MUSD_ADDRESS,
68
+ decimals: 6,
69
+ symbol: 'mUSD',
70
+ name: 'MetaMask USD',
71
+ };
72
+ /**
73
+ * Hex chain IDs on which mUSD is deployed and should be shown by default.
74
+ * - 0x1 — Ethereum mainnet (1)
75
+ * - 0xe708 — Linea (59144)
76
+ * - 0x8f — Monad mainnet (143)
77
+ */
78
+ const MUSD_SUPPORTED_CHAIN_IDS = new Set([
79
+ '0x1',
80
+ '0xe708',
81
+ '0x8f',
82
+ ]);
58
83
  const getDefaultTokensState = () => {
59
84
  return {
60
85
  allTokens: {},
@@ -108,6 +133,27 @@ class TokensController extends base_controller_1.BaseController {
108
133
  this.messenger.subscribe('AccountsController:selectedEvmAccountChange', __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_onSelectedAccountChange).bind(this));
109
134
  this.messenger.subscribe('NetworkController:stateChange', __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_onNetworkStateChange).bind(this));
110
135
  this.messenger.subscribe('KeyringController:accountRemoved', (accountAddress) => __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_handleOnAccountRemoved).call(this, accountAddress));
136
+ this.messenger.subscribe('NetworkController:networkAdded', (networkConfiguration) => {
137
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_onNetworkAdded).call(this, networkConfiguration.chainId);
138
+ });
139
+ // Seed mUSD for accounts already known to AccountsController (may return
140
+ // empty on first start if AccountsController hasn't loaded yet).
141
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAllAccounts).call(this);
142
+ // Also seed from existing persisted allTokens state so returning users see
143
+ // mUSD immediately without waiting for KeyringController:unlock.
144
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdFromExistingState).call(this);
145
+ // Re-seed mUSD after unlock, because accounts may not be available during
146
+ // construction (e.g. on restart before AccountsController has finished loading).
147
+ this.messenger.subscribe('KeyringController:unlock', () => {
148
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAllAccounts).call(this);
149
+ });
150
+ // Re-seed mUSD whenever a new account is added. This is the most reliable
151
+ // trigger when AccountsController populates accounts asynchronously after
152
+ // TokensController construction — it fires once per account as each one
153
+ // becomes available.
154
+ this.messenger.subscribe('AccountsController:accountAdded', (account) => {
155
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAccount).call(this, account.address);
156
+ });
111
157
  this.messenger.subscribe('TokenListController:stateChange', ({ tokensChainsCache }) => {
112
158
  const { allTokens } = this.state;
113
159
  const selectedAddress = __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_getSelectedAddress).call(this);
@@ -545,11 +591,17 @@ _TokensController_mutex = new WeakMap(), _TokensController_selectedAccountId = n
545
591
  state.allIgnoredTokens = newAllIgnoredTokens;
546
592
  state.allDetectedTokens = newAllDetectedTokens;
547
593
  });
594
+ }, _TokensController_onNetworkAdded = function _TokensController_onNetworkAdded(chainId) {
595
+ if (MUSD_SUPPORTED_CHAIN_IDS.has(chainId)) {
596
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAllAccounts).call(this);
597
+ }
548
598
  }, _TokensController_onNetworkStateChange = function _TokensController_onNetworkStateChange(_, patches) {
549
- // Remove state for deleted networks
550
599
  for (const patch of patches) {
551
- if (patch.op === 'remove' &&
552
- patch.path[0] === 'networkConfigurationsByChainId') {
600
+ if (patch.path[0] !== 'networkConfigurationsByChainId') {
601
+ continue;
602
+ }
603
+ if (patch.op === 'remove') {
604
+ // Remove state for deleted networks
553
605
  const removedChainId = patch.path[1];
554
606
  this.update((state) => {
555
607
  delete state.allTokens[removedChainId];
@@ -557,9 +609,19 @@ _TokensController_mutex = new WeakMap(), _TokensController_selectedAccountId = n
557
609
  delete state.allDetectedTokens[removedChainId];
558
610
  });
559
611
  }
612
+ else if (patch.op === 'add') {
613
+ // When a new chain is added, seed mUSD if it is a supported chain.
614
+ const addedChainId = patch.path[1];
615
+ if (MUSD_SUPPORTED_CHAIN_IDS.has(addedChainId)) {
616
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAllAccounts).call(this);
617
+ }
618
+ }
560
619
  }
561
620
  }, _TokensController_onSelectedAccountChange = function _TokensController_onSelectedAccountChange(selectedAccount) {
562
621
  __classPrivateFieldSet(this, _TokensController_selectedAccountId, selectedAccount.id, "f");
622
+ // Ensure mUSD is seeded for the newly active account (e.g. freshly
623
+ // created account that has never been the selected account before).
624
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAccount).call(this, selectedAccount.address);
563
625
  }, _TokensController_fetchTokenMetadata =
564
626
  /**
565
627
  * Fetch metadata for a token.
@@ -703,6 +765,40 @@ async function _TokensController_detectIsERC721(tokenAddress, networkClientId) {
703
765
  type: controller_utils_1.ApprovalType.WatchAsset,
704
766
  requestData,
705
767
  }, true);
768
+ }, _TokensController_seedMusdForAccount = function _TokensController_seedMusdForAccount(accountAddress) {
769
+ if (!(0, utils_1.isStrictHexString)(accountAddress.toLowerCase()) ||
770
+ !(0, controller_utils_1.isValidHexAddress)(accountAddress)) {
771
+ return;
772
+ }
773
+ this.update((state) => {
774
+ var _a;
775
+ for (const chainId of MUSD_SUPPORTED_CHAIN_IDS) {
776
+ (_a = state.allTokens)[chainId] ?? (_a[chainId] = {});
777
+ const accountTokens = state.allTokens[chainId][accountAddress] ?? [];
778
+ const alreadyPresent = accountTokens.some((token) => token.address.toLowerCase() === MUSD_ADDRESS);
779
+ if (!alreadyPresent) {
780
+ state.allTokens[chainId][accountAddress] = [
781
+ ...accountTokens,
782
+ MUSD_TOKEN,
783
+ ];
784
+ }
785
+ }
786
+ });
787
+ }, _TokensController_seedMusdForAllAccounts = function _TokensController_seedMusdForAllAccounts() {
788
+ const accounts = this.messenger.call('AccountsController:listAccounts');
789
+ for (const account of accounts) {
790
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAccount).call(this, account.address);
791
+ }
792
+ }, _TokensController_seedMusdFromExistingState = function _TokensController_seedMusdFromExistingState() {
793
+ const addresses = new Set();
794
+ for (const chainTokens of Object.values(this.state.allTokens)) {
795
+ for (const address of Object.keys(chainTokens)) {
796
+ addresses.add(address);
797
+ }
798
+ }
799
+ for (const address of addresses) {
800
+ __classPrivateFieldGet(this, _TokensController_instances, "m", _TokensController_seedMusdForAccount).call(this, address);
801
+ }
706
802
  }, _TokensController_getSelectedAccount = function _TokensController_getSelectedAccount() {
707
803
  return this.messenger.call('AccountsController:getSelectedAccount');
708
804
  }, _TokensController_getSelectedAddress = function _TokensController_getSelectedAddress() {