@metamask/assets-controllers 87.1.0 → 88.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +20 -1
  2. package/dist/AccountTrackerController.cjs.map +1 -1
  3. package/dist/AccountTrackerController.d.cts +2 -2
  4. package/dist/AccountTrackerController.d.mts +2 -2
  5. package/dist/AccountTrackerController.mjs.map +1 -1
  6. package/dist/AssetsContractController.cjs.map +1 -1
  7. package/dist/AssetsContractController.mjs.map +1 -1
  8. package/dist/CurrencyRateController.cjs.map +1 -1
  9. package/dist/CurrencyRateController.d.cts +2 -2
  10. package/dist/CurrencyRateController.d.mts +2 -2
  11. package/dist/CurrencyRateController.mjs.map +1 -1
  12. package/dist/DeFiPositionsController/DeFiPositionsController.cjs.map +1 -1
  13. package/dist/DeFiPositionsController/DeFiPositionsController.d.cts +2 -2
  14. package/dist/DeFiPositionsController/DeFiPositionsController.d.mts +2 -2
  15. package/dist/DeFiPositionsController/DeFiPositionsController.mjs.map +1 -1
  16. package/dist/DeFiPositionsController/fetch-positions.cjs.map +1 -1
  17. package/dist/DeFiPositionsController/fetch-positions.mjs.map +1 -1
  18. package/dist/DeFiPositionsController/group-defi-positions.cjs.map +1 -1
  19. package/dist/DeFiPositionsController/group-defi-positions.mjs.map +1 -1
  20. package/dist/MultichainAssetsController/MultichainAssetsController.cjs.map +1 -1
  21. package/dist/MultichainAssetsController/MultichainAssetsController.mjs.map +1 -1
  22. package/dist/MultichainAssetsController/utils.cjs.map +1 -1
  23. package/dist/MultichainAssetsController/utils.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.mts +2 -2
  27. package/dist/MultichainAssetsRatesController/MultichainAssetsRatesController.mjs.map +1 -1
  28. package/dist/MultichainBalancesController/MultichainBalancesController.cjs +2 -2
  29. package/dist/MultichainBalancesController/MultichainBalancesController.cjs.map +1 -1
  30. package/dist/MultichainBalancesController/MultichainBalancesController.mjs +2 -2
  31. package/dist/MultichainBalancesController/MultichainBalancesController.mjs.map +1 -1
  32. package/dist/NftController.cjs.map +1 -1
  33. package/dist/NftController.mjs.map +1 -1
  34. package/dist/NftDetectionController.cjs +2 -2
  35. package/dist/NftDetectionController.cjs.map +1 -1
  36. package/dist/NftDetectionController.mjs +2 -2
  37. package/dist/NftDetectionController.mjs.map +1 -1
  38. package/dist/RatesController/RatesController.cjs.map +1 -1
  39. package/dist/RatesController/RatesController.mjs.map +1 -1
  40. package/dist/Standards/ERC20Standard.cjs.map +1 -1
  41. package/dist/Standards/ERC20Standard.mjs.map +1 -1
  42. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.cjs.map +1 -1
  43. package/dist/Standards/NftStandards/ERC1155/ERC1155Standard.mjs.map +1 -1
  44. package/dist/Standards/NftStandards/ERC721/ERC721Standard.cjs.map +1 -1
  45. package/dist/Standards/NftStandards/ERC721/ERC721Standard.mjs.map +1 -1
  46. package/dist/TokenBalancesController.cjs.map +1 -1
  47. package/dist/TokenBalancesController.d.cts +2 -2
  48. package/dist/TokenBalancesController.d.mts +2 -2
  49. package/dist/TokenBalancesController.mjs.map +1 -1
  50. package/dist/TokenDetectionController.cjs.map +1 -1
  51. package/dist/TokenDetectionController.d.cts +2 -2
  52. package/dist/TokenDetectionController.d.mts +2 -2
  53. package/dist/TokenDetectionController.mjs.map +1 -1
  54. package/dist/TokenListController.cjs.map +1 -1
  55. package/dist/TokenListController.d.cts +2 -2
  56. package/dist/TokenListController.d.mts +2 -2
  57. package/dist/TokenListController.mjs.map +1 -1
  58. package/dist/TokenRatesController.cjs.map +1 -1
  59. package/dist/TokenRatesController.d.cts +2 -2
  60. package/dist/TokenRatesController.d.mts +2 -2
  61. package/dist/TokenRatesController.mjs.map +1 -1
  62. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.cjs.map +1 -1
  63. package/dist/TokenSearchDiscoveryDataController/TokenSearchDiscoveryDataController.mjs.map +1 -1
  64. package/dist/TokensController.cjs.map +1 -1
  65. package/dist/TokensController.mjs.map +1 -1
  66. package/dist/assetsUtil.cjs.map +1 -1
  67. package/dist/assetsUtil.d.cts +20 -20
  68. package/dist/assetsUtil.d.cts.map +1 -1
  69. package/dist/assetsUtil.d.mts +20 -20
  70. package/dist/assetsUtil.d.mts.map +1 -1
  71. package/dist/assetsUtil.mjs.map +1 -1
  72. package/dist/balances.cjs.map +1 -1
  73. package/dist/balances.mjs.map +1 -1
  74. package/dist/constants.cjs +9 -9
  75. package/dist/constants.cjs.map +1 -1
  76. package/dist/constants.mjs +9 -9
  77. package/dist/constants.mjs.map +1 -1
  78. package/dist/crypto-compare-service/crypto-compare.cjs.map +1 -1
  79. package/dist/crypto-compare-service/crypto-compare.mjs.map +1 -1
  80. package/dist/multi-chain-accounts-service/api-balance-fetcher.cjs.map +1 -1
  81. package/dist/multi-chain-accounts-service/api-balance-fetcher.mjs.map +1 -1
  82. package/dist/multi-chain-accounts-service/multi-chain-accounts.cjs.map +1 -1
  83. package/dist/multi-chain-accounts-service/multi-chain-accounts.mjs.map +1 -1
  84. package/dist/multicall.cjs.map +1 -1
  85. package/dist/multicall.mjs.map +1 -1
  86. package/dist/rpc-service/rpc-balance-fetcher.cjs.map +1 -1
  87. package/dist/rpc-service/rpc-balance-fetcher.mjs.map +1 -1
  88. package/dist/selectors/stringify-balance.cjs.map +1 -1
  89. package/dist/selectors/stringify-balance.mjs.map +1 -1
  90. package/dist/selectors/token-selectors.cjs.map +1 -1
  91. package/dist/selectors/token-selectors.mjs.map +1 -1
  92. package/dist/token-prices-service/codefi-v2.cjs.map +1 -1
  93. package/dist/token-prices-service/codefi-v2.mjs.map +1 -1
  94. package/dist/token-service.cjs +0 -3
  95. package/dist/token-service.cjs.map +1 -1
  96. package/dist/token-service.d.cts.map +1 -1
  97. package/dist/token-service.d.mts.map +1 -1
  98. package/dist/token-service.mjs +0 -3
  99. package/dist/token-service.mjs.map +1 -1
  100. package/dist/utils/formatters.cjs.map +1 -1
  101. package/dist/utils/formatters.mjs.map +1 -1
  102. package/dist/utils/timeout-with-retry.cjs.map +1 -1
  103. package/dist/utils/timeout-with-retry.mjs.map +1 -1
  104. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"token-service.cjs","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":";;;AAAA,iEAKoC;AAGpC,iDAA8D;AAEjD,QAAA,mBAAmB,GAAG,kCAAkC,CAAC;AACzD,QAAA,+BAA+B,GAC1C,iEAAiE,CAAC;AAEpE;;;;;GAKG;AACH,SAAS,YAAY,CAAC,OAAY;IAChC,MAAM,eAAe,GAAG,OAAO,KAAK,0BAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,OAAO,GAAG,2BAAmB,WAAW,IAAA,sCAAmB,EACzD,OAAO,CACR,oBAAoB,eAAe,wHAAwH,CAAC;AAC/J,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,OAAY,EAAE,YAAoB;IAC7D,OAAO,GAAG,2BAAmB,UAAU,IAAA,sCAAmB,EACxD,OAAO,CACR,YAAY,YAAY,EAAE,CAAC;AAC9B,CAAC;AAWD;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,QAAuB,EAAE,KAAa,EAAE,KAAK,GAAG,EAAE;IAC3E,MAAM,YAAY,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC/C,MAAM,eAAe,GAAG,QAAQ;SAC7B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;SACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,GAAG,2BAAmB,2BAA2B,eAAe,UAAU,YAAY,UAAU,KAAK,EAAE,CAAC;AACjH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAS,oBAAoB,CAAC,OAQ7B;IACC,MAAM,eAAe,GAAG,OAAO,CAAC,QAAQ;SACrC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;SACnC,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,mDAAmD;IACnD,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;IAC1C,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC5C,IAAI,KAAK,KAAK,SAAS,EAAE;YACvB,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;SACxC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,2BAAmB,gCAAgC,eAAe,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9I,CAAC;AAED,MAAM,wBAAwB,GAAG,KAAM,CAAC;AAExC,qCAAqC;AACrC,yGAAyG;AACzG,MAAM,cAAc,GAAG,wBAAwB,CAAC;AAEhD;;;;;;;;;GASG;AACI,KAAK,UAAU,uBAAuB,CAC3C,OAAY,EACZ,WAAwB,EACxB,EAAE,OAAO,GAAG,cAAc,EAAE,GAAG,EAAE;IAEjC,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAChE,IAAI,QAAQ,EAAE;QACZ,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,KAAK,0BAAO,CAAC,eAAe,CAAC,EAAE;YACjE,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CACvE,CAAC;SACH;QACD,OAAO,MAAM,CAAC;KACf;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAlBD,0DAkBC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,YAAY,CAChC,QAAuB,EACvB,KAAa,EACb,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,EAAE;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;QACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAC/B;IAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAEjE,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAW,EAAC,cAAc,CAAC,CAAC;QAEjD,6FAA6F;QAC7F,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YACtE,OAAO;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM;gBACzC,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC;SACH;QAED,gCAAgC;QAChC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAC/B;IAAC,OAAO,KAAK,EAAE;QACd,4EAA4E;QAC5E,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAC/B;AACH,CAAC;AA7BD,oCA6BC;AAwBD;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,iBAAiB,CAAC,EACtC,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,GASb;IACC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;QACzB,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACpC,OAAO,EAAE,CAAC;KACX;IAED,MAAM,iBAAiB,GAAG,oBAAoB,CAAC;QAC7C,QAAQ;QACR,MAAM;QACN,YAAY;QACZ,eAAe;QACf,eAAe;QACf,YAAY;QACZ,YAAY;KACb,CAAC,CAAC;IAEH,IAAI;QACF,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAW,EAAC,iBAAiB,CAAC,CAAC;QAEpD,0CAA0C;QAC1C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YACzB,OAAO,MAAM,CAAC;SACf;QAED,gCAAgC;QAChC,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,MAAM,CAAC,CAAC;QAC1E,OAAO,EAAE,CAAC;KACX;IAAC,OAAO,KAAK,EAAE;QACd,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,EAAE,CAAC;KACX;AACH,CAAC;AA/CD,8CA+CC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,kBAAkB,CACtC,OAAY,EACZ,YAAoB,EACpB,WAAwB,EACxB,EAAE,OAAO,GAAG,cAAc,EAAE,GAAG,EAAE;IAEjC,IAAI,CAAC,IAAA,2CAA8B,EAAC,OAAO,CAAC,EAAE;QAC5C,MAAM,IAAI,KAAK,CAAC,uCAA+B,CAAC,CAAC;KAClD;IACD,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACxE,IAAI,QAAQ,EAAE;QACZ,OAAO,iBAAiB,CAAC,QAAQ,CAAe,CAAC;KAClD;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAfD,gDAeC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,WAAwB,EACxB,OAAe;IAEf,MAAM,YAAY,GAAgB;QAChC,QAAQ,EAAE,MAAM;QAChB,cAAc,EAAE,4BAA4B;QAC5C,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,SAAS;KACjB,CAAC;IACF,YAAY,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;IAC5C,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAC7D,IAAI;QACF,OAAO,MAAM,IAAA,+BAAY,EAAC,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;KAC1D;IAAC,OAAO,KAAK,EAAE;QACd,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE;YACzD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;SACnC;KACF;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,iBAAiB,CAAC,WAAqB;IACpD,MAAM,WAAW,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IAC7C,0EAA0E;IAC1E,IAAI,WAAW,EAAE,KAAK,EAAE;QACtB,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;KAC7D;IACD,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import {\n ChainId,\n convertHexToDecimal,\n handleFetch,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport { isTokenListSupportedForNetwork } from './assetsUtil';\n\nexport const TOKEN_END_POINT_API = 'https://token.api.cx.metamask.io';\nexport const TOKEN_METADATA_NO_SUPPORT_ERROR =\n 'TokenService Error: Network does not support fetchTokenMetadata';\n\n/**\n * Get the tokens URL for a specific network.\n *\n * @param chainId - The chain ID of the network the tokens requested are on.\n * @returns The tokens URL.\n */\nfunction getTokensURL(chainId: Hex) {\n const occurrenceFloor = chainId === ChainId['linea-mainnet'] ? 1 : 3;\n\n return `${TOKEN_END_POINT_API}/tokens/${convertHexToDecimal(\n chainId,\n )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`;\n}\n\n/**\n * Get the token metadata URL for the given network and token.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The token address.\n * @returns The token metadata URL.\n */\nfunction getTokenMetadataURL(chainId: Hex, tokenAddress: string) {\n return `${TOKEN_END_POINT_API}/token/${convertHexToDecimal(\n chainId,\n )}?address=${tokenAddress}`;\n}\n\n/**\n * The sort by field for trending tokens.\n */\nexport type SortTrendingBy =\n | 'm5_trending'\n | 'h1_trending'\n | 'h6_trending'\n | 'h24_trending';\n\n/**\n * Get the token search URL for the given networks and search query.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., 'eip155:1', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp').\n * @param query - The search query (token name, symbol, or address).\n * @param limit - Optional limit for the number of results (defaults to 10).\n * @returns The token search URL.\n */\nfunction getTokenSearchURL(chainIds: CaipChainId[], query: string, limit = 10) {\n const encodedQuery = encodeURIComponent(query);\n const encodedChainIds = chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n return `${TOKEN_END_POINT_API}/tokens/search?chainIds=${encodedChainIds}&query=${encodedQuery}&limit=${limit}`;\n}\n\n/**\n * Get the trending tokens URL for the given networks and search query.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens URL.\n */\nfunction getTrendingTokensURL(options: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): string {\n const encodedChainIds = options.chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n // Add the rest of query params if they are defined\n const queryParams = new URLSearchParams();\n const { chainIds, ...rest } = options;\n Object.entries(rest).forEach(([key, value]) => {\n if (value !== undefined) {\n queryParams.append(key, String(value));\n }\n });\n\n return `${TOKEN_END_POINT_API}/v3/tokens/trending?chainIds=${encodedChainIds}${queryParams.toString() ? `&${queryParams.toString()}` : ''}`;\n}\n\nconst tenSecondsInMilliseconds = 10_000;\n\n// Token list averages 1.6 MB in size\n// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.\nconst defaultTimeout = tenSecondsInMilliseconds;\n\n/**\n * Fetch the list of token metadata for a given network. This request is cancellable using the\n * abort signal passed in.\n *\n * @param chainId - The chain ID of the network the requested tokens are on.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token list, or `undefined` if the request was cancelled.\n */\nexport async function fetchTokenListByChainId(\n chainId: Hex,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<unknown> {\n const tokenURL = getTokensURL(chainId);\n const response = await queryApi(tokenURL, abortSignal, timeout);\n if (response) {\n const result = await parseJsonResponse(response);\n if (Array.isArray(result) && chainId === ChainId['linea-mainnet']) {\n return result.filter(\n (elm) =>\n elm.aggregators.includes('lineaTeam') || elm.aggregators.length >= 3,\n );\n }\n return result;\n }\n return undefined;\n}\n\n/**\n * Search for tokens across one or more networks by query string using CAIP format chain IDs.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param query - The search query (token name, symbol, or address).\n * @param options - Additional fetch options.\n * @param options.limit - The maximum number of results to return.\n * @returns Object containing count and data array. Returns { count: 0, data: [] } if request fails.\n */\nexport async function searchTokens(\n chainIds: CaipChainId[],\n query: string,\n { limit = 10 } = {},\n): Promise<{ count: number; data: unknown[] }> {\n if (chainIds.length === 0) {\n return { count: 0, data: [] };\n }\n\n const tokenSearchURL = getTokenSearchURL(chainIds, query, limit);\n\n try {\n const result = await handleFetch(tokenSearchURL);\n\n // The API returns an object with structure: { count: number, data: array, pageInfo: object }\n if (result && typeof result === 'object' && Array.isArray(result.data)) {\n return {\n count: result.count || result.data.length,\n data: result.data,\n };\n }\n\n // Handle non-expected responses\n return { count: 0, data: [] };\n } catch (error) {\n // Handle 400 errors and other failures by returning count 0 and empty array\n console.log('Search request failed:', error);\n return { count: 0, data: [] };\n }\n}\n\n/**\n * The trending asset type.\n */\nexport type TrendingAsset = {\n assetId: string;\n name: string;\n symbol: string;\n decimals: number;\n price: string;\n aggregatedUsdVolume: number;\n marketCap: number;\n priceChangePct?: {\n m5?: string;\n m15?: string;\n m30?: string;\n h1?: string;\n h6?: string;\n h24?: string;\n };\n labels?: string[];\n};\n\n/**\n * Get the trending tokens for the given chains.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - The chains to get the trending tokens for.\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens.\n * @throws Will throw if the request fails.\n */\nexport async function getTrendingTokens({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n}: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): Promise<TrendingAsset[]> {\n if (chainIds.length === 0) {\n console.error('No chains provided');\n return [];\n }\n\n const trendingTokensURL = getTrendingTokensURL({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n });\n\n try {\n const result = await handleFetch(trendingTokensURL);\n\n // Validate that the API returned an array\n if (Array.isArray(result)) {\n return result;\n }\n\n // Handle non-expected responses\n console.error('Trending tokens API returned non-array response:', result);\n return [];\n } catch (error) {\n console.error('Trending tokens request failed:', error);\n return [];\n }\n}\n\n/**\n * Fetch metadata for the token address provided for a given network. This request is cancellable\n * using the abort signal passed in.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The address of the token to fetch metadata for.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token metadata, or `undefined` if the request was either aborted or failed.\n */\nexport async function fetchTokenMetadata<T>(\n chainId: Hex,\n tokenAddress: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<T | undefined> {\n if (!isTokenListSupportedForNetwork(chainId)) {\n throw new Error(TOKEN_METADATA_NO_SUPPORT_ERROR);\n }\n const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);\n const response = await queryApi(tokenMetadataURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response) as Promise<T>;\n }\n return undefined;\n}\n\n/**\n * Perform fetch request against the api.\n *\n * @param apiURL - The URL of the API to fetch.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param timeout - The fetch timeout.\n * @returns Promise resolving request response.\n */\nasync function queryApi(\n apiURL: string,\n abortSignal: AbortSignal,\n timeout: number,\n): Promise<Response | undefined> {\n const fetchOptions: RequestInit = {\n referrer: apiURL,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n signal: abortSignal,\n cache: 'default',\n };\n fetchOptions.headers = new window.Headers();\n fetchOptions.headers.set('Content-Type', 'application/json');\n try {\n return await timeoutFetch(apiURL, fetchOptions, timeout);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n console.log('Request is aborted');\n }\n }\n return undefined;\n}\n\n/**\n * Parse an API response and return the response JSON data.\n *\n * @param apiResponse - The API response to parse.\n * @returns The response JSON data.\n * @throws Will throw if the response includes an error.\n */\nasync function parseJsonResponse(apiResponse: Response): Promise<unknown> {\n const responseObj = await apiResponse.json();\n // api may return errors as json without setting an error http status code\n if (responseObj?.error) {\n throw new Error(`TokenService Error: ${responseObj.error}`);\n }\n return responseObj;\n}\n"]}
1
+ {"version":3,"file":"token-service.cjs","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChainId,\n convertHexToDecimal,\n handleFetch,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport { isTokenListSupportedForNetwork } from './assetsUtil';\n\nexport const TOKEN_END_POINT_API = 'https://token.api.cx.metamask.io';\nexport const TOKEN_METADATA_NO_SUPPORT_ERROR =\n 'TokenService Error: Network does not support fetchTokenMetadata';\n\n/**\n * Get the tokens URL for a specific network.\n *\n * @param chainId - The chain ID of the network the tokens requested are on.\n * @returns The tokens URL.\n */\nfunction getTokensURL(chainId: Hex) {\n const occurrenceFloor = chainId === ChainId['linea-mainnet'] ? 1 : 3;\n\n return `${TOKEN_END_POINT_API}/tokens/${convertHexToDecimal(\n chainId,\n )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`;\n}\n\n/**\n * Get the token metadata URL for the given network and token.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The token address.\n * @returns The token metadata URL.\n */\nfunction getTokenMetadataURL(chainId: Hex, tokenAddress: string) {\n return `${TOKEN_END_POINT_API}/token/${convertHexToDecimal(\n chainId,\n )}?address=${tokenAddress}`;\n}\n\n/**\n * The sort by field for trending tokens.\n */\nexport type SortTrendingBy =\n | 'm5_trending'\n | 'h1_trending'\n | 'h6_trending'\n | 'h24_trending';\n\n/**\n * Get the token search URL for the given networks and search query.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., 'eip155:1', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp').\n * @param query - The search query (token name, symbol, or address).\n * @param limit - Optional limit for the number of results (defaults to 10).\n * @returns The token search URL.\n */\nfunction getTokenSearchURL(chainIds: CaipChainId[], query: string, limit = 10) {\n const encodedQuery = encodeURIComponent(query);\n const encodedChainIds = chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n return `${TOKEN_END_POINT_API}/tokens/search?chainIds=${encodedChainIds}&query=${encodedQuery}&limit=${limit}`;\n}\n\n/**\n * Get the trending tokens URL for the given networks and search query.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens URL.\n */\nfunction getTrendingTokensURL(options: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): string {\n const encodedChainIds = options.chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n // Add the rest of query params if they are defined\n const queryParams = new URLSearchParams();\n const { chainIds, ...rest } = options;\n Object.entries(rest).forEach(([key, value]) => {\n if (value !== undefined) {\n queryParams.append(key, String(value));\n }\n });\n\n return `${TOKEN_END_POINT_API}/v3/tokens/trending?chainIds=${encodedChainIds}${queryParams.toString() ? `&${queryParams.toString()}` : ''}`;\n}\n\nconst tenSecondsInMilliseconds = 10_000;\n\n// Token list averages 1.6 MB in size\n// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.\nconst defaultTimeout = tenSecondsInMilliseconds;\n\n/**\n * Fetch the list of token metadata for a given network. This request is cancellable using the\n * abort signal passed in.\n *\n * @param chainId - The chain ID of the network the requested tokens are on.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token list, or `undefined` if the request was cancelled.\n */\nexport async function fetchTokenListByChainId(\n chainId: Hex,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<unknown> {\n const tokenURL = getTokensURL(chainId);\n const response = await queryApi(tokenURL, abortSignal, timeout);\n if (response) {\n const result = await parseJsonResponse(response);\n if (Array.isArray(result) && chainId === ChainId['linea-mainnet']) {\n return result.filter(\n (elm) =>\n elm.aggregators.includes('lineaTeam') || elm.aggregators.length >= 3,\n );\n }\n return result;\n }\n return undefined;\n}\n\n/**\n * Search for tokens across one or more networks by query string using CAIP format chain IDs.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param query - The search query (token name, symbol, or address).\n * @param options - Additional fetch options.\n * @param options.limit - The maximum number of results to return.\n * @returns Object containing count and data array. Returns { count: 0, data: [] } if request fails.\n */\nexport async function searchTokens(\n chainIds: CaipChainId[],\n query: string,\n { limit = 10 } = {},\n): Promise<{ count: number; data: unknown[] }> {\n const tokenSearchURL = getTokenSearchURL(chainIds, query, limit);\n\n try {\n const result = await handleFetch(tokenSearchURL);\n\n // The API returns an object with structure: { count: number, data: array, pageInfo: object }\n if (result && typeof result === 'object' && Array.isArray(result.data)) {\n return {\n count: result.count || result.data.length,\n data: result.data,\n };\n }\n\n // Handle non-expected responses\n return { count: 0, data: [] };\n } catch (error) {\n // Handle 400 errors and other failures by returning count 0 and empty array\n console.log('Search request failed:', error);\n return { count: 0, data: [] };\n }\n}\n\n/**\n * The trending asset type.\n */\nexport type TrendingAsset = {\n assetId: string;\n name: string;\n symbol: string;\n decimals: number;\n price: string;\n aggregatedUsdVolume: number;\n marketCap: number;\n priceChangePct?: {\n m5?: string;\n m15?: string;\n m30?: string;\n h1?: string;\n h6?: string;\n h24?: string;\n };\n labels?: string[];\n};\n\n/**\n * Get the trending tokens for the given chains.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - The chains to get the trending tokens for.\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens.\n * @throws Will throw if the request fails.\n */\nexport async function getTrendingTokens({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n}: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): Promise<TrendingAsset[]> {\n if (chainIds.length === 0) {\n console.error('No chains provided');\n return [];\n }\n\n const trendingTokensURL = getTrendingTokensURL({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n });\n\n try {\n const result = await handleFetch(trendingTokensURL);\n\n // Validate that the API returned an array\n if (Array.isArray(result)) {\n return result;\n }\n\n // Handle non-expected responses\n console.error('Trending tokens API returned non-array response:', result);\n return [];\n } catch (error) {\n console.error('Trending tokens request failed:', error);\n return [];\n }\n}\n\n/**\n * Fetch metadata for the token address provided for a given network. This request is cancellable\n * using the abort signal passed in.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The address of the token to fetch metadata for.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token metadata, or `undefined` if the request was either aborted or failed.\n */\nexport async function fetchTokenMetadata<T>(\n chainId: Hex,\n tokenAddress: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<T | undefined> {\n if (!isTokenListSupportedForNetwork(chainId)) {\n throw new Error(TOKEN_METADATA_NO_SUPPORT_ERROR);\n }\n const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);\n const response = await queryApi(tokenMetadataURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response) as Promise<T>;\n }\n return undefined;\n}\n\n/**\n * Perform fetch request against the api.\n *\n * @param apiURL - The URL of the API to fetch.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param timeout - The fetch timeout.\n * @returns Promise resolving request response.\n */\nasync function queryApi(\n apiURL: string,\n abortSignal: AbortSignal,\n timeout: number,\n): Promise<Response | undefined> {\n const fetchOptions: RequestInit = {\n referrer: apiURL,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n signal: abortSignal,\n cache: 'default',\n };\n fetchOptions.headers = new window.Headers();\n fetchOptions.headers.set('Content-Type', 'application/json');\n try {\n return await timeoutFetch(apiURL, fetchOptions, timeout);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n console.log('Request is aborted');\n }\n }\n return undefined;\n}\n\n/**\n * Parse an API response and return the response JSON data.\n *\n * @param apiResponse - The API response to parse.\n * @returns The response JSON data.\n * @throws Will throw if the response includes an error.\n */\nasync function parseJsonResponse(apiResponse: Response): Promise<unknown> {\n const responseObj = await apiResponse.json();\n // api may return errors as json without setting an error http status code\n if (responseObj?.error) {\n throw new Error(`TokenService Error: ${responseObj.error}`);\n }\n return responseObj;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"token-service.d.cts","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,wBAAwB;AAIxD,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AACtE,eAAO,MAAM,+BAA+B,oEACuB,CAAC;AA6BpE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,aAAa,GACb,cAAc,CAAC;AA6DnB;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,EAAE,KAAU,EAAE;;CAAK,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAyB7C;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+B3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAUxB"}
1
+ {"version":3,"file":"token-service.d.cts","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,wBAAwB;AAIxD,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AACtE,eAAO,MAAM,+BAA+B,oEACuB,CAAC;AA6BpE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,aAAa,GACb,cAAc,CAAC;AA6DnB;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,EAAE,KAAU,EAAE;;CAAK,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAqB7C;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+B3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAUxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"token-service.d.mts","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,wBAAwB;AAIxD,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AACtE,eAAO,MAAM,+BAA+B,oEACuB,CAAC;AA6BpE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,aAAa,GACb,cAAc,CAAC;AA6DnB;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,EAAE,KAAU,EAAE;;CAAK,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAyB7C;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+B3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAUxB"}
1
+ {"version":3,"file":"token-service.d.mts","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,wBAAwB;AAIxD,eAAO,MAAM,mBAAmB,qCAAqC,CAAC;AACtE,eAAO,MAAM,+BAA+B,oEACuB,CAAC;AA6BpE;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,aAAa,GACb,aAAa,GACb,cAAc,CAAC;AA6DnB;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,GAAG,EACZ,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,OAAO,CAAC,CAclB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,EAAE,KAAU,EAAE;;CAAK,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAqB7C;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE;QACf,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,GACb,EAAE;IACD,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+B3B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,EACxB,EAAE,OAAwB,EAAE;;CAAK,GAChC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAUxB"}
@@ -100,9 +100,6 @@ export async function fetchTokenListByChainId(chainId, abortSignal, { timeout =
100
100
  * @returns Object containing count and data array. Returns { count: 0, data: [] } if request fails.
101
101
  */
102
102
  export async function searchTokens(chainIds, query, { limit = 10 } = {}) {
103
- if (chainIds.length === 0) {
104
- return { count: 0, data: [] };
105
- }
106
103
  const tokenSearchURL = getTokenSearchURL(chainIds, query, limit);
107
104
  try {
108
105
  const result = await handleFetch(tokenSearchURL);
@@ -1 +1 @@
1
- {"version":3,"file":"token-service.mjs","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChainId,\n convertHexToDecimal,\n handleFetch,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport { isTokenListSupportedForNetwork } from './assetsUtil';\n\nexport const TOKEN_END_POINT_API = 'https://token.api.cx.metamask.io';\nexport const TOKEN_METADATA_NO_SUPPORT_ERROR =\n 'TokenService Error: Network does not support fetchTokenMetadata';\n\n/**\n * Get the tokens URL for a specific network.\n *\n * @param chainId - The chain ID of the network the tokens requested are on.\n * @returns The tokens URL.\n */\nfunction getTokensURL(chainId: Hex) {\n const occurrenceFloor = chainId === ChainId['linea-mainnet'] ? 1 : 3;\n\n return `${TOKEN_END_POINT_API}/tokens/${convertHexToDecimal(\n chainId,\n )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`;\n}\n\n/**\n * Get the token metadata URL for the given network and token.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The token address.\n * @returns The token metadata URL.\n */\nfunction getTokenMetadataURL(chainId: Hex, tokenAddress: string) {\n return `${TOKEN_END_POINT_API}/token/${convertHexToDecimal(\n chainId,\n )}?address=${tokenAddress}`;\n}\n\n/**\n * The sort by field for trending tokens.\n */\nexport type SortTrendingBy =\n | 'm5_trending'\n | 'h1_trending'\n | 'h6_trending'\n | 'h24_trending';\n\n/**\n * Get the token search URL for the given networks and search query.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., 'eip155:1', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp').\n * @param query - The search query (token name, symbol, or address).\n * @param limit - Optional limit for the number of results (defaults to 10).\n * @returns The token search URL.\n */\nfunction getTokenSearchURL(chainIds: CaipChainId[], query: string, limit = 10) {\n const encodedQuery = encodeURIComponent(query);\n const encodedChainIds = chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n return `${TOKEN_END_POINT_API}/tokens/search?chainIds=${encodedChainIds}&query=${encodedQuery}&limit=${limit}`;\n}\n\n/**\n * Get the trending tokens URL for the given networks and search query.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens URL.\n */\nfunction getTrendingTokensURL(options: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): string {\n const encodedChainIds = options.chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n // Add the rest of query params if they are defined\n const queryParams = new URLSearchParams();\n const { chainIds, ...rest } = options;\n Object.entries(rest).forEach(([key, value]) => {\n if (value !== undefined) {\n queryParams.append(key, String(value));\n }\n });\n\n return `${TOKEN_END_POINT_API}/v3/tokens/trending?chainIds=${encodedChainIds}${queryParams.toString() ? `&${queryParams.toString()}` : ''}`;\n}\n\nconst tenSecondsInMilliseconds = 10_000;\n\n// Token list averages 1.6 MB in size\n// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.\nconst defaultTimeout = tenSecondsInMilliseconds;\n\n/**\n * Fetch the list of token metadata for a given network. This request is cancellable using the\n * abort signal passed in.\n *\n * @param chainId - The chain ID of the network the requested tokens are on.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token list, or `undefined` if the request was cancelled.\n */\nexport async function fetchTokenListByChainId(\n chainId: Hex,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<unknown> {\n const tokenURL = getTokensURL(chainId);\n const response = await queryApi(tokenURL, abortSignal, timeout);\n if (response) {\n const result = await parseJsonResponse(response);\n if (Array.isArray(result) && chainId === ChainId['linea-mainnet']) {\n return result.filter(\n (elm) =>\n elm.aggregators.includes('lineaTeam') || elm.aggregators.length >= 3,\n );\n }\n return result;\n }\n return undefined;\n}\n\n/**\n * Search for tokens across one or more networks by query string using CAIP format chain IDs.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param query - The search query (token name, symbol, or address).\n * @param options - Additional fetch options.\n * @param options.limit - The maximum number of results to return.\n * @returns Object containing count and data array. Returns { count: 0, data: [] } if request fails.\n */\nexport async function searchTokens(\n chainIds: CaipChainId[],\n query: string,\n { limit = 10 } = {},\n): Promise<{ count: number; data: unknown[] }> {\n if (chainIds.length === 0) {\n return { count: 0, data: [] };\n }\n\n const tokenSearchURL = getTokenSearchURL(chainIds, query, limit);\n\n try {\n const result = await handleFetch(tokenSearchURL);\n\n // The API returns an object with structure: { count: number, data: array, pageInfo: object }\n if (result && typeof result === 'object' && Array.isArray(result.data)) {\n return {\n count: result.count || result.data.length,\n data: result.data,\n };\n }\n\n // Handle non-expected responses\n return { count: 0, data: [] };\n } catch (error) {\n // Handle 400 errors and other failures by returning count 0 and empty array\n console.log('Search request failed:', error);\n return { count: 0, data: [] };\n }\n}\n\n/**\n * The trending asset type.\n */\nexport type TrendingAsset = {\n assetId: string;\n name: string;\n symbol: string;\n decimals: number;\n price: string;\n aggregatedUsdVolume: number;\n marketCap: number;\n priceChangePct?: {\n m5?: string;\n m15?: string;\n m30?: string;\n h1?: string;\n h6?: string;\n h24?: string;\n };\n labels?: string[];\n};\n\n/**\n * Get the trending tokens for the given chains.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - The chains to get the trending tokens for.\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens.\n * @throws Will throw if the request fails.\n */\nexport async function getTrendingTokens({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n}: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): Promise<TrendingAsset[]> {\n if (chainIds.length === 0) {\n console.error('No chains provided');\n return [];\n }\n\n const trendingTokensURL = getTrendingTokensURL({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n });\n\n try {\n const result = await handleFetch(trendingTokensURL);\n\n // Validate that the API returned an array\n if (Array.isArray(result)) {\n return result;\n }\n\n // Handle non-expected responses\n console.error('Trending tokens API returned non-array response:', result);\n return [];\n } catch (error) {\n console.error('Trending tokens request failed:', error);\n return [];\n }\n}\n\n/**\n * Fetch metadata for the token address provided for a given network. This request is cancellable\n * using the abort signal passed in.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The address of the token to fetch metadata for.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token metadata, or `undefined` if the request was either aborted or failed.\n */\nexport async function fetchTokenMetadata<T>(\n chainId: Hex,\n tokenAddress: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<T | undefined> {\n if (!isTokenListSupportedForNetwork(chainId)) {\n throw new Error(TOKEN_METADATA_NO_SUPPORT_ERROR);\n }\n const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);\n const response = await queryApi(tokenMetadataURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response) as Promise<T>;\n }\n return undefined;\n}\n\n/**\n * Perform fetch request against the api.\n *\n * @param apiURL - The URL of the API to fetch.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param timeout - The fetch timeout.\n * @returns Promise resolving request response.\n */\nasync function queryApi(\n apiURL: string,\n abortSignal: AbortSignal,\n timeout: number,\n): Promise<Response | undefined> {\n const fetchOptions: RequestInit = {\n referrer: apiURL,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n signal: abortSignal,\n cache: 'default',\n };\n fetchOptions.headers = new window.Headers();\n fetchOptions.headers.set('Content-Type', 'application/json');\n try {\n return await timeoutFetch(apiURL, fetchOptions, timeout);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n console.log('Request is aborted');\n }\n }\n return undefined;\n}\n\n/**\n * Parse an API response and return the response JSON data.\n *\n * @param apiResponse - The API response to parse.\n * @returns The response JSON data.\n * @throws Will throw if the response includes an error.\n */\nasync function parseJsonResponse(apiResponse: Response): Promise<unknown> {\n const responseObj = await apiResponse.json();\n // api may return errors as json without setting an error http status code\n if (responseObj?.error) {\n throw new Error(`TokenService Error: ${responseObj.error}`);\n }\n return responseObj;\n}\n"]}
1
+ {"version":3,"file":"token-service.mjs","sourceRoot":"","sources":["../src/token-service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ChainId,\n convertHexToDecimal,\n handleFetch,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport type { CaipChainId, Hex } from '@metamask/utils';\n\nimport { isTokenListSupportedForNetwork } from './assetsUtil';\n\nexport const TOKEN_END_POINT_API = 'https://token.api.cx.metamask.io';\nexport const TOKEN_METADATA_NO_SUPPORT_ERROR =\n 'TokenService Error: Network does not support fetchTokenMetadata';\n\n/**\n * Get the tokens URL for a specific network.\n *\n * @param chainId - The chain ID of the network the tokens requested are on.\n * @returns The tokens URL.\n */\nfunction getTokensURL(chainId: Hex) {\n const occurrenceFloor = chainId === ChainId['linea-mainnet'] ? 1 : 3;\n\n return `${TOKEN_END_POINT_API}/tokens/${convertHexToDecimal(\n chainId,\n )}?occurrenceFloor=${occurrenceFloor}&includeNativeAssets=false&includeTokenFees=false&includeAssetType=false&includeERC20Permit=false&includeStorage=false`;\n}\n\n/**\n * Get the token metadata URL for the given network and token.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The token address.\n * @returns The token metadata URL.\n */\nfunction getTokenMetadataURL(chainId: Hex, tokenAddress: string) {\n return `${TOKEN_END_POINT_API}/token/${convertHexToDecimal(\n chainId,\n )}?address=${tokenAddress}`;\n}\n\n/**\n * The sort by field for trending tokens.\n */\nexport type SortTrendingBy =\n | 'm5_trending'\n | 'h1_trending'\n | 'h6_trending'\n | 'h24_trending';\n\n/**\n * Get the token search URL for the given networks and search query.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., 'eip155:1', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp').\n * @param query - The search query (token name, symbol, or address).\n * @param limit - Optional limit for the number of results (defaults to 10).\n * @returns The token search URL.\n */\nfunction getTokenSearchURL(chainIds: CaipChainId[], query: string, limit = 10) {\n const encodedQuery = encodeURIComponent(query);\n const encodedChainIds = chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n return `${TOKEN_END_POINT_API}/tokens/search?chainIds=${encodedChainIds}&query=${encodedQuery}&limit=${limit}`;\n}\n\n/**\n * Get the trending tokens URL for the given networks and search query.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens URL.\n */\nfunction getTrendingTokensURL(options: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): string {\n const encodedChainIds = options.chainIds\n .map((id) => encodeURIComponent(id))\n .join(',');\n // Add the rest of query params if they are defined\n const queryParams = new URLSearchParams();\n const { chainIds, ...rest } = options;\n Object.entries(rest).forEach(([key, value]) => {\n if (value !== undefined) {\n queryParams.append(key, String(value));\n }\n });\n\n return `${TOKEN_END_POINT_API}/v3/tokens/trending?chainIds=${encodedChainIds}${queryParams.toString() ? `&${queryParams.toString()}` : ''}`;\n}\n\nconst tenSecondsInMilliseconds = 10_000;\n\n// Token list averages 1.6 MB in size\n// timeoutFetch by default has a 500ms timeout, which will almost always timeout given the response size.\nconst defaultTimeout = tenSecondsInMilliseconds;\n\n/**\n * Fetch the list of token metadata for a given network. This request is cancellable using the\n * abort signal passed in.\n *\n * @param chainId - The chain ID of the network the requested tokens are on.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token list, or `undefined` if the request was cancelled.\n */\nexport async function fetchTokenListByChainId(\n chainId: Hex,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<unknown> {\n const tokenURL = getTokensURL(chainId);\n const response = await queryApi(tokenURL, abortSignal, timeout);\n if (response) {\n const result = await parseJsonResponse(response);\n if (Array.isArray(result) && chainId === ChainId['linea-mainnet']) {\n return result.filter(\n (elm) =>\n elm.aggregators.includes('lineaTeam') || elm.aggregators.length >= 3,\n );\n }\n return result;\n }\n return undefined;\n}\n\n/**\n * Search for tokens across one or more networks by query string using CAIP format chain IDs.\n *\n * @param chainIds - Array of CAIP format chain IDs (e.g., ['eip155:1', 'eip155:137', 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp']).\n * @param query - The search query (token name, symbol, or address).\n * @param options - Additional fetch options.\n * @param options.limit - The maximum number of results to return.\n * @returns Object containing count and data array. Returns { count: 0, data: [] } if request fails.\n */\nexport async function searchTokens(\n chainIds: CaipChainId[],\n query: string,\n { limit = 10 } = {},\n): Promise<{ count: number; data: unknown[] }> {\n const tokenSearchURL = getTokenSearchURL(chainIds, query, limit);\n\n try {\n const result = await handleFetch(tokenSearchURL);\n\n // The API returns an object with structure: { count: number, data: array, pageInfo: object }\n if (result && typeof result === 'object' && Array.isArray(result.data)) {\n return {\n count: result.count || result.data.length,\n data: result.data,\n };\n }\n\n // Handle non-expected responses\n return { count: 0, data: [] };\n } catch (error) {\n // Handle 400 errors and other failures by returning count 0 and empty array\n console.log('Search request failed:', error);\n return { count: 0, data: [] };\n }\n}\n\n/**\n * The trending asset type.\n */\nexport type TrendingAsset = {\n assetId: string;\n name: string;\n symbol: string;\n decimals: number;\n price: string;\n aggregatedUsdVolume: number;\n marketCap: number;\n priceChangePct?: {\n m5?: string;\n m15?: string;\n m30?: string;\n h1?: string;\n h6?: string;\n h24?: string;\n };\n labels?: string[];\n};\n\n/**\n * Get the trending tokens for the given chains.\n *\n * @param options - Options for getting trending tokens.\n * @param options.chainIds - The chains to get the trending tokens for.\n * @param options.sortBy - The sort by field.\n * @param options.minLiquidity - The minimum liquidity.\n * @param options.minVolume24hUsd - The minimum volume 24h in USD.\n * @param options.maxVolume24hUsd - The maximum volume 24h in USD.\n * @param options.minMarketCap - The minimum market cap.\n * @param options.maxMarketCap - The maximum market cap.\n * @returns The trending tokens.\n * @throws Will throw if the request fails.\n */\nexport async function getTrendingTokens({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n}: {\n chainIds: CaipChainId[];\n sortBy?: SortTrendingBy;\n minLiquidity?: number;\n minVolume24hUsd?: number;\n maxVolume24hUsd?: number;\n minMarketCap?: number;\n maxMarketCap?: number;\n}): Promise<TrendingAsset[]> {\n if (chainIds.length === 0) {\n console.error('No chains provided');\n return [];\n }\n\n const trendingTokensURL = getTrendingTokensURL({\n chainIds,\n sortBy,\n minLiquidity,\n minVolume24hUsd,\n maxVolume24hUsd,\n minMarketCap,\n maxMarketCap,\n });\n\n try {\n const result = await handleFetch(trendingTokensURL);\n\n // Validate that the API returned an array\n if (Array.isArray(result)) {\n return result;\n }\n\n // Handle non-expected responses\n console.error('Trending tokens API returned non-array response:', result);\n return [];\n } catch (error) {\n console.error('Trending tokens request failed:', error);\n return [];\n }\n}\n\n/**\n * Fetch metadata for the token address provided for a given network. This request is cancellable\n * using the abort signal passed in.\n *\n * @param chainId - The chain ID of the network the token is on.\n * @param tokenAddress - The address of the token to fetch metadata for.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param options - Additional fetch options.\n * @param options.timeout - The fetch timeout.\n * @returns The token metadata, or `undefined` if the request was either aborted or failed.\n */\nexport async function fetchTokenMetadata<T>(\n chainId: Hex,\n tokenAddress: string,\n abortSignal: AbortSignal,\n { timeout = defaultTimeout } = {},\n): Promise<T | undefined> {\n if (!isTokenListSupportedForNetwork(chainId)) {\n throw new Error(TOKEN_METADATA_NO_SUPPORT_ERROR);\n }\n const tokenMetadataURL = getTokenMetadataURL(chainId, tokenAddress);\n const response = await queryApi(tokenMetadataURL, abortSignal, timeout);\n if (response) {\n return parseJsonResponse(response) as Promise<T>;\n }\n return undefined;\n}\n\n/**\n * Perform fetch request against the api.\n *\n * @param apiURL - The URL of the API to fetch.\n * @param abortSignal - The abort signal used to cancel the request if necessary.\n * @param timeout - The fetch timeout.\n * @returns Promise resolving request response.\n */\nasync function queryApi(\n apiURL: string,\n abortSignal: AbortSignal,\n timeout: number,\n): Promise<Response | undefined> {\n const fetchOptions: RequestInit = {\n referrer: apiURL,\n referrerPolicy: 'no-referrer-when-downgrade',\n method: 'GET',\n mode: 'cors',\n signal: abortSignal,\n cache: 'default',\n };\n fetchOptions.headers = new window.Headers();\n fetchOptions.headers.set('Content-Type', 'application/json');\n try {\n return await timeoutFetch(apiURL, fetchOptions, timeout);\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n console.log('Request is aborted');\n }\n }\n return undefined;\n}\n\n/**\n * Parse an API response and return the response JSON data.\n *\n * @param apiResponse - The API response to parse.\n * @returns The response JSON data.\n * @throws Will throw if the response includes an error.\n */\nasync function parseJsonResponse(apiResponse: Response): Promise<unknown> {\n const responseObj = await apiResponse.json();\n // api may return errors as json without setting an error http status code\n if (responseObj?.error) {\n throw new Error(`TokenService Error: ${responseObj.error}`);\n }\n return responseObj;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.cjs","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"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","sourcesContent":["const FALLBACK_LOCALE = 'en';\n\nconst twoDecimals = {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n};\n\nconst oneSignificantDigit = {\n minimumSignificantDigits: 1,\n maximumSignificantDigits: 1,\n};\n\nconst threeSignificantDigits = {\n minimumSignificantDigits: 3,\n maximumSignificantDigits: 3,\n};\n\nconst numberFormatCache: Record<string, Intl.NumberFormat> = {};\n\n/**\n * Get cached number format instance.\n *\n * @param locale - Locale string.\n * @param options - Optional Intl.NumberFormat options.\n * @returns Cached Intl.NumberFormat instance.\n */\nfunction getCachedNumberFormat(\n locale: string,\n options: Intl.NumberFormatOptions = {},\n) {\n const key = `${locale}_${JSON.stringify(options)}`;\n\n let format = numberFormatCache[key];\n\n if (format) {\n return format;\n }\n\n try {\n format = new Intl.NumberFormat(locale, options);\n } catch (error) {\n if (error instanceof RangeError) {\n // Fallback for invalid options (e.g. currency code)\n format = new Intl.NumberFormat(locale, twoDecimals);\n } else {\n throw error;\n }\n }\n\n numberFormatCache[key] = format;\n return format;\n}\n\n/**\n * Format a number with optional Intl overrides.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted number string.\n */\nfunction formatNumber(\n config: { locale: string },\n value: number | bigint | `${number}`,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, options);\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Format a value as a currency string.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted currency string.\n */\nfunction formatCurrency(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'currency',\n currency,\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Compact currency formatting (e.g. $1.2K, $3.4M).\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted compact currency string.\n */\nfunction formatCurrencyCompact(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n return formatCurrency(config, value, currency, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Currency formatting with minimum threshold for small values.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted currency string with threshold handling.\n */\nfunction formatCurrencyWithMinThreshold(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.01;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n const formattedMin = formatCurrency(config, minThreshold, currency);\n return `<${formattedMin}`;\n }\n\n return formatCurrency(config, number, currency);\n}\n\n/**\n * Format a value as a token string with symbol.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted token string.\n */\nfunction formatToken(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'decimal',\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n const formattedNumber = numberFormat.format(value);\n\n return `${formattedNumber} ${symbol}`;\n}\n\n/**\n * Format token price with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted token price string.\n */\nfunction formatCurrencyTokenPrice(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.00000001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatCurrency(config, minThreshold, currency, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatCurrency(config, number, currency, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatCurrency(config, number, currency);\n }\n\n return formatCurrencyCompact(config, number, currency);\n}\n\n/**\n * Format token quantity with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @returns Formatted token quantity string.\n */\nfunction formatTokenQuantity(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n) {\n const minThreshold = 0.00001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatToken(config, 0, symbol);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatToken(config, minThreshold, symbol, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatToken(config, number, symbol, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatToken(config, number, symbol);\n }\n\n return formatToken(config, number, symbol, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Create formatter functions with the given locale.\n *\n * @param options - Configuration options.\n * @param options.locale - Locale string.\n * @returns Object with formatter functions.\n */\nexport function createFormatters({ locale = FALLBACK_LOCALE }) {\n return {\n /**\n * Format a number with optional Intl overrides.\n *\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatNumber: formatNumber.bind(null, { locale }),\n /**\n * Format a value as a currency string.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code (e.g. 'USD').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatCurrency: formatCurrency.bind(null, { locale }),\n /**\n * Compact currency (e.g. $1.2K, $3.4M) with up to two decimal digits.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyCompact: formatCurrencyCompact.bind(null, { locale }),\n /**\n * Currency with thresholds for small values.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyWithMinThreshold: formatCurrencyWithMinThreshold.bind(null, {\n locale,\n }),\n /**\n * Format token price with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyTokenPrice: formatCurrencyTokenPrice.bind(null, { locale }),\n /**\n * Format a value as a token string with symbol.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatToken: formatToken.bind(null, { locale }),\n /**\n * Format token quantity with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n */\n formatTokenQuantity: formatTokenQuantity.bind(null, { locale }),\n };\n}\n"]}
1
+ {"version":3,"file":"formatters.cjs","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"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","sourcesContent":["const FALLBACK_LOCALE = 'en';\n\nconst twoDecimals = {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n};\n\nconst oneSignificantDigit = {\n minimumSignificantDigits: 1,\n maximumSignificantDigits: 1,\n};\n\nconst threeSignificantDigits = {\n minimumSignificantDigits: 3,\n maximumSignificantDigits: 3,\n};\n\nconst numberFormatCache: Record<string, Intl.NumberFormat> = {};\n\n/**\n * Get cached number format instance.\n *\n * @param locale - Locale string.\n * @param options - Optional Intl.NumberFormat options.\n * @returns Cached Intl.NumberFormat instance.\n */\nfunction getCachedNumberFormat(\n locale: string,\n options: Intl.NumberFormatOptions = {},\n) {\n const key = `${locale}_${JSON.stringify(options)}`;\n\n let format = numberFormatCache[key];\n\n if (format) {\n return format;\n }\n\n try {\n format = new Intl.NumberFormat(locale, options);\n } catch (error) {\n if (error instanceof RangeError) {\n // Fallback for invalid options (e.g. currency code)\n format = new Intl.NumberFormat(locale, twoDecimals);\n } else {\n throw error;\n }\n }\n\n numberFormatCache[key] = format;\n return format;\n}\n\n/**\n * Format a number with optional Intl overrides.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted number string.\n */\nfunction formatNumber(\n config: { locale: string },\n value: number | bigint | `${number}`,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, options);\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Format a value as a currency string.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted currency string.\n */\nfunction formatCurrency(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'currency',\n currency,\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Compact currency formatting (e.g. $1.2K, $3.4M).\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted compact currency string.\n */\nfunction formatCurrencyCompact(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n return formatCurrency(config, value, currency, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Currency formatting with minimum threshold for small values.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted currency string with threshold handling.\n */\nfunction formatCurrencyWithMinThreshold(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.01;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n const formattedMin = formatCurrency(config, minThreshold, currency);\n return `<${formattedMin}`;\n }\n\n return formatCurrency(config, number, currency);\n}\n\n/**\n * Format a value as a token string with symbol.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted token string.\n */\nfunction formatToken(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'decimal',\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n const formattedNumber = numberFormat.format(value);\n\n return `${formattedNumber} ${symbol}`;\n}\n\n/**\n * Format token price with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted token price string.\n */\nfunction formatCurrencyTokenPrice(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.00000001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatCurrency(config, minThreshold, currency, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatCurrency(config, number, currency, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatCurrency(config, number, currency);\n }\n\n return formatCurrencyCompact(config, number, currency);\n}\n\n/**\n * Format token quantity with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @returns Formatted token quantity string.\n */\nfunction formatTokenQuantity(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n) {\n const minThreshold = 0.00001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatToken(config, 0, symbol);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatToken(config, minThreshold, symbol, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatToken(config, number, symbol, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatToken(config, number, symbol);\n }\n\n return formatToken(config, number, symbol, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Create formatter functions with the given locale.\n *\n * @param options - Configuration options.\n * @param options.locale - Locale string.\n * @returns Object with formatter functions.\n */\nexport function createFormatters({ locale = FALLBACK_LOCALE }) {\n return {\n /**\n * Format a number with optional Intl overrides.\n *\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatNumber: formatNumber.bind(null, { locale }),\n /**\n * Format a value as a currency string.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code (e.g. 'USD').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatCurrency: formatCurrency.bind(null, { locale }),\n /**\n * Compact currency (e.g. $1.2K, $3.4M) with up to two decimal digits.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyCompact: formatCurrencyCompact.bind(null, { locale }),\n /**\n * Currency with thresholds for small values.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyWithMinThreshold: formatCurrencyWithMinThreshold.bind(null, {\n locale,\n }),\n /**\n * Format token price with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyTokenPrice: formatCurrencyTokenPrice.bind(null, { locale }),\n /**\n * Format a value as a token string with symbol.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatToken: formatToken.bind(null, { locale }),\n /**\n * Format token quantity with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n */\n formatTokenQuantity: formatTokenQuantity.bind(null, { locale }),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"formatters.mjs","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"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","sourcesContent":["const FALLBACK_LOCALE = 'en';\n\nconst twoDecimals = {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n};\n\nconst oneSignificantDigit = {\n minimumSignificantDigits: 1,\n maximumSignificantDigits: 1,\n};\n\nconst threeSignificantDigits = {\n minimumSignificantDigits: 3,\n maximumSignificantDigits: 3,\n};\n\nconst numberFormatCache: Record<string, Intl.NumberFormat> = {};\n\n/**\n * Get cached number format instance.\n *\n * @param locale - Locale string.\n * @param options - Optional Intl.NumberFormat options.\n * @returns Cached Intl.NumberFormat instance.\n */\nfunction getCachedNumberFormat(\n locale: string,\n options: Intl.NumberFormatOptions = {},\n) {\n const key = `${locale}_${JSON.stringify(options)}`;\n\n let format = numberFormatCache[key];\n\n if (format) {\n return format;\n }\n\n try {\n format = new Intl.NumberFormat(locale, options);\n } catch (error) {\n if (error instanceof RangeError) {\n // Fallback for invalid options (e.g. currency code)\n format = new Intl.NumberFormat(locale, twoDecimals);\n } else {\n throw error;\n }\n }\n\n numberFormatCache[key] = format;\n return format;\n}\n\n/**\n * Format a number with optional Intl overrides.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted number string.\n */\nfunction formatNumber(\n config: { locale: string },\n value: number | bigint | `${number}`,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, options);\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Format a value as a currency string.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted currency string.\n */\nfunction formatCurrency(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'currency',\n currency,\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Compact currency formatting (e.g. $1.2K, $3.4M).\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted compact currency string.\n */\nfunction formatCurrencyCompact(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n return formatCurrency(config, value, currency, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Currency formatting with minimum threshold for small values.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted currency string with threshold handling.\n */\nfunction formatCurrencyWithMinThreshold(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.01;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n const formattedMin = formatCurrency(config, minThreshold, currency);\n return `<${formattedMin}`;\n }\n\n return formatCurrency(config, number, currency);\n}\n\n/**\n * Format a value as a token string with symbol.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted token string.\n */\nfunction formatToken(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'decimal',\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n const formattedNumber = numberFormat.format(value);\n\n return `${formattedNumber} ${symbol}`;\n}\n\n/**\n * Format token price with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted token price string.\n */\nfunction formatCurrencyTokenPrice(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.00000001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatCurrency(config, minThreshold, currency, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatCurrency(config, number, currency, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatCurrency(config, number, currency);\n }\n\n return formatCurrencyCompact(config, number, currency);\n}\n\n/**\n * Format token quantity with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @returns Formatted token quantity string.\n */\nfunction formatTokenQuantity(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n) {\n const minThreshold = 0.00001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatToken(config, 0, symbol);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatToken(config, minThreshold, symbol, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatToken(config, number, symbol, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatToken(config, number, symbol);\n }\n\n return formatToken(config, number, symbol, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Create formatter functions with the given locale.\n *\n * @param options - Configuration options.\n * @param options.locale - Locale string.\n * @returns Object with formatter functions.\n */\nexport function createFormatters({ locale = FALLBACK_LOCALE }) {\n return {\n /**\n * Format a number with optional Intl overrides.\n *\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatNumber: formatNumber.bind(null, { locale }),\n /**\n * Format a value as a currency string.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code (e.g. 'USD').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatCurrency: formatCurrency.bind(null, { locale }),\n /**\n * Compact currency (e.g. $1.2K, $3.4M) with up to two decimal digits.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyCompact: formatCurrencyCompact.bind(null, { locale }),\n /**\n * Currency with thresholds for small values.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyWithMinThreshold: formatCurrencyWithMinThreshold.bind(null, {\n locale,\n }),\n /**\n * Format token price with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyTokenPrice: formatCurrencyTokenPrice.bind(null, { locale }),\n /**\n * Format a value as a token string with symbol.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatToken: formatToken.bind(null, { locale }),\n /**\n * Format token quantity with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n */\n formatTokenQuantity: formatTokenQuantity.bind(null, { locale }),\n };\n}\n"]}
1
+ {"version":3,"file":"formatters.mjs","sourceRoot":"","sources":["../../src/utils/formatters.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,MAAM,WAAW,GAAG;IAClB,qBAAqB,EAAE,CAAC;IACxB,qBAAqB,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,mBAAmB,GAAG;IAC1B,wBAAwB,EAAE,CAAC;IAC3B,wBAAwB,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,sBAAsB,GAAG;IAC7B,wBAAwB,EAAE,CAAC;IAC3B,wBAAwB,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,iBAAiB,GAAsC,EAAE,CAAC;AAEhE;;;;;;GAMG;AACH,SAAS,qBAAqB,CAC5B,MAAc,EACd,UAAoC,EAAE;IAEtC,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;IAEnD,IAAI,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;YAChC,oDAAoD;YACpD,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,iBAAiB,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CACnB,MAA0B,EAC1B,KAAoC,EACpC,UAAoC,EAAE;IAEtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,YAAY,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnE,0EAA0E;IAC1E,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,cAAc,CACrB,MAA0B,EAC1B,KAAoC,EACpC,QAA8C,EAC9C,UAAoC,EAAE;IAEtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,YAAY,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE;QACxD,KAAK,EAAE,UAAU;QACjB,QAAQ;QACR,GAAG,OAAO;KACX,CAAC,CAAC;IAEH,0EAA0E;IAC1E,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,qBAAqB,CAC5B,MAA0B,EAC1B,KAAoC,EACpC,QAA8C;IAE9C,OAAO,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;QAC7C,QAAQ,EAAE,SAAS;QACnB,GAAG,WAAW;KACf,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,8BAA8B,CACrC,MAA0B,EAC1B,KAAoC,EACpC,QAA8C;IAE9C,MAAM,YAAY,GAAG,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,aAAa,GAAG,YAAY,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;QACpE,OAAO,IAAI,YAAY,EAAE,CAAC;IAC5B,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,WAAW,CAClB,MAA0B,EAC1B,KAAoC,EACpC,MAAc,EACd,UAAoC,EAAE;IAEtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,YAAY,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE;QACxD,KAAK,EAAE,SAAS;QAChB,GAAG,OAAO;KACX,CAAC,CAAC;IAEH,0EAA0E;IAC1E,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEnD,OAAO,GAAG,eAAe,IAAI,MAAM,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,wBAAwB,CAC/B,MAA0B,EAC1B,KAAoC,EACpC,QAA8C;IAE9C,MAAM,YAAY,GAAG,UAAU,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,aAAa,GAAG,YAAY,EAAE,CAAC;QACjC,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,mBAAmB,CAAC,EAAE,CAAC;IACnF,CAAC;IAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,aAAa,GAAG,OAAS,EAAE,CAAC;QAC9B,OAAO,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,mBAAmB,CAC1B,MAA0B,EAC1B,KAAoC,EACpC,MAAc;IAEd,MAAM,YAAY,GAAG,OAAO,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,aAAa,GAAG,YAAY,EAAE,CAAC;QACjC,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC;IAC9E,CAAC;IAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,aAAa,GAAG,OAAS,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;QACzC,QAAQ,EAAE,SAAS;QACnB,GAAG,WAAW;KACf,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE;IAC3D,OAAO;QACL;;;;;WAKG;QACH,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;QACjD;;;;;;WAMG;QACH,cAAc,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;QACrD;;;;;WAKG;QACH,qBAAqB,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;QACnE;;;;;WAKG;QACH,8BAA8B,EAAE,8BAA8B,CAAC,IAAI,CAAC,IAAI,EAAE;YACxE,MAAM;SACP,CAAC;QACF;;;;;WAKG;QACH,wBAAwB,EAAE,wBAAwB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;QACzE;;;;;;WAMG;QACH,WAAW,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;QAC/C;;;;;WAKG;QACH,mBAAmB,EAAE,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC;KAChE,CAAC;AACJ,CAAC","sourcesContent":["const FALLBACK_LOCALE = 'en';\n\nconst twoDecimals = {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n};\n\nconst oneSignificantDigit = {\n minimumSignificantDigits: 1,\n maximumSignificantDigits: 1,\n};\n\nconst threeSignificantDigits = {\n minimumSignificantDigits: 3,\n maximumSignificantDigits: 3,\n};\n\nconst numberFormatCache: Record<string, Intl.NumberFormat> = {};\n\n/**\n * Get cached number format instance.\n *\n * @param locale - Locale string.\n * @param options - Optional Intl.NumberFormat options.\n * @returns Cached Intl.NumberFormat instance.\n */\nfunction getCachedNumberFormat(\n locale: string,\n options: Intl.NumberFormatOptions = {},\n) {\n const key = `${locale}_${JSON.stringify(options)}`;\n\n let format = numberFormatCache[key];\n\n if (format) {\n return format;\n }\n\n try {\n format = new Intl.NumberFormat(locale, options);\n } catch (error) {\n if (error instanceof RangeError) {\n // Fallback for invalid options (e.g. currency code)\n format = new Intl.NumberFormat(locale, twoDecimals);\n } else {\n throw error;\n }\n }\n\n numberFormatCache[key] = format;\n return format;\n}\n\n/**\n * Format a number with optional Intl overrides.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted number string.\n */\nfunction formatNumber(\n config: { locale: string },\n value: number | bigint | `${number}`,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, options);\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Format a value as a currency string.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted currency string.\n */\nfunction formatCurrency(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'currency',\n currency,\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n return numberFormat.format(value);\n}\n\n/**\n * Compact currency formatting (e.g. $1.2K, $3.4M).\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted compact currency string.\n */\nfunction formatCurrencyCompact(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n return formatCurrency(config, value, currency, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Currency formatting with minimum threshold for small values.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted currency string with threshold handling.\n */\nfunction formatCurrencyWithMinThreshold(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.01;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n const formattedMin = formatCurrency(config, minThreshold, currency);\n return `<${formattedMin}`;\n }\n\n return formatCurrency(config, number, currency);\n}\n\n/**\n * Format a value as a token string with symbol.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @param options - Optional Intl.NumberFormat overrides.\n * @returns Formatted token string.\n */\nfunction formatToken(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n options: Intl.NumberFormatOptions = {},\n) {\n if (!Number.isFinite(Number(value))) {\n return '';\n }\n\n const numberFormat = getCachedNumberFormat(config.locale, {\n style: 'decimal',\n ...options,\n });\n\n // @ts-expect-error Remove this comment once TypeScript is updated to 5.5+\n const formattedNumber = numberFormat.format(value);\n\n return `${formattedNumber} ${symbol}`;\n}\n\n/**\n * Format token price with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n * @returns Formatted token price string.\n */\nfunction formatCurrencyTokenPrice(\n config: { locale: string },\n value: number | bigint | `${number}`,\n currency: Intl.NumberFormatOptions['currency'],\n) {\n const minThreshold = 0.00000001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatCurrency(config, 0, currency);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatCurrency(config, minThreshold, currency, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatCurrency(config, number, currency, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatCurrency(config, number, currency);\n }\n\n return formatCurrencyCompact(config, number, currency);\n}\n\n/**\n * Format token quantity with varying precision based on value.\n *\n * @param config - Configuration object with locale.\n * @param config.locale - Locale string.\n * @param value - Numeric value to format.\n * @param symbol - Token symbol.\n * @returns Formatted token quantity string.\n */\nfunction formatTokenQuantity(\n config: { locale: string },\n value: number | bigint | `${number}`,\n symbol: string,\n) {\n const minThreshold = 0.00001;\n const number = Number(value);\n const absoluteValue = Math.abs(number);\n\n if (!Number.isFinite(number)) {\n return '';\n }\n\n if (number === 0) {\n return formatToken(config, 0, symbol);\n }\n\n if (absoluteValue < minThreshold) {\n return `<${formatToken(config, minThreshold, symbol, oneSignificantDigit)}`;\n }\n\n if (absoluteValue < 1) {\n return formatToken(config, number, symbol, threeSignificantDigits);\n }\n\n if (absoluteValue < 1_000_000) {\n return formatToken(config, number, symbol);\n }\n\n return formatToken(config, number, symbol, {\n notation: 'compact',\n ...twoDecimals,\n });\n}\n\n/**\n * Create formatter functions with the given locale.\n *\n * @param options - Configuration options.\n * @param options.locale - Locale string.\n * @returns Object with formatter functions.\n */\nexport function createFormatters({ locale = FALLBACK_LOCALE }) {\n return {\n /**\n * Format a number with optional Intl overrides.\n *\n * @param value - Numeric value to format.\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatNumber: formatNumber.bind(null, { locale }),\n /**\n * Format a value as a currency string.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code (e.g. 'USD').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatCurrency: formatCurrency.bind(null, { locale }),\n /**\n * Compact currency (e.g. $1.2K, $3.4M) with up to two decimal digits.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyCompact: formatCurrencyCompact.bind(null, { locale }),\n /**\n * Currency with thresholds for small values.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyWithMinThreshold: formatCurrencyWithMinThreshold.bind(null, {\n locale,\n }),\n /**\n * Format token price with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param currency - ISO 4217 currency code.\n */\n formatCurrencyTokenPrice: formatCurrencyTokenPrice.bind(null, { locale }),\n /**\n * Format a value as a token string with symbol.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n * @param options - Optional Intl.NumberFormat overrides.\n */\n formatToken: formatToken.bind(null, { locale }),\n /**\n * Format token quantity with varying precision based on value.\n *\n * @param value - Numeric value to format.\n * @param symbol - Token symbol (e.g. 'ETH', 'SepoliaETH').\n */\n formatTokenQuantity: formatTokenQuantity.bind(null, { locale }),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timeout-with-retry.cjs","sourceRoot":"","sources":["../../src/utils/timeout-with-retry.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AAEzC,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;AAE3C;;;;;;GAMG;AACH,6CAA6C;AACtC,KAAK,UAAU,gBAAgB,CACpC,IAAO,EACP,OAAe,EACf,UAAkB;IAGlB,IAAA,cAAM,EAAC,UAAU,IAAI,CAAC,EAAE,+CAA+C,CAAC,CAAC;IAEzE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,OAAO,IAAI,UAAU,EAAE;QAC5B,IAAI;YACF,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;gBACzB,IAAI,EAAE;gBACN,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CACjD;aACF,CAAC,CAA2B,CAAC;SAC/B;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,GAAG,KAAK,aAAa,IAAI,OAAO,GAAG,UAAU,EAAE;gBACjD,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;aACV;YACD,MAAM,GAAG,CAAC;SACX;KACF;AACH,CAAC;AA1BD,4CA0BC","sourcesContent":["import { assert } from '@metamask/utils';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\n/**\n *\n * @param call - The async function to call.\n * @param timeout - Timeout in milliseconds for each call attempt.\n * @param maxRetries - Maximum number of retries on timeout.\n * @returns The resolved value of the call, or throws the last error if not a timeout or retries exhausted.\n */\n// eslint-disable-next-line consistent-return\nexport async function timeoutWithRetry<T extends () => Promise<unknown>>(\n call: T,\n timeout: number,\n maxRetries: number,\n // @ts-expect-error TS2366: Assertion guarantees loop executes\n): Promise<Awaited<ReturnType<T>>> {\n assert(maxRetries >= 0, 'maxRetries must be greater than or equal to 0');\n\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n return (await Promise.race([\n call(),\n new Promise((_resolve, reject) =>\n setTimeout(() => reject(TIMEOUT_ERROR), timeout),\n ),\n ])) as Awaited<ReturnType<T>>;\n } catch (err) {\n if (err === TIMEOUT_ERROR && attempt < maxRetries) {\n attempt += 1;\n continue;\n }\n throw err;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"timeout-with-retry.cjs","sourceRoot":"","sources":["../../src/utils/timeout-with-retry.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AAEzC,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;AAE3C;;;;;;GAMG;AACH,6CAA6C;AACtC,KAAK,UAAU,gBAAgB,CACpC,IAAO,EACP,OAAe,EACf,UAAkB;IAGlB,IAAA,cAAM,EAAC,UAAU,IAAI,CAAC,EAAE,+CAA+C,CAAC,CAAC;IAEzE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,OAAO,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;gBACzB,IAAI,EAAE;gBACN,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CACjD;aACF,CAAC,CAA2B,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,KAAK,aAAa,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBAClD,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC;AA1BD,4CA0BC","sourcesContent":["import { assert } from '@metamask/utils';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\n/**\n *\n * @param call - The async function to call.\n * @param timeout - Timeout in milliseconds for each call attempt.\n * @param maxRetries - Maximum number of retries on timeout.\n * @returns The resolved value of the call, or throws the last error if not a timeout or retries exhausted.\n */\n// eslint-disable-next-line consistent-return\nexport async function timeoutWithRetry<T extends () => Promise<unknown>>(\n call: T,\n timeout: number,\n maxRetries: number,\n // @ts-expect-error TS2366: Assertion guarantees loop executes\n): Promise<Awaited<ReturnType<T>>> {\n assert(maxRetries >= 0, 'maxRetries must be greater than or equal to 0');\n\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n return (await Promise.race([\n call(),\n new Promise((_resolve, reject) =>\n setTimeout(() => reject(TIMEOUT_ERROR), timeout),\n ),\n ])) as Awaited<ReturnType<T>>;\n } catch (err) {\n if (err === TIMEOUT_ERROR && attempt < maxRetries) {\n attempt += 1;\n continue;\n }\n throw err;\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timeout-with-retry.mjs","sourceRoot":"","sources":["../../src/utils/timeout-with-retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAEzC,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;AAE3C;;;;;;GAMG;AACH,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAO,EACP,OAAe,EACf,UAAkB;IAGlB,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,+CAA+C,CAAC,CAAC;IAEzE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,OAAO,IAAI,UAAU,EAAE;QAC5B,IAAI;YACF,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;gBACzB,IAAI,EAAE;gBACN,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CACjD;aACF,CAAC,CAA2B,CAAC;SAC/B;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,GAAG,KAAK,aAAa,IAAI,OAAO,GAAG,UAAU,EAAE;gBACjD,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;aACV;YACD,MAAM,GAAG,CAAC;SACX;KACF;AACH,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\n/**\n *\n * @param call - The async function to call.\n * @param timeout - Timeout in milliseconds for each call attempt.\n * @param maxRetries - Maximum number of retries on timeout.\n * @returns The resolved value of the call, or throws the last error if not a timeout or retries exhausted.\n */\n// eslint-disable-next-line consistent-return\nexport async function timeoutWithRetry<T extends () => Promise<unknown>>(\n call: T,\n timeout: number,\n maxRetries: number,\n // @ts-expect-error TS2366: Assertion guarantees loop executes\n): Promise<Awaited<ReturnType<T>>> {\n assert(maxRetries >= 0, 'maxRetries must be greater than or equal to 0');\n\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n return (await Promise.race([\n call(),\n new Promise((_resolve, reject) =>\n setTimeout(() => reject(TIMEOUT_ERROR), timeout),\n ),\n ])) as Awaited<ReturnType<T>>;\n } catch (err) {\n if (err === TIMEOUT_ERROR && attempt < maxRetries) {\n attempt += 1;\n continue;\n }\n throw err;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"timeout-with-retry.mjs","sourceRoot":"","sources":["../../src/utils/timeout-with-retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAEzC,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC;AAE3C;;;;;;GAMG;AACH,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAO,EACP,OAAe,EACf,UAAkB;IAGlB,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,+CAA+C,CAAC,CAAC;IAEzE,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,OAAO,OAAO,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;gBACzB,IAAI,EAAE;gBACN,IAAI,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CACjD;aACF,CAAC,CAA2B,CAAC;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,KAAK,aAAa,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBAClD,OAAO,IAAI,CAAC,CAAC;gBACb,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\n\nconst TIMEOUT_ERROR = new Error('timeout');\n\n/**\n *\n * @param call - The async function to call.\n * @param timeout - Timeout in milliseconds for each call attempt.\n * @param maxRetries - Maximum number of retries on timeout.\n * @returns The resolved value of the call, or throws the last error if not a timeout or retries exhausted.\n */\n// eslint-disable-next-line consistent-return\nexport async function timeoutWithRetry<T extends () => Promise<unknown>>(\n call: T,\n timeout: number,\n maxRetries: number,\n // @ts-expect-error TS2366: Assertion guarantees loop executes\n): Promise<Awaited<ReturnType<T>>> {\n assert(maxRetries >= 0, 'maxRetries must be greater than or equal to 0');\n\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n return (await Promise.race([\n call(),\n new Promise((_resolve, reject) =>\n setTimeout(() => reject(TIMEOUT_ERROR), timeout),\n ),\n ])) as Awaited<ReturnType<T>>;\n } catch (err) {\n if (err === TIMEOUT_ERROR && attempt < maxRetries) {\n attempt += 1;\n continue;\n }\n throw err;\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/assets-controllers",
3
- "version": "87.1.0",
3
+ "version": "88.0.0",
4
4
  "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -82,7 +82,7 @@
82
82
  "devDependencies": {
83
83
  "@babel/runtime": "^7.23.9",
84
84
  "@metamask/account-api": "^0.12.0",
85
- "@metamask/account-tree-controller": "^2.0.0",
85
+ "@metamask/account-tree-controller": "^3.0.0",
86
86
  "@metamask/accounts-controller": "^34.0.0",
87
87
  "@metamask/approval-controller": "^8.0.0",
88
88
  "@metamask/auto-changelog": "^3.4.4",
@@ -91,7 +91,7 @@
91
91
  "@metamask/keyring-controller": "^24.0.0",
92
92
  "@metamask/keyring-internal-api": "^9.0.0",
93
93
  "@metamask/keyring-snap-client": "^8.0.0",
94
- "@metamask/multichain-account-service": "^2.1.0",
94
+ "@metamask/multichain-account-service": "^3.0.0",
95
95
  "@metamask/network-controller": "^25.0.0",
96
96
  "@metamask/permission-controller": "^12.1.0",
97
97
  "@metamask/phishing-controller": "^15.0.0",
@@ -111,11 +111,11 @@
111
111
  "ts-jest": "^27.1.4",
112
112
  "typedoc": "^0.24.8",
113
113
  "typedoc-plugin-missing-exports": "^2.0.0",
114
- "typescript": "~5.2.2",
114
+ "typescript": "~5.3.3",
115
115
  "webextension-polyfill": "^0.12.0"
116
116
  },
117
117
  "peerDependencies": {
118
- "@metamask/account-tree-controller": "^2.0.0",
118
+ "@metamask/account-tree-controller": "^3.0.0",
119
119
  "@metamask/accounts-controller": "^34.0.0",
120
120
  "@metamask/approval-controller": "^8.0.0",
121
121
  "@metamask/core-backend": "^4.0.0",