@lifi/widget 3.29.0 → 3.30.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 (174) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts +1 -1
  3. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +3 -2
  4. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  5. package/dist/esm/components/AmountInput/PriceFormHelperText.d.ts +1 -1
  6. package/dist/esm/components/AmountInput/PriceFormHelperText.js +3 -2
  7. package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
  8. package/dist/esm/components/BottomSheet/BottomSheet.js +2 -2
  9. package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
  10. package/dist/esm/components/BottomSheet/types.d.ts +1 -0
  11. package/dist/esm/components/ChainSelect/ChainSelect.js +35 -18
  12. package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
  13. package/dist/esm/components/ChainSelect/useChainSelect.d.ts +1 -1
  14. package/dist/esm/components/ChainSelect/useChainSelect.js +3 -3
  15. package/dist/esm/components/ChainSelect/useChainSelect.js.map +1 -1
  16. package/dist/esm/components/Chains/AllChainsAvatar.d.ts +7 -0
  17. package/dist/esm/components/Chains/AllChainsAvatar.js +77 -0
  18. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -0
  19. package/dist/esm/components/Chains/ChainList.d.ts +2 -1
  20. package/dist/esm/components/Chains/ChainList.js +2 -2
  21. package/dist/esm/components/Chains/ChainList.js.map +1 -1
  22. package/dist/esm/components/Chains/ChainSearchInput.js +2 -2
  23. package/dist/esm/components/Chains/ChainSearchInput.js.map +1 -1
  24. package/dist/esm/components/Chains/SelectChainContent.js +1 -1
  25. package/dist/esm/components/Chains/SelectChainContent.js.map +1 -1
  26. package/dist/esm/components/Chains/VirtualizedChainList.d.ts +2 -1
  27. package/dist/esm/components/Chains/VirtualizedChainList.js +42 -10
  28. package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
  29. package/dist/esm/components/RouteCard/RouteCardEssentials.js +1 -1
  30. package/dist/esm/components/RouteCard/RouteCardEssentials.js.map +1 -1
  31. package/dist/esm/components/TokenList/TokenDetailsSheet.d.ts +1 -5
  32. package/dist/esm/components/TokenList/TokenDetailsSheet.js +5 -3
  33. package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
  34. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +2 -2
  35. package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
  36. package/dist/esm/components/TokenList/TokenList.js +11 -53
  37. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  38. package/dist/esm/components/TokenList/TokenListItem.d.ts +1 -1
  39. package/dist/esm/components/TokenList/TokenListItem.js +29 -25
  40. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  41. package/dist/esm/components/TokenList/VirtualizedTokenList.js +56 -37
  42. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  43. package/dist/esm/components/TokenList/types.d.ts +6 -10
  44. package/dist/esm/components/TokenList/useTokenSelect.js +3 -4
  45. package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
  46. package/dist/esm/components/TransactionDetails.js +2 -2
  47. package/dist/esm/components/TransactionDetails.js.map +1 -1
  48. package/dist/esm/config/version.d.ts +1 -1
  49. package/dist/esm/config/version.js +1 -1
  50. package/dist/esm/hooks/useAccountsBalancesData.d.ts +6 -0
  51. package/dist/esm/hooks/useAccountsBalancesData.js +64 -0
  52. package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -0
  53. package/dist/esm/hooks/useFilteredByTokenBalances.d.ts +8 -0
  54. package/dist/esm/hooks/useFilteredByTokenBalances.js +69 -0
  55. package/dist/esm/hooks/useFilteredByTokenBalances.js.map +1 -0
  56. package/dist/esm/hooks/useListHeight.d.ts +0 -1
  57. package/dist/esm/hooks/useListHeight.js +0 -1
  58. package/dist/esm/hooks/useListHeight.js.map +1 -1
  59. package/dist/esm/hooks/useToken.d.ts +2 -2
  60. package/dist/esm/hooks/useToken.js +13 -11
  61. package/dist/esm/hooks/useToken.js.map +1 -1
  62. package/dist/esm/hooks/useTokenAddressBalance.d.ts +2 -3
  63. package/dist/esm/hooks/useTokenAddressBalance.js +10 -14
  64. package/dist/esm/hooks/useTokenAddressBalance.js.map +1 -1
  65. package/dist/esm/hooks/useTokenBalances.d.ts +6 -9
  66. package/dist/esm/hooks/useTokenBalances.js +57 -72
  67. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  68. package/dist/esm/hooks/useTokenBalancesQueries.d.ts +11 -0
  69. package/dist/esm/hooks/useTokenBalancesQueries.js +74 -0
  70. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -0
  71. package/dist/esm/hooks/useTokens.d.ts +6 -6
  72. package/dist/esm/hooks/useTokens.js +78 -70
  73. package/dist/esm/hooks/useTokens.js.map +1 -1
  74. package/dist/esm/i18n/bn.json +3 -3
  75. package/dist/esm/i18n/de.json +3 -3
  76. package/dist/esm/i18n/en.json +3 -3
  77. package/dist/esm/i18n/es.json +3 -3
  78. package/dist/esm/i18n/fr.json +3 -3
  79. package/dist/esm/i18n/hi.json +3 -3
  80. package/dist/esm/i18n/id.json +3 -3
  81. package/dist/esm/i18n/it.json +3 -3
  82. package/dist/esm/i18n/ja.json +3 -3
  83. package/dist/esm/i18n/ko.json +3 -3
  84. package/dist/esm/i18n/pl.json +3 -3
  85. package/dist/esm/i18n/pt.json +3 -3
  86. package/dist/esm/i18n/th.json +3 -3
  87. package/dist/esm/i18n/tr.json +3 -3
  88. package/dist/esm/i18n/uk.json +3 -3
  89. package/dist/esm/i18n/vi.json +3 -3
  90. package/dist/esm/i18n/zh.json +3 -3
  91. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.js +6 -1
  92. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.js.map +1 -1
  93. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +2 -4
  94. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  95. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +1 -1
  96. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  97. package/dist/esm/stores/chains/createChainOrderStore.d.ts +3 -2
  98. package/dist/esm/stores/chains/createChainOrderStore.js +13 -8
  99. package/dist/esm/stores/chains/createChainOrderStore.js.map +1 -1
  100. package/dist/esm/stores/chains/types.d.ts +2 -0
  101. package/dist/esm/stores/chains/useChainOrder.js +5 -1
  102. package/dist/esm/stores/chains/useChainOrder.js.map +1 -1
  103. package/dist/esm/types/token.d.ts +7 -2
  104. package/dist/esm/utils/chainType.d.ts +1 -0
  105. package/dist/esm/utils/chainType.js +2 -0
  106. package/dist/esm/utils/chainType.js.map +1 -1
  107. package/dist/esm/utils/token.d.ts +8 -0
  108. package/dist/esm/utils/token.js +29 -0
  109. package/dist/esm/utils/token.js.map +1 -0
  110. package/dist/esm/utils/tokenList.d.ts +13 -0
  111. package/dist/esm/utils/tokenList.js +106 -0
  112. package/dist/esm/utils/tokenList.js.map +1 -0
  113. package/package.json +8 -8
  114. package/package.json.tmp +7 -7
  115. package/src/components/AmountInput/AmountInputEndAdornment.tsx +3 -2
  116. package/src/components/AmountInput/PriceFormHelperText.tsx +3 -2
  117. package/src/components/BottomSheet/BottomSheet.tsx +2 -2
  118. package/src/components/BottomSheet/types.ts +1 -0
  119. package/src/components/ChainSelect/ChainSelect.tsx +112 -40
  120. package/src/components/ChainSelect/useChainSelect.ts +3 -3
  121. package/src/components/Chains/AllChainsAvatar.tsx +113 -0
  122. package/src/components/Chains/ChainList.tsx +3 -0
  123. package/src/components/Chains/ChainSearchInput.tsx +2 -2
  124. package/src/components/Chains/SelectChainContent.tsx +1 -0
  125. package/src/components/Chains/VirtualizedChainList.tsx +80 -12
  126. package/src/components/RouteCard/RouteCardEssentials.tsx +1 -1
  127. package/src/components/TokenList/TokenDetailsSheet.tsx +5 -10
  128. package/src/components/TokenList/TokenDetailsSheetContent.tsx +2 -6
  129. package/src/components/TokenList/TokenList.tsx +57 -129
  130. package/src/components/TokenList/TokenListItem.tsx +191 -166
  131. package/src/components/TokenList/VirtualizedTokenList.tsx +88 -48
  132. package/src/components/TokenList/types.ts +14 -10
  133. package/src/components/TokenList/useTokenSelect.ts +3 -4
  134. package/src/components/TransactionDetails.tsx +2 -2
  135. package/src/config/version.ts +1 -1
  136. package/src/hooks/useAccountsBalancesData.ts +101 -0
  137. package/src/hooks/useFilteredByTokenBalances.ts +101 -0
  138. package/src/hooks/useListHeight.ts +0 -1
  139. package/src/hooks/useToken.ts +26 -14
  140. package/src/hooks/useTokenAddressBalance.ts +14 -20
  141. package/src/hooks/useTokenBalances.ts +81 -80
  142. package/src/hooks/useTokenBalancesQueries.ts +94 -0
  143. package/src/hooks/useTokens.ts +118 -90
  144. package/src/i18n/bn.json +3 -3
  145. package/src/i18n/de.json +3 -3
  146. package/src/i18n/en.json +3 -3
  147. package/src/i18n/es.json +3 -3
  148. package/src/i18n/fr.json +3 -3
  149. package/src/i18n/hi.json +3 -3
  150. package/src/i18n/id.json +3 -3
  151. package/src/i18n/it.json +3 -3
  152. package/src/i18n/ja.json +3 -3
  153. package/src/i18n/ko.json +3 -3
  154. package/src/i18n/pl.json +3 -3
  155. package/src/i18n/pt.json +3 -3
  156. package/src/i18n/th.json +3 -3
  157. package/src/i18n/tr.json +3 -3
  158. package/src/i18n/uk.json +3 -3
  159. package/src/i18n/vi.json +3 -3
  160. package/src/i18n/zh.json +3 -3
  161. package/src/pages/SelectTokenPage/SearchTokenInput.tsx +5 -0
  162. package/src/pages/SelectTokenPage/SelectTokenPage.tsx +7 -13
  163. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +1 -1
  164. package/src/stores/chains/createChainOrderStore.ts +17 -8
  165. package/src/stores/chains/types.ts +2 -0
  166. package/src/stores/chains/useChainOrder.ts +5 -1
  167. package/src/types/token.ts +11 -2
  168. package/src/utils/chainType.ts +2 -0
  169. package/src/utils/token.ts +65 -0
  170. package/src/utils/tokenList.ts +172 -0
  171. package/dist/esm/components/TokenList/utils.d.ts +0 -2
  172. package/dist/esm/components/TokenList/utils.js +0 -35
  173. package/dist/esm/components/TokenList/utils.js.map +0 -1
  174. package/src/components/TokenList/utils.ts +0 -42
package/src/i18n/ja.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": ""
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "すべてのトークン",
216
217
  "bridgeStepDetails": "{{from}} から {{to}} を {{tool}} でブリッジ",
217
218
  "checkoutStepDetails": "{{tool}} 経由で購入",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "損失額",
313
- "searchChain": "",
314
- "searchChains": "",
315
314
  "searchBridges": "",
316
- "searchExchanges": ""
315
+ "searchExchanges": "",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/ko.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": ""
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "",
216
217
  "bridgeStepDetails": "",
217
218
  "checkoutStepDetails": "",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "가치 손실",
313
- "searchChain": "",
314
- "searchChains": "",
315
314
  "searchBridges": "",
316
- "searchExchanges": ""
315
+ "searchExchanges": "",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/pl.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": ""
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "",
216
217
  "bridgeStepDetails": "",
217
218
  "checkoutStepDetails": "",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "",
313
- "searchChain": "",
314
- "searchChains": "",
315
314
  "searchBridges": "",
316
- "searchExchanges": ""
315
+ "searchExchanges": "",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/pt.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": "A diferença percentual máxima entre o preço esperado, e o preço atual pelo qual a transferência é executada. Esse valor pode ser alterado nas configurações."
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "Todos os tokens",
216
217
  "bridgeStepDetails": "Ponte de {{from}} para {{to}} via {{tool}}",
217
218
  "checkoutStepDetails": "Comprar via {{tool}}",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "{{amount, numberExt}} {{tokenSymbol}} na {{chainName}}",
311
312
  "tokenSearch": "Pesquisar por token ou endereço",
312
313
  "valueLoss": "Perda de Valor",
313
- "searchChain": "Pesquisar cadeia",
314
- "searchChains": "Pesquisar pelo nome da rede",
315
314
  "searchBridges": "Pesquisar pelo nome da ponte",
316
- "searchExchanges": "Pesquisar pelo nome da corretora"
315
+ "searchExchanges": "Pesquisar pelo nome da corretora",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "Aparência",
package/src/i18n/th.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": ""
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "โทเคนทั้งหมด",
216
217
  "bridgeStepDetails": "บริดจ์จาก{{from}} ไปยัง {{to}} โดย {{tool}}",
217
218
  "checkoutStepDetails": "ซื้อผ่าน {{tool}}",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "มูลค่าที่สูญเสีย",
313
- "searchChain": "",
314
- "searchChains": "",
315
314
  "searchBridges": "",
316
- "searchExchanges": ""
315
+ "searchExchanges": "",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/tr.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": "Beklenen fiyat ile transferin gerçekleştirildiği gerçek fiyat arasındaki maksimum yüzde fark. Bu değer ayarlardan değiştirilebilir."
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "Tüm varlıklar",
216
217
  "bridgeStepDetails": "{{tool}} aracılığıyla {{from}} ağından {{to}} ağına köprüle",
217
218
  "checkoutStepDetails": "{{tool}} aracılığıyla alım yap",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "Değer kaybı",
313
- "searchChain": "",
314
- "searchChains": "Zincir adına göre ara",
315
314
  "searchBridges": "Köprü adına göre ara",
316
- "searchExchanges": "Borsa adına göre ara"
315
+ "searchExchanges": "Borsa adına göre ara",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/uk.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": "Максимальна процентна різниця між очікуваною ціною і фактичною ціною з якою виконується трансфер. Ця величина може бути змінена в налаштуваннях."
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "Всі токени",
216
217
  "bridgeStepDetails": "Бридж з {{from}} до {{to}} через {{tool}}",
217
218
  "checkoutStepDetails": "Купівля через {{tool}}",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "{{amount, numberExt}} {{tokenSymbol}} на {{chainName}}",
311
312
  "tokenSearch": "Шукати за ім'ям або адресою",
312
313
  "valueLoss": "Втрата вартості",
313
- "searchChain": "Шукати чейн",
314
- "searchChains": "Пошук за назвою чейна",
315
314
  "searchBridges": "Пошук за назвою моста",
316
- "searchExchanges": "Пошук за назвою обмінника"
315
+ "searchExchanges": "Пошук за назвою обмінника",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "Вигляд",
package/src/i18n/vi.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": ""
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "Tất cả mã thông báo",
216
217
  "bridgeStepDetails": "Chuyển từ {{from}} đến {{to}} thông qua {{tool}}",
217
218
  "checkoutStepDetails": "Thanh toán thông qua {{tool}}",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "Bạn sẽ mất",
313
- "searchChain": "",
314
- "searchChains": "",
315
314
  "searchBridges": "",
316
- "searchExchanges": ""
315
+ "searchExchanges": "",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
package/src/i18n/zh.json CHANGED
@@ -212,6 +212,7 @@
212
212
  "slippage": "真实的成交价位与预设的成交价位间相差的最大百分比。该值可以在设置中更改。"
213
213
  },
214
214
  "main": {
215
+ "allNetworks": "",
215
216
  "allTokens": "所有代币",
216
217
  "bridgeStepDetails": "通过 {{tool}} 把资产从 {{from}} 链跨到 {{to}} 链上",
217
218
  "checkoutStepDetails": "通过 {{tool}} 购买",
@@ -310,10 +311,9 @@
310
311
  "tokenOnChainAmount": "",
311
312
  "tokenSearch": "",
312
313
  "valueLoss": "资金损失",
313
- "searchChain": "",
314
- "searchChains": "搜索链",
315
314
  "searchBridges": "搜索跨链桥",
316
- "searchExchanges": "搜索交易所"
315
+ "searchExchanges": "搜索交易所",
316
+ "searchNetwork": ""
317
317
  },
318
318
  "settings": {
319
319
  "appearance": "",
@@ -1,6 +1,7 @@
1
1
  import { useCallback, useEffect } from 'react'
2
2
  import { useTranslation } from 'react-i18next'
3
3
  import { SearchInput } from '../../components/Search/SearchInput.js'
4
+ import { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'
4
5
  import { useFieldActions } from '../../stores/form/useFieldActions.js'
5
6
  import { useFieldValues } from '../../stores/form/useFieldValues.js'
6
7
 
@@ -8,6 +9,8 @@ export const SearchTokenInput = () => {
8
9
  const { t } = useTranslation()
9
10
  const [value] = useFieldValues('tokenSearchFilter')
10
11
  const { setFieldValue, setAsTouched } = useFieldActions()
12
+ const [fromChain, toChain] = useFieldValues('fromChain', 'toChain')
13
+ const isAllNetworks = useChainOrderStore((state) => state.isAllNetworks)
11
14
 
12
15
  const onChange = useCallback(
13
16
  (newValue: string | number | undefined) => {
@@ -32,6 +35,8 @@ export const SearchTokenInput = () => {
32
35
 
33
36
  return (
34
37
  <SearchInput
38
+ // Reset the search input when a chain or the "All Networks" is changed
39
+ key={`${fromChain}-${toChain}-${isAllNetworks}`}
35
40
  name="tokenSearchFilter"
36
41
  placeholder={t('main.tokenSearch')}
37
42
  onChange={(e) => onChange((e.target as HTMLInputElement).value)}
@@ -92,22 +92,16 @@ type WrappedTokenListProps = {
92
92
  const WrappedTokenList = ({ headerRef, formType }: WrappedTokenListProps) => {
93
93
  const { navigateBack } = useNavigateBack()
94
94
  const listParentRef = useRef<HTMLUListElement | null>(null)
95
- const { listHeight, minListHeight } = useListHeight({
95
+ const { listHeight } = useListHeight({
96
96
  listParentRef,
97
97
  headerRef,
98
98
  })
99
99
  return (
100
- <Box
101
- sx={{
102
- height: minListHeight,
103
- }}
104
- >
105
- <TokenList
106
- parentRef={listParentRef}
107
- height={listHeight}
108
- onClick={navigateBack}
109
- formType={formType}
110
- />
111
- </Box>
100
+ <TokenList
101
+ parentRef={listParentRef}
102
+ height={listHeight}
103
+ onClick={navigateBack}
104
+ formType={formType}
105
+ />
112
106
  )
113
107
  }
@@ -113,7 +113,7 @@ const TokenValueBottomSheetContent: React.FC<TokenValueBottomSheetProps> = ({
113
113
  fontWeight: 600,
114
114
  }}
115
115
  >
116
- {hasRelayerSupport
116
+ {hasRelayerSupport || !gasCostUSD
117
117
  ? t('main.fees.free')
118
118
  : t('format.currency', { value: gasCostUSD })}
119
119
  </Typography>
@@ -4,8 +4,13 @@ import { createWithEqualityFn } from 'zustand/traditional'
4
4
  import type { PersistStoreProps } from '../types.js'
5
5
  import type { ChainOrderState } from './types.js'
6
6
 
7
- export const maxChainsToOrder = 9
8
- export const maxChainsToShow = 10
7
+ // (10 tiles: 9 + 1 for "All chains")
8
+ export const maxGridItemsToShow = 10
9
+ export const maxChainsToShow = maxGridItemsToShow - 1
10
+ // If there are more than maxChainsToShow chains to show,
11
+ // -1 tile to show a button "+ N" more chains
12
+ export const maxChainsToOrder = maxChainsToShow - 1
13
+
9
14
  const defaultChainState = {
10
15
  from: [],
11
16
  to: [],
@@ -16,6 +21,7 @@ export const createChainOrderStore = ({ namePrefix }: PersistStoreProps) =>
16
21
  persist(
17
22
  (set, get) => ({
18
23
  chainOrder: defaultChainState,
24
+ isAllNetworks: true,
19
25
  availableChains: defaultChainState,
20
26
  pinnedChains: [],
21
27
  initializeChains: (chainIds, type) => {
@@ -53,7 +59,7 @@ export const createChainOrderStore = ({ namePrefix }: PersistStoreProps) =>
53
59
  },
54
60
  }
55
61
  })
56
- return get().chainOrder[type]
62
+ return get().chainOrder[type].slice(0, maxChainsToOrder)
57
63
  },
58
64
  setChain: (chainId, type) => {
59
65
  const state = get()
@@ -64,11 +70,10 @@ export const createChainOrderStore = ({ namePrefix }: PersistStoreProps) =>
64
70
  return
65
71
  }
66
72
  set((state: ChainOrderState) => {
67
- const chainOrder = state.chainOrder[type].slice()
68
- chainOrder.unshift(chainId)
69
- if (chainOrder.length > maxChainsToOrder) {
70
- chainOrder.pop()
71
- }
73
+ const chainOrder = [chainId, ...state.chainOrder[type]].slice(
74
+ 0,
75
+ maxChainsToOrder
76
+ )
72
77
  return {
73
78
  chainOrder: {
74
79
  ...state.chainOrder,
@@ -77,6 +82,9 @@ export const createChainOrderStore = ({ namePrefix }: PersistStoreProps) =>
77
82
  }
78
83
  })
79
84
  },
85
+ setIsAllNetworks: (isAllNetworks) => {
86
+ set({ isAllNetworks })
87
+ },
80
88
  setPinnedChain: (chainId) => {
81
89
  set((state: ChainOrderState) => {
82
90
  const pinnedChains = [...state.pinnedChains]
@@ -97,6 +105,7 @@ export const createChainOrderStore = ({ namePrefix }: PersistStoreProps) =>
97
105
  version: 2,
98
106
  partialize: (state) => ({
99
107
  chainOrder: state.chainOrder,
108
+ isAllNetworks: state.isAllNetworks,
100
109
  pinnedChains: state.pinnedChains,
101
110
  }),
102
111
  }
@@ -9,11 +9,13 @@ export interface ChainOrderProps {
9
9
  from: number[]
10
10
  to: number[]
11
11
  }
12
+ isAllNetworks: boolean
12
13
  pinnedChains: number[]
13
14
  }
14
15
 
15
16
  export interface ChainOrderState extends ChainOrderProps {
16
17
  initializeChains(chainIds: number[], type: FormType): number[]
17
18
  setChain(chainId: number, type: FormType): void
19
+ setIsAllNetworks(isAllNetworks: boolean): void
18
20
  setPinnedChain(chainId: number): void
19
21
  }
@@ -1,8 +1,12 @@
1
1
  import type { FormType } from '../form/types.js'
2
2
  import { useChainOrderStore } from './ChainOrderStore.js'
3
+ import { maxChainsToOrder } from './createChainOrderStore.js'
3
4
 
4
5
  export const useChainOrder = (
5
6
  type: FormType
6
7
  ): [number[], (chainId: number, type: FormType) => void] => {
7
- return useChainOrderStore((state) => [state.chainOrder[type], state.setChain])
8
+ return useChainOrderStore((state) => [
9
+ state.chainOrder[type].slice(0, maxChainsToOrder),
10
+ state.setChain,
11
+ ])
8
12
  }
@@ -1,6 +1,15 @@
1
- import type { TokenAmount as SDKTokenAmount } from '@lifi/sdk'
1
+ import type {
2
+ TokenAmount as SDKTokenAmount,
3
+ TokenAmountExtended as SDKTokenAmountExtended,
4
+ } from '@lifi/sdk'
2
5
 
3
- export interface TokenAmount extends SDKTokenAmount {
6
+ interface TokenFlags {
4
7
  featured?: boolean
5
8
  popular?: boolean
6
9
  }
10
+
11
+ export interface TokenAmount extends SDKTokenAmount, TokenFlags {}
12
+
13
+ export interface TokenAmountExtended
14
+ extends SDKTokenAmountExtended,
15
+ TokenFlags {}
@@ -8,6 +8,7 @@ const chainTypeAddressValidation = {
8
8
  [ChainType.SVM]: isSVMAddress,
9
9
  [ChainType.MVM]: isValidSuiAddress,
10
10
  [ChainType.UTXO]: isUTXOAddress,
11
+ [ChainType.TVM]: () => false,
11
12
  }
12
13
 
13
14
  export const getChainTypeFromAddress = (
@@ -27,4 +28,5 @@ export const defaultChainIdsByType = {
27
28
  [ChainType.SVM]: ChainId.SOL,
28
29
  [ChainType.UTXO]: ChainId.BTC,
29
30
  [ChainType.MVM]: ChainId.SUI,
31
+ [ChainType.TVM]: ChainId.TRN,
30
32
  }
@@ -0,0 +1,65 @@
1
+ import type { BaseToken, TokenExtended } from '@lifi/sdk'
2
+ import type { FormType } from '../stores/form/types.js'
3
+ import type { WidgetChains, WidgetTokens } from '../types/widget.js'
4
+ import {
5
+ getConfigItemSets,
6
+ isFormItemAllowed,
7
+ isItemAllowedForSets,
8
+ } from './item.js'
9
+
10
+ export const filterAllowedTokens = (
11
+ dataTokens: { [chainId: number]: TokenExtended[] } | undefined,
12
+ configTokens?: WidgetTokens,
13
+ chainsConfig?: WidgetChains,
14
+ formType?: FormType
15
+ ): { [chainId: number]: TokenExtended[] } | undefined => {
16
+ if (!dataTokens) {
17
+ return
18
+ }
19
+
20
+ const includedTokens = configTokens?.include || []
21
+ const allChainIds = Array.from(
22
+ new Set([
23
+ ...includedTokens.map((t) => t.chainId),
24
+ ...Object.keys(dataTokens),
25
+ ])
26
+ ).map((chainId) => Number(chainId))
27
+
28
+ const configChainIdsSet = getConfigItemSets(
29
+ chainsConfig,
30
+ (chainIds: number[]) => new Set(chainIds),
31
+ formType
32
+ )
33
+ const allowedChainIds = configChainIdsSet
34
+ ? allChainIds.filter((chainId) =>
35
+ isItemAllowedForSets(chainId, configChainIdsSet)
36
+ )
37
+ : allChainIds
38
+
39
+ const allowedTokensByChain: { [chainId: number]: TokenExtended[] } = {}
40
+ for (const chainId of allowedChainIds) {
41
+ const chainTokens = [
42
+ ...dataTokens[chainId],
43
+ ...includedTokens.filter((t) => Number(t.chainId) === chainId),
44
+ ]
45
+
46
+ const allowedAddresses = getConfigItemSets(
47
+ configTokens,
48
+ (tokens: BaseToken[]) =>
49
+ new Set(
50
+ tokens
51
+ .filter((t) => Number(t.chainId) === chainId)
52
+ .map((t) => t.address)
53
+ ),
54
+ formType
55
+ )
56
+
57
+ const filtered = chainTokens.filter((token) =>
58
+ isFormItemAllowed(token, allowedAddresses, formType, (t) => t.address)
59
+ )
60
+
61
+ allowedTokensByChain[chainId] = filtered
62
+ }
63
+
64
+ return allowedTokensByChain
65
+ }
@@ -0,0 +1,172 @@
1
+ import type { TokenExtended, WalletTokenExtended } from '@lifi/sdk'
2
+ import { formatUnits } from 'viem'
3
+ import type { TokenAmount, TokenAmountExtended } from '../types/token.js'
4
+ import type { WidgetTokens } from '../types/widget.js'
5
+
6
+ const sortByBalances = (a: TokenAmount, b: TokenAmount) =>
7
+ Number.parseFloat(formatUnits(b.amount ?? 0n, b.decimals)) *
8
+ Number.parseFloat(b.priceUSD ?? '0') -
9
+ Number.parseFloat(formatUnits(a.amount ?? 0n, a.decimals)) *
10
+ Number.parseFloat(a.priceUSD ?? '0')
11
+
12
+ const sortByVolume = (a: TokenExtended, b: TokenExtended) =>
13
+ (b.volumeUSD24H ?? 0) - (a.volumeUSD24H ?? 0)
14
+
15
+ export const processTokenBalances = (
16
+ isBalanceLoading: boolean,
17
+ isAllNetworks: boolean,
18
+ configTokens?: WidgetTokens,
19
+ selectedChainId?: number,
20
+ tokens?: TokenExtended[],
21
+ tokensWithBalances?: TokenAmount[]
22
+ ) => {
23
+ if (isBalanceLoading) {
24
+ if (isAllNetworks) {
25
+ const sortedTokens = [...(tokens ?? [])].sort(sortByVolume)
26
+ return {
27
+ processedTokens: sortedTokens,
28
+ withCategories: false,
29
+ }
30
+ } else {
31
+ return processedTypedTokens(
32
+ tokens ?? [],
33
+ [],
34
+ selectedChainId,
35
+ configTokens
36
+ )
37
+ }
38
+ }
39
+
40
+ const sortedTokensWithBalances = [...(tokensWithBalances ?? [])].sort(
41
+ sortByBalances
42
+ )
43
+
44
+ const tokensWithBalancesSet = new Set(
45
+ sortedTokensWithBalances.map(
46
+ (token) => `${token.chainId}-${token.address.toLowerCase()}`
47
+ )
48
+ )
49
+ const tokensWithoutBalances =
50
+ tokens
51
+ ?.filter((token) => {
52
+ const tokenKey = `${token.chainId}-${token.address.toLowerCase()}`
53
+ return !tokensWithBalancesSet.has(tokenKey)
54
+ })
55
+ .sort(sortByVolume) ?? []
56
+
57
+ if (isAllNetworks) {
58
+ return {
59
+ processedTokens: [...sortedTokensWithBalances, ...tokensWithoutBalances],
60
+ withCategories: false,
61
+ }
62
+ } else {
63
+ return processedTypedTokens(
64
+ tokensWithoutBalances,
65
+ sortedTokensWithBalances,
66
+ selectedChainId,
67
+ configTokens
68
+ )
69
+ }
70
+ }
71
+
72
+ // NB: only for non-all-networks
73
+ export const processedTypedTokens = (
74
+ tokens: TokenAmount[],
75
+ tokensWithBalances: TokenAmount[],
76
+ selectedChainId?: number,
77
+ configTokens?: WidgetTokens
78
+ ) => {
79
+ const filteredTokensMap = new Map(
80
+ tokens.map((token) => [token.address, token])
81
+ )
82
+
83
+ const featuredTokensFromConfig: TokenAmount[] = []
84
+ const popularTokensFromConfig: TokenAmount[] = []
85
+
86
+ ;(['popular', 'featured'] as const).forEach((tokenType) => {
87
+ const typedTokens = configTokens?.[tokenType]?.filter(
88
+ (token) => token.chainId === selectedChainId
89
+ )
90
+
91
+ typedTokens?.forEach((token) => {
92
+ const tokenAmount = { ...token } as TokenAmount
93
+ tokenAmount[tokenType] = true
94
+
95
+ const match = filteredTokensMap.get(token.address)
96
+ if (match?.priceUSD) {
97
+ tokenAmount.priceUSD = match.priceUSD
98
+ }
99
+ if (!token.logoURI && match?.logoURI) {
100
+ tokenAmount.logoURI = match.logoURI
101
+ }
102
+
103
+ if (tokenType === 'popular') {
104
+ popularTokensFromConfig.push(tokenAmount)
105
+ } else {
106
+ featuredTokensFromConfig.push(tokenAmount)
107
+ }
108
+ })
109
+ })
110
+
111
+ // Filter out config-added tokens from main list
112
+ const configTokenAddresses = new Set(
113
+ [...popularTokensFromConfig, ...featuredTokensFromConfig].map(
114
+ (t) => t.address
115
+ )
116
+ )
117
+
118
+ const remainingTokens = tokens.filter(
119
+ (token) => !configTokenAddresses.has(token.address)
120
+ )
121
+
122
+ const otherTokens: TokenAmount[] = []
123
+
124
+ for (const token of remainingTokens) {
125
+ if (token.featured) {
126
+ featuredTokensFromConfig.push(token)
127
+ } else if (token.popular) {
128
+ popularTokensFromConfig.push(token)
129
+ } else {
130
+ otherTokens.push(token)
131
+ }
132
+ }
133
+
134
+ const sortedFeaturedTokens = [...featuredTokensFromConfig].sort(sortByVolume)
135
+ const sortedPopularTokens = [...popularTokensFromConfig].sort(sortByVolume)
136
+ const sortedOtherTokens = [...otherTokens].sort(sortByVolume)
137
+
138
+ return {
139
+ processedTokens: [
140
+ ...sortedFeaturedTokens,
141
+ ...tokensWithBalances,
142
+ ...sortedPopularTokens,
143
+ ...sortedOtherTokens,
144
+ ],
145
+ withCategories: Boolean(
146
+ featuredTokensFromConfig?.length || popularTokensFromConfig?.length
147
+ ),
148
+ }
149
+ }
150
+
151
+ export const isSearchMatch = (
152
+ token: TokenExtended | TokenAmountExtended,
153
+ search?: string
154
+ ) => {
155
+ if (!search) {
156
+ return true
157
+ }
158
+
159
+ const searchLowerCase = search.toLowerCase()
160
+ return (
161
+ token.name?.toLowerCase().includes(searchLowerCase) ||
162
+ token.symbol
163
+ ?.replaceAll('₮', 'T')
164
+ .toLowerCase()
165
+ .includes(searchLowerCase) ||
166
+ token.address?.toLowerCase().includes(searchLowerCase)
167
+ )
168
+ }
169
+
170
+ export const isSupportedToken = (token: WalletTokenExtended) => {
171
+ return token.name && token.symbol && token.priceUSD && token.chainId
172
+ }
@@ -1,2 +0,0 @@
1
- import type { TokenAmount } from '../../types/token.js';
2
- export declare const filteredTokensComparator: (searchFilter: string) => (tokenA: TokenAmount, tokenB: TokenAmount) => 0 | 1 | -1;
@@ -1,35 +0,0 @@
1
- export const filteredTokensComparator = (searchFilter) => {
2
- const isExactMatch = (token) => {
3
- return (token.name?.toUpperCase() === searchFilter ||
4
- token.symbol.toUpperCase() === searchFilter ||
5
- token.address.toUpperCase() === searchFilter);
6
- };
7
- return (tokenA, tokenB) => {
8
- const isExactMatchA = isExactMatch(tokenA);
9
- const isExactMatchB = isExactMatch(tokenB);
10
- // Exact match with logo
11
- if (isExactMatchB && tokenB.logoURI) {
12
- return 1;
13
- }
14
- if (isExactMatchA && tokenA.logoURI) {
15
- return -1;
16
- }
17
- // Any token with a logo (exact match or not)
18
- if (tokenB.logoURI && !tokenA.logoURI) {
19
- return 1;
20
- }
21
- if (tokenA.logoURI && !tokenB.logoURI) {
22
- return -1;
23
- }
24
- // Exact match without logo
25
- if (isExactMatchB && !tokenB.logoURI) {
26
- return 1;
27
- }
28
- if (isExactMatchA && !tokenA.logoURI) {
29
- return -1;
30
- }
31
- // All other tokens are considered equal in sorting priority
32
- return 0;
33
- };
34
- };
35
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/components/TokenList/utils.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,YAAoB,EAAE,EAAE;IAC/D,MAAM,YAAY,GAAG,CAAC,KAAkB,EAAE,EAAE;QAC1C,OAAO,CACL,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,YAAY;YAC1C,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,YAAY;YAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,YAAY,CAC7C,CAAA;IACH,CAAC,CAAA;IACD,OAAO,CAAC,MAAmB,EAAE,MAAmB,EAAE,EAAE;QAClD,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;QAC1C,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;QAE1C,wBAAwB;QACxB,IAAI,aAAa,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO,CAAC,CAAA;QACV,CAAC;QACD,IAAI,aAAa,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,CAAA;QACX,CAAC;QAED,6CAA6C;QAC7C,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtC,OAAO,CAAC,CAAA;QACV,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtC,OAAO,CAAC,CAAC,CAAA;QACX,CAAC;QAED,2BAA2B;QAC3B,IAAI,aAAa,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,OAAO,CAAC,CAAA;QACV,CAAC;QACD,IAAI,aAAa,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrC,OAAO,CAAC,CAAC,CAAA;QACX,CAAC;QAED,4DAA4D;QAC5D,OAAO,CAAC,CAAA;IACV,CAAC,CAAA;AACH,CAAC,CAAA"}