@metamask/assets-controller 0.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 (252) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +20 -0
  3. package/README.md +15 -0
  4. package/dist/AssetsController.cjs +1057 -0
  5. package/dist/AssetsController.cjs.map +1 -0
  6. package/dist/AssetsController.d.cts +260 -0
  7. package/dist/AssetsController.d.cts.map +1 -0
  8. package/dist/AssetsController.d.mts +260 -0
  9. package/dist/AssetsController.d.mts.map +1 -0
  10. package/dist/AssetsController.mjs +1050 -0
  11. package/dist/AssetsController.mjs.map +1 -0
  12. package/dist/data-sources/AbstractDataSource.cjs +103 -0
  13. package/dist/data-sources/AbstractDataSource.cjs.map +1 -0
  14. package/dist/data-sources/AbstractDataSource.d.cts +92 -0
  15. package/dist/data-sources/AbstractDataSource.d.cts.map +1 -0
  16. package/dist/data-sources/AbstractDataSource.d.mts +92 -0
  17. package/dist/data-sources/AbstractDataSource.d.mts.map +1 -0
  18. package/dist/data-sources/AbstractDataSource.mjs +99 -0
  19. package/dist/data-sources/AbstractDataSource.mjs.map +1 -0
  20. package/dist/data-sources/AccountsApiDataSource.cjs +421 -0
  21. package/dist/data-sources/AccountsApiDataSource.cjs.map +1 -0
  22. package/dist/data-sources/AccountsApiDataSource.d.cts +103 -0
  23. package/dist/data-sources/AccountsApiDataSource.d.cts.map +1 -0
  24. package/dist/data-sources/AccountsApiDataSource.d.mts +103 -0
  25. package/dist/data-sources/AccountsApiDataSource.d.mts.map +1 -0
  26. package/dist/data-sources/AccountsApiDataSource.mjs +416 -0
  27. package/dist/data-sources/AccountsApiDataSource.mjs.map +1 -0
  28. package/dist/data-sources/BackendWebsocketDataSource.cjs +388 -0
  29. package/dist/data-sources/BackendWebsocketDataSource.cjs.map +1 -0
  30. package/dist/data-sources/BackendWebsocketDataSource.d.cts +95 -0
  31. package/dist/data-sources/BackendWebsocketDataSource.d.cts.map +1 -0
  32. package/dist/data-sources/BackendWebsocketDataSource.d.mts +95 -0
  33. package/dist/data-sources/BackendWebsocketDataSource.d.mts.map +1 -0
  34. package/dist/data-sources/BackendWebsocketDataSource.mjs +383 -0
  35. package/dist/data-sources/BackendWebsocketDataSource.mjs.map +1 -0
  36. package/dist/data-sources/PriceDataSource.cjs +343 -0
  37. package/dist/data-sources/PriceDataSource.cjs.map +1 -0
  38. package/dist/data-sources/PriceDataSource.d.cts +153 -0
  39. package/dist/data-sources/PriceDataSource.d.cts.map +1 -0
  40. package/dist/data-sources/PriceDataSource.d.mts +153 -0
  41. package/dist/data-sources/PriceDataSource.d.mts.map +1 -0
  42. package/dist/data-sources/PriceDataSource.mjs +339 -0
  43. package/dist/data-sources/PriceDataSource.mjs.map +1 -0
  44. package/dist/data-sources/RpcDataSource.cjs +829 -0
  45. package/dist/data-sources/RpcDataSource.cjs.map +1 -0
  46. package/dist/data-sources/RpcDataSource.d.cts +243 -0
  47. package/dist/data-sources/RpcDataSource.d.cts.map +1 -0
  48. package/dist/data-sources/RpcDataSource.d.mts +243 -0
  49. package/dist/data-sources/RpcDataSource.d.mts.map +1 -0
  50. package/dist/data-sources/RpcDataSource.mjs +820 -0
  51. package/dist/data-sources/RpcDataSource.mjs.map +1 -0
  52. package/dist/data-sources/SnapDataSource.cjs +463 -0
  53. package/dist/data-sources/SnapDataSource.cjs.map +1 -0
  54. package/dist/data-sources/SnapDataSource.d.cts +155 -0
  55. package/dist/data-sources/SnapDataSource.d.cts.map +1 -0
  56. package/dist/data-sources/SnapDataSource.d.mts +155 -0
  57. package/dist/data-sources/SnapDataSource.d.mts.map +1 -0
  58. package/dist/data-sources/SnapDataSource.mjs +456 -0
  59. package/dist/data-sources/SnapDataSource.mjs.map +1 -0
  60. package/dist/data-sources/TokenDataSource.cjs +211 -0
  61. package/dist/data-sources/TokenDataSource.cjs.map +1 -0
  62. package/dist/data-sources/TokenDataSource.d.cts +62 -0
  63. package/dist/data-sources/TokenDataSource.d.cts.map +1 -0
  64. package/dist/data-sources/TokenDataSource.d.mts +62 -0
  65. package/dist/data-sources/TokenDataSource.d.mts.map +1 -0
  66. package/dist/data-sources/TokenDataSource.mjs +207 -0
  67. package/dist/data-sources/TokenDataSource.mjs.map +1 -0
  68. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs +638 -0
  69. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.cjs.map +1 -0
  70. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.cts +47 -0
  71. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.cts.map +1 -0
  72. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.mts +47 -0
  73. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.d.mts.map +1 -0
  74. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs +632 -0
  75. package/dist/data-sources/evm-rpc-services/clients/MulticallClient.mjs.map +1 -0
  76. package/dist/data-sources/evm-rpc-services/clients/index.cjs +8 -0
  77. package/dist/data-sources/evm-rpc-services/clients/index.cjs.map +1 -0
  78. package/dist/data-sources/evm-rpc-services/clients/index.d.cts +3 -0
  79. package/dist/data-sources/evm-rpc-services/clients/index.d.cts.map +1 -0
  80. package/dist/data-sources/evm-rpc-services/clients/index.d.mts +3 -0
  81. package/dist/data-sources/evm-rpc-services/clients/index.d.mts.map +1 -0
  82. package/dist/data-sources/evm-rpc-services/clients/index.mjs +2 -0
  83. package/dist/data-sources/evm-rpc-services/clients/index.mjs.map +1 -0
  84. package/dist/data-sources/evm-rpc-services/index.cjs +12 -0
  85. package/dist/data-sources/evm-rpc-services/index.cjs.map +1 -0
  86. package/dist/data-sources/evm-rpc-services/index.d.cts +5 -0
  87. package/dist/data-sources/evm-rpc-services/index.d.cts.map +1 -0
  88. package/dist/data-sources/evm-rpc-services/index.d.mts +5 -0
  89. package/dist/data-sources/evm-rpc-services/index.d.mts.map +1 -0
  90. package/dist/data-sources/evm-rpc-services/index.mjs +4 -0
  91. package/dist/data-sources/evm-rpc-services/index.mjs.map +1 -0
  92. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs +202 -0
  93. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.cjs.map +1 -0
  94. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts +75 -0
  95. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.cts.map +1 -0
  96. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts +75 -0
  97. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.d.mts.map +1 -0
  98. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs +198 -0
  99. package/dist/data-sources/evm-rpc-services/services/BalanceFetcher.mjs.map +1 -0
  100. package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs +214 -0
  101. package/dist/data-sources/evm-rpc-services/services/TokenDetector.cjs.map +1 -0
  102. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts +71 -0
  103. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.cts.map +1 -0
  104. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts +71 -0
  105. package/dist/data-sources/evm-rpc-services/services/TokenDetector.d.mts.map +1 -0
  106. package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs +210 -0
  107. package/dist/data-sources/evm-rpc-services/services/TokenDetector.mjs.map +1 -0
  108. package/dist/data-sources/evm-rpc-services/services/index.cjs +8 -0
  109. package/dist/data-sources/evm-rpc-services/services/index.cjs.map +1 -0
  110. package/dist/data-sources/evm-rpc-services/services/index.d.cts +3 -0
  111. package/dist/data-sources/evm-rpc-services/services/index.d.cts.map +1 -0
  112. package/dist/data-sources/evm-rpc-services/services/index.d.mts +3 -0
  113. package/dist/data-sources/evm-rpc-services/services/index.d.mts.map +1 -0
  114. package/dist/data-sources/evm-rpc-services/services/index.mjs +3 -0
  115. package/dist/data-sources/evm-rpc-services/services/index.mjs.map +1 -0
  116. package/dist/data-sources/evm-rpc-services/types/assets.cjs +3 -0
  117. package/dist/data-sources/evm-rpc-services/types/assets.cjs.map +1 -0
  118. package/dist/data-sources/evm-rpc-services/types/assets.d.cts +53 -0
  119. package/dist/data-sources/evm-rpc-services/types/assets.d.cts.map +1 -0
  120. package/dist/data-sources/evm-rpc-services/types/assets.d.mts +53 -0
  121. package/dist/data-sources/evm-rpc-services/types/assets.d.mts.map +1 -0
  122. package/dist/data-sources/evm-rpc-services/types/assets.mjs +2 -0
  123. package/dist/data-sources/evm-rpc-services/types/assets.mjs.map +1 -0
  124. package/dist/data-sources/evm-rpc-services/types/config.cjs +3 -0
  125. package/dist/data-sources/evm-rpc-services/types/config.cjs.map +1 -0
  126. package/dist/data-sources/evm-rpc-services/types/config.d.cts +18 -0
  127. package/dist/data-sources/evm-rpc-services/types/config.d.cts.map +1 -0
  128. package/dist/data-sources/evm-rpc-services/types/config.d.mts +18 -0
  129. package/dist/data-sources/evm-rpc-services/types/config.d.mts.map +1 -0
  130. package/dist/data-sources/evm-rpc-services/types/config.mjs +2 -0
  131. package/dist/data-sources/evm-rpc-services/types/config.mjs.map +1 -0
  132. package/dist/data-sources/evm-rpc-services/types/core.cjs +3 -0
  133. package/dist/data-sources/evm-rpc-services/types/core.cjs.map +1 -0
  134. package/dist/data-sources/evm-rpc-services/types/core.d.cts +19 -0
  135. package/dist/data-sources/evm-rpc-services/types/core.d.cts.map +1 -0
  136. package/dist/data-sources/evm-rpc-services/types/core.d.mts +19 -0
  137. package/dist/data-sources/evm-rpc-services/types/core.d.mts.map +1 -0
  138. package/dist/data-sources/evm-rpc-services/types/core.mjs +2 -0
  139. package/dist/data-sources/evm-rpc-services/types/core.mjs.map +1 -0
  140. package/dist/data-sources/evm-rpc-services/types/index.cjs +3 -0
  141. package/dist/data-sources/evm-rpc-services/types/index.cjs.map +1 -0
  142. package/dist/data-sources/evm-rpc-services/types/index.d.cts +7 -0
  143. package/dist/data-sources/evm-rpc-services/types/index.d.cts.map +1 -0
  144. package/dist/data-sources/evm-rpc-services/types/index.d.mts +7 -0
  145. package/dist/data-sources/evm-rpc-services/types/index.d.mts.map +1 -0
  146. package/dist/data-sources/evm-rpc-services/types/index.mjs +2 -0
  147. package/dist/data-sources/evm-rpc-services/types/index.mjs.map +1 -0
  148. package/dist/data-sources/evm-rpc-services/types/multicall.cjs +3 -0
  149. package/dist/data-sources/evm-rpc-services/types/multicall.cjs.map +1 -0
  150. package/dist/data-sources/evm-rpc-services/types/multicall.d.cts +24 -0
  151. package/dist/data-sources/evm-rpc-services/types/multicall.d.cts.map +1 -0
  152. package/dist/data-sources/evm-rpc-services/types/multicall.d.mts +24 -0
  153. package/dist/data-sources/evm-rpc-services/types/multicall.d.mts.map +1 -0
  154. package/dist/data-sources/evm-rpc-services/types/multicall.mjs +2 -0
  155. package/dist/data-sources/evm-rpc-services/types/multicall.mjs.map +1 -0
  156. package/dist/data-sources/evm-rpc-services/types/services.cjs +3 -0
  157. package/dist/data-sources/evm-rpc-services/types/services.cjs.map +1 -0
  158. package/dist/data-sources/evm-rpc-services/types/services.d.cts +74 -0
  159. package/dist/data-sources/evm-rpc-services/types/services.d.cts.map +1 -0
  160. package/dist/data-sources/evm-rpc-services/types/services.d.mts +74 -0
  161. package/dist/data-sources/evm-rpc-services/types/services.d.mts.map +1 -0
  162. package/dist/data-sources/evm-rpc-services/types/services.mjs +2 -0
  163. package/dist/data-sources/evm-rpc-services/types/services.mjs.map +1 -0
  164. package/dist/data-sources/evm-rpc-services/types/state.cjs +3 -0
  165. package/dist/data-sources/evm-rpc-services/types/state.cjs.map +1 -0
  166. package/dist/data-sources/evm-rpc-services/types/state.d.cts +52 -0
  167. package/dist/data-sources/evm-rpc-services/types/state.d.cts.map +1 -0
  168. package/dist/data-sources/evm-rpc-services/types/state.d.mts +52 -0
  169. package/dist/data-sources/evm-rpc-services/types/state.d.mts.map +1 -0
  170. package/dist/data-sources/evm-rpc-services/types/state.mjs +2 -0
  171. package/dist/data-sources/evm-rpc-services/types/state.mjs.map +1 -0
  172. package/dist/data-sources/evm-rpc-services/utils/batch.cjs +45 -0
  173. package/dist/data-sources/evm-rpc-services/utils/batch.cjs.map +1 -0
  174. package/dist/data-sources/evm-rpc-services/utils/batch.d.cts +28 -0
  175. package/dist/data-sources/evm-rpc-services/utils/batch.d.cts.map +1 -0
  176. package/dist/data-sources/evm-rpc-services/utils/batch.d.mts +28 -0
  177. package/dist/data-sources/evm-rpc-services/utils/batch.d.mts.map +1 -0
  178. package/dist/data-sources/evm-rpc-services/utils/batch.mjs +40 -0
  179. package/dist/data-sources/evm-rpc-services/utils/batch.mjs.map +1 -0
  180. package/dist/data-sources/evm-rpc-services/utils/index.cjs +7 -0
  181. package/dist/data-sources/evm-rpc-services/utils/index.cjs.map +1 -0
  182. package/dist/data-sources/evm-rpc-services/utils/index.d.cts +2 -0
  183. package/dist/data-sources/evm-rpc-services/utils/index.d.cts.map +1 -0
  184. package/dist/data-sources/evm-rpc-services/utils/index.d.mts +2 -0
  185. package/dist/data-sources/evm-rpc-services/utils/index.d.mts.map +1 -0
  186. package/dist/data-sources/evm-rpc-services/utils/index.mjs +2 -0
  187. package/dist/data-sources/evm-rpc-services/utils/index.mjs.map +1 -0
  188. package/dist/data-sources/index.cjs +33 -0
  189. package/dist/data-sources/index.cjs.map +1 -0
  190. package/dist/data-sources/index.d.cts +9 -0
  191. package/dist/data-sources/index.d.cts.map +1 -0
  192. package/dist/data-sources/index.d.mts +9 -0
  193. package/dist/data-sources/index.d.mts.map +1 -0
  194. package/dist/data-sources/index.mjs +15 -0
  195. package/dist/data-sources/index.mjs.map +1 -0
  196. package/dist/data-sources/initDataSources.cjs +215 -0
  197. package/dist/data-sources/initDataSources.cjs.map +1 -0
  198. package/dist/data-sources/initDataSources.d.cts +140 -0
  199. package/dist/data-sources/initDataSources.d.cts.map +1 -0
  200. package/dist/data-sources/initDataSources.d.mts +140 -0
  201. package/dist/data-sources/initDataSources.d.mts.map +1 -0
  202. package/dist/data-sources/initDataSources.mjs +210 -0
  203. package/dist/data-sources/initDataSources.mjs.map +1 -0
  204. package/dist/index.cjs +47 -0
  205. package/dist/index.cjs.map +1 -0
  206. package/dist/index.d.cts +21 -0
  207. package/dist/index.d.cts.map +1 -0
  208. package/dist/index.d.mts +21 -0
  209. package/dist/index.d.mts.map +1 -0
  210. package/dist/index.mjs +25 -0
  211. package/dist/index.mjs.map +1 -0
  212. package/dist/logger.cjs +7 -0
  213. package/dist/logger.cjs.map +1 -0
  214. package/dist/logger.d.cts +5 -0
  215. package/dist/logger.d.cts.map +1 -0
  216. package/dist/logger.d.mts +5 -0
  217. package/dist/logger.d.mts.map +1 -0
  218. package/dist/logger.mjs +4 -0
  219. package/dist/logger.mjs.map +1 -0
  220. package/dist/middlewares/DetectionMiddleware.cjs +101 -0
  221. package/dist/middlewares/DetectionMiddleware.cjs.map +1 -0
  222. package/dist/middlewares/DetectionMiddleware.d.cts +54 -0
  223. package/dist/middlewares/DetectionMiddleware.d.cts.map +1 -0
  224. package/dist/middlewares/DetectionMiddleware.d.mts +54 -0
  225. package/dist/middlewares/DetectionMiddleware.d.mts.map +1 -0
  226. package/dist/middlewares/DetectionMiddleware.mjs +97 -0
  227. package/dist/middlewares/DetectionMiddleware.mjs.map +1 -0
  228. package/dist/middlewares/index.cjs +6 -0
  229. package/dist/middlewares/index.cjs.map +1 -0
  230. package/dist/middlewares/index.d.cts +2 -0
  231. package/dist/middlewares/index.d.cts.map +1 -0
  232. package/dist/middlewares/index.d.mts +2 -0
  233. package/dist/middlewares/index.d.mts.map +1 -0
  234. package/dist/middlewares/index.mjs +2 -0
  235. package/dist/middlewares/index.mjs.map +1 -0
  236. package/dist/types.cjs +39 -0
  237. package/dist/types.cjs.map +1 -0
  238. package/dist/types.d.cts +433 -0
  239. package/dist/types.d.cts.map +1 -0
  240. package/dist/types.d.mts +433 -0
  241. package/dist/types.d.mts.map +1 -0
  242. package/dist/types.mjs +35 -0
  243. package/dist/types.mjs.map +1 -0
  244. package/dist/utils.cjs +28 -0
  245. package/dist/utils.cjs.map +1 -0
  246. package/dist/utils.d.cts +13 -0
  247. package/dist/utils.d.cts.map +1 -0
  248. package/dist/utils.d.mts +13 -0
  249. package/dist/utils.d.mts.map +1 -0
  250. package/dist/utils.mjs +24 -0
  251. package/dist/utils.mjs.map +1 -0
  252. package/package.json +93 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AbstractDataSource.mjs","sourceRoot":"","sources":["../../src/data-sources/AbstractDataSource.ts"],"names":[],"mappings":"AAsCA,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,OAAgB,kBAAkB;IAYtC,YAAY,IAAU,EAAE,YAAmB;QAJ3C,iCAAiC;QACd,wBAAmB,GACpC,IAAI,GAAG,EAAE,CAAC;QAGV,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;IAC5B,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,eAAe;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;IACjC,CAAC;IAOD;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,cAAsB;QACtC,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAClE,IAAI,YAAY,EAAE,CAAC;YACjB,YAAY,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACO,kBAAkB,CAC1B,MAAiB,EACjB,YAAyC;QAEzC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAElC,wCAAwC;QACxC,MAAM,UAAU,GACd,cAAc,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;YACtC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAErD,sBAAsB;QACtB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC;QAEjC,iDAAiD;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,YAAY,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACO,cAAc,CACtB,OAAgB,EAChB,YAAyC;QAEzC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAChE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACO,iBAAiB,CACzB,OAAgB,EAChB,YAAyC;QAEzC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CACtD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,OAAO,CAC7B,CAAC;YACF,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,OAAO;QACL,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7D,YAAY,CAAC,OAAO,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IACnC,CAAC;CACF","sourcesContent":["import type { ChainId, DataRequest } from '../types';\n\n// ============================================================================\n// DATA SOURCE BASE TYPES\n// ============================================================================\n\n/**\n * Subscription request from AssetsController.\n */\nexport type SubscriptionRequest = {\n request: DataRequest;\n subscriptionId: string;\n isUpdate: boolean;\n};\n\n/**\n * Active subscription entry stored by data sources.\n * Data sources can extend this with additional fields as needed.\n */\nexport type ActiveSubscription = {\n /** Cleanup function to unsubscribe */\n cleanup: () => void;\n /** Currently subscribed chains */\n chains: ChainId[];\n /** Original request (for polling data sources to handle account changes) */\n request?: DataRequest;\n /** Account addresses (for WebSocket data sources to detect account changes) */\n addresses?: string[];\n};\n\n/**\n * Base state for all data sources.\n */\nexport type DataSourceState = {\n /** Currently active chains (supported AND available) */\n activeChains: ChainId[];\n};\n\n// ============================================================================\n// ABSTRACT DATA SOURCE\n// ============================================================================\n\n/**\n * Abstract base class for data sources.\n *\n * Data sources communicate with AssetsController via Messenger:\n * - Register actions that AssetsController can call\n * - Publish events that AssetsController subscribes to\n */\nexport abstract class AbstractDataSource<\n Name extends string,\n State extends DataSourceState = DataSourceState,\n> {\n protected readonly name: Name;\n\n protected state: State;\n\n /** Active subscriptions by ID */\n protected readonly activeSubscriptions: Map<string, ActiveSubscription> =\n new Map();\n\n constructor(name: Name, initialState: State) {\n this.name = name;\n this.state = initialState;\n }\n\n /**\n * Get the data source name/ID.\n *\n * @returns The name of this data source.\n */\n getName(): Name {\n return this.name;\n }\n\n /**\n * Get currently active chains (supported AND available).\n *\n * @returns Array of currently active chain IDs.\n */\n async getActiveChains(): Promise<ChainId[]> {\n return this.state.activeChains;\n }\n\n /**\n * Subscribe to updates for the given request.\n */\n abstract subscribe(request: SubscriptionRequest): Promise<void>;\n\n /**\n * Unsubscribe from updates.\n *\n * @param subscriptionId - The ID of the subscription to cancel.\n */\n async unsubscribe(subscriptionId: string): Promise<void> {\n const subscription = this.activeSubscriptions.get(subscriptionId);\n if (subscription) {\n subscription.cleanup();\n this.activeSubscriptions.delete(subscriptionId);\n }\n }\n\n /**\n * Update active chains and notify listeners only if changed.\n *\n * @param chains - Array of chain IDs to set as active.\n * @param publishEvent - Callback to publish chain changes to listeners.\n */\n protected updateActiveChains(\n chains: ChainId[],\n publishEvent: (chains: ChainId[]) => void,\n ): void {\n const previousChains = new Set(this.state.activeChains);\n const newChains = new Set(chains);\n\n // Check if chains have actually changed\n const hasChanges =\n previousChains.size !== newChains.size ||\n chains.some((chain) => !previousChains.has(chain));\n\n // Always update state\n this.state.activeChains = chains;\n\n // Only publish event if there are actual changes\n if (hasChanges) {\n publishEvent(chains);\n }\n }\n\n /**\n * Add a chain to active chains.\n *\n * @param chainId - The chain ID to add.\n * @param publishEvent - Callback to publish chain changes to listeners.\n */\n protected addActiveChain(\n chainId: ChainId,\n publishEvent: (chains: ChainId[]) => void,\n ): void {\n if (!this.state.activeChains.includes(chainId)) {\n this.state.activeChains = [...this.state.activeChains, chainId];\n publishEvent(this.state.activeChains);\n }\n }\n\n /**\n * Remove a chain from active chains.\n *\n * @param chainId - The chain ID to remove.\n * @param publishEvent - Callback to publish chain changes to listeners.\n */\n protected removeActiveChain(\n chainId: ChainId,\n publishEvent: (chains: ChainId[]) => void,\n ): void {\n if (this.state.activeChains.includes(chainId)) {\n this.state.activeChains = this.state.activeChains.filter(\n (chain) => chain !== chainId,\n );\n publishEvent(this.state.activeChains);\n }\n }\n\n /**\n * Destroy the data source and clean up resources.\n */\n destroy(): void {\n for (const subscription of this.activeSubscriptions.values()) {\n subscription.cleanup();\n }\n this.activeSubscriptions.clear();\n }\n}\n"]}
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _AccountsApiDataSource_instances, _AccountsApiDataSource_messenger, _AccountsApiDataSource_pollInterval, _AccountsApiDataSource_apiClient, _AccountsApiDataSource_chainsRefreshTimer, _AccountsApiDataSource_registerActionHandlers, _AccountsApiDataSource_initializeActiveChains, _AccountsApiDataSource_refreshActiveChains, _AccountsApiDataSource_fetchActiveChains, _AccountsApiDataSource_accountSupportsChain, _AccountsApiDataSource_processV5Balances;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createAccountsApiDataSource = exports.AccountsApiDataSource = void 0;
16
+ const core_backend_1 = require("@metamask/core-backend");
17
+ const AbstractDataSource_1 = require("./AbstractDataSource.cjs");
18
+ const logger_1 = require("../logger.cjs");
19
+ const utils_1 = require("../utils.cjs");
20
+ // ============================================================================
21
+ // CONSTANTS
22
+ // ============================================================================
23
+ const CONTROLLER_NAME = 'AccountsApiDataSource';
24
+ const DEFAULT_POLL_INTERVAL = 30000;
25
+ const log = (0, logger_1.createModuleLogger)(logger_1.projectLogger, CONTROLLER_NAME);
26
+ const defaultState = {
27
+ activeChains: [],
28
+ };
29
+ // ============================================================================
30
+ // HELPER FUNCTIONS
31
+ // ============================================================================
32
+ function decimalToChainId(decimalChainId) {
33
+ // Handle both decimal numbers and already-formatted CAIP chain IDs
34
+ if (typeof decimalChainId === 'string') {
35
+ // If already a CAIP chain ID (e.g., "eip155:1"), return as-is
36
+ if (decimalChainId.startsWith('eip155:')) {
37
+ return decimalChainId;
38
+ }
39
+ // If it's a string number, convert
40
+ return `eip155:${decimalChainId}`;
41
+ }
42
+ return `eip155:${decimalChainId}`;
43
+ }
44
+ /**
45
+ * Convert a CAIP-2 chain ID from the API response to our ChainId type.
46
+ * Handles both formats: "eip155:1" or just "1" (decimal).
47
+ *
48
+ * @param chainIdStr - The chain ID string to convert.
49
+ * @returns The normalized ChainId.
50
+ */
51
+ function caipChainIdToChainId(chainIdStr) {
52
+ // If already in CAIP-2 format, return as-is
53
+ if (chainIdStr.includes(':')) {
54
+ return chainIdStr;
55
+ }
56
+ // If decimal number, convert to CAIP-2
57
+ return `eip155:${chainIdStr}`;
58
+ }
59
+ // ============================================================================
60
+ // ACCOUNTS API DATA SOURCE
61
+ // ============================================================================
62
+ /**
63
+ * Data source for fetching balances from the MetaMask Accounts API.
64
+ *
65
+ * Uses Messenger pattern for all interactions:
66
+ * - Calls BackendApiClient methods via messenger actions
67
+ * - Exposes its own actions for AssetsController to call
68
+ * - Publishes events for AssetsController to subscribe to
69
+ *
70
+ * Actions exposed:
71
+ * - AccountsApiDataSource:getActiveChains
72
+ * - AccountsApiDataSource:fetch
73
+ * - AccountsApiDataSource:subscribe
74
+ * - AccountsApiDataSource:unsubscribe
75
+ *
76
+ * Events published:
77
+ * - AccountsApiDataSource:activeChainsUpdated
78
+ * - AccountsApiDataSource:assetsUpdated
79
+ *
80
+ * Actions called (from BackendApiClient):
81
+ * - BackendApiClient:Accounts:getV2SupportedNetworks
82
+ * - BackendApiClient:Accounts:getV5MultiAccountBalances
83
+ */
84
+ class AccountsApiDataSource extends AbstractDataSource_1.AbstractDataSource {
85
+ constructor(options) {
86
+ super(CONTROLLER_NAME, {
87
+ ...defaultState,
88
+ ...options.state,
89
+ });
90
+ _AccountsApiDataSource_instances.add(this);
91
+ _AccountsApiDataSource_messenger.set(this, void 0);
92
+ _AccountsApiDataSource_pollInterval.set(this, void 0);
93
+ /** ApiPlatformClient for cached API calls */
94
+ _AccountsApiDataSource_apiClient.set(this, void 0);
95
+ /** Chains refresh timer */
96
+ _AccountsApiDataSource_chainsRefreshTimer.set(this, null);
97
+ __classPrivateFieldSet(this, _AccountsApiDataSource_messenger, options.messenger, "f");
98
+ __classPrivateFieldSet(this, _AccountsApiDataSource_pollInterval, options.pollInterval ?? DEFAULT_POLL_INTERVAL, "f");
99
+ __classPrivateFieldSet(this, _AccountsApiDataSource_apiClient, options.queryApiClient, "f");
100
+ __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_registerActionHandlers).call(this);
101
+ __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_initializeActiveChains).call(this).catch(console.error);
102
+ }
103
+ // ============================================================================
104
+ // FETCH
105
+ // ============================================================================
106
+ async fetch(request) {
107
+ const response = {};
108
+ // Filter to only chains supported by Accounts API
109
+ const supportedChains = new Set(this.state.activeChains);
110
+ const chainsToFetch = request.chainIds.filter((chainId) => supportedChains.has(chainId));
111
+ if (chainsToFetch.length === 0) {
112
+ // Mark unsupported chains as errors so they pass to next middleware
113
+ for (const chainId of request.chainIds) {
114
+ if (!supportedChains.has(chainId)) {
115
+ response.errors = response.errors ?? {};
116
+ response.errors[chainId] = 'Chain not supported by Accounts API';
117
+ }
118
+ }
119
+ return response;
120
+ }
121
+ try {
122
+ // Build CAIP-10 account IDs (e.g., "eip155:1:0x1234...")
123
+ // Only include account-chain combinations where the account's scopes
124
+ // overlap with the chains being fetched
125
+ const accountIds = request.accounts.flatMap((account) => chainsToFetch
126
+ .filter((chainId) => __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_accountSupportsChain).call(this, account, chainId))
127
+ .map((chainId) => `${chainId}:${account.address}`));
128
+ // Skip API call if no valid account-chain combinations
129
+ if (accountIds.length === 0) {
130
+ return response;
131
+ }
132
+ const apiResponse = await __classPrivateFieldGet(this, _AccountsApiDataSource_apiClient, "f").accounts.fetchV5MultiAccountBalances(accountIds);
133
+ // Handle unprocessed networks - these will be passed to next middleware
134
+ if (apiResponse.unprocessedNetworks.length > 0) {
135
+ const unprocessedChainIds = apiResponse.unprocessedNetworks.map(caipChainIdToChainId);
136
+ // Add unprocessed chains to errors so middleware passes them to next data source
137
+ response.errors = response.errors ?? {};
138
+ for (const chainId of unprocessedChainIds) {
139
+ response.errors[chainId] = 'Unprocessed by Accounts API';
140
+ }
141
+ }
142
+ const { assetsBalance } = __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_processV5Balances).call(this, apiResponse.balances, request);
143
+ response.assetsBalance = assetsBalance;
144
+ }
145
+ catch (error) {
146
+ log('Fetch FAILED', { error, chains: chainsToFetch });
147
+ // On error, mark all chains as errors so they can be handled by next middleware
148
+ response.errors = response.errors ?? {};
149
+ for (const chainId of chainsToFetch) {
150
+ response.errors[chainId] =
151
+ `Fetch failed: ${error instanceof Error ? error.message : String(error)}`;
152
+ }
153
+ }
154
+ // Mark unsupported chains as errors so they pass to next middleware
155
+ for (const chainId of request.chainIds) {
156
+ if (!supportedChains.has(chainId)) {
157
+ response.errors = response.errors ?? {};
158
+ response.errors[chainId] = 'Chain not supported by Accounts API';
159
+ }
160
+ }
161
+ return response;
162
+ }
163
+ // ============================================================================
164
+ // MIDDLEWARE
165
+ // ============================================================================
166
+ /**
167
+ * Get the middleware for fetching balances via Accounts API.
168
+ * This middleware:
169
+ * - Supports multiple accounts in a single request
170
+ * - Uses unprocessedNetworks from API response to determine what to pass to next middleware
171
+ * - Merges response into context
172
+ * - Removes handled chains from request for next middleware
173
+ *
174
+ * @returns The middleware function for the assets pipeline.
175
+ */
176
+ get assetsMiddleware() {
177
+ return async (context, next) => {
178
+ var _a;
179
+ const { request } = context;
180
+ // If no chains requested, skip to next middleware
181
+ if (request.chainIds.length === 0) {
182
+ return next(context);
183
+ }
184
+ let successfullyHandledChains = [];
185
+ try {
186
+ const response = await this.fetch(request);
187
+ // Merge response into context
188
+ if (response.assetsBalance) {
189
+ (_a = context.response).assetsBalance ?? (_a.assetsBalance = {});
190
+ for (const [accountId, accountBalances] of Object.entries(response.assetsBalance)) {
191
+ context.response.assetsBalance[accountId] = {
192
+ ...context.response.assetsBalance[accountId],
193
+ ...accountBalances,
194
+ };
195
+ }
196
+ }
197
+ // Determine successfully handled chains (exclude unprocessed/error chains)
198
+ const unprocessedChains = new Set(Object.keys(response.errors ?? {}));
199
+ successfullyHandledChains = request.chainIds.filter((chainId) => !unprocessedChains.has(chainId));
200
+ }
201
+ catch (error) {
202
+ log('Middleware fetch failed', { error });
203
+ successfullyHandledChains = [];
204
+ }
205
+ // Remove successfully handled chains from request for next middleware
206
+ if (successfullyHandledChains.length > 0) {
207
+ const remainingChains = request.chainIds.filter((chainId) => !successfullyHandledChains.includes(chainId));
208
+ return next({
209
+ ...context,
210
+ request: {
211
+ ...request,
212
+ chainIds: remainingChains,
213
+ },
214
+ });
215
+ }
216
+ // No chains handled - pass context unchanged
217
+ return next(context);
218
+ };
219
+ }
220
+ // ============================================================================
221
+ // SUBSCRIBE
222
+ // ============================================================================
223
+ async subscribe(subscriptionRequest) {
224
+ const { request, subscriptionId, isUpdate } = subscriptionRequest;
225
+ // Try all requested chains - API will handle unsupported ones via unprocessedNetworks
226
+ const chainsToSubscribe = request.chainIds;
227
+ if (chainsToSubscribe.length === 0) {
228
+ return;
229
+ }
230
+ // Handle subscription update - update both chains AND request (for accounts)
231
+ if (isUpdate) {
232
+ const existing = this.activeSubscriptions.get(subscriptionId);
233
+ if (existing) {
234
+ existing.chains = chainsToSubscribe;
235
+ existing.request = request;
236
+ return;
237
+ }
238
+ }
239
+ // Clean up existing subscription if any
240
+ await this.unsubscribe(subscriptionId);
241
+ const pollInterval = request.updateInterval ?? __classPrivateFieldGet(this, _AccountsApiDataSource_pollInterval, "f");
242
+ // Create poll function for this subscription
243
+ const pollFn = async () => {
244
+ try {
245
+ const subscription = this.activeSubscriptions.get(subscriptionId);
246
+ if (!subscription?.request) {
247
+ return;
248
+ }
249
+ // Use stored request (which gets updated on account changes)
250
+ const fetchResponse = await this.fetch({
251
+ ...subscription.request,
252
+ chainIds: subscription.chains,
253
+ });
254
+ // Report update to AssetsController
255
+ await __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").call('AssetsController:assetsUpdate', fetchResponse, CONTROLLER_NAME);
256
+ }
257
+ catch (error) {
258
+ log('Subscription poll failed', { subscriptionId, error });
259
+ }
260
+ };
261
+ // Set up polling
262
+ const timer = setInterval(() => {
263
+ pollFn().catch(console.error);
264
+ }, pollInterval);
265
+ // Store subscription with request for account updates
266
+ this.activeSubscriptions.set(subscriptionId, {
267
+ cleanup: () => {
268
+ clearInterval(timer);
269
+ },
270
+ chains: chainsToSubscribe,
271
+ request,
272
+ });
273
+ // Initial fetch
274
+ await pollFn();
275
+ }
276
+ // ============================================================================
277
+ // CLEANUP
278
+ // ============================================================================
279
+ destroy() {
280
+ // Clean up timers
281
+ if (__classPrivateFieldGet(this, _AccountsApiDataSource_chainsRefreshTimer, "f")) {
282
+ clearInterval(__classPrivateFieldGet(this, _AccountsApiDataSource_chainsRefreshTimer, "f"));
283
+ }
284
+ // Clean up subscriptions
285
+ super.destroy();
286
+ }
287
+ }
288
+ exports.AccountsApiDataSource = AccountsApiDataSource;
289
+ _AccountsApiDataSource_messenger = new WeakMap(), _AccountsApiDataSource_pollInterval = new WeakMap(), _AccountsApiDataSource_apiClient = new WeakMap(), _AccountsApiDataSource_chainsRefreshTimer = new WeakMap(), _AccountsApiDataSource_instances = new WeakSet(), _AccountsApiDataSource_registerActionHandlers = function _AccountsApiDataSource_registerActionHandlers() {
290
+ // Define strongly-typed handlers
291
+ const getAssetsMiddlewareHandler = () => this.assetsMiddleware;
292
+ const getActiveChainsHandler = async () => this.getActiveChains();
293
+ const fetchHandler = async (request) => this.fetch(request);
294
+ const subscribeHandler = async (request) => this.subscribe(request);
295
+ const unsubscribeHandler = async (subscriptionId) => this.unsubscribe(subscriptionId);
296
+ // Register handlers
297
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").registerActionHandler('AccountsApiDataSource:getAssetsMiddleware', getAssetsMiddlewareHandler);
298
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").registerActionHandler('AccountsApiDataSource:getActiveChains', getActiveChainsHandler);
299
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").registerActionHandler('AccountsApiDataSource:fetch', fetchHandler);
300
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").registerActionHandler('AccountsApiDataSource:subscribe', subscribeHandler);
301
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").registerActionHandler('AccountsApiDataSource:unsubscribe', unsubscribeHandler);
302
+ }, _AccountsApiDataSource_initializeActiveChains = async function _AccountsApiDataSource_initializeActiveChains() {
303
+ try {
304
+ const chains = await __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_fetchActiveChains).call(this);
305
+ this.updateActiveChains(chains, (updatedChains) => {
306
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").call('AssetsController:activeChainsUpdate', CONTROLLER_NAME, updatedChains);
307
+ // Also publish event for BackendWebsocketDataSource to sync
308
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").publish('AccountsApiDataSource:activeChainsUpdated', updatedChains);
309
+ });
310
+ // Periodically refresh active chains (every 20 minutes)
311
+ __classPrivateFieldSet(this, _AccountsApiDataSource_chainsRefreshTimer, setInterval(() => {
312
+ __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_refreshActiveChains).call(this).catch(console.error);
313
+ }, 20 * 60 * 1000), "f");
314
+ }
315
+ catch (error) {
316
+ log('Failed to fetch active chains', error);
317
+ }
318
+ }, _AccountsApiDataSource_refreshActiveChains = async function _AccountsApiDataSource_refreshActiveChains() {
319
+ try {
320
+ const chains = await __classPrivateFieldGet(this, _AccountsApiDataSource_instances, "m", _AccountsApiDataSource_fetchActiveChains).call(this);
321
+ const previousChains = new Set(this.state.activeChains);
322
+ const newChains = new Set(chains);
323
+ // Check if chains changed
324
+ const added = chains.filter((chain) => !previousChains.has(chain));
325
+ const removed = Array.from(previousChains).filter((chain) => !newChains.has(chain));
326
+ if (added.length > 0 || removed.length > 0) {
327
+ this.updateActiveChains(chains, (updatedChains) => {
328
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").call('AssetsController:activeChainsUpdate', CONTROLLER_NAME, updatedChains);
329
+ // Also publish event for BackendWebsocketDataSource to sync
330
+ __classPrivateFieldGet(this, _AccountsApiDataSource_messenger, "f").publish('AccountsApiDataSource:activeChainsUpdated', updatedChains);
331
+ });
332
+ }
333
+ }
334
+ catch (error) {
335
+ log('Failed to refresh active chains', error);
336
+ }
337
+ }, _AccountsApiDataSource_fetchActiveChains = async function _AccountsApiDataSource_fetchActiveChains() {
338
+ const response = await __classPrivateFieldGet(this, _AccountsApiDataSource_apiClient, "f").accounts.fetchV2SupportedNetworks();
339
+ // Use fullSupport networks as active chains
340
+ return response.fullSupport.map(decimalToChainId);
341
+ }, _AccountsApiDataSource_accountSupportsChain = function _AccountsApiDataSource_accountSupportsChain(account, chainId) {
342
+ const scopes = account.scopes ?? [];
343
+ // If no scopes defined, assume it supports the chain (backward compatibility)
344
+ if (scopes.length === 0) {
345
+ return true;
346
+ }
347
+ // Extract namespace and reference from chainId (e.g., "eip155:1" -> ["eip155", "1"])
348
+ const [chainNamespace, chainReference] = chainId.split(':');
349
+ for (const scope of scopes) {
350
+ const [scopeNamespace, scopeReference] = scope.split(':');
351
+ // Check if namespaces match
352
+ if (scopeNamespace !== chainNamespace) {
353
+ continue;
354
+ }
355
+ // Wildcard scope (e.g., "eip155:0" means all chains in that namespace)
356
+ if (scopeReference === '0') {
357
+ return true;
358
+ }
359
+ // Exact match check - normalize hex to decimal for EIP155
360
+ if (chainNamespace === 'eip155') {
361
+ const normalizedScopeRef = scopeReference?.startsWith('0x')
362
+ ? parseInt(scopeReference, 16).toString()
363
+ : scopeReference;
364
+ if (normalizedScopeRef === chainReference) {
365
+ return true;
366
+ }
367
+ }
368
+ else if (scopeReference === chainReference) {
369
+ return true;
370
+ }
371
+ }
372
+ return false;
373
+ }, _AccountsApiDataSource_processV5Balances = function _AccountsApiDataSource_processV5Balances(balances, request) {
374
+ const assetsBalance = {};
375
+ // Build a map of lowercase addresses to account IDs for efficient lookup
376
+ const addressToAccountId = new Map();
377
+ for (const account of request.accounts) {
378
+ if (account.address) {
379
+ addressToAccountId.set(account.address.toLowerCase(), account.id);
380
+ }
381
+ }
382
+ // V5 response: array of { accountId, assetId, balance, ... }
383
+ for (const item of balances) {
384
+ // Extract address from CAIP-10 account ID (e.g., "eip155:1:0x1234..." -> "0x1234...")
385
+ const addressParts = item.accountId.split(':');
386
+ if (addressParts.length < 3) {
387
+ continue;
388
+ }
389
+ const address = addressParts[2].toLowerCase();
390
+ // Find the matching account ID from request
391
+ const accountId = addressToAccountId.get(address);
392
+ if (!accountId) {
393
+ // This is normal - API returns balances for all chains, but request may only have one account
394
+ continue;
395
+ }
396
+ if (!assetsBalance[accountId]) {
397
+ assetsBalance[accountId] = {};
398
+ }
399
+ // Normalize asset ID (checksum EVM addresses for ERC20 tokens)
400
+ const normalizedAssetId = (0, utils_1.normalizeAssetId)(item.assetId);
401
+ // Store balance as returned by API
402
+ assetsBalance[accountId][normalizedAssetId] = {
403
+ amount: item.balance,
404
+ };
405
+ }
406
+ return { assetsBalance };
407
+ };
408
+ // ============================================================================
409
+ // FACTORY FUNCTION
410
+ // ============================================================================
411
+ /**
412
+ * Creates an AccountsApiDataSource instance.
413
+ *
414
+ * @param options - Configuration options for the data source.
415
+ * @returns A new AccountsApiDataSource instance.
416
+ */
417
+ function createAccountsApiDataSource(options) {
418
+ return new AccountsApiDataSource(options);
419
+ }
420
+ exports.createAccountsApiDataSource = createAccountsApiDataSource;
421
+ //# sourceMappingURL=AccountsApiDataSource.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountsApiDataSource.cjs","sourceRoot":"","sources":["../../src/data-sources/AccountsApiDataSource.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AACA,yDAA2D;AAQ3D,iEAA0D;AAC1D,0CAA8D;AAS9D,wCAA4C;AAE5C,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAChD,MAAM,qBAAqB,GAAG,KAAM,CAAC;AAErC,MAAM,GAAG,GAAG,IAAA,2BAAkB,EAAC,sBAAa,EAAE,eAAe,CAAC,CAAC;AAmF/D,MAAM,YAAY,GAA+B;IAC/C,YAAY,EAAE,EAAE;CACjB,CAAC;AAcF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,SAAS,gBAAgB,CAAC,cAA+B;IACvD,mEAAmE;IACnE,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QACvC,8DAA8D;QAC9D,IAAI,cAAc,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,OAAO,cAAyB,CAAC;QACnC,CAAC;QACD,mCAAmC;QACnC,OAAO,UAAU,cAAc,EAAa,CAAC;IAC/C,CAAC;IACD,OAAO,UAAU,cAAc,EAAa,CAAC;AAC/C,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,4CAA4C;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,UAAqB,CAAC;IAC/B,CAAC;IACD,uCAAuC;IACvC,OAAO,UAAU,UAAU,EAAa,CAAC;AAC3C,CAAC;AAED,+EAA+E;AAC/E,2BAA2B;AAC3B,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAa,qBAAsB,SAAQ,uCAG1C;IAWC,YAAY,OAAqC;QAC/C,KAAK,CAAC,eAAe,EAAE;YACrB,GAAG,YAAY;YACf,GAAG,OAAO,CAAC,KAAK;SACjB,CAAC,CAAC;;QAdI,mDAA2C;QAE3C,sDAAsB;QAE/B,6CAA6C;QACpC,mDAA8B;QAEvC,2BAA2B;QAC3B,oDAA6D,IAAI,EAAC;QAQhE,uBAAA,IAAI,oCAAc,OAAO,CAAC,SAAS,MAAA,CAAC;QACpC,uBAAA,IAAI,uCAAiB,OAAO,CAAC,YAAY,IAAI,qBAAqB,MAAA,CAAC;QACnE,uBAAA,IAAI,oCAAc,OAAO,CAAC,cAAc,MAAA,CAAC;QAEzC,uBAAA,IAAI,uFAAwB,MAA5B,IAAI,CAA0B,CAAC;QAC/B,uBAAA,IAAI,uFAAwB,MAA5B,IAAI,CAA0B,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IAyKD,+EAA+E;IAC/E,QAAQ;IACR,+EAA+E;IAE/E,KAAK,CAAC,KAAK,CAAC,OAAoB;QAC9B,MAAM,QAAQ,GAAiB,EAAE,CAAC;QAElC,kDAAkD;QAClD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACzD,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACxD,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAC7B,CAAC;QAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,oEAAoE;YACpE,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACvC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClC,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;oBACxC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,qCAAqC,CAAC;gBACnE,CAAC;YACH,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,yDAAyD;YACzD,qEAAqE;YACrE,wCAAwC;YACxC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CACtD,aAAa;iBACV,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,uBAAA,IAAI,qFAAsB,MAA1B,IAAI,EAAuB,OAAO,EAAE,OAAO,CAAC,CAAC;iBACjE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CACrD,CAAC;YAEF,uDAAuD;YACvD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,MAAM,WAAW,GACf,MAAM,uBAAA,IAAI,wCAAW,CAAC,QAAQ,CAAC,2BAA2B,CAAC,UAAU,CAAC,CAAC;YAEzE,wEAAwE;YACxE,IAAI,WAAW,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,mBAAmB,GACvB,WAAW,CAAC,mBAAmB,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;gBAE5D,iFAAiF;gBACjF,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;gBACxC,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;oBAC1C,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,6BAA6B,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,MAAM,EAAE,aAAa,EAAE,GAAG,uBAAA,IAAI,kFAAmB,MAAvB,IAAI,EAC5B,WAAW,CAAC,QAAQ,EACpB,OAAO,CACR,CAAC;YAEF,QAAQ,CAAC,aAAa,GAAG,aAAa,CAAC;QACzC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;YAEtD,gFAAgF;YAChF,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;YACxC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;gBACpC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC;oBACtB,iBAAiB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9E,CAAC;QACH,CAAC;QAED,oEAAoE;QACpE,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClC,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;gBACxC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,qCAAqC,CAAC;YACnE,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IA6DD,+EAA+E;IAC/E,aAAa;IACb,+EAA+E;IAE/E;;;;;;;;;OASG;IACH,IAAI,gBAAgB;QAClB,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;;YAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;YAE5B,kDAAkD;YAClD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,yBAAyB,GAAc,EAAE,CAAC;YAE9C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBAE3C,8BAA8B;gBAC9B,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;oBAC3B,MAAA,OAAO,CAAC,QAAQ,EAAC,aAAa,QAAb,aAAa,GAAK,EAAE,EAAC;oBACtC,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CACvD,QAAQ,CAAC,aAAa,CACvB,EAAE,CAAC;wBACF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG;4BAC1C,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;4BAC5C,GAAG,eAAe;yBACnB,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,2EAA2E;gBAC3E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;gBACtE,yBAAyB,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CACjD,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAC7C,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC1C,yBAAyB,GAAG,EAAE,CAAC;YACjC,CAAC;YAED,sEAAsE;YACtE,IAAI,yBAAyB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAC7C,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,yBAAyB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC1D,CAAC;gBAEF,OAAO,IAAI,CAAC;oBACV,GAAG,OAAO;oBACV,OAAO,EAAE;wBACP,GAAG,OAAO;wBACV,QAAQ,EAAE,eAAe;qBAC1B;iBACF,CAAC,CAAC;YACL,CAAC;YAED,6CAA6C;YAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,YAAY;IACZ,+EAA+E;IAE/E,KAAK,CAAC,SAAS,CAAC,mBAAwC;QACtD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC;QAElE,sFAAsF;QACtF,MAAM,iBAAiB,GAAG,OAAO,CAAC,QAAQ,CAAC;QAE3C,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC9D,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,MAAM,GAAG,iBAAiB,CAAC;gBACpC,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;gBAC3B,OAAO;YACT,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAEvC,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,IAAI,uBAAA,IAAI,2CAAc,CAAC;QAElE,6CAA6C;QAC7C,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;YACvC,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAClE,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;oBAC3B,OAAO;gBACT,CAAC;gBAED,6DAA6D;gBAC7D,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;oBACrC,GAAG,YAAY,CAAC,OAAO;oBACvB,QAAQ,EAAE,YAAY,CAAC,MAAM;iBAC9B,CAAC,CAAC;gBAEH,oCAAoC;gBACpC,MAAM,uBAAA,IAAI,wCAAW,CAAC,IAAI,CACxB,+BAA+B,EAC/B,aAAa,EACb,eAAe,CAChB,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,0BAA0B,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC,CAAC;QAEF,iBAAiB;QACjB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC,EAAE,YAAY,CAAC,CAAC;QAEjB,sDAAsD;QACtD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,EAAE;YAC3C,OAAO,EAAE,GAAG,EAAE;gBACZ,aAAa,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,EAAE,iBAAiB;YACzB,OAAO;SACR,CAAC,CAAC;QAEH,gBAAgB;QAChB,MAAM,MAAM,EAAE,CAAC;IACjB,CAAC;IAED,+EAA+E;IAC/E,UAAU;IACV,+EAA+E;IAE/E,OAAO;QACL,kBAAkB;QAClB,IAAI,uBAAA,IAAI,iDAAoB,EAAE,CAAC;YAC7B,aAAa,CAAC,uBAAA,IAAI,iDAAoB,CAAC,CAAC;QAC1C,CAAC;QAED,yBAAyB;QACzB,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF;AA5eD,sDA4eC;;IA3cG,iCAAiC;IACjC,MAAM,0BAA0B,GAC9B,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC;IAE9B,MAAM,sBAAsB,GAC1B,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;IAErC,MAAM,YAAY,GAAgD,KAAK,EACrE,OAAO,EACP,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAEzB,MAAM,gBAAgB,GACpB,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,kBAAkB,GACtB,KAAK,EAAE,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;IAE7D,oBAAoB;IACpB,uBAAA,IAAI,wCAAW,CAAC,qBAAqB,CACnC,2CAA2C,EAC3C,0BAA0B,CAC3B,CAAC;IAEF,uBAAA,IAAI,wCAAW,CAAC,qBAAqB,CACnC,uCAAuC,EACvC,sBAAsB,CACvB,CAAC;IAEF,uBAAA,IAAI,wCAAW,CAAC,qBAAqB,CACnC,6BAA6B,EAC7B,YAAY,CACb,CAAC;IAEF,uBAAA,IAAI,wCAAW,CAAC,qBAAqB,CACnC,iCAAiC,EACjC,gBAAgB,CACjB,CAAC;IAEF,uBAAA,IAAI,wCAAW,CAAC,qBAAqB,CACnC,mCAAmC,EACnC,kBAAkB,CACnB,CAAC;AACJ,CAAC,kDAED,KAAK;IACH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,kFAAmB,MAAvB,IAAI,CAAqB,CAAC;QAC/C,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE;YAChD,uBAAA,IAAI,wCAAW,CAAC,IAAI,CAClB,qCAAqC,EACrC,eAAe,EACf,aAAa,CACd,CAAC;YACF,4DAA4D;YAC5D,uBAAA,IAAI,wCAAW,CAAC,OAAO,CACrB,2CAA2C,EAC3C,aAAa,CACd,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,wDAAwD;QACxD,uBAAA,IAAI,6CAAuB,WAAW,CACpC,GAAG,EAAE;YACH,uBAAA,IAAI,oFAAqB,MAAzB,IAAI,CAAuB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACnD,CAAC,EACD,EAAE,GAAG,EAAE,GAAG,IAAI,CACf,MAAA,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC,+CAED,KAAK;IACH,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,uBAAA,IAAI,kFAAmB,MAAvB,IAAI,CAAqB,CAAC;QAC/C,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAElC,0BAA0B;QAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,MAAM,CAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CACjC,CAAC;QAEF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,EAAE;gBAChD,uBAAA,IAAI,wCAAW,CAAC,IAAI,CAClB,qCAAqC,EACrC,eAAe,EACf,aAAa,CACd,CAAC;gBACF,4DAA4D;gBAC5D,uBAAA,IAAI,wCAAW,CAAC,OAAO,CACrB,2CAA2C,EAC3C,aAAa,CACd,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;AACH,CAAC,6CAED,KAAK;IACH,MAAM,QAAQ,GAAG,MAAM,uBAAA,IAAI,wCAAW,CAAC,QAAQ,CAAC,wBAAwB,EAAE,CAAC;IAE3E,4CAA4C;IAC5C,OAAO,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACpD,CAAC,qGAcqB,OAAwB,EAAE,OAAgB;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IAEpC,8EAA8E;IAC9E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qFAAqF;IACrF,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE5D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,cAAc,EAAE,cAAc,CAAC,GAAI,KAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEtE,4BAA4B;QAC5B,IAAI,cAAc,KAAK,cAAc,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QAED,uEAAuE;QACvE,IAAI,cAAc,KAAK,GAAG,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,0DAA0D;QAC1D,IAAI,cAAc,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,kBAAkB,GAAG,cAAc,EAAE,UAAU,CAAC,IAAI,CAAC;gBACzD,CAAC,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;gBACzC,CAAC,CAAC,cAAc,CAAC;YACnB,IAAI,kBAAkB,KAAK,cAAc,EAAE,CAAC;gBAC1C,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;aAAM,IAAI,cAAc,KAAK,cAAc,EAAE,CAAC;YAC7C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,+FA6FC,QAAyB,EACzB,OAAoB;IAIpB,MAAM,aAAa,GAGf,EAAE,CAAC;IAEP,yEAAyE;IACzE,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrD,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,sFAAsF;QACtF,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,4CAA4C;QAC5C,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,8FAA8F;YAC9F,SAAS;QACX,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,aAAa,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;QAChC,CAAC;QAED,+DAA+D;QAC/D,MAAM,iBAAiB,GAAG,IAAA,wBAAgB,EAAC,IAAI,CAAC,OAAwB,CAAC,CAAC;QAE1E,mCAAmC;QACnC,aAAa,CAAC,SAAS,CAAC,CAAC,iBAAiB,CAAC,GAAG;YAC5C,MAAM,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC;AAgKH,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;GAKG;AACH,SAAgB,2BAA2B,CACzC,OAAqC;IAErC,OAAO,IAAI,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAJD,kEAIC","sourcesContent":["import type { V5BalanceItem } from '@metamask/core-backend';\nimport { ApiPlatformClient } from '@metamask/core-backend';\nimport type { InternalAccount } from '@metamask/keyring-internal-api';\nimport type { Messenger } from '@metamask/messenger';\n\nimport type {\n DataSourceState,\n SubscriptionRequest,\n} from './AbstractDataSource';\nimport { AbstractDataSource } from './AbstractDataSource';\nimport { projectLogger, createModuleLogger } from '../logger';\nimport type {\n ChainId,\n Caip19AssetId,\n AssetBalance,\n DataRequest,\n DataResponse,\n Middleware,\n} from '../types';\nimport { normalizeAssetId } from '../utils';\n\n// ============================================================================\n// CONSTANTS\n// ============================================================================\n\nconst CONTROLLER_NAME = 'AccountsApiDataSource';\nconst DEFAULT_POLL_INTERVAL = 30_000;\n\nconst log = createModuleLogger(projectLogger, CONTROLLER_NAME);\n\n// ============================================================================\n// MESSENGER TYPES\n// ============================================================================\n\n// Action types that AccountsApiDataSource exposes\nexport type AccountsApiDataSourceGetAssetsMiddlewareAction = {\n type: 'AccountsApiDataSource:getAssetsMiddleware';\n handler: () => Middleware;\n};\n\nexport type AccountsApiDataSourceGetActiveChainsAction = {\n type: 'AccountsApiDataSource:getActiveChains';\n handler: () => Promise<ChainId[]>;\n};\n\nexport type AccountsApiDataSourceFetchAction = {\n type: 'AccountsApiDataSource:fetch';\n handler: (request: DataRequest) => Promise<DataResponse>;\n};\n\nexport type AccountsApiDataSourceSubscribeAction = {\n type: 'AccountsApiDataSource:subscribe';\n handler: (request: SubscriptionRequest) => Promise<void>;\n};\n\nexport type AccountsApiDataSourceUnsubscribeAction = {\n type: 'AccountsApiDataSource:unsubscribe';\n handler: (subscriptionId: string) => Promise<void>;\n};\n\nexport type AccountsApiDataSourceActions =\n | AccountsApiDataSourceGetAssetsMiddlewareAction\n | AccountsApiDataSourceGetActiveChainsAction\n | AccountsApiDataSourceFetchAction\n | AccountsApiDataSourceSubscribeAction\n | AccountsApiDataSourceUnsubscribeAction;\n\n// Event types that AccountsApiDataSource publishes\nexport type AccountsApiDataSourceActiveChainsChangedEvent = {\n type: 'AccountsApiDataSource:activeChainsUpdated';\n payload: [ChainId[]];\n};\n\nexport type AccountsApiDataSourceAssetsUpdatedEvent = {\n type: 'AccountsApiDataSource:assetsUpdated';\n payload: [DataResponse, string | undefined];\n};\n\nexport type AccountsApiDataSourceEvents =\n | AccountsApiDataSourceActiveChainsChangedEvent\n | AccountsApiDataSourceAssetsUpdatedEvent;\n\n// Actions to report to AssetsController\ntype AssetsControllerActiveChainsUpdateAction = {\n type: 'AssetsController:activeChainsUpdate';\n handler: (dataSourceId: string, activeChains: ChainId[]) => void;\n};\n\ntype AssetsControllerAssetsUpdateAction = {\n type: 'AssetsController:assetsUpdate';\n handler: (response: DataResponse, sourceId: string) => Promise<void>;\n};\n\n// Allowed actions that AccountsApiDataSource can call\n// Note: Uses ApiPlatformClient directly, so no BackendApiClient actions needed\nexport type AccountsApiDataSourceAllowedActions =\n | AssetsControllerActiveChainsUpdateAction\n | AssetsControllerAssetsUpdateAction;\n\nexport type AccountsApiDataSourceMessenger = Messenger<\n typeof CONTROLLER_NAME,\n AccountsApiDataSourceActions | AccountsApiDataSourceAllowedActions,\n AccountsApiDataSourceEvents\n>;\n\n// ============================================================================\n// STATE\n// ============================================================================\n\nexport type AccountsApiDataSourceState = DataSourceState;\n\nconst defaultState: AccountsApiDataSourceState = {\n activeChains: [],\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport type AccountsApiDataSourceOptions = {\n messenger: AccountsApiDataSourceMessenger;\n /** ApiPlatformClient for API calls with caching */\n queryApiClient: ApiPlatformClient;\n pollInterval?: number;\n state?: Partial<AccountsApiDataSourceState>;\n};\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nfunction decimalToChainId(decimalChainId: number | string): ChainId {\n // Handle both decimal numbers and already-formatted CAIP chain IDs\n if (typeof decimalChainId === 'string') {\n // If already a CAIP chain ID (e.g., \"eip155:1\"), return as-is\n if (decimalChainId.startsWith('eip155:')) {\n return decimalChainId as ChainId;\n }\n // If it's a string number, convert\n return `eip155:${decimalChainId}` as ChainId;\n }\n return `eip155:${decimalChainId}` as ChainId;\n}\n\n/**\n * Convert a CAIP-2 chain ID from the API response to our ChainId type.\n * Handles both formats: \"eip155:1\" or just \"1\" (decimal).\n *\n * @param chainIdStr - The chain ID string to convert.\n * @returns The normalized ChainId.\n */\nfunction caipChainIdToChainId(chainIdStr: string): ChainId {\n // If already in CAIP-2 format, return as-is\n if (chainIdStr.includes(':')) {\n return chainIdStr as ChainId;\n }\n // If decimal number, convert to CAIP-2\n return `eip155:${chainIdStr}` as ChainId;\n}\n\n// ============================================================================\n// ACCOUNTS API DATA SOURCE\n// ============================================================================\n\n/**\n * Data source for fetching balances from the MetaMask Accounts API.\n *\n * Uses Messenger pattern for all interactions:\n * - Calls BackendApiClient methods via messenger actions\n * - Exposes its own actions for AssetsController to call\n * - Publishes events for AssetsController to subscribe to\n *\n * Actions exposed:\n * - AccountsApiDataSource:getActiveChains\n * - AccountsApiDataSource:fetch\n * - AccountsApiDataSource:subscribe\n * - AccountsApiDataSource:unsubscribe\n *\n * Events published:\n * - AccountsApiDataSource:activeChainsUpdated\n * - AccountsApiDataSource:assetsUpdated\n *\n * Actions called (from BackendApiClient):\n * - BackendApiClient:Accounts:getV2SupportedNetworks\n * - BackendApiClient:Accounts:getV5MultiAccountBalances\n */\nexport class AccountsApiDataSource extends AbstractDataSource<\n typeof CONTROLLER_NAME,\n AccountsApiDataSourceState\n> {\n readonly #messenger: AccountsApiDataSourceMessenger;\n\n readonly #pollInterval: number;\n\n /** ApiPlatformClient for cached API calls */\n readonly #apiClient: ApiPlatformClient;\n\n /** Chains refresh timer */\n #chainsRefreshTimer: ReturnType<typeof setInterval> | null = null;\n\n constructor(options: AccountsApiDataSourceOptions) {\n super(CONTROLLER_NAME, {\n ...defaultState,\n ...options.state,\n });\n\n this.#messenger = options.messenger;\n this.#pollInterval = options.pollInterval ?? DEFAULT_POLL_INTERVAL;\n this.#apiClient = options.queryApiClient;\n\n this.#registerActionHandlers();\n this.#initializeActiveChains().catch(console.error);\n }\n\n // ============================================================================\n // INITIALIZATION\n // ============================================================================\n\n #registerActionHandlers(): void {\n // Define strongly-typed handlers\n const getAssetsMiddlewareHandler: AccountsApiDataSourceGetAssetsMiddlewareAction['handler'] =\n () => this.assetsMiddleware;\n\n const getActiveChainsHandler: AccountsApiDataSourceGetActiveChainsAction['handler'] =\n async () => this.getActiveChains();\n\n const fetchHandler: AccountsApiDataSourceFetchAction['handler'] = async (\n request,\n ) => this.fetch(request);\n\n const subscribeHandler: AccountsApiDataSourceSubscribeAction['handler'] =\n async (request) => this.subscribe(request);\n\n const unsubscribeHandler: AccountsApiDataSourceUnsubscribeAction['handler'] =\n async (subscriptionId) => this.unsubscribe(subscriptionId);\n\n // Register handlers\n this.#messenger.registerActionHandler(\n 'AccountsApiDataSource:getAssetsMiddleware',\n getAssetsMiddlewareHandler,\n );\n\n this.#messenger.registerActionHandler(\n 'AccountsApiDataSource:getActiveChains',\n getActiveChainsHandler,\n );\n\n this.#messenger.registerActionHandler(\n 'AccountsApiDataSource:fetch',\n fetchHandler,\n );\n\n this.#messenger.registerActionHandler(\n 'AccountsApiDataSource:subscribe',\n subscribeHandler,\n );\n\n this.#messenger.registerActionHandler(\n 'AccountsApiDataSource:unsubscribe',\n unsubscribeHandler,\n );\n }\n\n async #initializeActiveChains(): Promise<void> {\n try {\n const chains = await this.#fetchActiveChains();\n this.updateActiveChains(chains, (updatedChains) => {\n this.#messenger.call(\n 'AssetsController:activeChainsUpdate',\n CONTROLLER_NAME,\n updatedChains,\n );\n // Also publish event for BackendWebsocketDataSource to sync\n this.#messenger.publish(\n 'AccountsApiDataSource:activeChainsUpdated',\n updatedChains,\n );\n });\n\n // Periodically refresh active chains (every 20 minutes)\n this.#chainsRefreshTimer = setInterval(\n () => {\n this.#refreshActiveChains().catch(console.error);\n },\n 20 * 60 * 1000,\n );\n } catch (error) {\n log('Failed to fetch active chains', error);\n }\n }\n\n async #refreshActiveChains(): Promise<void> {\n try {\n const chains = await this.#fetchActiveChains();\n const previousChains = new Set(this.state.activeChains);\n const newChains = new Set(chains);\n\n // Check if chains changed\n const added = chains.filter((chain) => !previousChains.has(chain));\n const removed = Array.from(previousChains).filter(\n (chain) => !newChains.has(chain),\n );\n\n if (added.length > 0 || removed.length > 0) {\n this.updateActiveChains(chains, (updatedChains) => {\n this.#messenger.call(\n 'AssetsController:activeChainsUpdate',\n CONTROLLER_NAME,\n updatedChains,\n );\n // Also publish event for BackendWebsocketDataSource to sync\n this.#messenger.publish(\n 'AccountsApiDataSource:activeChainsUpdated',\n updatedChains,\n );\n });\n }\n } catch (error) {\n log('Failed to refresh active chains', error);\n }\n }\n\n async #fetchActiveChains(): Promise<ChainId[]> {\n const response = await this.#apiClient.accounts.fetchV2SupportedNetworks();\n\n // Use fullSupport networks as active chains\n return response.fullSupport.map(decimalToChainId);\n }\n\n // ============================================================================\n // ACCOUNT SCOPE HELPERS\n // ============================================================================\n\n /**\n * Check if an account supports a specific chain based on its scopes.\n * AccountsApiDataSource only handles EVM chains, so we check for EIP155 scopes.\n *\n * @param account - The account to check\n * @param chainId - The chain ID to check (e.g., \"eip155:1\")\n * @returns True if the account supports the chain\n */\n #accountSupportsChain(account: InternalAccount, chainId: ChainId): boolean {\n const scopes = account.scopes ?? [];\n\n // If no scopes defined, assume it supports the chain (backward compatibility)\n if (scopes.length === 0) {\n return true;\n }\n\n // Extract namespace and reference from chainId (e.g., \"eip155:1\" -> [\"eip155\", \"1\"])\n const [chainNamespace, chainReference] = chainId.split(':');\n\n for (const scope of scopes) {\n const [scopeNamespace, scopeReference] = (scope as string).split(':');\n\n // Check if namespaces match\n if (scopeNamespace !== chainNamespace) {\n continue;\n }\n\n // Wildcard scope (e.g., \"eip155:0\" means all chains in that namespace)\n if (scopeReference === '0') {\n return true;\n }\n\n // Exact match check - normalize hex to decimal for EIP155\n if (chainNamespace === 'eip155') {\n const normalizedScopeRef = scopeReference?.startsWith('0x')\n ? parseInt(scopeReference, 16).toString()\n : scopeReference;\n if (normalizedScopeRef === chainReference) {\n return true;\n }\n } else if (scopeReference === chainReference) {\n return true;\n }\n }\n\n return false;\n }\n\n // ============================================================================\n // FETCH\n // ============================================================================\n\n async fetch(request: DataRequest): Promise<DataResponse> {\n const response: DataResponse = {};\n\n // Filter to only chains supported by Accounts API\n const supportedChains = new Set(this.state.activeChains);\n const chainsToFetch = request.chainIds.filter((chainId) =>\n supportedChains.has(chainId),\n );\n\n if (chainsToFetch.length === 0) {\n // Mark unsupported chains as errors so they pass to next middleware\n for (const chainId of request.chainIds) {\n if (!supportedChains.has(chainId)) {\n response.errors = response.errors ?? {};\n response.errors[chainId] = 'Chain not supported by Accounts API';\n }\n }\n return response;\n }\n\n try {\n // Build CAIP-10 account IDs (e.g., \"eip155:1:0x1234...\")\n // Only include account-chain combinations where the account's scopes\n // overlap with the chains being fetched\n const accountIds = request.accounts.flatMap((account) =>\n chainsToFetch\n .filter((chainId) => this.#accountSupportsChain(account, chainId))\n .map((chainId) => `${chainId}:${account.address}`),\n );\n\n // Skip API call if no valid account-chain combinations\n if (accountIds.length === 0) {\n return response;\n }\n\n const apiResponse =\n await this.#apiClient.accounts.fetchV5MultiAccountBalances(accountIds);\n\n // Handle unprocessed networks - these will be passed to next middleware\n if (apiResponse.unprocessedNetworks.length > 0) {\n const unprocessedChainIds =\n apiResponse.unprocessedNetworks.map(caipChainIdToChainId);\n\n // Add unprocessed chains to errors so middleware passes them to next data source\n response.errors = response.errors ?? {};\n for (const chainId of unprocessedChainIds) {\n response.errors[chainId] = 'Unprocessed by Accounts API';\n }\n }\n\n const { assetsBalance } = this.#processV5Balances(\n apiResponse.balances,\n request,\n );\n\n response.assetsBalance = assetsBalance;\n } catch (error) {\n log('Fetch FAILED', { error, chains: chainsToFetch });\n\n // On error, mark all chains as errors so they can be handled by next middleware\n response.errors = response.errors ?? {};\n for (const chainId of chainsToFetch) {\n response.errors[chainId] =\n `Fetch failed: ${error instanceof Error ? error.message : String(error)}`;\n }\n }\n\n // Mark unsupported chains as errors so they pass to next middleware\n for (const chainId of request.chainIds) {\n if (!supportedChains.has(chainId)) {\n response.errors = response.errors ?? {};\n response.errors[chainId] = 'Chain not supported by Accounts API';\n }\n }\n\n return response;\n }\n\n /**\n * Process V5 API balances response.\n * V5 returns a flat array of balance items, each with accountId and assetId.\n *\n * @param balances - Array of balance items from the V5 API response.\n * @param request - The original data request containing accounts to map.\n * @returns Object containing processed asset balances by account.\n */\n #processV5Balances(\n balances: V5BalanceItem[],\n request: DataRequest,\n ): {\n assetsBalance: Record<string, Record<Caip19AssetId, AssetBalance>>;\n } {\n const assetsBalance: Record<\n string,\n Record<Caip19AssetId, AssetBalance>\n > = {};\n\n // Build a map of lowercase addresses to account IDs for efficient lookup\n const addressToAccountId = new Map<string, string>();\n for (const account of request.accounts) {\n if (account.address) {\n addressToAccountId.set(account.address.toLowerCase(), account.id);\n }\n }\n\n // V5 response: array of { accountId, assetId, balance, ... }\n for (const item of balances) {\n // Extract address from CAIP-10 account ID (e.g., \"eip155:1:0x1234...\" -> \"0x1234...\")\n const addressParts = item.accountId.split(':');\n if (addressParts.length < 3) {\n continue;\n }\n const address = addressParts[2].toLowerCase();\n\n // Find the matching account ID from request\n const accountId = addressToAccountId.get(address);\n if (!accountId) {\n // This is normal - API returns balances for all chains, but request may only have one account\n continue;\n }\n\n if (!assetsBalance[accountId]) {\n assetsBalance[accountId] = {};\n }\n\n // Normalize asset ID (checksum EVM addresses for ERC20 tokens)\n const normalizedAssetId = normalizeAssetId(item.assetId as Caip19AssetId);\n\n // Store balance as returned by API\n assetsBalance[accountId][normalizedAssetId] = {\n amount: item.balance,\n };\n }\n\n return { assetsBalance };\n }\n\n // ============================================================================\n // MIDDLEWARE\n // ============================================================================\n\n /**\n * Get the middleware for fetching balances via Accounts API.\n * This middleware:\n * - Supports multiple accounts in a single request\n * - Uses unprocessedNetworks from API response to determine what to pass to next middleware\n * - Merges response into context\n * - Removes handled chains from request for next middleware\n *\n * @returns The middleware function for the assets pipeline.\n */\n get assetsMiddleware(): Middleware {\n return async (context, next) => {\n const { request } = context;\n\n // If no chains requested, skip to next middleware\n if (request.chainIds.length === 0) {\n return next(context);\n }\n\n let successfullyHandledChains: ChainId[] = [];\n\n try {\n const response = await this.fetch(request);\n\n // Merge response into context\n if (response.assetsBalance) {\n context.response.assetsBalance ??= {};\n for (const [accountId, accountBalances] of Object.entries(\n response.assetsBalance,\n )) {\n context.response.assetsBalance[accountId] = {\n ...context.response.assetsBalance[accountId],\n ...accountBalances,\n };\n }\n }\n\n // Determine successfully handled chains (exclude unprocessed/error chains)\n const unprocessedChains = new Set(Object.keys(response.errors ?? {}));\n successfullyHandledChains = request.chainIds.filter(\n (chainId) => !unprocessedChains.has(chainId),\n );\n } catch (error) {\n log('Middleware fetch failed', { error });\n successfullyHandledChains = [];\n }\n\n // Remove successfully handled chains from request for next middleware\n if (successfullyHandledChains.length > 0) {\n const remainingChains = request.chainIds.filter(\n (chainId) => !successfullyHandledChains.includes(chainId),\n );\n\n return next({\n ...context,\n request: {\n ...request,\n chainIds: remainingChains,\n },\n });\n }\n\n // No chains handled - pass context unchanged\n return next(context);\n };\n }\n\n // ============================================================================\n // SUBSCRIBE\n // ============================================================================\n\n async subscribe(subscriptionRequest: SubscriptionRequest): Promise<void> {\n const { request, subscriptionId, isUpdate } = subscriptionRequest;\n\n // Try all requested chains - API will handle unsupported ones via unprocessedNetworks\n const chainsToSubscribe = request.chainIds;\n\n if (chainsToSubscribe.length === 0) {\n return;\n }\n\n // Handle subscription update - update both chains AND request (for accounts)\n if (isUpdate) {\n const existing = this.activeSubscriptions.get(subscriptionId);\n if (existing) {\n existing.chains = chainsToSubscribe;\n existing.request = request;\n return;\n }\n }\n\n // Clean up existing subscription if any\n await this.unsubscribe(subscriptionId);\n\n const pollInterval = request.updateInterval ?? this.#pollInterval;\n\n // Create poll function for this subscription\n const pollFn = async (): Promise<void> => {\n try {\n const subscription = this.activeSubscriptions.get(subscriptionId);\n if (!subscription?.request) {\n return;\n }\n\n // Use stored request (which gets updated on account changes)\n const fetchResponse = await this.fetch({\n ...subscription.request,\n chainIds: subscription.chains,\n });\n\n // Report update to AssetsController\n await this.#messenger.call(\n 'AssetsController:assetsUpdate',\n fetchResponse,\n CONTROLLER_NAME,\n );\n } catch (error) {\n log('Subscription poll failed', { subscriptionId, error });\n }\n };\n\n // Set up polling\n const timer = setInterval(() => {\n pollFn().catch(console.error);\n }, pollInterval);\n\n // Store subscription with request for account updates\n this.activeSubscriptions.set(subscriptionId, {\n cleanup: () => {\n clearInterval(timer);\n },\n chains: chainsToSubscribe,\n request,\n });\n\n // Initial fetch\n await pollFn();\n }\n\n // ============================================================================\n // CLEANUP\n // ============================================================================\n\n destroy(): void {\n // Clean up timers\n if (this.#chainsRefreshTimer) {\n clearInterval(this.#chainsRefreshTimer);\n }\n\n // Clean up subscriptions\n super.destroy();\n }\n}\n\n// ============================================================================\n// FACTORY FUNCTION\n// ============================================================================\n\n/**\n * Creates an AccountsApiDataSource instance.\n *\n * @param options - Configuration options for the data source.\n * @returns A new AccountsApiDataSource instance.\n */\nexport function createAccountsApiDataSource(\n options: AccountsApiDataSourceOptions,\n): AccountsApiDataSource {\n return new AccountsApiDataSource(options);\n}\n"]}
@@ -0,0 +1,103 @@
1
+ import { ApiPlatformClient } from "@metamask/core-backend";
2
+ import type { Messenger } from "@metamask/messenger";
3
+ import type { DataSourceState, SubscriptionRequest } from "./AbstractDataSource.cjs";
4
+ import { AbstractDataSource } from "./AbstractDataSource.cjs";
5
+ import type { ChainId, DataRequest, DataResponse, Middleware } from "../types.cjs";
6
+ declare const CONTROLLER_NAME = "AccountsApiDataSource";
7
+ export type AccountsApiDataSourceGetAssetsMiddlewareAction = {
8
+ type: 'AccountsApiDataSource:getAssetsMiddleware';
9
+ handler: () => Middleware;
10
+ };
11
+ export type AccountsApiDataSourceGetActiveChainsAction = {
12
+ type: 'AccountsApiDataSource:getActiveChains';
13
+ handler: () => Promise<ChainId[]>;
14
+ };
15
+ export type AccountsApiDataSourceFetchAction = {
16
+ type: 'AccountsApiDataSource:fetch';
17
+ handler: (request: DataRequest) => Promise<DataResponse>;
18
+ };
19
+ export type AccountsApiDataSourceSubscribeAction = {
20
+ type: 'AccountsApiDataSource:subscribe';
21
+ handler: (request: SubscriptionRequest) => Promise<void>;
22
+ };
23
+ export type AccountsApiDataSourceUnsubscribeAction = {
24
+ type: 'AccountsApiDataSource:unsubscribe';
25
+ handler: (subscriptionId: string) => Promise<void>;
26
+ };
27
+ export type AccountsApiDataSourceActions = AccountsApiDataSourceGetAssetsMiddlewareAction | AccountsApiDataSourceGetActiveChainsAction | AccountsApiDataSourceFetchAction | AccountsApiDataSourceSubscribeAction | AccountsApiDataSourceUnsubscribeAction;
28
+ export type AccountsApiDataSourceActiveChainsChangedEvent = {
29
+ type: 'AccountsApiDataSource:activeChainsUpdated';
30
+ payload: [ChainId[]];
31
+ };
32
+ export type AccountsApiDataSourceAssetsUpdatedEvent = {
33
+ type: 'AccountsApiDataSource:assetsUpdated';
34
+ payload: [DataResponse, string | undefined];
35
+ };
36
+ export type AccountsApiDataSourceEvents = AccountsApiDataSourceActiveChainsChangedEvent | AccountsApiDataSourceAssetsUpdatedEvent;
37
+ type AssetsControllerActiveChainsUpdateAction = {
38
+ type: 'AssetsController:activeChainsUpdate';
39
+ handler: (dataSourceId: string, activeChains: ChainId[]) => void;
40
+ };
41
+ type AssetsControllerAssetsUpdateAction = {
42
+ type: 'AssetsController:assetsUpdate';
43
+ handler: (response: DataResponse, sourceId: string) => Promise<void>;
44
+ };
45
+ export type AccountsApiDataSourceAllowedActions = AssetsControllerActiveChainsUpdateAction | AssetsControllerAssetsUpdateAction;
46
+ export type AccountsApiDataSourceMessenger = Messenger<typeof CONTROLLER_NAME, AccountsApiDataSourceActions | AccountsApiDataSourceAllowedActions, AccountsApiDataSourceEvents>;
47
+ export type AccountsApiDataSourceState = DataSourceState;
48
+ export type AccountsApiDataSourceOptions = {
49
+ messenger: AccountsApiDataSourceMessenger;
50
+ /** ApiPlatformClient for API calls with caching */
51
+ queryApiClient: ApiPlatformClient;
52
+ pollInterval?: number;
53
+ state?: Partial<AccountsApiDataSourceState>;
54
+ };
55
+ /**
56
+ * Data source for fetching balances from the MetaMask Accounts API.
57
+ *
58
+ * Uses Messenger pattern for all interactions:
59
+ * - Calls BackendApiClient methods via messenger actions
60
+ * - Exposes its own actions for AssetsController to call
61
+ * - Publishes events for AssetsController to subscribe to
62
+ *
63
+ * Actions exposed:
64
+ * - AccountsApiDataSource:getActiveChains
65
+ * - AccountsApiDataSource:fetch
66
+ * - AccountsApiDataSource:subscribe
67
+ * - AccountsApiDataSource:unsubscribe
68
+ *
69
+ * Events published:
70
+ * - AccountsApiDataSource:activeChainsUpdated
71
+ * - AccountsApiDataSource:assetsUpdated
72
+ *
73
+ * Actions called (from BackendApiClient):
74
+ * - BackendApiClient:Accounts:getV2SupportedNetworks
75
+ * - BackendApiClient:Accounts:getV5MultiAccountBalances
76
+ */
77
+ export declare class AccountsApiDataSource extends AbstractDataSource<typeof CONTROLLER_NAME, AccountsApiDataSourceState> {
78
+ #private;
79
+ constructor(options: AccountsApiDataSourceOptions);
80
+ fetch(request: DataRequest): Promise<DataResponse>;
81
+ /**
82
+ * Get the middleware for fetching balances via Accounts API.
83
+ * This middleware:
84
+ * - Supports multiple accounts in a single request
85
+ * - Uses unprocessedNetworks from API response to determine what to pass to next middleware
86
+ * - Merges response into context
87
+ * - Removes handled chains from request for next middleware
88
+ *
89
+ * @returns The middleware function for the assets pipeline.
90
+ */
91
+ get assetsMiddleware(): Middleware;
92
+ subscribe(subscriptionRequest: SubscriptionRequest): Promise<void>;
93
+ destroy(): void;
94
+ }
95
+ /**
96
+ * Creates an AccountsApiDataSource instance.
97
+ *
98
+ * @param options - Configuration options for the data source.
99
+ * @returns A new AccountsApiDataSource instance.
100
+ */
101
+ export declare function createAccountsApiDataSource(options: AccountsApiDataSourceOptions): AccountsApiDataSource;
102
+ export {};
103
+ //# sourceMappingURL=AccountsApiDataSource.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccountsApiDataSource.d.cts","sourceRoot":"","sources":["../../src/data-sources/AccountsApiDataSource.ts"],"names":[],"mappings":"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"}